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.
 
 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.
 
 
 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
           interactive-comments
                        allow comments to appear in interactive commands
           keyword      same as -k
+#if defined (JOB_CONTROL)
           monitor      same as -m
           monitor      same as -m
+#endif
           noclobber    same as -C
           noexec       same as -n
           noglob       same as -f
           nolog        currently accepted but ignored
           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
           notify       same as -b
+#endif
           nounset      same as -u
           onecmd       same as -t
           physical     same as -P
           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 */
   -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.
       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  },
   { "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  },
   { "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  },
   { "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
 
 $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.
 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
 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.
 
 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;
 {
 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;
 
   char *name;
 
-  unset_function = unset_variable = unset_array = any_failed = 0;
+  unset_function = unset_variable = unset_array = nameref = any_failed = 0;
 
   reset_internal_getopt ();
 
   reset_internal_getopt ();
-  while ((opt = internal_getopt (list, "fv")) != -1)
+  while ((opt = internal_getopt (list, "fnv")) != -1)
     {
       switch (opt)
        {
     {
       switch (opt)
        {
@@ -758,6 +766,9 @@ unset_builtin (list)
        case 'v':
          unset_variable = 1;
          break;
        case 'v':
          unset_variable = 1;
          break;
+       case 'n':
+         nameref = 1;
+         break;
        default:
          builtin_usage ();
          return (EX_USAGE);
        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);
     }
       builtin_error (_("cannot simultaneously unset a function and a variable"));
       return (EXECUTION_FAILURE);
     }
+  else if (unset_function && nameref)
+    nameref = 0;
 
   while (list)
     {
 
   while (list)
     {
@@ -791,6 +804,8 @@ unset_builtin (list)
          unset_array++;
        }
 #endif
          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
 
       /* 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 ();
        }
 
          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 ();
        }
 
        {
          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"),
       /* 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 ();
        }
 
          NEXT_VARIABLE ();
        }
 
@@ -823,7 +851,7 @@ unset_builtin (list)
        {
          if (array_p (var) == 0 && assoc_p (var) == 0)
            {
        {
          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
              NEXT_VARIABLE ();
            }
          else
@@ -835,13 +863,13 @@ unset_builtin (list)
        }
       else
 #endif /* ARRAY_VARS */
        }
       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.'' */
         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
        tem = unbind_func (name);
 
       /* SUSv3, POSIX.1-2001 say:  ``Unsetting a variable or function that