This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
-Copyright (C) 1987-2009 Free Software Foundation, Inc.
+Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
interactive-comments
allow comments to appear in interactive commands
keyword same as -k
+#if defined (JOB_CONTROL)
monitor same as -m
+#endif
noclobber same as -C
noexec same as -n
noglob same as -f
nolog currently accepted but ignored
+#if defined (JOB_CONTROL)
notify same as -b
+#endif
nounset same as -u
onecmd same as -t
physical same as -P
-H Enable ! style history substitution. This flag is on
by default when the shell is interactive.
#endif /* BANG_HISTORY */
- -P If set, do not follow symbolic links when executing commands
+ -P If set, do not resolve symbolic links when executing commands
such as cd which change the current directory.
-T If set, the DEBUG trap is inherited by shell functions.
-- Assign any remaining arguments to the positional parameters.
{ "ignoreeof", '\0', &ignoreeof, set_ignoreeof, (setopt_get_func_t *)NULL },
{ "interactive-comments", '\0', &interactive_comments, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "keyword", 'k', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+#if defined (JOB_CONTROL)
{ "monitor", 'm', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
+#endif
{ "noclobber", 'C', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noexec", 'n', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
{ "noglob", 'f', (int *)NULL, (setopt_set_func_t *)NULL, (setopt_get_func_t *)NULL },
$BUILTIN unset
$FUNCTION unset_builtin
-$SHORT_DOC unset [-f] [-v] [name ...]
+$SHORT_DOC unset [-f] [-v] [-n] [name ...]
Unset values and attributes of shell variables and functions.
For each NAME, remove the corresponding variable or function.
Options:
-f treat each NAME as a shell function
-v treat each NAME as a shell variable
+ -n treat each NAME as a name reference and unset the variable itself
+ rather than the variable it references
Without options, unset first tries to unset a variable, and if that fails,
tries to unset a function.
unset_builtin (list)
WORD_LIST *list;
{
- int unset_function, unset_variable, unset_array, opt, any_failed;
+ int unset_function, unset_variable, unset_array, opt, nameref, any_failed;
char *name;
- unset_function = unset_variable = unset_array = any_failed = 0;
+ unset_function = unset_variable = unset_array = nameref = any_failed = 0;
reset_internal_getopt ();
- while ((opt = internal_getopt (list, "fv")) != -1)
+ while ((opt = internal_getopt (list, "fnv")) != -1)
{
switch (opt)
{
case 'v':
unset_variable = 1;
break;
+ case 'n':
+ nameref = 1;
+ break;
default:
builtin_usage ();
return (EX_USAGE);
builtin_error (_("cannot simultaneously unset a function and a variable"));
return (EXECUTION_FAILURE);
}
+ else if (unset_function && nameref)
+ nameref = 0;
while (list)
{
unset_array++;
}
#endif
+ /* Get error checking out of the way first. The low-level functions
+ just perform the unset, relying on the caller to verify. */
/* Bash allows functions with names which are not valid identifiers
to be created when not in posix mode, so check only when in posix
NEXT_VARIABLE ();
}
- var = unset_function ? find_function (name) : find_variable (name);
+ /* Only search for functions here if -f supplied. */
+ var = unset_function ? find_function (name)
+ : (nameref ? find_variable_last_nameref (name) : find_variable (name));
- if (var && !unset_function && non_unsettable_p (var))
+ /* Some variables (but not functions yet) cannot be unset, period. */
+ if (var && unset_function == 0 && non_unsettable_p (var))
{
builtin_error (_("%s: cannot unset"), name);
NEXT_VARIABLE ();
}
+ /* Posix.2 says try variables first, then functions. If we would
+ find a function after unsuccessfully searching for a variable,
+ note that we're acting on a function now as if -f were
+ supplied. The readonly check below takes care of it. */
+ if (var == 0 && unset_variable == 0 && unset_function == 0)
+ {
+ if (var = find_function (name))
+ unset_function = 1;
+ }
+
/* 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");
+ var->name, unset_function ? "function" : "variable");
NEXT_VARIABLE ();
}
{
if (array_p (var) == 0 && assoc_p (var) == 0)
{
- builtin_error (_("%s: not an array variable"), name);
+ builtin_error (_("%s: not an array variable"), var->name);
NEXT_VARIABLE ();
}
else
}
else
#endif /* ARRAY_VARS */
- tem = unset_function ? unbind_func (name) : unbind_variable (name);
+ tem = unset_function ? unbind_func (name) : (nameref ? unbind_nameref (name) : unbind_variable (name));
- /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
+ /* This is what Posix.2 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)
+ if (tem == -1 && unset_function == 0 && unset_variable == 0)
tem = unbind_func (name);
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that