Bash-4.4 distribution sources and documentation
This commit is contained in:
parent
30a978b7d8
commit
a0c0a00fc4
588 changed files with 130746 additions and 80164 deletions
|
|
@ -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-2012 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
|
@ -31,9 +31,9 @@ display the attributes and values of all variables.
|
|||
Options:
|
||||
-f restrict action or display to function names and definitions
|
||||
-F restrict display to function names only (plus line number and
|
||||
source file when debugging)
|
||||
source file when debugging)
|
||||
-g create global variables when used in a shell function; otherwise
|
||||
ignored
|
||||
ignored
|
||||
-p display the attributes and value of each NAME
|
||||
|
||||
Options which set attributes:
|
||||
|
|
@ -62,10 +62,10 @@ $END
|
|||
|
||||
$BUILTIN typeset
|
||||
$FUNCTION declare_builtin
|
||||
$SHORT_DOC typeset [-aAfFgilrtux] [-p] name[=value] ...
|
||||
$SHORT_DOC typeset [-aAfFgilnrtux] [-p] name[=value] ...
|
||||
Set variable values and attributes.
|
||||
|
||||
Obsolete. See `help declare'.
|
||||
A synonym for `declare'. See `help declare'.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
|
@ -83,6 +83,7 @@ $END
|
|||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "../flags.h"
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
#include "bashgetopt.h"
|
||||
|
|
@ -149,10 +150,12 @@ declare_internal (list, local_var)
|
|||
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)
|
||||
while ((opt = internal_getopt (list, DECLARE_OPTS)) != -1)
|
||||
{
|
||||
flags = list_opttype == '+' ? &flags_off : &flags_on;
|
||||
|
||||
/* If you add options here, see whether or not they need to be added to
|
||||
the loop in subst.c:shell_expand_word_list() */
|
||||
switch (opt)
|
||||
{
|
||||
case 'a':
|
||||
|
|
@ -221,6 +224,7 @@ declare_internal (list, local_var)
|
|||
flags_off |= att_capcase|att_lowercase;
|
||||
break;
|
||||
#endif /* CASEMOD_ATTRS */
|
||||
CASE_HELPOPT;
|
||||
default:
|
||||
builtin_usage ();
|
||||
return (EX_USAGE);
|
||||
|
|
@ -282,15 +286,28 @@ declare_internal (list, local_var)
|
|||
/* There are arguments left, so we are making variables. */
|
||||
while (list) /* declare [-aAfFirx] name [name ...] */
|
||||
{
|
||||
char *value, *name;
|
||||
int offset, aflags;
|
||||
char *value, *name, *oldname;
|
||||
int offset, aflags, wflags, created_var, namelen;
|
||||
#if defined (ARRAY_VARS)
|
||||
int making_array_special, compound_array_assign, simple_array_assign;
|
||||
int var_exists, array_exists, creating_array, array_subscript_assignment;
|
||||
#endif
|
||||
|
||||
name = savestring (list->word->word);
|
||||
wflags = list->word->flags;
|
||||
offset = assignment (name, 0);
|
||||
aflags = 0;
|
||||
created_var = 0;
|
||||
|
||||
if (local_var && variable_context && STREQ (name, "-"))
|
||||
{
|
||||
var = make_local_variable ("-");
|
||||
FREE (value_cell (var)); /* just in case */
|
||||
value = get_current_options ();
|
||||
var_setvalue (var, value);
|
||||
VSETATTR (var, att_invisible);
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
if (offset) /* declare [-aAfFirx] name=value */
|
||||
{
|
||||
|
|
@ -309,8 +326,8 @@ declare_internal (list, local_var)
|
|||
that is specific to nameref variables. */
|
||||
if (flags_on & att_nameref)
|
||||
{
|
||||
#if defined (ARRAY_VARIABLES)
|
||||
if (valid_array_reference (name))
|
||||
#if defined (ARRAY_VARS)
|
||||
if (valid_array_reference (name, 0))
|
||||
{
|
||||
builtin_error (_("%s: reference variable cannot be an array"), name);
|
||||
assign_error++;
|
||||
|
|
@ -318,22 +335,39 @@ declare_internal (list, local_var)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
/* disallow self references at global scope */
|
||||
if (STREQ (name, value) && variable_context == 0)
|
||||
/* disallow self references at global scope, warn at function scope */
|
||||
if (check_selfref (name, value, 0))
|
||||
{
|
||||
builtin_error (_("%s: nameref variable self references not allowed"), name);
|
||||
if (variable_context == 0)
|
||||
{
|
||||
builtin_error (_("%s: nameref variable self references not allowed"), name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else
|
||||
builtin_warning (_("%s: circular name reference"), name);
|
||||
}
|
||||
#if 1
|
||||
if (value && *value && (aflags & ASS_APPEND) == 0 && valid_nameref_value (value, 1) == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
restart_new_var_name:
|
||||
#if defined (ARRAY_VARS)
|
||||
var_exists = array_exists = creating_array = 0;
|
||||
compound_array_assign = simple_array_assign = 0;
|
||||
array_subscript_assignment = 0;
|
||||
subscript_start = (char *)NULL;
|
||||
if (t = strchr (name, '[')) /* ] */
|
||||
{
|
||||
/* If offset != 0 we have already validated any array reference */
|
||||
if (offset == 0 && valid_array_reference (name) == 0)
|
||||
/* If offset != 0 we have already validated any array reference
|
||||
because assignment() calls skipsubscript() */
|
||||
if (offset == 0 && valid_array_reference (name, 0) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
|
|
@ -341,7 +375,8 @@ declare_internal (list, local_var)
|
|||
}
|
||||
subscript_start = t;
|
||||
*t = '\0';
|
||||
making_array_special = 1;
|
||||
making_array_special = 1; /* XXX - should this check offset? */
|
||||
array_subscript_assignment = offset != 0;
|
||||
}
|
||||
else
|
||||
making_array_special = 0;
|
||||
|
|
@ -368,6 +403,7 @@ declare_internal (list, local_var)
|
|||
refvar = (SHELL_VAR *)NULL;
|
||||
if (variable_context && mkglobal == 0 && ((flags_on & att_function) == 0))
|
||||
{
|
||||
/* check name for validity here? */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (flags_on & att_assoc)
|
||||
var = make_local_assoc_variable (name);
|
||||
|
|
@ -375,12 +411,41 @@ declare_internal (list, local_var)
|
|||
var = make_local_array_variable (name, making_array_special);
|
||||
else
|
||||
#endif
|
||||
if (offset == 0 && (flags_on & att_nameref))
|
||||
{
|
||||
/* First look for refvar at current scope */
|
||||
refvar = find_variable_last_nameref (name, 1);
|
||||
var = find_variable (name);
|
||||
/* VARIABLE_CONTEXT != 0, so we are attempting to create or modify
|
||||
the attributes for a local variable at the same scope. If we've
|
||||
used a reference from a previous context to resolve VAR, we
|
||||
want to throw REFVAR and VAR away and create a new local var. */
|
||||
if (refvar && refvar->context != variable_context)
|
||||
{
|
||||
refvar = 0;
|
||||
var = make_local_variable (name);
|
||||
}
|
||||
else if (refvar && refvar->context == variable_context)
|
||||
var = refvar;
|
||||
/* Maybe we just want to create a new local variable */
|
||||
else if (var == 0 || var->context != variable_context)
|
||||
var = make_local_variable (name);
|
||||
/* otherwise we have a var at the right context */
|
||||
}
|
||||
else
|
||||
/* XXX - check name for validity here with valid_nameref_value */
|
||||
var = make_local_variable (name); /* sets att_invisible for new vars */
|
||||
if (var == 0)
|
||||
{
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
if (var && nameref_p (var) && readonly_p (var) && nameref_cell (var) && (flags_off & att_nameref))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else
|
||||
var = (SHELL_VAR *)NULL;
|
||||
|
|
@ -444,18 +509,33 @@ declare_internal (list, local_var)
|
|||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
else /* declare -[aAirx] name [name...] */
|
||||
else /* declare -[aAinrx] name [name...] */
|
||||
{
|
||||
/* Non-null if we just created or fetched a local variable. */
|
||||
#if 0
|
||||
/* This is bash-4.3 code. */
|
||||
/* 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. */
|
||||
#else
|
||||
/* Here's what ksh93 seems to do as of the 2012 version: if we are
|
||||
using declare -n to modify the value of an existing nameref
|
||||
variable, don't follow the nameref chain at all and just search
|
||||
for a nameref at the current context. If we have a nameref,
|
||||
modify its value (changing which variable it references). */
|
||||
#endif
|
||||
if (var == 0 && (flags_on & att_nameref))
|
||||
{
|
||||
#if 0
|
||||
/* See if we are trying to modify an existing nameref variable */
|
||||
var = mkglobal ? find_global_variable_last_nameref (name) : find_variable_last_nameref (name);
|
||||
var = mkglobal ? find_global_variable_last_nameref (name, 1) : find_variable_last_nameref (name, 1);
|
||||
#else
|
||||
/* See if we are trying to modify an existing nameref variable,
|
||||
but don't follow the nameref chain. */
|
||||
var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name);
|
||||
#endif
|
||||
if (var && nameref_p (var) == 0)
|
||||
var = 0;
|
||||
}
|
||||
|
|
@ -467,41 +547,137 @@ declare_internal (list, local_var)
|
|||
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);
|
||||
refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0);
|
||||
if (refvar && nameref_p (refvar) == 0)
|
||||
refvar = 0;
|
||||
/* If the nameref is readonly but doesn't have a value, ksh93
|
||||
allows the nameref attribute to be removed. If it's readonly
|
||||
and has a value, even if the value doesn't reference an
|
||||
existing variable, we disallow the modification */
|
||||
if (refvar && nameref_cell (refvar) && readonly_p (refvar))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
if (refvar)
|
||||
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
|
||||
}
|
||||
#if defined (ARRAY_VARS)
|
||||
/* If we have an array assignment to a nameref, remove the nameref
|
||||
attribute and go on. */
|
||||
else if (var == 0 && offset && array_subscript_assignment)
|
||||
{
|
||||
var = mkglobal ? find_global_variable_noref (name) : find_variable_noref (name);
|
||||
if (var && nameref_p (var))
|
||||
{
|
||||
internal_warning (_("%s: removing nameref attribute"), name);
|
||||
FREE (value_cell (var)); /* XXX - bash-4.3 compat */
|
||||
var_setvalue (var, (char *)NULL);
|
||||
VUNSETATTR (var, att_nameref);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* See if we are trying to set flags or value for an existing nameref
|
||||
that points to a non-existent variable: e.g.,
|
||||
declare -n foo=bar
|
||||
unset foo # unsets bar
|
||||
declare -i foo
|
||||
foo=4+4
|
||||
declare -p foo */
|
||||
if (var == 0 && (flags_on || flags_off || offset))
|
||||
{
|
||||
refvar = mkglobal ? find_global_variable_last_nameref (name, 0) : find_variable_last_nameref (name, 0);
|
||||
if (refvar && nameref_p (refvar) == 0)
|
||||
refvar = 0;
|
||||
if (refvar)
|
||||
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
|
||||
if (refvar && var == 0)
|
||||
{
|
||||
oldname = name; /* need to free this */
|
||||
|
||||
namelen = strlen (nameref_cell (refvar));
|
||||
#if defined (ARRAY_VARS)
|
||||
if (subscript_start)
|
||||
{
|
||||
*subscript_start = '['; /*]*/
|
||||
namelen += strlen (subscript_start);
|
||||
}
|
||||
#endif
|
||||
name = xmalloc (namelen + 2 + strlen (value) + 1);
|
||||
strcpy (name, nameref_cell (refvar));
|
||||
#if defined (ARRAY_VARS)
|
||||
if (subscript_start)
|
||||
strcpy (name + strlen (nameref_cell (refvar)), subscript_start);
|
||||
#endif
|
||||
/* We are committed to using the new name, so reset */
|
||||
if (offset)
|
||||
{
|
||||
/* Rebuild assignment and restore offset and value */
|
||||
if (aflags & ASS_APPEND)
|
||||
name[namelen++] = '+';
|
||||
name[namelen++] = '=';
|
||||
if (value && *value)
|
||||
strcpy (name + namelen, value);
|
||||
else
|
||||
name[namelen] = '\0';
|
||||
offset = assignment (name, 0);
|
||||
/* if offset was valid previously, but the substituting
|
||||
of the nameref value results in an invalid assignment,
|
||||
throw an invalid identifier error */
|
||||
if (offset == 0)
|
||||
{
|
||||
free (oldname);
|
||||
sh_invalidid (name);
|
||||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
name[offset] = '\0';
|
||||
value = name + namelen;
|
||||
}
|
||||
free (oldname);
|
||||
goto restart_new_var_name;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (var == 0)
|
||||
var = mkglobal ? find_global_variable (name) : find_variable (name);
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
var_exists = var != 0;
|
||||
array_exists = var && (array_p (var) || assoc_p (var));
|
||||
creating_array = flags_on & (att_array|att_assoc);
|
||||
#endif
|
||||
|
||||
if (var == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (flags_on & att_assoc)
|
||||
{
|
||||
var = make_new_assoc_variable (name);
|
||||
if (offset == 0)
|
||||
if (var && offset == 0 && no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else if ((flags_on & att_array) || making_array_special)
|
||||
{
|
||||
var = make_new_array_variable (name);
|
||||
if (offset == 0)
|
||||
if (var && offset == 0 && no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (offset)
|
||||
var = mkglobal ? bind_global_variable (name, "", 0) : bind_variable (name, "", 0);
|
||||
else
|
||||
{
|
||||
var = mkglobal ? bind_global_variable (name, (char *)NULL, 0) : bind_variable (name, (char *)NULL, 0);
|
||||
VSETATTR (var, att_invisible);
|
||||
var = mkglobal ? bind_global_variable (name, (char *)NULL, ASS_FORCE) : bind_variable (name, (char *)NULL, ASS_FORCE);
|
||||
if (var && offset == 0 && no_invisible_vars == 0)
|
||||
VSETATTR (var, att_invisible);
|
||||
}
|
||||
if (var == 0)
|
||||
{
|
||||
/* Has to appear in brackets */
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
created_var = 1;
|
||||
}
|
||||
/* Can't take an existing array variable and make it a nameref */
|
||||
else if ((array_p (var) || assoc_p (var)) && (flags_on & att_nameref))
|
||||
|
|
@ -510,8 +686,30 @@ declare_internal (list, local_var)
|
|||
assign_error++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else if (nameref_p (var) && (flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0 && offset && valid_nameref_value (value, 1) == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
else if (flags_on & att_nameref)
|
||||
{
|
||||
#if 1
|
||||
/* Check of offset is to allow an assignment to a nameref var as
|
||||
part of the declare word to override existing value */
|
||||
if (nameref_p (var) == 0 && var_isset (var) && offset == 0 && valid_nameref_value (value_cell (var), 0) == 0)
|
||||
{
|
||||
builtin_error (_("`%s': invalid variable name for name reference"), value_cell (var));
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
#endif
|
||||
if (readonly_p (var))
|
||||
{
|
||||
sh_readonly (name);
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
/* ksh93 compat: turning on nameref attribute turns off -ilu */
|
||||
VUNSETATTR (var, att_integer|att_uppercase|att_lowercase|att_capcase);
|
||||
}
|
||||
|
|
@ -519,7 +717,7 @@ declare_internal (list, local_var)
|
|||
/* Cannot use declare +r to turn off readonly attribute. */
|
||||
if (readonly_p (var) && (flags_off & att_readonly))
|
||||
{
|
||||
sh_readonly (name);
|
||||
sh_readonly (name_cell (var));
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
|
@ -535,12 +733,28 @@ declare_internal (list, local_var)
|
|||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
if ((making_array_special || (flags_on & (att_array|att_assoc)) || array_p (var) || assoc_p (var)) && offset)
|
||||
/* make declare a[2]=foo as similar to a[2]=foo as possible if
|
||||
a is already an array or assoc variable. */
|
||||
if (array_subscript_assignment && array_exists && creating_array == 0)
|
||||
simple_array_assign = 1;
|
||||
else if ((making_array_special || creating_array || array_exists) && offset)
|
||||
{
|
||||
int vlen;
|
||||
vlen = STRLEN (value);
|
||||
|
||||
if (value[0] == '(' && value[vlen-1] == ')')
|
||||
/*itrace("declare_builtin: name = %s value = %s flags = %d", name, value, wflags);*/
|
||||
if (shell_compatibility_level > 43 && (wflags & W_COMPASSIGN) == 0 &&
|
||||
value[0] == '(' && value[vlen-1] == ')')
|
||||
{
|
||||
/* The warning is only printed when using compound assignment
|
||||
to an array variable that doesn't already exist. We use
|
||||
creating_array to allow things like
|
||||
declare -a foo$bar='(abc)' to work. */
|
||||
if (array_exists == 0 && creating_array == 0)
|
||||
internal_warning (_("%s: quoted compound array assignment deprecated"), list->word->word);
|
||||
compound_array_assign = array_exists || creating_array;
|
||||
simple_array_assign = making_array_special;
|
||||
}
|
||||
else if (value[0] == '(' && value[vlen-1] == ')' && (shell_compatibility_level < 44 || (wflags & W_COMPASSIGN)))
|
||||
compound_array_assign = 1;
|
||||
else
|
||||
simple_array_assign = 1;
|
||||
|
|
@ -604,12 +818,13 @@ declare_internal (list, local_var)
|
|||
|
||||
#if defined (ARRAY_VARS)
|
||||
if (offset && compound_array_assign)
|
||||
assign_array_var_from_string (var, value, aflags);
|
||||
assign_array_var_from_string (var, value, aflags|ASS_FORCE);
|
||||
else if (simple_array_assign && subscript_start)
|
||||
{
|
||||
/* declare [-aA] name[N]=value */
|
||||
*subscript_start = '['; /* ] */
|
||||
var = assign_array_element (name, value, 0); /* XXX - not aflags */
|
||||
/* XXX - problem here with appending */
|
||||
var = assign_array_element (name, value, aflags&ASS_APPEND); /* XXX - not aflags */
|
||||
*subscript_start = '\0';
|
||||
if (var == 0) /* some kind of assignment error */
|
||||
{
|
||||
|
|
@ -623,25 +838,30 @@ declare_internal (list, local_var)
|
|||
{
|
||||
/* let bind_{array,assoc}_variable take care of this. */
|
||||
if (assoc_p (var))
|
||||
bind_assoc_variable (var, name, savestring ("0"), value, aflags);
|
||||
bind_assoc_variable (var, name, savestring ("0"), value, aflags|ASS_FORCE);
|
||||
else
|
||||
bind_array_variable (name, 0, value, aflags);
|
||||
bind_array_variable (name, 0, value, aflags|ASS_FORCE);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* XXX - no ASS_FORCE here */
|
||||
/* bind_variable_value duplicates the essential internals of
|
||||
bind_variable() */
|
||||
if (offset)
|
||||
{
|
||||
if (onref)
|
||||
if (onref || nameref_p (var))
|
||||
aflags |= ASS_NAMEREF;
|
||||
v = bind_variable_value (var, value, aflags);
|
||||
if (v == 0 && onref)
|
||||
if (v == 0 && (onref || nameref_p (var)))
|
||||
{
|
||||
sh_invalidid (value);
|
||||
if (valid_nameref_value (value, 1) == 0)
|
||||
sh_invalidid (value);
|
||||
assign_error++;
|
||||
/* XXX - unset this variable? or leave it as normal var? */
|
||||
delete_var (var->name, mkglobal ? global_variables : shell_variables);
|
||||
if (created_var)
|
||||
delete_var (var->name, mkglobal ? global_variables : shell_variables);
|
||||
flags_on |= onref; /* undo change from above */
|
||||
flags_off |= offref;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
}
|
||||
|
|
@ -681,9 +901,16 @@ declare_internal (list, local_var)
|
|||
flags_on |= onref;
|
||||
VUNSETATTR (var, offref);
|
||||
flags_off |= offref;
|
||||
/* Yuck. ksh93 compatibility */
|
||||
/* Yuck. ksh93 compatibility. XXX - need to investigate more but
|
||||
definitely happens when turning off nameref attribute on nameref
|
||||
(see comments above). Under no circumstances allow this to turn
|
||||
off readonly attribute on readonly nameref variable. */
|
||||
if (refvar)
|
||||
VUNSETATTR (refvar, flags_off);
|
||||
{
|
||||
if (flags_off & att_readonly)
|
||||
flags_off &= ~att_readonly;
|
||||
VUNSETATTR (refvar, flags_off);
|
||||
}
|
||||
|
||||
stupidly_hack_special_variables (name);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue