summaryrefslogtreecommitdiff
path: root/builtins/set.def
diff options
context:
space:
mode:
Diffstat (limited to 'builtins/set.def')
-rw-r--r--builtins/set.def642
1 files changed, 428 insertions, 214 deletions
diff --git a/builtins/set.def b/builtins/set.def
index a97168c4..d31e77e8 100644
--- a/builtins/set.def
+++ b/builtins/set.def
@@ -21,62 +21,79 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES set.c
+#include <config.h>
+
+#if defined (HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
#include <stdio.h>
+
+#include "../bashansi.h"
+
#include "../shell.h"
#include "../flags.h"
-
+#include "common.h"
#include "bashgetopt.h"
+#if defined (READLINE)
+# include "../input.h"
+# include "../bashline.h"
+# include <readline/readline.h>
+#endif
+
+#if defined (HISTORY)
+# include "../bashhist.h"
+#endif
+
extern int interactive;
-extern int noclobber, no_brace_expansion, posixly_correct;
+extern int noclobber, posixly_correct, ignoreeof, eof_encountered_limit;
#if defined (READLINE)
extern int rl_editing_mode, no_line_editing;
#endif /* READLINE */
-#define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
-
$BUILTIN set
$FUNCTION set_builtin
-$SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
+$SHORT_DOC set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
-a Mark variables which are modified or created for export.
-b Notify of job termination immediately.
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
- -h Locate and remember function commands as functions are
- defined. Function commands are normally looked up when
- the function is executed.
+ -h Remember the location of commands as they are looked up.
-i Force the shell to be an "interactive" one. Interactive shells
always read `~/.bashrc' on startup.
- -k All keyword arguments are placed in the environment for a
+ -k All assignment arguments are placed in the environment for a
command, not just those that precede the command name.
-m Job control is enabled.
-n Read commands but do not execute them.
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
- braceexpand the shell will perform brace expansion
+ braceexpand same as -B
#if defined (READLINE)
emacs use an emacs-style line editing interface
#endif /* READLINE */
errexit same as -e
+ hashall same as -h
#if defined (BANG_HISTORY)
histexpand same as -H
#endif /* BANG_HISTORY */
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
+ keyword same as -k
monitor same as -m
- noclobber disallow redirection to existing files
+ noclobber same as -C
noexec same as -n
noglob same as -f
- nohash same as -d
notify save as -b
nounset same as -u
- physical same as -P
- posix change the behavior of bash where the default
- operation differs from the 1003.2 standard to
- match the standard
- privileged same as -p
+ onecmd same as -t
+ physical same as -P
+ posix change the behavior of bash where the default
+ operation differs from the 1003.2 standard to
+ match the standard
+ privileged same as -p
verbose same as -v
#if defined (READLINE)
vi use a vi-style line editing interface
@@ -85,15 +102,14 @@ $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
-p Turned on whenever the real and effective user ids do not match.
Disables processing of the $ENV file and importing of shell
functions. Turning this option off causes the effective uid and
- gid to be set to the real uid and gid.
+ gid to be set to the real uid and gid.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
- -l Save and restore the binding of the NAME in a FOR command.
- -d Disable the hashing of commands that are looked up for execution.
- Normally, commands are remembered in a hash table, and once
- found, do not have to be looked up again.
+#if defined (BRACE_EXPANSION)
+ -B the shell will perform brace expansion
+#endif /* BRACE_EXPANSION */
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
by default.
@@ -110,6 +126,20 @@ parameters and are assigned, in order, to $1, $2, .. $n. If no
ARGs are given, all shell variables are printed.
$END
+static int set_ignoreeof ();
+
+#if defined (READLINE)
+static int set_edit_mode ();
+static int get_edit_mode ();
+#endif
+
+#if defined (HISTORY)
+static int bash_set_history ();
+#endif
+
+static char *on = "on";
+static char *off = "off";
+
/* An a-list used to match long options for set -o to the corresponding
option letter. */
struct {
@@ -117,201 +147,354 @@ struct {
int letter;
} o_options[] = {
{ "allexport", 'a' },
+#if defined (BRACE_EXPANSION)
+ { "braceexpand",'B' },
+#endif
{ "errexit", 'e' },
+ { "hashall", 'h' },
#if defined (BANG_HISTORY)
{ "histexpand", 'H' },
#endif /* BANG_HISTORY */
+ { "keyword", 'k' },
{ "monitor", 'm' },
+ { "noclobber", 'C' },
{ "noexec", 'n' },
{ "noglob", 'f' },
- { "nohash", 'd' },
#if defined (JOB_CONTROL)
{ "notify", 'b' },
#endif /* JOB_CONTROL */
- {"nounset", 'u' },
- {"physical", 'P' },
- {"privileged", 'p' },
- {"verbose", 'v' },
- {"xtrace", 'x' },
- {(char *)NULL, 0},
+ { "nounset", 'u' },
+ { "onecmd", 't' },
+ { "physical", 'P' },
+ { "privileged", 'p' },
+ { "verbose", 'v' },
+ { "xtrace", 'x' },
+ {(char *)NULL, 0 },
+};
+
+struct {
+ char *name;
+ int *variable;
+ Function *set_func;
+ Function *get_func;
+} binary_o_options[] = {
+#if defined (HISTORY)
+ { "history", &remember_on_history, bash_set_history, (Function *)NULL },
+#endif
+ { "ignoreeof", &ignoreeof, set_ignoreeof, (Function *)NULL },
+ { "interactive-comments", &interactive_comments, (Function *)NULL, (Function *)NULL },
+ { "posix", &posixly_correct, (Function *)NULL, (Function *)NULL },
+#if defined (READLINE)
+ { "emacs", (int *)NULL, set_edit_mode, get_edit_mode },
+ { "vi", (int *)NULL, set_edit_mode, get_edit_mode },
+#endif
+ { (char *)NULL, (int *)NULL }
};
+#define GET_BINARY_O_OPTION_VALUE(i, name) \
+ ((binary_o_options[i].get_func) ? (*binary_o_options[i].get_func) (name) \
+ : (*binary_o_options[i].variable))
+
+#define SET_BINARY_O_OPTION_VALUE(i, onoff, name) \
+ ((binary_o_options[i].set_func) ? (*binary_o_options[i].set_func) (onoff, name) \
+ : (*binary_o_options[i].variable = (onoff == FLAG_ON)))
+
+int
+minus_o_option_value (name)
+ char *name;
+{
+ register int i;
+ int *on_or_off;
+
+ for (i = 0; o_options[i].name; i++)
+ {
+ if (STREQ (name, o_options[i].name))
+ {
+ on_or_off = find_flag (o_options[i].letter);
+ return ((on_or_off == FLAG_UNKNOWN) ? -1 : *on_or_off);
+ }
+ }
+ for (i = 0; binary_o_options[i].name; i++)
+ {
+ if (STREQ (name, binary_o_options[i].name))
+ return (GET_BINARY_O_OPTION_VALUE (i, name));
+ }
+
+ return (-1);
+}
+
#define MINUS_O_FORMAT "%-15s\t%s\n"
void
-list_minus_o_opts ()
+list_minus_o_opts (mode)
+ int mode;
{
register int i;
- char *on = "on", *off = "off";
+ int *on_or_off, value;
- printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
- printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
+ for (value = i = 0; o_options[i].name; i++)
+ {
+ on_or_off = find_flag (o_options[i].letter);
+ if (on_or_off == FLAG_UNKNOWN)
+ on_or_off = &value;
+ if (mode == -1 || mode == *on_or_off)
+ printf (MINUS_O_FORMAT, o_options[i].name, *on_or_off ? on : off);
+ }
+ for (i = 0; binary_o_options[i].name; i++)
+ {
+ value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
+ if (mode == -1 || mode == value)
+ printf (MINUS_O_FORMAT, binary_o_options[i].name, value ? on : off);
+ }
+}
- if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
- printf (MINUS_O_FORMAT, "ignoreeof", on);
- else
- printf (MINUS_O_FORMAT, "ignoreeof", off);
+static void
+minus_o_option_commands ()
+{
+ register int i;
+ int *on_or_off, value;
- printf (MINUS_O_FORMAT, "interactive-comments",
- interactive_comments ? on : off);
+ for (value = i = 0; o_options[i].name; i++)
+ {
+ on_or_off = find_flag (o_options[i].letter);
+ if (on_or_off == FLAG_UNKNOWN)
+ on_or_off = &value;
+ printf ("set %co %s\n", *on_or_off ? '-' : '+', o_options[i].name);
+ }
+ for (i = 0; binary_o_options[i].name; i++)
+ {
+ value = GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name);
+ printf ("set %co %s\n", value ? '-' : '+', binary_o_options[i].name);
+ }
+}
- printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
+static int
+set_ignoreeof (on_or_off, option_name)
+ int on_or_off;
+ char *option_name;
+{
+ ignoreeof = on_or_off == FLAG_ON;
+ unbind_variable ("ignoreeof");
+ if (ignoreeof)
+ bind_variable ("IGNOREEOF", "10");
+ else
+ unbind_variable ("IGNOREEOF");
+ sv_ignoreeof ("IGNOREEOF");
+ return 0;
+}
#if defined (READLINE)
- if (no_line_editing)
+/* Magic. This code `knows' how readline handles rl_editing_mode. */
+static int
+set_edit_mode (on_or_off, option_name)
+ int on_or_off;
+ char *option_name;
+{
+ int isemacs;
+
+ if (on_or_off == FLAG_ON)
{
- printf (MINUS_O_FORMAT, "emacs", off);
- printf (MINUS_O_FORMAT, "vi", off);
+ rl_variable_bind ("editing-mode", option_name);
+
+ if (interactive)
+ with_input_from_stdin ();
+ no_line_editing = 0;
}
else
{
- /* Magic. This code `knows' how readline handles rl_editing_mode. */
- printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
- printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
+ isemacs = rl_editing_mode == 1;
+ if ((isemacs && *option_name == 'e') || (!isemacs && *option_name == 'v'))
+ {
+ if (interactive)
+ with_input_from_stream (stdin, "stdin");
+ no_line_editing = 1;
+ }
}
+ return 1-no_line_editing;
+}
+
+static int
+get_edit_mode (name)
+ char *name;
+{
+ return (*name == 'e' ? no_line_editing == 0 && rl_editing_mode == 1
+ : no_line_editing == 0 && rl_editing_mode == 0);
+}
#endif /* READLINE */
- for (i = 0; o_options[i].name; i++)
+#if defined (HISTORY)
+static int
+bash_set_history (on_or_off, option_name)
+ int on_or_off;
+ char *option_name;
+{
+ if (on_or_off == FLAG_ON)
{
- int *on_or_off, zero = 0;
-
- on_or_off = find_flag (o_options[i].letter);
- if (on_or_off == FLAG_UNKNOWN)
- on_or_off = &zero;
- printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
+ bash_history_enable ();
+ if (history_lines_this_session == 0)
+ load_history ();
}
+ else
+ bash_history_disable ();
+ return (1 - remember_on_history);
}
+#endif
+int
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
- int option_char = -1;
+ int option_char;
+ VFunction *set_func;
+ register int i;
- if (STREQ (option_name, "braceexpand"))
+ for (i = 0; binary_o_options[i].name; i++)
{
- if (on_or_off == FLAG_ON)
- no_brace_expansion = 0;
- else
- no_brace_expansion = 1;
+ if (STREQ (option_name, binary_o_options[i].name))
+ {
+ SET_BINARY_O_OPTION_VALUE (i, on_or_off, option_name);
+ return (EXECUTION_SUCCESS);
+ }
}
- else if (STREQ (option_name, "noclobber"))
+
+ for (i = 0, option_char = -1, set_func = 0; o_options[i].name; i++)
{
- if (on_or_off == FLAG_ON)
- bind_variable ("noclobber", "");
- else
- unbind_variable ("noclobber");
- stupidly_hack_special_variables ("noclobber");
+ if (STREQ (option_name, o_options[i].name))
+ {
+ option_char = o_options[i].letter;
+ break;
+ }
}
- else if (STREQ (option_name, "ignoreeof"))
+ if (option_char == -1)
{
- unbind_variable ("ignoreeof");
- unbind_variable ("IGNOREEOF");
- if (on_or_off == FLAG_ON)
- bind_variable ("IGNOREEOF", "10");
- stupidly_hack_special_variables ("IGNOREEOF");
+ builtin_error ("%s: unknown option name", option_name);
+ return (EXECUTION_FAILURE);
}
-
-#if defined (READLINE)
- else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
+ if (change_flag (option_char, on_or_off) == FLAG_ERROR)
{
- if (on_or_off == FLAG_ON)
- {
- rl_variable_bind ("editing-mode", option_name);
+ bad_option (option_name);
+ return (EXECUTION_FAILURE);
+ }
+ return (EXECUTION_SUCCESS);
+}
- if (interactive)
- with_input_from_stdin ();
- no_line_editing = 0;
- }
- else
- {
- int isemacs = (rl_editing_mode == 1);
- if ((isemacs && STREQ (option_name, "emacs")) ||
- (!isemacs && STREQ (option_name, "vi")))
- {
- if (interactive)
- with_input_from_stream (stdin, "stdin");
- no_line_editing = 1;
- }
- else
- builtin_error ("not in %s editing mode", option_name);
- }
+static void
+print_all_shell_variables ()
+{
+ SHELL_VAR **vars;
+
+ vars = all_shell_variables ();
+ if (vars)
+ {
+ print_var_list (vars);
+ free (vars);
}
-#endif /* READLINE */
- else if (STREQ (option_name, "interactive-comments"))
- interactive_comments = (on_or_off == FLAG_ON);
- else if (STREQ (option_name, "posix"))
+
+ vars = all_shell_functions ();
+ if (vars)
{
- posixly_correct = (on_or_off == FLAG_ON);
- unbind_variable ("POSIXLY_CORRECT");
- unbind_variable ("POSIX_PEDANTIC");
- if (on_or_off == FLAG_ON)
- {
- bind_variable ("POSIXLY_CORRECT", "");
- stupidly_hack_special_variables ("POSIXLY_CORRECT");
- }
+ print_var_list (vars);
+ free (vars);
}
- else
+}
+
+void
+set_shellopts ()
+{
+ char *value;
+ int vsize, i, vptr, *ip;
+ SHELL_VAR *v;
+
+ for (vsize = i = 0; o_options[i].name; i++)
{
- register int i;
- for (i = 0; o_options[i].name; i++)
- {
- if (STREQ (option_name, o_options[i].name))
- {
- option_char = o_options[i].letter;
- break;
- }
- }
- if (option_char == -1)
- {
- builtin_error ("%s: unknown option name", option_name);
- return (EXECUTION_FAILURE);
- }
- if (change_flag (option_char, on_or_off) == FLAG_ERROR)
+ ip = find_flag (o_options[i].letter);
+ if (ip && *ip)
+ vsize += strlen (o_options[i].name) + 1;
+ }
+ for (i = 0; binary_o_options[i].name; i++)
+ if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
+ vsize += strlen (binary_o_options[i].name) + 1;
+
+ value = xmalloc (vsize + 1);
+
+ for (i = vptr = 0; o_options[i].name; i++)
+ {
+ ip = find_flag (o_options[i].letter);
+ if (ip && *ip)
{
- bad_option (option_name);
- return (EXECUTION_FAILURE);
+ strcpy (value + vptr, o_options[i].name);
+ vptr += strlen (o_options[i].name);
+ value[vptr++] = ':';
}
}
- return (EXECUTION_SUCCESS);
+ for (i = 0; binary_o_options[i].name; i++)
+ if (GET_BINARY_O_OPTION_VALUE (i, binary_o_options[i].name))
+ {
+ strcpy (value + vptr, binary_o_options[i].name);
+ vptr += strlen (binary_o_options[i].name);
+ value[vptr++] = ':';
+ }
+ value[--vptr] = '\0'; /* cut off trailing colon */
+
+ v = find_variable ("SHELLOPTS");
+ if (v)
+ v->attributes &= ~att_readonly;
+ v = bind_variable ("SHELLOPTS", value);
+ v->attributes |= att_readonly;
+
+ free (value);
+}
+
+void
+parse_shellopts (value)
+ char *value;
+{
+ char *vname;
+ int vptr;
+
+ vptr = 0;
+ while (vname = extract_colon_unit (value, &vptr))
+ {
+ set_minus_o_option (FLAG_ON, vname);
+ free (vname);
+ }
+}
+
+void
+initialize_shell_options ()
+{
+ char *temp;
+
+ /* set up any shell options we may have inherited. */
+ if (temp = get_string_value ("SHELLOPTS"))
+ parse_shellopts (temp);
+
+ /* Set up the $SHELLOPTS variable. */
+ set_shellopts ();
}
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
+int
set_builtin (list)
WORD_LIST *list;
{
- int on_or_off, flag_name, force_assignment = 0;
+ int on_or_off, flag_name, force_assignment, opts_changed;
+ WORD_LIST *l;
+ register char *arg;
- if (!list)
+ if (list == 0)
{
- SHELL_VAR **vars;
-
- vars = all_shell_variables ();
- if (vars)
- {
- print_var_list (vars);
- free (vars);
- }
-
- vars = all_shell_functions ();
- if (vars)
- {
- print_var_list (vars);
- free (vars);
- }
-
+ print_all_shell_variables ();
return (EXECUTION_SUCCESS);
}
/* Check validity of flag arguments. */
if (*list->word->word == '-' || *list->word->word == '+')
{
- register char *arg;
- WORD_LIST *save_list = list;
-
- while (list && (arg = list->word->word))
+ for (l = list; l && (arg = l->word->word); l = l->next)
{
char c;
@@ -319,8 +502,7 @@ set_builtin (list)
break;
/* `-' or `--' signifies end of flag arguments. */
- if (arg[0] == '-' &&
- (!arg[1] || (arg[1] == '-' && !arg[2])))
+ if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
break;
while (c = *++arg)
@@ -331,30 +513,28 @@ set_builtin (list)
s[0] = c; s[1] = '\0';
bad_option (s);
if (c == '?')
- printf ("usage: %s\n", USAGE_STRING);
+ builtin_usage ();
return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
}
- list = list->next;
}
- list = save_list;
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
- while (list)
+ for (force_assignment = opts_changed = 0; list; )
{
- char *string = list->word->word;
+ arg = list->word->word;
/* If the argument is `--' or `-' then signal the end of the list
and remember the remaining arguments. */
- if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
+ if (arg[0] == '-' && (!arg[1] || (arg[1] == '-' && !arg[2])))
{
list = list->next;
/* `set --' unsets the positional parameters. */
- if (string[1] == '-')
+ if (arg[1] == '-')
force_assignment = 1;
/* Until told differently, the old shell behaviour of
@@ -364,20 +544,19 @@ set_builtin (list)
{
change_flag ('x', '+');
change_flag ('v', '+');
+ opts_changed = 1;
}
break;
}
- if ((on_or_off = *string) &&
- (on_or_off == '-' || on_or_off == '+'))
+ if ((on_or_off = *arg) && (on_or_off == '-' || on_or_off == '+'))
{
- int i = 1;
- while (flag_name = string[i++])
+ while (flag_name = *++arg)
{
if (flag_name == '?')
{
- printf ("usage: %s\n", USAGE_STRING);
+ builtin_usage ();
return (EXECUTION_SUCCESS);
}
else if (flag_name == 'o') /* -+o option-name */
@@ -387,36 +566,47 @@ set_builtin (list)
opt = list->next;
- if (!opt)
+ if (opt == 0)
{
- list_minus_o_opts ();
+ if (on_or_off == '-')
+ list_minus_o_opts (-1);
+ else
+ minus_o_option_commands ();
continue;
}
option_name = opt->word->word;
- if (!option_name || !*option_name || (*option_name == '-'))
+ if (option_name == 0 || *option_name == '\0' ||
+ *option_name == '-' || *option_name == '+')
{
- list_minus_o_opts ();
+ if (on_or_off == '-')
+ list_minus_o_opts (-1);
+ else
+ minus_o_option_commands ();
continue;
}
list = list->next; /* Skip over option name. */
+ opts_changed = 1;
if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
- return (EXECUTION_FAILURE);
- }
- else
- {
- if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
- char opt[3];
- opt[0] = on_or_off;
- opt[1] = flag_name;
- opt[2] = '\0';
- bad_option (opt);
+ set_shellopts ();
return (EXECUTION_FAILURE);
}
}
+ else if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
+ {
+ char opt[3];
+ opt[0] = on_or_off;
+ opt[1] = flag_name;
+ opt[2] = '\0';
+ bad_option (opt);
+ builtin_usage ();
+ set_shellopts ();
+ return (EXECUTION_FAILURE);
+ }
+ opts_changed = 1;
}
}
else
@@ -429,6 +619,9 @@ set_builtin (list)
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
+ /* Set up new value of $SHELLOPTS */
+ if (opts_changed)
+ set_shellopts ();
return (EXECUTION_SUCCESS);
}
@@ -443,13 +636,17 @@ function. Some variables (such as PATH and IFS) cannot be unset; also
see readonly.
$END
+#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
+
+int
unset_builtin (list)
WORD_LIST *list;
{
- int unset_function = 0, unset_variable = 0, opt;
- int any_failed = 0;
+ int unset_function, unset_variable, unset_array, opt, any_failed;
char *name;
+ unset_function = unset_variable = unset_array = any_failed = 0;
+
reset_internal_getopt ();
while ((opt = internal_getopt (list, "fv")) != -1)
{
@@ -462,7 +659,8 @@ unset_builtin (list)
unset_variable = 1;
break;
default:
- return (EXECUTION_FAILURE);
+ builtin_usage ();
+ return (EX_USAGE);
}
}
@@ -476,53 +674,69 @@ unset_builtin (list)
while (list)
{
+ SHELL_VAR *var;
+ int tem;
+#if defined (ARRAY_VARS)
+ char *t;
+#endif
+
name = list->word->word;
- if (!unset_function &&
- find_name_in_list (name, non_unsettable_vars) > -1)
+#if defined (ARRAY_VARS)
+ if (!unset_function && valid_array_reference (name))
{
- builtin_error ("%s: cannot unset", name);
- any_failed++;
+ t = strchr (name, '[');
+ *t++ = '\0';
+ unset_array++;
}
- else
+#endif
+
+ var = unset_function ? find_function (name) : find_variable (name);
+
+ if (var && !unset_function && non_unsettable_p (var))
{
- SHELL_VAR *var;
- int tem;
+ builtin_error ("%s: cannot unset", name);
+ NEXT_VARIABLE ();
+ }
- var = unset_function ? find_function (name) : find_variable (name);
+ /* Posix.2 says that unsetting readonly variables is an error. */
+ if (var && readonly_p (var))
+ {
+ builtin_error ("%s: cannot unset: readonly %s",
+ name, unset_function ? "function" : "variable");
+ NEXT_VARIABLE ();
+ }
- /* Posix.2 says that unsetting readonly variables is an error. */
- if (var && readonly_p (var))
+ /* Unless the -f option is supplied, the name refers to a variable. */
+#if defined (ARRAY_VARS)
+ if (var && unset_array)
+ {
+ if (array_p (var) == 0)
{
- builtin_error ("%s: cannot unset: readonly %s",
- name, unset_function ? "function" : "variable");
- any_failed++;
- list = list->next;
- continue;
+ builtin_error ("%s: not an array variable", name);
+ NEXT_VARIABLE ();
}
-
- /* Unless the -f option is supplied, the name refers to a
- variable. */
- tem = makunbound
- (name, unset_function ? shell_functions : shell_variables);
-
- /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
- is specified, the name refers to a variable; if a variable by
- that name does not exist, a function by that name, if any,
- shall be unset.'' */
- if ((tem == -1) && !unset_function && !unset_variable)
- tem = makunbound (name, shell_functions);
-
- if (tem == -1)
- any_failed++;
- else if (!unset_function)
- stupidly_hack_special_variables (name);
+ else
+ tem = unbind_array_element (var, t);
}
+ else
+#endif /* ARRAY_VARS */
+ tem = makunbound (name, unset_function ? shell_functions : shell_variables);
+
+ /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
+ is specified, the name refers to a variable; if a variable by
+ that name does not exist, a function by that name, if any,
+ shall be unset.'' */
+ if (tem == -1 && !unset_function && !unset_variable)
+ tem = makunbound (name, shell_functions);
+
+ if (tem == -1)
+ any_failed++;
+ else if (!unset_function)
+ stupidly_hack_special_variables (name);
+
list = list->next;
}
- if (any_failed)
- return (EXECUTION_FAILURE);
- else
- return (EXECUTION_SUCCESS);
+ return (any_failed ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}