Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / builtins / set.def
index 6e69eb6..c4a7001 100644 (file)
@@ -1,7 +1,7 @@
 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.
 
@@ -96,12 +96,16 @@ Options:
           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
@@ -135,7 +139,7 @@ Options:
   -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.
@@ -205,7 +209,9 @@ const struct {
   { "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  },
@@ -718,7 +724,7 @@ set_builtin (list)
 
 $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.
@@ -726,6 +732,8 @@ 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.
@@ -742,13 +750,13 @@ int
 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)
        {
@@ -758,6 +766,9 @@ unset_builtin (list)
        case 'v':
          unset_variable = 1;
          break;
+       case 'n':
+         nameref = 1;
+         break;
        default:
          builtin_usage ();
          return (EX_USAGE);
@@ -771,6 +782,8 @@ unset_builtin (list)
       builtin_error (_("cannot simultaneously unset a function and a variable"));
       return (EXECUTION_FAILURE);
     }
+  else if (unset_function && nameref)
+    nameref = 0;
 
   while (list)
     {
@@ -791,6 +804,8 @@ unset_builtin (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
@@ -801,19 +816,32 @@ unset_builtin (list)
          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 ();
        }
 
@@ -823,7 +851,7 @@ unset_builtin (list)
        {
          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
@@ -835,13 +863,13 @@ unset_builtin (list)
        }
       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