]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
20120705 commit rest of changes for nameref variables
authorChet Ramey <chet.ramey@case.edu>
Tue, 10 Jul 2012 13:38:15 +0000 (09:38 -0400)
committerChet Ramey <chet.ramey@case.edu>
Tue, 10 Jul 2012 13:38:15 +0000 (09:38 -0400)
builtins/set.def
doc/bash.1
doc/bashref.texi
variables.c

index b69e63236fb68f9a2f5a1aa0298cd825c92c000f..421105be50d096aa67082c987e3c8959c3f29693 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-2011 Free Software Foundation, Inc.
+Copyright (C) 1987-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
@@ -724,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.
@@ -732,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.
@@ -748,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)
        {
@@ -764,6 +766,9 @@ unset_builtin (list)
        case 'v':
          unset_variable = 1;
          break;
+       case 'n':
+         nameref = 1;
+         break;
        default:
          builtin_usage ();
          return (EX_USAGE);
@@ -777,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)
     {
@@ -810,7 +817,8 @@ unset_builtin (list)
        }
 
       /* Only search for functions here if -f supplied. */
-      var = unset_function ? find_function (name) : find_variable (name);
+      var = unset_function ? find_function (name)
+                          : (nameref ? find_variable_last_nameref (name) : find_variable (name));
 
       /* Some variables (but not functions yet) cannot be unset, period. */
       if (var && unset_function == 0 && non_unsettable_p (var))
@@ -837,7 +845,6 @@ unset_builtin (list)
          NEXT_VARIABLE ();
        }
 
-      
       /* Unless the -f option is supplied, the name refers to a variable. */
 #if defined (ARRAY_VARS)
       if (var && unset_array)
index 3cdcc07a98d6c8176506e58389b5b4436cd6b7c1..8af3319ff5a2d6b4e4b0f6559fed9a4ebbb36f6d 100644 (file)
@@ -5,12 +5,12 @@
 .\"    Case Western Reserve University
 .\"    chet@po.cwru.edu
 .\"
