Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / builtins / setattr.def
index 28102bc..3be3189 100644 (file)
@@ -1,23 +1,22 @@
 This file is setattr.def, from which is created setattr.c.
 It implements the builtins "export" and "readonly", in Bash.
 
-Copyright (C) 1987-2004 Free Software Foundation, Inc.
+Copyright (C) 1987-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Bash, the Bourne Again SHell.
 
-Bash is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
-version.
+Bash is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
-Bash is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
+Bash is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License along
-with Bash; see the file COPYING.  If not, write to the Free Software
-Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
+You should have received a copy of the GNU General Public License
+along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 
 $PRODUCES setattr.c
 
@@ -52,14 +51,21 @@ extern int declare_builtin __P((WORD_LIST *));
 
 $BUILTIN export
 $FUNCTION export_builtin
-$SHORT_DOC export [-nf] [name[=value] ...] or export -p
-NAMEs are marked for automatic export to the environment of
-subsequently executed commands.  If the -f option is given,
-the NAMEs refer to functions.  If no NAMEs are given, or if `-p'
-is given, a list of all names that are exported in this shell is
-printed.  An argument of `-n' says to remove the export property
-from subsequent NAMEs.  An argument of `--' disables further option
-processing.
+$SHORT_DOC export [-fn] [name[=value] ...] or export -p
+Set export attribute for shell variables.
+
+Marks each NAME for automatic export to the environment of subsequently
+executed commands.  If VALUE is supplied, assign VALUE before exporting.
+
+Options:
+  -f   refer to shell functions
+  -n   remove the export property from each NAME
+  -p   display a list of all exported variables and functions
+
+An argument of `--' disables further option processing.
+
+Exit Status:
+Returns success unless an invalid option is given or NAME is invalid.
 $END
 
 /* For each variable name in LIST, make that variable appear in the
@@ -76,14 +82,24 @@ export_builtin (list)
 
 $BUILTIN readonly
 $FUNCTION readonly_builtin
-$SHORT_DOC readonly [-af] [name[=value] ...] or readonly -p
-The given NAMEs are marked readonly and the values of these NAMEs may
-not be changed by subsequent assignment.  If the -f option is given,
-then functions corresponding to the NAMEs are so marked.  If no
-arguments are given, or if `-p' is given, a list of all readonly names
-is printed.  The `-a' option means to treat each NAME as
-an array variable.  An argument of `--' disables further option
-processing.
+$SHORT_DOC readonly [-aAf] [name[=value] ...] or readonly -p
+Mark shell variables as unchangeable.
+
+Mark each NAME as read-only; the values of these NAMEs may not be
+changed by subsequent assignment.  If VALUE is supplied, assign VALUE
+before marking as read-only.
+
+Options:
+  -a   refer to indexed array variables
+  -A   refer to associative array variables
+  -f   refer to shell functions
+  -p   display a list of all readonly variables or functions, depending on
+        whether or not the -f option is given
+
+An argument of `--' disables further option processing.
+
+Exit Status:
+Returns success unless an invalid option is given or NAME is invalid.
 $END
 
 /* For each variable name in LIST, make that variable readonly.  Given an
@@ -96,7 +112,7 @@ readonly_builtin (list)
 }
 
 #if defined (ARRAY_VARS)
-#  define ATTROPTS     "afnp"
+#  define ATTROPTS     "aAfnp"
 #else
 #  define ATTROPTS     "fnp"
 #endif
@@ -110,7 +126,8 @@ set_or_show_attributes (list, attribute, nodefs)
      int attribute, nodefs;
 {
   register SHELL_VAR *var;
-  int assign, undo, functions_only, arrays_only, any_failed, assign_error, opt;
+  int assign, undo, any_failed, assign_error, opt;
+  int functions_only, arrays_only, assoc_only;
   int aflags;
   char *name;
 #if defined (ARRAY_VARS)
@@ -118,7 +135,8 @@ set_or_show_attributes (list, attribute, nodefs)
   WORD_DESC *w;
 #endif
 
-  undo = functions_only = arrays_only = any_failed = assign_error = 0;
+  functions_only = arrays_only = assoc_only = 0;
+  undo = any_failed = assign_error = 0;
   /* Read arguments from the front of the list. */
   reset_internal_getopt ();
   while ((opt = internal_getopt (list, ATTROPTS)) != -1)
