merge the nameref code, using mksh standard scoping as discussed
This commit is contained in:
parent
574d6725aa
commit
9531e12b36
115
check.t
115
check.t
@ -1,4 +1,4 @@
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.302 2009/08/30 21:01:59 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.303 2009/09/06 17:42:11 tg Exp $
|
||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
@ -4197,7 +4197,7 @@ name: xxx-param-subst-qmark-1
|
||||
description:
|
||||
Check suppresion of error message with null string. According to
|
||||
POSIX, it shouldn't print the error as 'word' isn't ommitted.
|
||||
ksh88, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error,
|
||||
ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error,
|
||||
that's why the condition is reversed.
|
||||
stdin:
|
||||
unset foo
|
||||
@ -4731,6 +4731,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -4753,6 +4754,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -4799,6 +4801,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -4823,6 +4826,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -4846,6 +4850,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -4868,6 +4873,7 @@ expected-stdout:
|
||||
integer='typeset -i'
|
||||
local=typeset
|
||||
login='exec login'
|
||||
nameref='typeset -n'
|
||||
nohup='nohup '
|
||||
r='fc -e -'
|
||||
source='PATH=$PATH:. command .'
|
||||
@ -5006,6 +5012,33 @@ expected-stdout:
|
||||
g 0<0>1<1>2<4> = g
|
||||
h 0<0>1<1>2<4> = h
|
||||
---
|
||||
name: arrays-7
|
||||
description:
|
||||
Check if we can get the array keys (indices) for indexed arrays,
|
||||
Korn shell style, in some corner cases
|
||||
stdin:
|
||||
print !arz: ${!arz}
|
||||
print !arz[0]: ${!arz[0]}
|
||||
print !arz[1]: ${!arz[1]}
|
||||
arz=foo
|
||||
print !arz: ${!arz}
|
||||
print !arz[0]: ${!arz[0]}
|
||||
print !arz[1]: ${!arz[1]}
|
||||
unset arz
|
||||
print !arz: ${!arz}
|
||||
print !arz[0]: ${!arz[0]}
|
||||
print !arz[1]: ${!arz[1]}
|
||||
expected-stdout:
|
||||
!arz: 0
|
||||
!arz[0]:
|
||||
!arz[1]:
|
||||
!arz: arz
|
||||
!arz[0]: 0
|
||||
!arz[1]:
|
||||
!arz: 0
|
||||
!arz[0]:
|
||||
!arz[1]:
|
||||
---
|
||||
name: varexpand-substr-1
|
||||
description:
|
||||
Check if bash-style substring expansion works
|
||||
@ -6100,3 +6133,81 @@ expected-stdout:
|
||||
mypid=nz
|
||||
=15
|
||||
---
|
||||
name: nameref-1
|
||||
description:
|
||||
Testsuite for nameref (bound variables)
|
||||
stdin:
|
||||
bar=global
|
||||
typeset -n ir2=bar
|
||||
typeset -n ind=ir2
|
||||
print !ind: ${!ind}
|
||||
print ind: $ind
|
||||
print !ir2: ${!ir2}
|
||||
print ir2: $ir2
|
||||
typeset +n ind
|
||||
print !ind: ${!ind}
|
||||
print ind: $ind
|
||||
typeset -n ir2=ind
|
||||
print !ir2: ${!ir2}
|
||||
print ir2: $ir2
|
||||
set|grep ^ir2|sed 's/^/s1: /'
|
||||
typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/'
|
||||
blub=(e1 e2 e3)
|
||||
typeset -n ind=blub
|
||||
typeset -n ir2=blub[2]
|
||||
print !ind[1]: ${!ind[1]}
|
||||
print !ir2: $!ir2
|
||||
print ind[1]: ${ind[1]}
|
||||
print ir2: $ir2
|
||||
expected-stdout:
|
||||
!ind: bar
|
||||
ind: global
|
||||
!ir2: bar
|
||||
ir2: global
|
||||
!ind: ind
|
||||
ind: ir2
|
||||
!ir2: ind
|
||||
ir2: ir2
|
||||
s1: ir2=ind
|
||||
s2: typeset -n ir2
|
||||
!ind[1]: 1
|
||||
!ir2: ir2
|
||||
ind[1]: e2
|
||||
ir2: e3
|
||||
---
|
||||
name: nameref-2da
|
||||
description:
|
||||
Testsuite for nameref (bound variables)
|
||||
Functions, argument given directly, after local
|
||||
stdin:
|
||||
function foo {
|
||||
typeset bar=lokal baz=auch
|
||||
typeset -n v=bar
|
||||
print entering
|
||||
print !v: ${!v}
|
||||
print !bar: ${!bar}
|
||||
print !baz: ${!baz}
|
||||
print bar: $bar
|
||||
print v: $v
|
||||
v=123
|
||||
print bar: $bar
|
||||
print v: $v
|
||||
print exiting
|
||||
}
|
||||
bar=global
|
||||
print bar: $bar
|
||||
foo bar
|
||||
print bar: $bar
|
||||
expected-stdout:
|
||||
bar: global
|
||||
entering
|
||||
!v: bar
|
||||
!bar: bar
|
||||
!baz: baz
|
||||
bar: lokal
|
||||
v: lokal
|
||||
bar: 123
|
||||
v: 123
|
||||
exiting
|
||||
bar: global
|
||||
---
|
||||
|
26
eval.c
26
eval.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.68 2009/08/28 22:39:09 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.69 2009/09/06 17:42:12 tg Exp $");
|
||||
|
||||
/*
|
||||
* string expansion
|
||||
@ -1021,8 +1021,7 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
if (!(vp->flag&ISSET))
|
||||
continue;
|
||||
XPput(wv, c == '!' ? shf_smprintf("%lu",
|
||||
vp->flag & AINDEX ?
|
||||
(unsigned long)vp->ua.index : 0) :
|
||||
arrayindex(vp)) :
|
||||
str_val(vp));
|
||||
}
|
||||
if (XPsize(wv) == 0) {
|
||||
@ -1037,14 +1036,27 @@ varsub(Expand *xp, const char *sp, const char *word,
|
||||
state = XARG;
|
||||
}
|
||||
} else {
|
||||
if (*sp == '!' && sp[1])
|
||||
return (-1);
|
||||
/* Can't assign things like $! or $1 */
|
||||
if ((stype & 0x7f) == '=' &&
|
||||
ctype(*sp, C_VAR1 | C_DIGIT))
|
||||
return (-1);
|
||||
xp->var = global(sp);
|
||||
xp->str = str_val(xp->var);
|
||||
if (*sp == '!' && sp[1]) {
|
||||
++sp;
|
||||
xp->var = global(sp);
|
||||
if (cstrchr(sp, '[')) {
|
||||
if (xp->var->flag & ISSET)
|
||||
xp->str = shf_smprintf("%lu",
|
||||
arrayindex(xp->var));
|
||||
else
|
||||
xp->str = null;
|
||||
} else if (xp->var->flag & ISSET)
|
||||
xp->str = xp->var->name;
|
||||
else
|
||||
xp->str = "0"; /* ksh93 compat */
|
||||
} else {
|
||||
xp->var = global(sp);
|
||||
xp->str = str_val(xp->var);
|
||||
}
|
||||
state = XSUB;
|
||||
}
|
||||
}
|
||||
|
26
funcs.c
26
funcs.c
@ -25,7 +25,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.128 2009/08/30 21:02:00 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.129 2009/09/06 17:42:12 tg Exp $");
|
||||
|
||||
#if HAVE_KILLPG
|
||||
/*
|
||||
@ -47,6 +47,8 @@ __RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.128 2009/08/30 21:02:00 tg Exp $");
|
||||
#define c_ulimit c_label
|
||||
#endif
|
||||
|
||||
extern uint8_t set_refflag;
|
||||
|
||||
/* A leading = means assignments before command are kept;
|
||||
* a leading * means a POSIX special builtin;
|
||||
* a leading + means a POSIX regular builtin
|
||||
@ -896,7 +898,7 @@ c_typeset(const char **wp)
|
||||
}
|
||||
|
||||
/* see comment below regarding possible opions */
|
||||
opts = istset ? "L#R#UZ#afi#lprtux" : "p";
|
||||
opts = istset ? "L#R#UZ#afi#lnprtux" : "p";
|
||||
|
||||
fieldstr = basestr = NULL;
|
||||
builtin_opt.flags |= GF_PLUSOPT;
|
||||
@ -947,6 +949,9 @@ c_typeset(const char **wp)
|
||||
case 'l':
|
||||
flag = LCASEV;
|
||||
break;
|
||||
case 'n':
|
||||
set_refflag = (builtin_opt.info & GI_PLUS) ? 2 : 1;
|
||||
break;
|
||||
case 'p':
|
||||
/* export, readonly: POSIX -p flag */
|
||||
/* typeset: show values as well */
|
||||
@ -995,13 +1000,14 @@ c_typeset(const char **wp)
|
||||
builtin_opt.optind++;
|
||||
}
|
||||
|
||||
if (func && ((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT))) {
|
||||
if (func && (((fset|fclr) & ~(TRACE|UCASEV_AL|EXPORT)) || set_refflag)) {
|
||||
bi_errorf("only -t, -u and -x options may be used with -f");
|
||||
set_refflag = 0;
|
||||
return (1);
|
||||
}
|
||||
if (wp[builtin_opt.optind]) {
|
||||
/* Take care of exclusions.
|
||||
* At this point, flags in fset are cleared in fclr and vise
|
||||
* At this point, flags in fset are cleared in fclr and vice
|
||||
* versa. This property should be preserved.
|
||||
*/
|
||||
if (fset & LCASEV) /* LCASEV has priority over UCASEV_AL */
|
||||
@ -1015,8 +1021,8 @@ c_typeset(const char **wp)
|
||||
/* Setting these attributes clears the others, unless they
|
||||
* are also set in this command
|
||||
*/
|
||||
if (fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV |
|
||||
INTEGER | INT_U | INT_L))
|
||||
if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV |
|
||||
INTEGER | INT_U | INT_L)) || set_refflag)
|
||||
fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL |
|
||||
LCASEV | INTEGER | INT_U | INT_L);
|
||||
}
|
||||
@ -1047,9 +1053,11 @@ c_typeset(const char **wp)
|
||||
"%s() %T\n", wp[i], f->val.t);
|
||||
} else if (!typeset(wp[i], fset, fclr, field, base)) {
|
||||
bi_errorf("%s: not identifier", wp[i]);
|
||||
set_refflag = 0;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
set_refflag = 0;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -1112,6 +1120,8 @@ c_typeset(const char **wp)
|
||||
* be suitable for re-entry...
|
||||
*/
|
||||
shf_puts("typeset ", shl_stdout);
|
||||
if (((vp->flag&(ARRAY|ASSOC))==ASSOC))
|
||||
shf_puts("-n ", shl_stdout);
|
||||
if ((vp->flag&INTEGER))
|
||||
shf_puts("-i ", shl_stdout);
|
||||
if ((vp->flag&EXPORT))
|
||||
@ -1160,9 +1170,7 @@ c_typeset(const char **wp)
|
||||
if ((vp->flag&ARRAY) && any_set)
|
||||
shprintf("%s[%lu]",
|
||||
vp->name,
|
||||
vp->flag & AINDEX ?
|
||||
(unsigned long)vp->ua.index :
|
||||
0);
|
||||
arrayindex(vp));
|
||||
else
|
||||
shf_puts(vp->name, shl_stdout);
|
||||
if (thing == '-' && (vp->flag&ISSET)) {
|
||||
|
3
main.c
3
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.143 2009/08/29 11:26:44 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.144 2009/09/06 17:42:13 tg Exp $");
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@ -67,6 +67,7 @@ static const char *initcoms[] = {
|
||||
"autoload=typeset -fu",
|
||||
"functions=typeset -f",
|
||||
"history=fc -l",
|
||||
"nameref=typeset -n",
|
||||
"nohup=nohup ",
|
||||
r_fc_e_,
|
||||
"source=PATH=$PATH:. command .",
|
||||
|
31
mksh.1
31
mksh.1
@ -1,4 +1,4 @@
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.180 2009/09/05 17:12:49 tg Exp $
|
||||
.\" $MirOS: src/bin/mksh/mksh.1,v 1.181 2009/09/06 17:42:13 tg Exp $
|
||||
.\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
|
||||
.\"-
|
||||
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
||||
@ -48,7 +48,7 @@
|
||||
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
|
||||
..
|
||||
.\"-
|
||||
.Dd $Mdocdate: September 5 2009 $
|
||||
.Dd $Mdocdate: September 6 2009 $
|
||||
.Dt MKSH 1
|
||||
.Os MirBSD
|
||||
.Sh NAME
|
||||
@ -883,6 +883,7 @@ history=\*(aqfc \-l\*(aq
|
||||
integer=\*(aqtypeset \-i\*(aq
|
||||
local=\*(aqtypeset\*(aq
|
||||
login=\*(aqexec login\*(aq
|
||||
nameref=\*(aqtypeset -n\*(aq
|
||||
nohup=\*(aqnohup \*(aq
|
||||
r=\*(aqfc \-e \-\*(aq
|
||||
stop=\*(aqkill \-STOP\*(aq
|
||||
@ -1261,6 +1262,18 @@ of the string value of parameter
|
||||
The number of elements in the array
|
||||
.Ar name .
|
||||
.Pp
|
||||
.It Pf ${! Ns Ar name Ns }
|
||||
The name of the variable referred to by
|
||||
.Ar name .
|
||||
This will be
|
||||
.Ar name
|
||||
except when
|
||||
.Ar name
|
||||
is a name reference (bound variable), created by the
|
||||
.Ic nameref
|
||||
command (which is an alias for
|
||||
.Ic typeset Fl n ) .
|
||||
.Pp
|
||||
.It Pf ${! Ns Ar name Ns [*]}
|
||||
.It Pf ${! Ns Ar name Ns [@]}
|
||||
The names of indices (keys) in the array
|
||||
@ -4110,7 +4123,7 @@ A command that exits with a zero value.
|
||||
.Pp
|
||||
.It Xo
|
||||
.Ic typeset
|
||||
.Oo Op Ic +\-alprtUux
|
||||
.Oo Op Ic +\-alpnrtUux
|
||||
.Op Fl L Ns Op Ar n
|
||||
.Op Fl R Ns Op Ar n
|
||||
.Op Fl Z Ns Op Ar n
|
||||
@ -4191,6 +4204,18 @@ All upper case characters in values are converted to lower case.
|
||||
when used with the
|
||||
.Fl i
|
||||
option.)
|
||||
.It Fl n
|
||||
Create a bound variable (name reference): any access to the variable
|
||||
.Ar name
|
||||
will access the variable
|
||||
.Ar value
|
||||
in the current scope (this is different from
|
||||
.At
|
||||
.Nm ksh93 ! )
|
||||
instead.
|
||||
This can be used by functions to access variables whose names are
|
||||
passed as parametres, instead of using
|
||||
.Ic eval .
|
||||
.It Fl p
|
||||
Print complete
|
||||
.Ic typeset
|
||||
|
6
sh.h
6
sh.h
@ -134,7 +134,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.337 2009/08/30 21:02:01 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.338 2009/09/06 17:42:14 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R39 2009/08/30"
|
||||
|
||||
@ -906,6 +906,7 @@ struct tbl { /* table item */
|
||||
#define EXPRINEVAL BIT(23) /* contents currently being evaluated */
|
||||
#define EXPRLVALUE BIT(24) /* useable as lvalue (temp flag) */
|
||||
#define AINDEX BIT(25) /* array index >0 = ua.index filled in */
|
||||
#define ASSOC BIT(26) /* ARRAY ? associative : reference */
|
||||
/* flag bits used for taliases/builtins/aliases/keywords/functions */
|
||||
#define KEEPASN BIT(8) /* keep command assignments (eg, var=x cmd) */
|
||||
#define FINUSE BIT(9) /* function being executed */
|
||||
@ -919,6 +920,9 @@ struct tbl { /* table item */
|
||||
#define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL|\
|
||||
LCASEV|UCASEV_AL|INT_U|INT_L)
|
||||
|
||||
#define arrayindex(vp) ((unsigned long)((vp)->flag & AINDEX ? \
|
||||
(vp)->ua.index : 0))
|
||||
|
||||
/* command types */
|
||||
#define CNONE 0 /* undefined */
|
||||
#define CSHELL 1 /* built-in */
|
||||
|
65
var.c
65
var.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.86 2009/08/28 22:44:47 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.87 2009/09/06 17:42:15 tg Exp $");
|
||||
|
||||
/*
|
||||
* Variables
|
||||
@ -47,6 +47,8 @@ static const char *array_index_calc(const char *, bool *, uint32_t *);
|
||||
static int rnd_get(void);
|
||||
static void rnd_set(unsigned long);
|
||||
|
||||
uint8_t set_refflag = 0;
|
||||
|
||||
/*
|
||||
* create a new block for function calls and simple commands
|
||||
* assume caller has allocated and set up e->loc
|
||||
@ -135,7 +137,7 @@ initvar(void)
|
||||
}
|
||||
|
||||
/* Used to calculate an array index for global()/local(). Sets *arrayp to
|
||||
* non-zero if this is an array, sets *valp to the array index, returns
|
||||
* true if this is an array, sets *valp to the array index, returns
|
||||
* the basename of the array.
|
||||
*/
|
||||
static const char *
|
||||
@ -143,9 +145,39 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
|
||||
{
|
||||
const char *p;
|
||||
int len;
|
||||
char *ap = NULL;
|
||||
|
||||
*arrayp = false;
|
||||
redo_from_ref:
|
||||
p = skip_varname(n, false);
|
||||
if (!set_refflag && (p != n) && ksh_isalphx(n[0])) {
|
||||
struct block *l = e->loc;
|
||||
struct tbl *vp;
|
||||
char *vn;
|
||||
uint32_t h;
|
||||
|
||||
strndupx(vn, n, p - n, ATEMP);
|
||||
h = hash(vn);
|
||||
/* check if this is a reference */
|
||||
for (l = e->loc; ; l = l->next) {
|
||||
if ((vp = ktsearch(&l->vars, vn, h)) != NULL)
|
||||
break;
|
||||
if (l->next == NULL)
|
||||
break;
|
||||
}
|
||||
afree(vn, ATEMP);
|
||||
if (vp && (vp->flag & (DEFINED|ASSOC|ARRAY)) ==
|
||||
(DEFINED|ASSOC)) {
|
||||
char *cp;
|
||||
|
||||
/* gotcha! */
|
||||
cp = shf_smprintf("%s%s", str_val(vp), p);
|
||||
afree(ap, ATEMP);
|
||||
n = ap = cp;
|
||||
goto redo_from_ref;
|
||||
}
|
||||
}
|
||||
|
||||
if (p != n && *p == '[' && (len = array_ref_len(p))) {
|
||||
char *sub, *tmp;
|
||||
mksh_ari_t rval;
|
||||
@ -646,6 +678,9 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base)
|
||||
if (*val == '[') {
|
||||
int len;
|
||||
|
||||
if (set_refflag)
|
||||
errorf("%s: reference variable cannot be an array",
|
||||
var);
|
||||
len = array_ref_len(val);
|
||||
if (len == 0)
|
||||
return (NULL);
|
||||
@ -680,6 +715,26 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base)
|
||||
|
||||
vp = (set&LOCAL) ? local(tvar, (set & LOCAL_COPY) ? true : false) :
|
||||
global(tvar);
|
||||
if (set_refflag == 2 && (vp->flag & (ARRAY|ASSOC)) == ASSOC)
|
||||
vp->flag &= ~ASSOC;
|
||||
else if (set_refflag == 1) {
|
||||
if (vp->flag & ARRAY) {
|
||||
struct tbl *a, *tmp;
|
||||
|
||||
/* Free up entire array */
|
||||
for (a = vp->u.array; a; ) {
|
||||
tmp = a;
|
||||
a = a->u.array;
|
||||
if (tmp->flag & ALLOC)
|
||||
afree(tmp->val.s, tmp->areap);
|
||||
afree(tmp, tmp->areap);
|
||||
}
|
||||
vp->u.array = NULL;
|
||||
vp->flag &= ~ARRAY;
|
||||
}
|
||||
vp->flag |= ASSOC;
|
||||
}
|
||||
|
||||
set &= ~(LOCAL|LOCAL_COPY);
|
||||
|
||||
vpbase = (vp->flag & ARRAY) ? global(arrayname(var)) : vp;
|
||||
@ -803,8 +858,8 @@ unset(struct tbl *vp, int array_ref)
|
||||
}
|
||||
|
||||
/* return a pointer to the first char past a legal variable name (returns the
|
||||
* argument if there is no legal name, returns * a pointer to the terminating
|
||||
* null if whole string is legal).
|
||||
* argument if there is no legal name, returns a pointer to the terminating
|
||||
* NUL if whole string is legal).
|
||||
*/
|
||||
const char *
|
||||
skip_varname(const char *s, int aok)
|
||||
@ -1240,7 +1295,7 @@ arraysearch(struct tbl *vp, uint32_t val)
|
||||
struct tbl *prev, *curr, *new;
|
||||
size_t len;
|
||||
|
||||
vp->flag |= ARRAY|DEFINED;
|
||||
vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC;
|
||||
/* The table entry is always [0] */
|
||||
if (val == 0)
|
||||
return (vp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user