Bash-4.3 distribution sources and documentation

This commit is contained in:
Chet Ramey 2014-02-26 09:36:43 -05:00
commit ac50fbac37
497 changed files with 129395 additions and 87598 deletions

View file

@ -1,7 +1,7 @@
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987-2010 Free Software Foundation, Inc.
Copyright (C) 1987-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@ -22,7 +22,7 @@ $PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-aAfFgilrtux] [-p] [name[=value] ...]
$SHORT_DOC declare [-aAfFgilnrtux] [-p] [name[=value] ...]
Set variable values and attributes.
Declare variables and give them attributes. If no NAMEs are given,
@ -41,6 +41,7 @@ Options which set attributes:
-A to make NAMEs associative arrays (if supported)
-i to make NAMEs have the `integer' attribute
-l to convert NAMEs to lower case on assignment
-n make NAME a reference to the variable named by its value
-r to make NAMEs readonly
-t to make NAMEs have the `trace' attribute
-u to convert NAMEs to upper case on assignment
@ -55,7 +56,8 @@ When used in a function, `declare' makes NAMEs local, as with the `local'
command. The `-g' option suppresses this behavior.
Exit Status:
Returns success unless an invalid option is supplied or an error occurs.
Returns success unless an invalid option is supplied or a variable
assignment error occurs.
$END
$BUILTIN typeset
@ -110,8 +112,8 @@ Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.
Exit Status:
Returns success unless an invalid option is supplied, an error occurs,
or the shell is not executing a function.
Returns success unless an invalid option is supplied, a variable
assignment error occurs, or the shell is not executing a function.
$END
int
local_builtin (list)
@ -127,9 +129,9 @@ local_builtin (list)
}
#if defined (ARRAY_VARS)
# define DECLARE_OPTS "+acfgilprtuxAF"
# define DECLARE_OPTS "+acfgilnprtuxAF"
#else
# define DECLARE_OPTS "+cfgilprtuxF"
# define DECLARE_OPTS "+cfgilnprtuxF"
#endif
/* The workhorse function. */
@ -139,12 +141,13 @@ declare_internal (list, local_var)
int local_var;
{
int flags_on, flags_off, *flags;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal;
int any_failed, assign_error, pflag, nodefs, opt, mkglobal, onref, offref;
char *t, *subscript_start;
SHELL_VAR *var;
SHELL_VAR *var, *refvar, *v;
FUNCTION_DEF *shell_fn;
flags_on = flags_off = any_failed = assign_error = pflag = nodefs = mkglobal = 0;
refvar = (SHELL_VAR *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, DECLARE_OPTS)) != EOF)
{
@ -186,6 +189,9 @@ declare_internal (list, local_var)
case 'i':
*flags |= att_integer;
break;
case 'n':
*flags |= att_nameref;
break;
case 'r':
*flags |= att_readonly;
break;
@ -258,7 +264,10 @@ declare_internal (list, local_var)
{
for (any_failed = 0; list; list = list->next)
{
pflag = show_name_attributes (list->word->word, nodefs);
if (flags_on & att_function)
pflag = show_func_attributes (list->word->word, nodefs);
else
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
{
sh_notfound (list->word->word);
@ -296,6 +305,28 @@ declare_internal (list, local_var)
else
value = "";
/* Do some lexical error checking on the LHS and RHS of the assignment
that is specific to nameref variables. */
if (flags_on & att_nameref)
{
#if defined (ARRAY_VARIABLES)
if (valid_array_reference (name))
{
builtin_error (_("%s: reference variable cannot be an array"), name);
assign_error++;
NEXT_VARIABLE ();
}
else
#endif
/* disallow self references at global scope */
if (STREQ (name, value) && variable_context == 0)
{
builtin_error (_("%s: nameref variable self references not allowed"), name);
assign_error++;
NEXT_VARIABLE ();
}
}
#if defined (ARRAY_VARS)
compound_array_assign = simple_array_assign = 0;
subscript_start = (char *)NULL;
@ -334,16 +365,17 @@ declare_internal (list, local_var)
/* XXX - this has consequences when we're making a local copy of a
variable that was in the temporary environment. Watch out
for this. */
refvar = (SHELL_VAR *)NULL;
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_local_assoc_variable (name);
else if ((flags_on & att_array) || making_array_special)
var = make_local_array_variable (name);
var = make_local_array_variable (name, making_array_special);
else
#endif
var = make_local_variable (name);
var = make_local_variable (name); /* sets att_invisible for new vars */
if (var == 0)
{
any_failed++;
@ -415,6 +447,33 @@ declare_internal (list, local_var)
else /* declare -[aAirx] name [name...] */
{
/* Non-null if we just created or fetched a local variable. */
/* Here's what ksh93 seems to do. If we are modifying an existing
nameref variable, we don't follow the nameref chain past the last
nameref, and we set the nameref variable's value so future
references to that variable will return the value of the variable
we're assigning right now. */
if (var == 0 && (flags_on & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
var = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (var && nameref_p (var) == 0)
var = 0;
}
/* However, if we're turning off the nameref attribute on an existing
nameref variable, we first follow the nameref chain to the end,
modify the value of the variable this nameref variable references,
*CHANGING ITS VALUE AS A SIDE EFFECT* then turn off the nameref
flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */
else if (var == 0 && (flags_off & att_nameref))
{
/* See if we are trying to modify an existing nameref variable */
refvar = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
if (refvar && nameref_p (refvar) == 0)
refvar = 0;
if (refvar)
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
}
if (var == 0)
var = mkglobal ? find_global_variable (name) : find_variable (name);
@ -422,20 +481,40 @@ declare_internal (list, local_var)
{
#if defined (ARRAY_VARS)
if (flags_on & att_assoc)
var = make_new_assoc_variable (name);
{
var = make_new_assoc_variable (name);
if (offset == 0)
VSETATTR (var, att_invisible);
}
else if ((flags_on & att_array) || making_array_special)
var = make_new_array_variable (name);
{
var = make_new_array_variable (name);
if (offset == 0)
VSETATTR (var, att_invisible);
}
else
#endif
if (offset)
var = bind_variable (name, "", 0);
var = mkglobal ? bind_global_variable (name, "", 0) : bind_variable (name, "", 0);
else
{
var = bind_variable (name, (char *)NULL, 0);
var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
}
/* Can't take an existing array variable and make it a nameref */
else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref))
{
builtin_error (_("%s: reference variable cannot be an array"), name);
assign_error++;
NEXT_VARIABLE ();
}
else if (flags_on & att_nameref)
{
/* ksh93 compat: turning on nameref attribute turns off -ilu */
VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase);
}
/* Cannot use declare +r to turn off readonly attribute. */
if (readonly_p (var) && (flags_off & att_readonly))
@ -501,6 +580,25 @@ declare_internal (list, local_var)
var = convert_var_to_array (var);
#endif /* ARRAY_VARS */
/* XXX - we note that we are turning on nameref attribute and defer
setting it until the assignment has been made so we don't do an
inadvertent nameref lookup. Might have to do the same thing for
flags_off&att_nameref. */
/* XXX - ksh93 makes it an error to set a readonly nameref variable
using a single typeset command. */
onref = (flags_on & att_nameref);
flags_on &= ~att_nameref;
#if defined (ARRAY_VARS)
if (array_p (var) || assoc_p (var)
|| (offset && compound_array_assign)
|| simple_array_assign)
onref = 0; /* array variables may not be namerefs */
#endif
/* ksh93 seems to do this */
offref = (flags_off & att_nameref);
flags_off &= ~att_nameref;
VSETATTR (var, flags_on);
VUNSETATTR (var, flags_off);
@ -516,6 +614,8 @@ declare_internal (list, local_var)
if (var == 0) /* some kind of assignment error */
{
assign_error++;
flags_on |= onref;
flags_off |= offref;
NEXT_VARIABLE ();
}
}
@ -532,7 +632,19 @@ declare_internal (list, local_var)
/* bind_variable_value duplicates the essential internals of
bind_variable() */
if (offset)
bind_variable_value (var, value, aflags);
{
if (onref)
aflags |= ASS_NAMEREF;
v = bind_variable_value (var, value, aflags);
if (v == 0 && onref)
{
sh_invalidid (value);
assign_error++;
/* XXX - unset this variable? or leave it as normal var? */
delete_var (var->name, mkglobal ? global_variables : shell_variables);
NEXT_VARIABLE ();
}
}
/* If we found this variable in the temporary environment, as with
`var=value declare -x var', make sure it is treated identically
@ -562,6 +674,17 @@ declare_internal (list, local_var)
}
}
/* Turn on nameref attribute we deferred above. */
/* XXX - should we turn on the noassign attribute for consistency with
ksh93 when we turn on the nameref attribute? */
VSETATTR (var, onref);
flags_on |= onref;
VUNSETATTR (var, offref);
flags_off |= offref;
/* Yuck. ksh93 compatibility */
if (refvar)
VUNSETATTR (refvar, flags_off);
stupidly_hack_special_variables (name);
NEXT_VARIABLE ();