-.\"    Last Change: Sun May 27 20:28:33 EDT 2012
+.\"    Last Change: Thu Jul  5 11:10:13 EDT 2012
 .\"
 .\" bash_builtins, strip all but Built-Ins section
 .if \n(zZ=1 .ig zZ
 .if \n(zY=1 .ig zY
-.TH BASH 1 "2012 May 27" "GNU Bash 4.2"
+.TH BASH 1 "2012 July 5" "GNU Bash 4.2"
 .\"
 .\" There's some problem with having a `@'
 .\" in a tagged paragraph with the BSD man macros.
@@ -1235,6 +1235,39 @@ appended to the array beginning at one greater than the array's maximum index
 associative array.
 When applied to a string-valued variable, \fIvalue\fP is expanded and
 appended to the variable's value.
+.PP
+A variable can be assigned the \fInameref\fP attribute using the
+\fB\-n\fP option to the \fBdeclare\fP or \fBlocal\fP builtin commands
+(see the descriptions of \fBdeclare\fP and \fBlocal\fP below)
+to create a \fInameref\fP, or a reference to another variable.
+This allows variables to be manipulated indirectly.
+Whenever the nameref variable is referenced or assigned to, the operation
+is actually performed on the variable specified by the nameref variable's
+value.
+A nameref is commonly used within shell functions to refer to a variable
+whose name is passed as an argument to the function.
+For instance, if a variable name is passed to a shell function as its first
+argument, running
+.sp .5
+.RS
+.if t \f(CWdeclare -n ref=$1\fP
+.if n declare -n ref=$1
+.RE
+.sp .5
+inside the function creates a nameref variable \fBref\fP whose value is
+the variable name passed as the first argument.
+References and assignments to \fBref\fP are treated as references and
+assignments to the variable whose name was passed as \fB$1\fP.
+If the control variable in a \fBfor\fP loop has the nameref attribute,
+the list of words can be a list of shell variables, and a name reference
+will be established for each word in the list, in turn, when the loop is
+executed.
+Array variables cannot be given the \fB\-n\fP attribute.
+However, nameref variables can reference array variables and subscripted
+array variables.
+Namerefs can be unset using the \fB\-n\fP option to the \fBunset\fP builtin.
+Otherwise, if \fBunset\fP is executed with the name of a nameref variable
+as an argument, the variable referenced by the nameref variable will be unset.
 .SS Positional Parameters
 .PP
 A
@@ -7279,10 +7312,10 @@ is greater than the number of enclosing loops, the last enclosing loop
 (the ``top-level'' loop) is resumed.
 The return value is 0 unless \fIn\fP is not greater than or equal to 1.
 .TP
-\fBdeclare\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+\fBdeclare\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
 .PD 0
 .TP
-\fBtypeset\fP [\fB\-aAfFgilrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
+\fBtypeset\fP [\fB\-aAfFgilnrtux\fP] [\fB\-p\fP] [\fIname\fP[=\fIvalue\fP] ...]
 .PD
 Declare variables and/or give them attributes.
 If no \fIname\fPs are given then display the values of variables.
@@ -7346,6 +7379,15 @@ When the variable is assigned a value, all upper-case characters are
 converted to lower-case.
 The upper-case attribute is disabled.
 .TP
+.B \-n
+Give each \fIname\fP the \fInameref\fP attribute, making
+it a name reference to another variable.
+That other variable is defined by the value of \fIname\fP.
+All references and assignments to \fIname\fP, except for changing the
+\fB\-n\fP attribute itself, are performed on the variable referenced by
+\fIname\fP's value.
+The \fB\-n\fP attribute cannot be applied to array variables.
+.TP
 .B \-r
 Make \fIname\fPs readonly.  These names cannot then be assigned values
 by subsequent assignment statements or unset.
@@ -9868,7 +9910,7 @@ value is true unless a supplied
 .I name
 is not a defined alias.
 .TP
-\fBunset\fP [\-\fBfv\fP] [\fIname\fP ...]
+\fBunset\fP [\-\fBfv\fP] [\-\fBn\fP] [\fIname\fP ...]
 For each
 .IR name ,
 remove the corresponding variable or function.
@@ -9884,6 +9926,12 @@ is specified, each
 .I name
 refers to a shell function, and the function definition
 is removed.
+If the
+.B \-n
+option is supplied, and \fIname\fP is a variable with the \fInameref\fP
+attribute, \fIname\fP will be unset rather than the variable it
+references.
+\fB\-n\fP has no effect if the \fB\-f\fP option is supplied.
 If no options are supplied, each \fIname\fP refers to a variable; if
 there is no variable by that name, any function with that name is
 unset.
index 8e3fbe65e810f5e11cf7f93dc77692bde8a7cd51..5eee0936e407c01def3d4fd00743d636ee4cb027 100644 (file)
@@ -1473,6 +1473,39 @@ in an associative array.
 When applied to a string-valued variable, @var{value} is expanded and
 appended to the variable's value.
 
+A variable can be assigned the @var{nameref} attribute using the
+@option{-n} option to the \fBdeclare\fP or \fBlocal\fP builtin commands
+(@pxref{Bash Builtins})
+to create a @var{nameref}, or a reference to another variable.
+This allows variables to be manipulated indirectly.
+Whenever the nameref variable is referenced or assigned to, the operation
+is actually performed on the variable specified by the nameref variable's
+value.
+A nameref is commonly used within shell functions to refer to a variable
+whose name is passed as an argument to the function.
+For instance, if a variable name is passed to a shell function as its first
+argument, running
+@example
+declare -n ref=$1
+@end example
+@noindent
+inside the function creates a nameref variable @var{ref} whose value is
+the variable name passed as the first argument.
+References and assignments to @var{ref} are treated as references and
+assignments to the variable whose name was passed as @code{$1}.
+
+If the control variable in a @code{for} loop has the nameref attribute,
+the list of words can be a list of shell variables, and a name reference
+will be established for each word in the list, in turn, when the loop is
+executed.
+Array variables cannot be given the @option{-n} attribute.
+However, nameref variables can reference array variables and subscripted
+array variables.
+Namerefs can be unset using the @option{-n} option to the @code{unset} builtin
+(@pxref{Bourne Shell Builtins}).
+Otherwise, if @code{unset} is executed with the name of a nameref variable
+as an argument, the variable referenced by the nameref variable will be unset.
+
 @node Positional Parameters
 @subsection Positional Parameters
 @cindex parameters, positional
@@ -3616,7 +3649,7 @@ results in permissions of @code{755}.
 @item unset
 @btindex unset
 @example
-unset [-fv] [@var{name}]
+unset [-fnv] [@var{name}]
 @end example
 
 Remove each variable or function @var{name}.
@@ -3624,6 +3657,10 @@ If the @option{-v} option is given, each
 @var{name} refers to a shell variable and that variable is remvoved.
 If the @option{-f} option is given, the @var{name}s refer to shell
 functions, and the function definition is removed.
+If the @option{-n} option is supplied, and @var{name} is a variable with
+the @var{nameref} attribute, @var{name} will be unset rather than the
+variable it references.
+@option{-n} has no effect if the @option{-f} option is supplied.
 If no options are supplied, each @var{name} refers to a variable; if
 there is no variable by that name, any function with that name is
 unset.
@@ -3812,7 +3849,7 @@ zero if @var{command} is found, and non-zero if not.
 @item declare
 @btindex declare
 @example
-declare [-aAfFgilrtux] [-p] [@var{name}[=@var{value}] @dots{}]
+declare [-aAfFgilnrtux] [-p] [@var{name}[=@var{value}] @dots{}]
 @end example
 
 Declare variables and give them attributes.  If no @var{name}s
@@ -3864,6 +3901,15 @@ When the variable is assigned a value, all upper-case characters are
 converted to lower-case.
 The upper-case attribute is disabled.
 
+@item -n
+Give each @var{name} the @var{nameref} attribute, making
+it a name reference to another variable.
+That other variable is defined by the value of @var{name}.
+All references and assignments to @var{name}, except for changing the
+@option{-n} attribute itself, are performed on the variable referenced by
+@var{name}'s value.
+The @option{-n} attribute cannot be applied to array variables.
+
 @item -r
 Make @var{name}s readonly.  These names cannot then be assigned values
 by subsequent assignment statements or unset.
@@ -4303,7 +4349,7 @@ if any are not found.
 @item typeset
 @btindex typeset
 @example
-typeset [-afFgrxilrtux] [-p] [@var{name}[=@var{value}] @dots{}]
+typeset [-afFgrxilnrtux] [-p] [@var{name}[=@var{value}] @dots{}]
 @end example
 
 The @code{typeset} command is supplied for compatibility with the Korn
index cd50db4ef4eb12ad6f15571c1d9077d40319be8b..b3350d9a8c3e0c9bd863875047f5d0dc204728b5 100644 (file)
@@ -2958,7 +2958,7 @@ dispose_variable (var)
 }
 
 /* Unset the shell variable referenced by NAME.  Unsetting a nameref variable
-   unsets both the variable and the variable it resolves to. */
+   unsets the variable it resolves to but leaves the nameref alone. */
 int
 unbind_variable (name)
      const char *name;
@@ -2969,13 +2969,23 @@ unbind_variable (name)
   v = var_lookup (name, shell_variables);
   nv = (v && nameref_p (v)) ? find_variable_nameref (v) : (SHELL_VAR *)NULL;
 
-  r = nv ? makunbound (nv->name, shell_variables) : 0;
-  if (r == 0)
-    r = makunbound (name, shell_variables);
-    
+  r = nv ? makunbound (nv->name, shell_variables) : makunbound (name, shell_variables);
   return r;
 }
 
+/* Unbind NAME, where NAME is assumed to be a nameref variable */
+int
+unbind_nameref (name)
+     const char *name;
+{
+  SHELL_VAR *v;
+
+  v = var_lookup (name, shell_variables);
+  if (v && nameref_p (v))
+    return makunbound (name, shell_variables);
+  return 0;
+}
+
 /* Unset the shell function named NAME. */
 int
 unbind_func (name)
@@ -3073,6 +3083,8 @@ makunbound (name, vc)
       else if (assoc_p (old_var))
        assoc_dispose (assoc_cell (old_var));
 #endif
+      else if (nameref_p (old_var))
+       FREE (nameref_cell (old_var));
       else
        FREE (value_cell (old_var));
       /* Reset the attributes.  Preserve the export attribute if the variable