@@ -133,8 +151,11 @@ set_or_show_attributes (list, attribute, nodefs)
            break;
 #if defined (ARRAY_VARS)
          case 'a':
-            arrays_only = 1;
-            break;
+           arrays_only = 1;
+           break;
+         case 'A':
+           assoc_only = 1;
+           break;
 #endif
          case 'p':
            break;
@@ -206,11 +227,11 @@ set_or_show_attributes (list, attribute, nodefs)
 #if defined (ARRAY_VARS)
              /* Let's try something here.  Turn readonly -a xxx=yyy into
                 declare -ra xxx=yyy and see what that gets us. */
-             if (arrays_only)
+             if (arrays_only || assoc_only)
                {
                  tlist = list->next;
                  list->next = (WORD_LIST *)NULL;
-                 w = make_word ("-ra");
+                 w = arrays_only ? make_word ("-ra") : make_word ("-rA");
                  nlist = make_word_list (w, list);
                  opt = declare_builtin (nlist);
                  if (opt != EXECUTION_SUCCESS)
@@ -257,6 +278,12 @@ set_or_show_attributes (list, attribute, nodefs)
          if (attribute != att_array)
            attribute &= ~att_array;
        }
+      else if (attribute & att_assoc)
+       {
+         assoc_only++;
+         if (attribute != att_assoc)
+           attribute &= ~att_assoc;
+       }
 #endif
 
       if (variable_list)
@@ -266,9 +293,15 @@ set_or_show_attributes (list, attribute, nodefs)
 #if defined (ARRAY_VARS)
              if (arrays_only && array_p (var) == 0)
                continue;
+             else if (assoc_only && assoc_p (var) == 0)
+               continue;
 #endif
              if ((var->attributes & attribute))
-               show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+               {
+                 show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+                 if (any_failed = sh_chkwrite (any_failed))
+                   break;
+               }
            }
          free (variable_list);
        }
@@ -279,6 +312,30 @@ set_or_show_attributes (list, attribute, nodefs)
                                            : EXECUTION_FAILURE));
 }
 
