]> git.ipfire.org Git - thirdparty/bash.git/blame - builtins/shopt.def
Bash-4.3 patch 43
[thirdparty/bash.git] / builtins / shopt.def
CommitLineData
ccc6cda3
JA
1This file is shopt.def, from which is created shopt.c.
2It implements the Bash `shopt' builtin.
3
ac50fbac 4Copyright (C) 1994-2012 Free Software Foundation, Inc.
ccc6cda3
JA
5
6This file is part of GNU Bash, the Bourne Again SHell.
7
3185942a
JA
8Bash 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.
ccc6cda3 12
3185942a
JA
13Bash 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.
ccc6cda3 17
3185942a
JA
18You should have received a copy of the GNU General Public License
19along with Bash. If not, see <http://www.gnu.org/licenses/>.
ccc6cda3
JA
20
21$PRODUCES shopt.c
22
23$BUILTIN shopt
ccc6cda3 24$FUNCTION shopt_builtin
3185942a
JA
25$SHORT_DOC shopt [-pqsu] [-o] [optname ...]
26Set and unset shell options.
27
28Change the setting of each shell option OPTNAME. Without any option
29arguments, list all shell options with an indication of whether or not each
30is set.
31
32Options:
33 -o restrict OPTNAMEs to those defined for use with `set -o'
34 -p print each shell option with an indication of its status
35 -q suppress output
36 -s enable (set) each OPTNAME
37 -u disable (unset) each OPTNAME
38
39Exit Status:
40Returns success if OPTNAME is enabled; fails if an invalid option is
41given or OPTNAME is disabled.
ccc6cda3
JA
42$END
43
44#include <config.h>
45
46#if defined (HAVE_UNISTD_H)
cce855bc
JA
47# ifdef _MINIX
48# include <sys/types.h>
49# endif
ccc6cda3
JA
50# include <unistd.h>
51#endif
52
53#include <stdio.h>
54
3185942a
JA
55#include "version.h"
56
b80f6443
JA
57#include "../bashintl.h"
58
ccc6cda3
JA
59#include "../shell.h"
60#include "../flags.h"
61#include "common.h"
62#include "bashgetopt.h"
63
16b2d7f4
CR
64#if defined (READLINE)
65# include "../bashline.h"
66#endif
67
3185942a
JA
68#if defined (HISTORY)
69# include "../bashhist.h"
70#endif
71
ccc6cda3
JA
72#define UNSETOPT 0
73#define SETOPT 1
74
75#define OPTFMT "%-15s\t%s\n"
76
b80f6443 77extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
ccc6cda3
JA
78extern int cdable_vars, mail_warning, source_uses_path;
79extern int no_exit_on_failed_exec, print_shift_error;
7117c2d2 80extern int check_hashed_filenames, promptvars;
ccc6cda3 81extern int cdspelling, expand_aliases;
b80f6443 82extern int extended_quote;
ccc6cda3 83extern int check_window_size;
95732b49 84extern int glob_ignore_case, match_ignore_case;
cce855bc 85extern int hup_on_exit;
bb70624e 86extern int xpg_echo;
b80f6443 87extern int gnu_error_format;
3185942a
JA
88extern int check_jobs_at_exit;
89extern int autocd;
90extern int glob_star;
ac50fbac 91extern int glob_asciirange;
495aee44 92extern int lastpipe_opt;
cce855bc
JA
93
94#if defined (EXTENDED_GLOB)
95extern int extended_glob;
96#endif
ccc6cda3 97
ccc6cda3 98#if defined (READLINE)
d166f048 99extern int hist_verify, history_reediting, perform_hostname_completion;
bb70624e 100extern int no_empty_command_completion;
b80f6443 101extern int force_fignore;
16b2d7f4 102extern int dircomplete_spelling, dircomplete_expand;
ac50fbac 103extern int complete_fullquote;
3185942a 104
f73dda09 105extern int enable_hostname_completion __P((int));
ccc6cda3
JA
106#endif
107
bb70624e
JA
108#if defined (PROGRAMMABLE_COMPLETION)
109extern int prog_completion_enabled;
110#endif
111
b72432fd 112#if defined (RESTRICTED_SHELL)
b72432fd
JA
113extern char *shell_name;
114#endif
115
b80f6443
JA
116#if defined (DEBUGGER)
117extern int debugging_mode;
118#endif
119
7117c2d2
JA
120static void shopt_error __P((char *));
121
0001803f
CR
122static int set_shellopts_after_change __P((char *, int));
123static int shopt_enable_hostname_completion __P((char *, int));
124static int set_compatibility_level __P((char *, int));
f1be666c 125
b72432fd 126#if defined (RESTRICTED_SHELL)
0001803f 127static int set_restricted_shell __P((char *, int));
b72432fd
JA
128#endif
129
16b2d7f4
CR
130#if defined (READLINE)
131static int shopt_set_complete_direxpand __P((char *, int));
132#endif
133
f73dda09 134static int shopt_login_shell;
f1be666c 135static int shopt_compat31;
3185942a 136static int shopt_compat32;
0001803f 137static int shopt_compat40;
495aee44 138static int shopt_compat41;
ac50fbac 139static int shopt_compat42;
f73dda09 140
0001803f 141typedef int shopt_set_func_t __P((char *, int));
f73dda09 142
ccc6cda3
JA
143static struct {
144 char *name;
145 int *value;
f73dda09 146 shopt_set_func_t *set_func;
ccc6cda3 147} shopt_vars[] = {
3185942a 148 { "autocd", &autocd, (shopt_set_func_t *)NULL },
f73dda09
JA
149 { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
150 { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
151 { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
3185942a
JA
152#if defined (JOB_CONTROL)
153 { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
154#endif
f73dda09 155 { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
ccc6cda3 156#if defined (HISTORY)
f73dda09 157 { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
ccc6cda3 158#endif
f1be666c 159 { "compat31", &shopt_compat31, set_compatibility_level },
3185942a 160 { "compat32", &shopt_compat32, set_compatibility_level },
0001803f 161 { "compat40", &shopt_compat40, set_compatibility_level },
495aee44 162 { "compat41", &shopt_compat41, set_compatibility_level },
ac50fbac 163 { "compat42", &shopt_compat41, set_compatibility_level },
3185942a 164#if defined (READLINE)
ac50fbac 165 { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
16b2d7f4 166 { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
3185942a
JA
167 { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
168#endif
f73dda09
JA
169 { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
170 { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
171 { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
b80f6443
JA
172#if defined (DEBUGGER)
173 { "extdebug", &debugging_mode, (shopt_set_func_t *)NULL },
174#endif
cce855bc 175#if defined (EXTENDED_GLOB)
f73dda09 176 { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
cce855bc 177#endif
b80f6443
JA
178 { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
179 { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
ccc6cda3 180#if defined (READLINE)
b80f6443 181 { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
ccc6cda3 182#endif
3185942a 183 { "globstar", &glob_star, (shopt_set_func_t *)NULL },
ac50fbac 184 { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
95732b49 185 { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
ccc6cda3 186#if defined (HISTORY)
f73dda09 187 { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
ccc6cda3
JA
188#endif
189#if defined (READLINE)
95732b49 190 { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
f73dda09 191 { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
0001803f 192 { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
ccc6cda3 193#endif
f73dda09 194 { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
b80f6443 195 { "interactive_comments", &interactive_comments, set_shellopts_after_change },
495aee44 196 { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
ccc6cda3 197#if defined (HISTORY)
f73dda09 198 { "lithist", &literal_history, (shopt_set_func_t *)NULL },
ccc6cda3 199#endif
f73dda09
JA
200 { "login_shell", &shopt_login_shell, set_login_shell },
201 { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
bb70624e 202#if defined (READLINE)
f73dda09 203 { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
bb70624e 204#endif
f73dda09 205 { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
95732b49 206 { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
f73dda09 207 { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
bb70624e 208#if defined (PROGRAMMABLE_COMPLETION)
f73dda09 209 { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
bb70624e 210#endif
f73dda09 211 { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
b72432fd
JA
212#if defined (RESTRICTED_SHELL)
213 { "restricted_shell", &restricted_shell, set_restricted_shell },
214#endif
f73dda09
JA
215 { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
216 { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
217 { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
218 { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
ccc6cda3
JA
219};
220
0001803f
CR
221#define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
222
223#define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
224
3185942a
JA
225static const char * const on = "on";
226static const char * const off = "off";
ccc6cda3 227
f73dda09
JA
228static int find_shopt __P((char *));
229static int toggle_shopts __P((int, WORD_LIST *, int));
230static void print_shopt __P((char *, int, int));
231static int list_shopts __P((WORD_LIST *, int));
232static int list_some_shopts __P((int, int));
233static int list_shopt_o_options __P((WORD_LIST *, int));
234static int list_some_o_options __P((int, int));
235static int set_shopt_o_options __P((int, WORD_LIST *, int));
ccc6cda3
JA
236
237#define SFLAG 0x01
238#define UFLAG 0x02
239#define QFLAG 0x04
240#define OFLAG 0x08
241#define PFLAG 0x10
242
243int
244shopt_builtin (list)
245 WORD_LIST *list;
246{
247 int opt, flags, rval;
248
249 flags = 0;
250 reset_internal_getopt ();
251 while ((opt = internal_getopt (list, "psuoq")) != -1)
252 {
253 switch (opt)
254 {
255 case 's':
256 flags |= SFLAG;
257 break;
258 case 'u':
259 flags |= UFLAG;
260 break;
261 case 'q':
262 flags |= QFLAG;
263 break;
264 case 'o':
265 flags |= OFLAG;
266 break;
267 case 'p':
268 flags |= PFLAG;
269 break;
270 default:
271 builtin_usage ();
272 return (EX_USAGE);
273 }
274 }
275 list = loptend;
276
277 if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
278 {
b80f6443 279 builtin_error (_("cannot set and unset shell options simultaneously"));
ccc6cda3
JA
280 return (EXECUTION_FAILURE);
281 }
282
283 rval = EXECUTION_SUCCESS;
284 if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
cce855bc 285 rval = list_shopt_o_options (list, flags);
ccc6cda3
JA
286 else if (list && (flags & OFLAG)) /* shopt -so args */
287 rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
288 else if (flags & OFLAG) /* shopt -so */
cce855bc 289 rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
ccc6cda3
JA
290 else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
291 rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
292 else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
cce855bc 293 rval = list_shopts (list, flags);
ccc6cda3 294 else /* shopt -su */
cce855bc 295 rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
ccc6cda3
JA
296 return (rval);
297}
298
d166f048
JA
299/* Reset the options managed by `shopt' to the values they would have at
300 shell startup. */
301void
302reset_shopt_options ()
303{
304 allow_null_glob_expansion = glob_dot_filenames = 0;
305 cdable_vars = mail_warning = 0;
306 no_exit_on_failed_exec = print_shift_error = 0;
ac50fbac 307 check_hashed_filenames = cdspelling = expand_aliases = 0;
d166f048
JA
308
309 source_uses_path = promptvars = 1;
310
ac50fbac
CR
311 check_window_size = CHECKWINSIZE_DEFAULT;
312
cce855bc
JA
313#if defined (EXTENDED_GLOB)
314 extended_glob = 0;
315#endif
316
d166f048
JA
317#if defined (HISTORY)
318 literal_history = force_append_history = 0;
319 command_oriented_history = 1;
320#endif
321
322#if defined (READLINE)
323 hist_verify = history_reediting = 0;
324 perform_hostname_completion = 1;
325#endif
f73dda09
JA
326
327 shopt_login_shell = login_shell;
d166f048
JA
328}
329
ccc6cda3
JA
330static int
331find_shopt (name)
332 char *name;
333{
334 int i;
335
336 for (i = 0; shopt_vars[i].name; i++)
337 if (STREQ (name, shopt_vars[i].name))
338 return i;
339 return -1;
340}
341
7117c2d2
JA
342static void
343shopt_error (s)
344 char *s;
345{
b80f6443 346 builtin_error (_("%s: invalid shell option name"), s);
7117c2d2 347}
ccc6cda3
JA
348
349static int
350toggle_shopts (mode, list, quiet)
351 int mode;
352 WORD_LIST *list;
353 int quiet;
354{
355 WORD_LIST *l;
356 int ind, rval;
357
358 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
359 {
360 ind = find_shopt (l->word->word);
361 if (ind < 0)
362 {
7117c2d2 363 shopt_error (l->word->word);
ccc6cda3
JA
364 rval = EXECUTION_FAILURE;
365 }
366 else
367 {
368 *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
369 if (shopt_vars[ind].set_func)
0001803f 370 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
ccc6cda3
JA
371 }
372 }
0001803f
CR
373
374 set_bashopts ();
ccc6cda3
JA
375 return (rval);
376}
377
b72432fd 378static void
cce855bc
JA
379print_shopt (name, val, flags)
380 char *name;
381 int val, flags;
382{
383 if (flags & PFLAG)
384 printf ("shopt %s %s\n", val ? "-s" : "-u", name);
385 else
386 printf (OPTFMT, name, val ? on : off);
387}
388
ccc6cda3
JA
389/* List the values of all or any of the `shopt' options. Returns 0 if
390 all were listed or all variables queried were on; 1 otherwise. */
391static int
cce855bc 392list_shopts (list, flags)
ccc6cda3 393 WORD_LIST *list;
cce855bc 394 int flags;
ccc6cda3
JA
395{
396 WORD_LIST *l;
397 int i, val, rval;
398
399 if (list == 0)
400 {
401 for (i = 0; shopt_vars[i].name; i++)
402 {
403 val = *shopt_vars[i].value;
cce855bc
JA
404 if ((flags & QFLAG) == 0)
405 print_shopt (shopt_vars[i].name, val, flags);
ccc6cda3 406 }
3185942a 407 return (sh_chkwrite (EXECUTION_SUCCESS));
ccc6cda3
JA
408 }
409
410 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
411 {
412 i = find_shopt (l->word->word);
413 if (i < 0)
414 {
7117c2d2 415 shopt_error (l->word->word);
ccc6cda3
JA
416 rval = EXECUTION_FAILURE;
417 continue;
418 }
419 val = *shopt_vars[i].value;
420 if (val == 0)
421 rval = EXECUTION_FAILURE;
cce855bc 422 if ((flags & QFLAG) == 0)
28ef6c31 423 print_shopt (l->word->word, val, flags);
ccc6cda3 424 }
28ef6c31 425
3185942a 426 return (sh_chkwrite (rval));
ccc6cda3
JA
427}
428
429static int
cce855bc
JA
430list_some_shopts (mode, flags)
431 int mode, flags;
ccc6cda3
JA
432{
433 int val, i;
434
435 for (i = 0; shopt_vars[i].name; i++)
436 {
437 val = *shopt_vars[i].value;
cce855bc
JA
438 if (((flags & QFLAG) == 0) && mode == val)
439 print_shopt (shopt_vars[i].name, val, flags);
ccc6cda3 440 }
3185942a 441 return (sh_chkwrite (EXECUTION_SUCCESS));
ccc6cda3
JA
442}
443
444static int
cce855bc 445list_shopt_o_options (list, flags)
ccc6cda3 446 WORD_LIST *list;
cce855bc 447 int flags;
ccc6cda3
JA
448{
449 WORD_LIST *l;
450 int val, rval;
451
452 if (list == 0)
453 {
cce855bc
JA
454 if ((flags & QFLAG) == 0)
455 list_minus_o_opts (-1, (flags & PFLAG));
3185942a 456 return (sh_chkwrite (EXECUTION_SUCCESS));
ccc6cda3
JA
457 }
458
459 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
460 {
461 val = minus_o_option_value (l->word->word);
462 if (val == -1)
463 {
7117c2d2 464 sh_invalidoptname (l->word->word);
ccc6cda3
JA
465 rval = EXECUTION_FAILURE;
466 continue;
467 }
468 if (val == 0)
469 rval = EXECUTION_FAILURE;
cce855bc
JA
470 if ((flags & QFLAG) == 0)
471 {
472 if (flags & PFLAG)
473 printf ("set %co %s\n", val ? '-' : '+', l->word->word);
474 else
475 printf (OPTFMT, l->word->word, val ? on : off);
476 }
ccc6cda3 477 }
3185942a 478 return (sh_chkwrite (rval));
ccc6cda3
JA
479}
480
481static int
cce855bc
JA
482list_some_o_options (mode, flags)
483 int mode, flags;
ccc6cda3 484{
cce855bc
JA
485 if ((flags & QFLAG) == 0)
486 list_minus_o_opts (mode, (flags & PFLAG));
3185942a 487 return (sh_chkwrite (EXECUTION_SUCCESS));
ccc6cda3
JA
488}
489
490static int
491set_shopt_o_options (mode, list, quiet)
492 int mode;
493 WORD_LIST *list;
494 int quiet;
495{
496 WORD_LIST *l;
497 int rval;
498
499 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
500 {
501 if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
502 rval = EXECUTION_FAILURE;
503 }
504 set_shellopts ();
505 return rval;
506}
507
508/* If we set or unset interactive_comments with shopt, make sure the
509 change is reflected in $SHELLOPTS. */
510static int
0001803f
CR
511set_shellopts_after_change (option_name, mode)
512 char *option_name;
ccc6cda3
JA
513 int mode;
514{
515 set_shellopts ();
516 return (0);
517}
b72432fd 518
f1be666c 519static int
0001803f
CR
520shopt_enable_hostname_completion (option_name, mode)
521 char *option_name;
522 int mode;
523{
524 return (enable_hostname_completion (mode));
525}
526
527static int
528set_compatibility_level (option_name, mode)
529 char *option_name;
f1be666c
JA
530 int mode;
531{
ac50fbac 532 int ind;
0001803f 533
ac50fbac
CR
534 /* If we're setting something, redo some of the work we did above in
535 toggle_shopt(). Unset everything and reset the appropriate option
536 based on OPTION_NAME. */
537 if (mode)
538 {
539 shopt_compat31 = shopt_compat32 = 0;
540 shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
541 ind = find_shopt (option_name);
542 *shopt_vars[ind].value = mode;
543 }
0001803f
CR
544
545 /* Then set shell_compatibility_level based on what remains */
f1be666c
JA
546 if (shopt_compat31)
547 shell_compatibility_level = 31;
3185942a 548 else if (shopt_compat32)
f1be666c 549 shell_compatibility_level = 32;
0001803f
CR
550 else if (shopt_compat40)
551 shell_compatibility_level = 40;
ac50fbac
CR
552 else if (shopt_compat41)
553 shell_compatibility_level = 41;
554 else if (shopt_compat42)
555 shell_compatibility_level = 42;
3185942a
JA
556 else
557 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
ac50fbac 558
f1be666c
JA
559 return 0;
560}
561
ac50fbac
CR
562/* Set and unset the various compatibility options from the value of
563 shell_compatibility_level; used by sv_shcompat */
564void
565set_compatibility_opts ()
566{
567 shopt_compat31 = shopt_compat32 = shopt_compat40 = shopt_compat41 = shopt_compat42 = 0;
568 switch (shell_compatibility_level)
569 {
570 case DEFAULT_COMPAT_LEVEL:
571 break;
572 case 42:
573 shopt_compat42 = 1; break;
574 case 41:
575 shopt_compat41 = 1; break;
576 case 40:
577 shopt_compat40 = 1; break;
578 case 32:
579 shopt_compat32 = 1; break;
580 case 31:
581 shopt_compat31 = 1; break;
582 }
583}
584
16b2d7f4
CR
585#if defined (READLINE)
586static int
587shopt_set_complete_direxpand (option_name, mode)
588 char *option_name;
589 int mode;
590{
591 set_directory_hook ();
592 return 0;
593}
594#endif
595
b72432fd
JA
596#if defined (RESTRICTED_SHELL)
597/* Don't allow the value of restricted_shell to be modified. */
598
599static int
0001803f
CR
600set_restricted_shell (option_name, mode)
601 char *option_name;
b72432fd
JA
602 int mode;
603{
604 static int save_restricted = -1;
605
606 if (save_restricted == -1)
607 save_restricted = shell_is_restricted (shell_name);
608
609 restricted_shell = save_restricted;
610 return (0);
611}
612#endif /* RESTRICTED_SHELL */
bb70624e 613
f73dda09
JA
614/* Not static so shell.c can call it to initialize shopt_login_shell */
615int
0001803f
CR
616set_login_shell (option_name, mode)
617 char *option_name;
f73dda09
JA
618 int mode;
619{
620 shopt_login_shell = login_shell != 0;
621 return (0);
622}
623
bb70624e
JA
624char **
625get_shopt_options ()
626{
627 char **ret;
628 int n, i;
629
630 n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
7117c2d2 631 ret = strvec_create (n + 1);
bb70624e
JA
632 for (i = 0; shopt_vars[i].name; i++)
633 ret[i] = savestring (shopt_vars[i].name);
634 ret[i] = (char *)NULL;
635 return ret;
636}
f73dda09
JA
637
638/*
639 * External interface for other parts of the shell. NAME is a string option;
640 * MODE is 0 if we want to unset an option; 1 if we want to set an option.
641 * REUSABLE is 1 if we want to print output in a form that may be reused.
642 */
643int
644shopt_setopt (name, mode)
645 char *name;
646 int mode;
647{
648 WORD_LIST *wl;
649 int r;
650
651 wl = add_string_to_list (name, (WORD_LIST *)NULL);
652 r = toggle_shopts (mode, wl, 0);
653 dispose_words (wl);
654 return r;
655}
656
657int
658shopt_listopt (name, reusable)
659 char *name;
660 int reusable;
661{
662 int i;
663
664 if (name == 0)
665 return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
666
667 i = find_shopt (name);
668 if (i < 0)
669 {
7117c2d2 670 shopt_error (name);
f73dda09
JA
671 return (EXECUTION_FAILURE);
672 }
673
674 print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
3185942a 675 return (sh_chkwrite (EXECUTION_SUCCESS));
f73dda09 676}
0001803f
CR
677
678void
679set_bashopts ()
680{
681 char *value;
682 char tflag[N_SHOPT_OPTIONS];
683 int vsize, i, vptr, *ip, exported;
684 SHELL_VAR *v;
685
686 for (vsize = i = 0; shopt_vars[i].name; i++)
687 {
688 tflag[i] = 0;
689 if (GET_SHOPT_OPTION_VALUE (i))
690 {
691 vsize += strlen (shopt_vars[i].name) + 1;
692 tflag[i] = 1;
693 }
694 }
695
696 value = (char *)xmalloc (vsize + 1);
697
698 for (i = vptr = 0; shopt_vars[i].name; i++)
699 {
700 if (tflag[i])
701 {
702 strcpy (value + vptr, shopt_vars[i].name);
703 vptr += strlen (shopt_vars[i].name);
704 value[vptr++] = ':';
705 }
706 }
707
708 if (vptr)
709 vptr--; /* cut off trailing colon */
710 value[vptr] = '\0';
711
712 v = find_variable ("BASHOPTS");
713
714 /* Turn off the read-only attribute so we can bind the new value, and
715 note whether or not the variable was exported. */
716 if (v)
717 {
718 VUNSETATTR (v, att_readonly);
719 exported = exported_p (v);
720 }
721 else
722 exported = 0;
723
724 v = bind_variable ("BASHOPTS", value, 0);
725
726 /* Turn the read-only attribute back on, and turn off the export attribute
727 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
728 exported before we bound the new value. */
729 VSETATTR (v, att_readonly);
730 if (mark_modified_vars && exported == 0 && exported_p (v))
731 VUNSETATTR (v, att_exported);
732
733 free (value);
734}
735
736void
737parse_bashopts (value)
738 char *value;
739{
740 char *vname;
741 int vptr, ind;
742
743 vptr = 0;
744 while (vname = extract_colon_unit (value, &vptr))
745 {
746 ind = find_shopt (vname);
747 if (ind >= 0)
748 *shopt_vars[ind].value = 1;
749 free (vname);
750 }
751}
752
753void
754initialize_bashopts (no_bashopts)
755 int no_bashopts;
756{
757 char *temp;
758 SHELL_VAR *var;
759
760 if (no_bashopts == 0)
761 {
762 var = find_variable ("BASHOPTS");
763 /* set up any shell options we may have inherited. */
764 if (var && imported_p (var))
765 {
766 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
767 if (temp)
768 {
769 parse_bashopts (temp);
770 free (temp);
771 }
772 }
773 }
774
775 /* Set up the $BASHOPTS variable. */
776 set_bashopts ();
777}