improve of cmpl.
[bush.git] / builtins / shopt.def
blob4dfc969c0c7490f280a4ef87d1d3059f6f1b506b
1 This file is shopt.def, from which is created shopt.c.
2 It implements the Bush `shopt' builtin.
4 Copyright (C) 1994-2020 Free Software Foundation, Inc.
6 This file is part of GNU Bush, the Bourne Again SHell.
8 Bush 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.
13 Bush 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.
18 You should have received a copy of the GNU General Public License
19 along with Bush. If not, see <http://www.gnu.org/licenses/>.
21 $PRODUCES shopt.c
23 $BUILTIN shopt
24 $FUNCTION shopt_builtin
25 $SHORT_DOC shopt [-pqsu] [-o] [optname ...]
26 Set and unset shell options.
28 Change the setting of each shell option OPTNAME. Without any option
29 arguments, list each supplied OPTNAME, or all shell options if no
30 OPTNAMEs are given, with an indication of whether or not each is set.
32 Options:
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
39 Exit Status:
40 Returns success if OPTNAME is enabled; fails if an invalid option is
41 given or OPTNAME is disabled.
42 $END
44 #include <config.h>
46 #if defined (HAVE_UNISTD_H)
47 # ifdef _MINIX
48 # include <sys/types.h>
49 # endif
50 # include <unistd.h>
51 #endif
53 #include <stdio.h>
55 #include "version.h"
57 #include "../src/bushintl.h"
59 #include "../src/shell.h"
60 #include "../src/flags.h"
61 #include "common.h"
62 #include "bushgetopt.h"
64 #if defined (READLINE)
65 # include "../src/input/bushline.h"
66 #endif
68 #if defined (HISTORY)
69 # include "../src/bushhist.h"
70 #endif
72 #define UNSETOPT 0
73 #define SETOPT 1
75 #define OPTFMT "%-15s\t%s\n"
77 extern int allow_null_glob_expansion, fail_glob_expansion, glob_dot_filenames;
78 extern int cdable_vars, mail_warning, source_uses_path;
79 extern int no_exit_on_failed_exec, print_shift_error;
80 extern int check_hashed_filenames, promptvars;
81 extern int cdspelling, expand_aliases;
82 extern int extended_quote;
83 extern int check_window_size;
84 extern int glob_ignore_case, match_ignore_case;
85 extern int hup_on_exit;
86 extern int xpg_echo;
87 extern int gnu_error_format;
88 extern int check_jobs_at_exit;
89 extern int autocd;
90 extern int glob_star;
91 extern int glob_asciirange;
92 extern int lastpipe_opt;
93 extern int inherit_errexit;
94 extern int localvar_inherit;
95 extern int localvar_unset;
97 #if defined (EXTENDED_GLOB)
98 extern int extended_glob;
99 #endif
101 #if defined (READLINE)
102 extern int hist_verify, history_reediting, perform_hostname_completion;
103 extern int no_empty_command_completion;
104 extern int force_fignore;
105 extern int dircomplete_spelling, dircomplete_expand;
106 extern int complete_fullquote;
108 extern int enable_hostname_completion PARAMS((int));
109 #endif
111 #if defined (PROGRAMMABLE_COMPLETION)
112 extern int prog_completion_enabled;
113 extern int progcomp_alias;
114 #endif
116 #if defined (DEBUGGER)
117 extern int debugging_mode;
118 #endif
120 #if defined (ARRAY_VARS)
121 extern int assoc_expand_once;
122 extern int array_expand_once;
123 #endif
125 #if defined (SYSLOG_HISTORY)
126 extern int syslog_history;
127 #endif
129 static void shopt_error PARAMS((char *));
131 static int set_shellopts_after_change PARAMS((char *, int));
132 static int set_compatibility_level PARAMS((char *, int));
134 #if defined (RESTRICTED_SHELL)
135 static int set_restricted_shell PARAMS((char *, int));
136 #endif
138 #if defined (READLINE)
139 static int shopt_enable_hostname_completion PARAMS((char *, int));
140 static int shopt_set_complete_direxpand PARAMS((char *, int));
141 #endif
143 static int shopt_set_debug_mode PARAMS((char *, int));
145 static int shopt_login_shell;
146 static int shopt_compat31;
147 static int shopt_compat32;
148 static int shopt_compat40;
149 static int shopt_compat41;
150 static int shopt_compat42;
151 static int shopt_compat43;
152 static int shopt_compat44;
154 typedef int shopt_set_func_t PARAMS((char *, int));
156 /* If you add a new variable name here, make sure to set the default value
157 appropriately in reset_shopt_options. */
159 static struct {
160 char *name;
161 int *value;
162 shopt_set_func_t *set_func;
163 } shopt_vars[] = {
164 { "autocd", &autocd, (shopt_set_func_t *)NULL },
165 #if defined (ARRAY_VARS)
166 { "assoc_expand_once", &assoc_expand_once, (shopt_set_func_t *)NULL },
167 #endif
168 { "cdable_vars", &cdable_vars, (shopt_set_func_t *)NULL },
169 { "cdspell", &cdspelling, (shopt_set_func_t *)NULL },
170 { "checkhash", &check_hashed_filenames, (shopt_set_func_t *)NULL },
171 #if defined (JOB_CONTROL)
172 { "checkjobs", &check_jobs_at_exit, (shopt_set_func_t *)NULL },
173 #endif
174 { "checkwinsize", &check_window_size, (shopt_set_func_t *)NULL },
175 #if defined (HISTORY)
176 { "cmdhist", &command_oriented_history, (shopt_set_func_t *)NULL },
177 #endif
178 { "compat31", &shopt_compat31, set_compatibility_level },
179 { "compat32", &shopt_compat32, set_compatibility_level },
180 { "compat40", &shopt_compat40, set_compatibility_level },
181 { "compat41", &shopt_compat41, set_compatibility_level },
182 { "compat42", &shopt_compat42, set_compatibility_level },
183 { "compat43", &shopt_compat43, set_compatibility_level },
184 { "compat44", &shopt_compat44, set_compatibility_level },
185 #if defined (READLINE)
186 { "complete_fullquote", &complete_fullquote, (shopt_set_func_t *)NULL},
187 { "direxpand", &dircomplete_expand, shopt_set_complete_direxpand },
188 { "dirspell", &dircomplete_spelling, (shopt_set_func_t *)NULL },
189 #endif
190 { "dotglob", &glob_dot_filenames, (shopt_set_func_t *)NULL },
191 { "execfail", &no_exit_on_failed_exec, (shopt_set_func_t *)NULL },
192 { "expand_aliases", &expand_aliases, (shopt_set_func_t *)NULL },
193 #if defined (DEBUGGER)
194 { "extdebug", &debugging_mode, shopt_set_debug_mode },
195 #endif
196 #if defined (EXTENDED_GLOB)
197 { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
198 #endif
199 { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
200 { "failglob", &fail_glob_expansion, (shopt_set_func_t *)NULL },
201 #if defined (READLINE)
202 { "force_fignore", &force_fignore, (shopt_set_func_t *)NULL },
203 #endif
204 { "globasciiranges", &glob_asciirange, (shopt_set_func_t *)NULL },
205 { "globstar", &glob_star, (shopt_set_func_t *)NULL },
206 { "gnu_errfmt", &gnu_error_format, (shopt_set_func_t *)NULL },
207 #if defined (HISTORY)
208 { "histappend", &force_append_history, (shopt_set_func_t *)NULL },
209 #endif
210 #if defined (READLINE)
211 { "histreedit", &history_reediting, (shopt_set_func_t *)NULL },
212 { "histverify", &hist_verify, (shopt_set_func_t *)NULL },
213 { "hostcomplete", &perform_hostname_completion, shopt_enable_hostname_completion },
214 #endif
215 { "huponexit", &hup_on_exit, (shopt_set_func_t *)NULL },
216 { "inherit_errexit", &inherit_errexit, (shopt_set_func_t *)NULL },
217 { "interactive_comments", &interactive_comments, set_shellopts_after_change },
218 { "lastpipe", &lastpipe_opt, (shopt_set_func_t *)NULL },
219 #if defined (HISTORY)
220 { "lithist", &literal_history, (shopt_set_func_t *)NULL },
221 #endif
222 { "localvar_inherit", &localvar_inherit, (shopt_set_func_t *)NULL },
223 { "localvar_unset", &localvar_unset, (shopt_set_func_t *)NULL },
224 { "login_shell", &shopt_login_shell, set_login_shell },
225 { "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
226 #if defined (READLINE)
227 { "no_empty_cmd_completion", &no_empty_command_completion, (shopt_set_func_t *)NULL },
228 #endif
229 { "nocaseglob", &glob_ignore_case, (shopt_set_func_t *)NULL },
230 { "nocasematch", &match_ignore_case, (shopt_set_func_t *)NULL },
231 { "nullglob", &allow_null_glob_expansion, (shopt_set_func_t *)NULL },
232 #if defined (PROGRAMMABLE_COMPLETION)
233 { "progcomp", &prog_completion_enabled, (shopt_set_func_t *)NULL },
234 # if defined (ALIAS)
235 { "progcomp_alias", &progcomp_alias, (shopt_set_func_t *)NULL },
236 # endif
237 #endif
238 { "promptvars", &promptvars, (shopt_set_func_t *)NULL },
239 #if defined (RESTRICTED_SHELL)
240 { "restricted_shell", &restricted_shell, set_restricted_shell },
241 #endif
242 { "shift_verbose", &print_shift_error, (shopt_set_func_t *)NULL },
243 { "sourcepath", &source_uses_path, (shopt_set_func_t *)NULL },
244 #if defined (SYSLOG_HISTORY) && defined (SYSLOG_SHOPT)
245 { "syslog_history", &syslog_history, (shopt_set_func_t *)NULL },
246 #endif
247 { "xpg_echo", &xpg_echo, (shopt_set_func_t *)NULL },
248 { (char *)0, (int *)0, (shopt_set_func_t *)NULL }
251 #define N_SHOPT_OPTIONS (sizeof (shopt_vars) / sizeof (shopt_vars[0]))
253 #define GET_SHOPT_OPTION_VALUE(i) (*shopt_vars[i].value)
255 static const char * const on = "on";
256 static const char * const off = "off";
258 static int find_shopt PARAMS((char *));
259 static int toggle_shopts PARAMS((int, WORD_LIST *, int));
260 static void print_shopt PARAMS((char *, int, int));
261 static int list_shopts PARAMS((WORD_LIST *, int));
262 static int list_some_shopts PARAMS((int, int));
263 static int list_shopt_o_options PARAMS((WORD_LIST *, int));
264 static int list_some_o_options PARAMS((int, int));
265 static int set_shopt_o_options PARAMS((int, WORD_LIST *, int));
267 #define SFLAG 0x01
268 #define UFLAG 0x02
269 #define QFLAG 0x04
270 #define OFLAG 0x08
271 #define PFLAG 0x10
274 shopt_builtin (list)
275 WORD_LIST *list;
277 int opt, flags, rval;
279 flags = 0;
280 reset_internal_getopt ();
281 while ((opt = internal_getopt (list, "psuoq")) != -1)
283 switch (opt)
285 case 's':
286 flags |= SFLAG;
287 break;
288 case 'u':
289 flags |= UFLAG;
290 break;
291 case 'q':
292 flags |= QFLAG;
293 break;
294 case 'o':
295 flags |= OFLAG;
296 break;
297 case 'p':
298 flags |= PFLAG;
299 break;
300 CASE_HELPOPT;
301 default:
302 builtin_usage ();
303 return (EX_USAGE);
306 list = loptend;
308 if ((flags & (SFLAG|UFLAG)) == (SFLAG|UFLAG))
310 builtin_error (_("cannot set and unset shell options simultaneously"));
311 return (EXECUTION_FAILURE);
314 rval = EXECUTION_SUCCESS;
315 if ((flags & OFLAG) && ((flags & (SFLAG|UFLAG)) == 0)) /* shopt -o */
316 rval = list_shopt_o_options (list, flags);
317 else if (list && (flags & OFLAG)) /* shopt -so args */
318 rval = set_shopt_o_options ((flags & SFLAG) ? FLAG_ON : FLAG_OFF, list, flags & QFLAG);
319 else if (flags & OFLAG) /* shopt -so */
320 rval = list_some_o_options ((flags & SFLAG) ? 1 : 0, flags);
321 else if (list && (flags & (SFLAG|UFLAG))) /* shopt -su args */
322 rval = toggle_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, list, flags & QFLAG);
323 else if ((flags & (SFLAG|UFLAG)) == 0) /* shopt [args] */
324 rval = list_shopts (list, flags);
325 else /* shopt -su */
326 rval = list_some_shopts ((flags & SFLAG) ? SETOPT : UNSETOPT, flags);
327 return (rval);
330 /* Reset the options managed by `shopt' to the values they would have at
331 shell startup. Variables from shopt_vars. */
332 void
333 reset_shopt_options ()
335 autocd = cdable_vars = cdspelling = 0;
336 check_hashed_filenames = CHECKHASH_DEFAULT;
337 check_window_size = CHECKWINSIZE_DEFAULT;
338 allow_null_glob_expansion = glob_dot_filenames = 0;
339 no_exit_on_failed_exec = 0;
340 expand_aliases = 0;
341 extended_quote = 1;
342 fail_glob_expansion = 0;
343 glob_asciirange = GLOBASCII_DEFAULT;
344 glob_star = 0;
345 gnu_error_format = 0;
346 hup_on_exit = 0;
347 inherit_errexit = 0;
348 interactive_comments = 1;
349 lastpipe_opt = 0;
350 localvar_inherit = localvar_unset = 0;
351 mail_warning = 0;
352 glob_ignore_case = match_ignore_case = 0;
353 print_shift_error = 0;
354 source_uses_path = promptvars = 1;
356 #if defined (JOB_CONTROL)
357 check_jobs_at_exit = 0;
358 #endif
360 #if defined (EXTENDED_GLOB)
361 extended_glob = EXTGLOB_DEFAULT;
362 #endif
364 #if defined (ARRAY_VARS)
365 assoc_expand_once = 0;
366 #endif
368 #if defined (HISTORY)
369 literal_history = 0;
370 force_append_history = 0;
371 command_oriented_history = 1;
372 #endif
374 #if defined (SYSLOG_HISTORY)
375 # if defined (SYSLOG_SHOPT)
376 syslog_history = SYSLOG_SHOPT;
377 # else
378 syslog_history = 1;
379 # endif /* SYSLOG_SHOPT */
380 #endif
382 #if defined (READLINE)
383 complete_fullquote = 1;
384 force_fignore = 1;
385 hist_verify = history_reediting = 0;
386 perform_hostname_completion = 1;
387 # if DIRCOMPLETE_EXPAND_DEFAULT
388 dircomplete_expand = 1;
389 # else
390 dircomplete_expand = 0;
391 #endif
392 dircomplete_spelling = 0;
393 no_empty_command_completion = 0;
394 #endif
396 #if defined (PROGRAMMABLE_COMPLETION)
397 prog_completion_enabled = 1;
398 # if defined (ALIAS)
399 progcomp_alias = 0;
400 # endif
401 #endif
403 #if defined (DEFAULT_ECHO_TO_XPG) || defined (STRICT_POSIX)
404 xpg_echo = 1;
405 #else
406 xpg_echo = 0;
407 #endif /* DEFAULT_ECHO_TO_XPG */
409 shopt_login_shell = login_shell;
412 static int
413 find_shopt (name)
414 char *name;
416 int i;
418 for (i = 0; shopt_vars[i].name; i++)
419 if (STREQ (name, shopt_vars[i].name))
420 return i;
421 return -1;
424 static void
425 shopt_error (s)
426 char *s;
428 builtin_error (_("%s: invalid shell option name"), s);
431 static int
432 toggle_shopts (mode, list, quiet)
433 int mode;
434 WORD_LIST *list;
435 int quiet;
437 WORD_LIST *l;
438 int ind, rval;
439 SHELL_VAR *v;
441 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
443 ind = find_shopt (l->word->word);
444 if (ind < 0)
446 shopt_error (l->word->word);
447 rval = EXECUTION_FAILURE;
449 else
451 *shopt_vars[ind].value = mode; /* 1 for set, 0 for unset */
452 if (shopt_vars[ind].set_func)
453 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, mode);
457 /* Don't set $BUSHOPTS here if it hasn't already been initialized */
458 if (v = find_variable ("BUSHOPTS"))
459 set_bushopts ();
460 return (rval);
463 static void
464 print_shopt (name, val, flags)
465 char *name;
466 int val, flags;
468 if (flags & PFLAG)
469 printf ("shopt %s %s\n", val ? "-s" : "-u", name);
470 else
471 printf (OPTFMT, name, val ? on : off);
474 /* List the values of all or any of the `shopt' options. Returns 0 if
475 all were listed or all variables queried were on; 1 otherwise. */
476 static int
477 list_shopts (list, flags)
478 WORD_LIST *list;
479 int flags;
481 WORD_LIST *l;
482 int i, val, rval;
484 if (list == 0)
486 for (i = 0; shopt_vars[i].name; i++)
488 val = *shopt_vars[i].value;
489 if ((flags & QFLAG) == 0)
490 print_shopt (shopt_vars[i].name, val, flags);
492 return (sh_chkwrite (EXECUTION_SUCCESS));
495 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
497 i = find_shopt (l->word->word);
498 if (i < 0)
500 shopt_error (l->word->word);
501 rval = EXECUTION_FAILURE;
502 continue;
504 val = *shopt_vars[i].value;
505 if (val == 0)
506 rval = EXECUTION_FAILURE;
507 if ((flags & QFLAG) == 0)
508 print_shopt (l->word->word, val, flags);
511 return (sh_chkwrite (rval));
514 static int
515 list_some_shopts (mode, flags)
516 int mode, flags;
518 int val, i;
520 for (i = 0; shopt_vars[i].name; i++)
522 val = *shopt_vars[i].value;
523 if (((flags & QFLAG) == 0) && mode == val)
524 print_shopt (shopt_vars[i].name, val, flags);
526 return (sh_chkwrite (EXECUTION_SUCCESS));
529 static int
530 list_shopt_o_options (list, flags)
531 WORD_LIST *list;
532 int flags;
534 WORD_LIST *l;
535 int val, rval;
537 if (list == 0)
539 if ((flags & QFLAG) == 0)
540 list_minus_o_opts (-1, (flags & PFLAG));
541 return (sh_chkwrite (EXECUTION_SUCCESS));
544 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
546 val = minus_o_option_value (l->word->word);
547 if (val == -1)
549 sh_invalidoptname (l->word->word);
550 rval = EXECUTION_FAILURE;
551 continue;
553 if (val == 0)
554 rval = EXECUTION_FAILURE;
555 if ((flags & QFLAG) == 0)
557 if (flags & PFLAG)
558 printf ("set %co %s\n", val ? '-' : '+', l->word->word);
559 else
560 printf (OPTFMT, l->word->word, val ? on : off);
563 return (sh_chkwrite (rval));
566 static int
567 list_some_o_options (mode, flags)
568 int mode, flags;
570 if ((flags & QFLAG) == 0)
571 list_minus_o_opts (mode, (flags & PFLAG));
572 return (sh_chkwrite (EXECUTION_SUCCESS));
575 static int
576 set_shopt_o_options (mode, list, quiet)
577 int mode;
578 WORD_LIST *list;
579 int quiet;
581 WORD_LIST *l;
582 int rval;
584 for (l = list, rval = EXECUTION_SUCCESS; l; l = l->next)
586 if (set_minus_o_option (mode, l->word->word) == EXECUTION_FAILURE)
587 rval = EXECUTION_FAILURE;
589 set_shellopts ();
590 return rval;
593 /* If we set or unset interactive_comments with shopt, make sure the
594 change is reflected in $SHELLOPTS. */
595 static int
596 set_shellopts_after_change (option_name, mode)
597 char *option_name;
598 int mode;
600 set_shellopts ();
601 return (0);
604 static int
605 shopt_set_debug_mode (option_name, mode)
606 char *option_name;
607 int mode;
609 #if defined (DEBUGGER)
610 error_trace_mode = function_trace_mode = debugging_mode;
611 set_shellopts ();
612 if (debugging_mode)
613 init_bush_argv ();
614 #endif
615 return (0);
618 #if defined (READLINE)
619 static int
620 shopt_enable_hostname_completion (option_name, mode)
621 char *option_name;
622 int mode;
624 return (enable_hostname_completion (mode));
626 #endif
628 static int
629 set_compatibility_level (option_name, mode)
630 char *option_name;
631 int mode;
633 int ind;
634 char *rhs;
636 /* If we're setting something, redo some of the work we did above in
637 toggle_shopt(). Unset everything and reset the appropriate option
638 based on OPTION_NAME. */
639 if (mode)
641 shopt_compat31 = shopt_compat32 = 0;
642 shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
643 shopt_compat44 = 0;
644 ind = find_shopt (option_name);
645 *shopt_vars[ind].value = mode;
648 /* Then set shell_compatibility_level based on what remains */
649 if (shopt_compat31)
650 shell_compatibility_level = 31;
651 else if (shopt_compat32)
652 shell_compatibility_level = 32;
653 else if (shopt_compat40)
654 shell_compatibility_level = 40;
655 else if (shopt_compat41)
656 shell_compatibility_level = 41;
657 else if (shopt_compat42)
658 shell_compatibility_level = 42;
659 else if (shopt_compat43)
660 shell_compatibility_level = 43;
661 else if (shopt_compat44)
662 shell_compatibility_level = 44;
663 else
664 shell_compatibility_level = DEFAULT_COMPAT_LEVEL;
666 /* Make sure the current compatibility level is reflected in BUSH_COMPAT */
667 rhs = itos (shell_compatibility_level);
668 bind_variable ("BUSH_COMPAT", rhs, 0);
669 free (rhs);
671 return 0;
674 /* Set and unset the various compatibility options from the value of
675 shell_compatibility_level; used by sv_shcompat */
676 void
677 set_compatibility_opts ()
679 shopt_compat31 = shopt_compat32 = 0;
680 shopt_compat40 = shopt_compat41 = shopt_compat42 = shopt_compat43 = 0;
681 shopt_compat44 = 0;
682 switch (shell_compatibility_level)
684 case DEFAULT_COMPAT_LEVEL:
685 break;
686 case 44:
687 shopt_compat44 = 1; break;
688 case 43:
689 shopt_compat43 = 1; break;
690 case 42:
691 shopt_compat42 = 1; break;
692 case 41:
693 shopt_compat41 = 1; break;
694 case 40:
695 shopt_compat40 = 1; break;
696 case 32:
697 shopt_compat32 = 1; break;
698 case 31:
699 shopt_compat31 = 1; break;
703 #if defined (READLINE)
704 static int
705 shopt_set_complete_direxpand (option_name, mode)
706 char *option_name;
707 int mode;
709 set_directory_hook ();
710 return 0;
712 #endif
714 #if defined (RESTRICTED_SHELL)
715 /* Don't allow the value of restricted_shell to be modified. */
717 static int
718 set_restricted_shell (option_name, mode)
719 char *option_name;
720 int mode;
722 static int save_restricted = -1;
724 if (save_restricted == -1)
725 save_restricted = shell_is_restricted (shell_name);
727 restricted_shell = save_restricted;
728 return (0);
730 #endif /* RESTRICTED_SHELL */
732 /* Not static so shell.c can call it to initialize shopt_login_shell */
734 set_login_shell (option_name, mode)
735 char *option_name;
736 int mode;
738 shopt_login_shell = login_shell != 0;
739 return (0);
742 char **
743 get_shopt_options ()
745 char **ret;
746 int n, i;
748 n = sizeof (shopt_vars) / sizeof (shopt_vars[0]);
749 ret = strvec_create (n + 1);
750 for (i = 0; shopt_vars[i].name; i++)
751 ret[i] = savestring (shopt_vars[i].name);
752 ret[i] = (char *)NULL;
753 return ret;
757 * External interface for other parts of the shell. NAME is a string option;
758 * MODE is 0 if we want to unset an option; 1 if we want to set an option.
759 * REUSABLE is 1 if we want to print output in a form that may be reused.
762 shopt_setopt (name, mode)
763 char *name;
764 int mode;
766 WORD_LIST *wl;
767 int r;
769 wl = add_string_to_list (name, (WORD_LIST *)NULL);
770 r = toggle_shopts (mode, wl, 0);
771 dispose_words (wl);
772 return r;
776 shopt_listopt (name, reusable)
777 char *name;
778 int reusable;
780 int i;
782 if (name == 0)
783 return (list_shopts ((WORD_LIST *)NULL, reusable ? PFLAG : 0));
785 i = find_shopt (name);
786 if (i < 0)
788 shopt_error (name);
789 return (EXECUTION_FAILURE);
792 print_shopt (name, *shopt_vars[i].value, reusable ? PFLAG : 0);
793 return (sh_chkwrite (EXECUTION_SUCCESS));
796 void
797 set_bushopts ()
799 char *value;
800 char tflag[N_SHOPT_OPTIONS];
801 int vsize, i, vptr, *ip, exported;
802 SHELL_VAR *v;
804 for (vsize = i = 0; shopt_vars[i].name; i++)
806 tflag[i] = 0;
807 if (GET_SHOPT_OPTION_VALUE (i))
809 vsize += strlen (shopt_vars[i].name) + 1;
810 tflag[i] = 1;
814 value = (char *)xmalloc (vsize + 1);
816 for (i = vptr = 0; shopt_vars[i].name; i++)
818 if (tflag[i])
820 strcpy (value + vptr, shopt_vars[i].name);
821 vptr += strlen (shopt_vars[i].name);
822 value[vptr++] = ':';
826 if (vptr)
827 vptr--; /* cut off trailing colon */
828 value[vptr] = '\0';
830 v = find_variable ("BUSHOPTS");
832 /* Turn off the read-only attribute so we can bind the new value, and
833 note whether or not the variable was exported. */
834 if (v)
836 VUNSETATTR (v, att_readonly);
837 exported = exported_p (v);
839 else
840 exported = 0;
842 v = bind_variable ("BUSHOPTS", value, 0);
844 /* Turn the read-only attribute back on, and turn off the export attribute
845 if it was set implicitly by mark_modified_vars and SHELLOPTS was not
846 exported before we bound the new value. */
847 VSETATTR (v, att_readonly);
848 if (mark_modified_vars && exported == 0 && exported_p (v))
849 VUNSETATTR (v, att_exported);
851 free (value);
854 void
855 parse_bushopts (value)
856 char *value;
858 char *vname;
859 int vptr, ind;
861 vptr = 0;
862 while (vname = extract_colon_unit (value, &vptr))
864 ind = find_shopt (vname);
865 if (ind >= 0)
867 *shopt_vars[ind].value = 1;
868 if (shopt_vars[ind].set_func)
869 (*shopt_vars[ind].set_func) (shopt_vars[ind].name, 1);
871 free (vname);
875 void
876 initialize_bushopts (no_bushopts)
877 int no_bushopts;
879 char *temp;
880 SHELL_VAR *var;
882 if (no_bushopts == 0)
884 var = find_variable ("BUSHOPTS");
885 /* set up any shell options we may have inherited. */
886 if (var && imported_p (var))
888 temp = (array_p (var) || assoc_p (var)) ? (char *)NULL : savestring (value_cell (var));
889 if (temp)
891 parse_bushopts (temp);
892 free (temp);
897 /* Set up the $BUSHOPTS variable. */
898 set_bushopts ();