+/* Show all variable variables (v == 1) or functions (v == 0) with
+   attributes. */
+int
+show_all_var_attributes (v, nodefs)
+     int v, nodefs;
+{
+  SHELL_VAR **variable_list, *var;
+  int any_failed;
+  register int i;
+
+  variable_list = v ? all_shell_variables () : all_shell_functions ();
+  if (variable_list == 0)  
+    return (EXECUTION_SUCCESS);
+
+  for (i = any_failed = 0; var = variable_list[i]; i++)
+    {
+      show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+      if (any_failed = sh_chkwrite (any_failed))
+        break;
+    }
+  free (variable_list);
+  return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
+}
+
 /* Show the attributes for shell variable VAR.  If NODEFS is non-zero,
    don't show function definitions along with the name.  If PATTR is
    non-zero, it indicates we're being called from `export' or `readonly'.
@@ -290,7 +347,7 @@ show_var_attributes (var, pattr, nodefs)
      SHELL_VAR *var;
      int pattr, nodefs;
 {
-  char flags[8], *x;
+  char flags[16], *x;
   int i;
 
   i = 0;
@@ -301,6 +358,9 @@ show_var_attributes (var, pattr, nodefs)
 #if defined (ARRAY_VARS)
       if (array_p (var))
        flags[i++] = 'a';
+
+      if (assoc_p (var))
+       flags[i++] = 'A';
 #endif
 
       if (function_p (var))
@@ -309,6 +369,9 @@ show_var_attributes (var, pattr, nodefs)
       if (integer_p (var))
        flags[i++] = 'i';
 
+      if (nameref_p (var))
+       flags[i++] = 'n';
+
       if (readonly_p (var))
        flags[i++] = 'r';
 
@@ -317,12 +380,24 @@ show_var_attributes (var, pattr, nodefs)
 
       if (exported_p (var))
        flags[i++] = 'x';
+
+      if (capcase_p (var))
+       flags[i++] = 'c';
+
+      if (lowercase_p (var))
+       flags[i++] = 'l';
+
+      if (uppercase_p (var))
+       flags[i++] = 'u';
     }
   else
     {
 #if defined (ARRAY_VARS)
       if (array_p (var))
        flags[i++] = 'a';
+
+      if (assoc_p (var))
+       flags[i++] = 'A';
 #endif
 
       if (function_p (var))
@@ -336,7 +411,7 @@ show_var_attributes (var, pattr, nodefs)
      reused as input to recreate the current state. */
   if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
     {
-      printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
+      printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
       nodefs++;
       if (pattr == 0 && i == 1 && flags[0] == 'f')
        return 0;               /* don't print `declare -f name' */
@@ -350,8 +425,10 @@ show_var_attributes (var, pattr, nodefs)
     printf ("%s ", this_command_name);
 
 #if defined (ARRAY_VARS)
- if (array_p (var))
 if (array_p (var))
     print_array_assignment (var, 1);
+  else if (assoc_p (var))
+    print_assoc_assignment (var, 1);
   else
 #endif
   /* force `readonly' and `export' to not print out function definitions
@@ -359,12 +436,12 @@ show_var_attributes (var, pattr, nodefs)
   if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
     printf ("%s\n", var->name);
   else if (function_p (var))
-    printf ("%s\n", named_function_string (var->name, function_cell (var), 1));
-  else if (invisible_p (var))
+    printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
+  else if (invisible_p (var) || var_isset (var) == 0)
     printf ("%s\n", var->name);
   else
     {
-      x = sh_double_quote (var_isset (var) ? value_cell (var) : "");
+      x = sh_double_quote (value_cell (var));
       printf ("%s=%s\n", var->name, x);
       free (x);
     }
@@ -378,7 +455,11 @@ show_name_attributes (name, nodefs)
 {
   SHELL_VAR *var;
 
-  var = find_variable_internal (name, 1);
+#if 0
+  var = find_variable_tempenv (name);
+#else
+  var = find_variable_noref (name);
+#endif
 
   if (var && invisible_p (var) == 0)
     {
@@ -389,12 +470,30 @@ show_name_attributes (name, nodefs)
     return (1);
 }
 
+int
+show_func_attributes (name, nodefs)
+     char *name;
+     int nodefs;
+{
+  SHELL_VAR *var;
+
+  var = find_function (name);
+
+  if (var)
+    {
+      show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
+      return (0);
+    }
+  else
+    return (1);
+}
+
 void
 set_var_attribute (name, attribute, undo)
      char *name;
      int attribute, undo;
 {
-  SHELL_VAR *var, *tv;
+  SHELL_VAR *var, *tv, *v;
   char *tvalue;
 
   if (undo)
@@ -411,7 +510,18 @@ set_var_attribute (name, attribute, undo)
 
          var = bind_variable (tv->name, tvalue, 0);
          var->attributes |= tv->attributes & ~att_tempvar;
-         VSETATTR (tv, att_propagate);
+         /* This avoids an error message when propagating a read-only var
+            later on. */
+         if (var->context == 0 && (attribute & att_readonly))
+           {
+             /* Don't bother to set the `propagate to the global variables
+                table' flag if we've just bound the variable in that table */
+             v = find_global_variable (tv->name);
+             if (v != var)
+               VSETATTR (tv, att_propagate);
+           }
+         else
+           VSETATTR (tv, att_propagate);
          if (var->context != 0)
            VSETATTR (var, att_propagate);
          SETVARATTR (tv, attribute, undo);     /* XXX */
@@ -422,7 +532,7 @@ set_var_attribute (name, attribute, undo)
        }
       else
        {
-         var = find_variable_internal (name, 0);
+         var = find_variable_notempenv (name);
          if (var == 0)
            {
              var = bind_variable (name, (char *)NULL, 0);