merge the nameref code, using mksh standard scoping as discussed

This commit is contained in:
tg 2009-09-06 17:42:15 +00:00
parent 574d6725aa
commit 9531e12b36
7 changed files with 244 additions and 28 deletions

115
check.t
View File

@ -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: 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: 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 $ # $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: description:
Check suppresion of error message with null string. According to Check suppresion of error message with null string. According to
POSIX, it shouldn't print the error as 'word' isn't ommitted. 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. that's why the condition is reversed.
stdin: stdin:
unset foo unset foo
@ -4731,6 +4731,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -4753,6 +4754,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -4799,6 +4801,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -4823,6 +4826,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -4846,6 +4850,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -4868,6 +4873,7 @@ expected-stdout:
integer='typeset -i' integer='typeset -i'
local=typeset local=typeset
login='exec login' login='exec login'
nameref='typeset -n'
nohup='nohup ' nohup='nohup '
r='fc -e -' r='fc -e -'
source='PATH=$PATH:. command .' source='PATH=$PATH:. command .'
@ -5006,6 +5012,33 @@ expected-stdout:
g 0<0>1<1>2<4> = g g 0<0>1<1>2<4> = g
h 0<0>1<1>2<4> = h 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 name: varexpand-substr-1
description: description:
Check if bash-style substring expansion works Check if bash-style substring expansion works
@ -6100,3 +6133,81 @@ expected-stdout:
mypid=nz mypid=nz
=15 =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
View File

@ -22,7 +22,7 @@
#include "sh.h" #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 * string expansion
@ -1021,8 +1021,7 @@ varsub(Expand *xp, const char *sp, const char *word,
if (!(vp->flag&ISSET)) if (!(vp->flag&ISSET))
continue; continue;
XPput(wv, c == '!' ? shf_smprintf("%lu", XPput(wv, c == '!' ? shf_smprintf("%lu",
vp->flag & AINDEX ? arrayindex(vp)) :
(unsigned long)vp->ua.index : 0) :
str_val(vp)); str_val(vp));
} }
if (XPsize(wv) == 0) { if (XPsize(wv) == 0) {
@ -1037,14 +1036,27 @@ varsub(Expand *xp, const char *sp, const char *word,
state = XARG; state = XARG;
} }
} else { } else {
if (*sp == '!' && sp[1])
return (-1);
/* Can't assign things like $! or $1 */ /* Can't assign things like $! or $1 */
if ((stype & 0x7f) == '=' && if ((stype & 0x7f) == '=' &&
ctype(*sp, C_VAR1 | C_DIGIT)) ctype(*sp, C_VAR1 | C_DIGIT))
return (-1); return (-1);
xp->var = global(sp); if (*sp == '!' && sp[1]) {
xp->str = str_val(xp->var); ++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; state = XSUB;
} }
} }

26
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h" #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 #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 #define c_ulimit c_label
#endif #endif
extern uint8_t set_refflag;
/* A leading = means assignments before command are kept; /* A leading = means assignments before command are kept;
* a leading * means a POSIX special builtin; * a leading * means a POSIX special builtin;
* a leading + means a POSIX regular builtin * a leading + means a POSIX regular builtin
@ -896,7 +898,7 @@ c_typeset(const char **wp)
} }
/* see comment below regarding possible opions */ /* 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; fieldstr = basestr = NULL;
builtin_opt.flags |= GF_PLUSOPT; builtin_opt.flags |= GF_PLUSOPT;
@ -947,6 +949,9 @@ c_typeset(const char **wp)
case 'l': case 'l':
flag = LCASEV; flag = LCASEV;
break; break;
case 'n':
set_refflag = (builtin_opt.info & GI_PLUS) ? 2 : 1;
break;
case 'p': case 'p':
/* export, readonly: POSIX -p flag */ /* export, readonly: POSIX -p flag */
/* typeset: show values as well */ /* typeset: show values as well */
@ -995,13 +1000,14 @@ c_typeset(const char **wp)
builtin_opt.optind++; 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"); bi_errorf("only -t, -u and -x options may be used with -f");
set_refflag = 0;
return (1); return (1);
} }
if (wp[builtin_opt.optind]) { if (wp[builtin_opt.optind]) {
/* Take care of exclusions. /* 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. * versa. This property should be preserved.
*/ */
if (fset & LCASEV) /* LCASEV has priority over UCASEV_AL */ 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 /* Setting these attributes clears the others, unless they
* are also set in this command * are also set in this command
*/ */
if (fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV | if ((fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | LCASEV |
INTEGER | INT_U | INT_L)) INTEGER | INT_U | INT_L)) || set_refflag)
fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL | fclr |= ~fset & (LJUST | RJUST | ZEROFIL | UCASEV_AL |
LCASEV | INTEGER | INT_U | INT_L); LCASEV | INTEGER | INT_U | INT_L);
} }
@ -1047,9 +1053,11 @@ c_typeset(const char **wp)
"%s() %T\n", wp[i], f->val.t); "%s() %T\n", wp[i], f->val.t);
} else if (!typeset(wp[i], fset, fclr, field, base)) { } else if (!typeset(wp[i], fset, fclr, field, base)) {
bi_errorf("%s: not identifier", wp[i]); bi_errorf("%s: not identifier", wp[i]);
set_refflag = 0;
return (1); return (1);
} }
} }
set_refflag = 0;
return (rv); return (rv);
} }
@ -1112,6 +1120,8 @@ c_typeset(const char **wp)
* be suitable for re-entry... * be suitable for re-entry...
*/ */
shf_puts("typeset ", shl_stdout); shf_puts("typeset ", shl_stdout);
if (((vp->flag&(ARRAY|ASSOC))==ASSOC))
shf_puts("-n ", shl_stdout);
if ((vp->flag&INTEGER)) if ((vp->flag&INTEGER))
shf_puts("-i ", shl_stdout); shf_puts("-i ", shl_stdout);
if ((vp->flag&EXPORT)) if ((vp->flag&EXPORT))
@ -1160,9 +1170,7 @@ c_typeset(const char **wp)
if ((vp->flag&ARRAY) && any_set) if ((vp->flag&ARRAY) && any_set)
shprintf("%s[%lu]", shprintf("%s[%lu]",
vp->name, vp->name,
vp->flag & AINDEX ? arrayindex(vp));
(unsigned long)vp->ua.index :
0);
else else
shf_puts(vp->name, shl_stdout); shf_puts(vp->name, shl_stdout);
if (thing == '-' && (vp->flag&ISSET)) { if (thing == '-' && (vp->flag&ISSET)) {

3
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #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; extern char **environ;
@ -67,6 +67,7 @@ static const char *initcoms[] = {
"autoload=typeset -fu", "autoload=typeset -fu",
"functions=typeset -f", "functions=typeset -f",
"history=fc -l", "history=fc -l",
"nameref=typeset -n",
"nohup=nohup ", "nohup=nohup ",
r_fc_e_, r_fc_e_,
"source=PATH=$PATH:. command .", "source=PATH=$PATH:. command .",

31
mksh.1
View File

@ -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 $ .\" $OpenBSD: ksh.1,v 1.129 2009/05/28 06:09:06 jmc Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
@ -48,7 +48,7 @@
.el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 .el .xD \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8
.. ..
.\"- .\"-
.Dd $Mdocdate: September 5 2009 $ .Dd $Mdocdate: September 6 2009 $
.Dt MKSH 1 .Dt MKSH 1
.Os MirBSD .Os MirBSD
.Sh NAME .Sh NAME
@ -883,6 +883,7 @@ history=\*(aqfc \-l\*(aq
integer=\*(aqtypeset \-i\*(aq integer=\*(aqtypeset \-i\*(aq
local=\*(aqtypeset\*(aq local=\*(aqtypeset\*(aq
login=\*(aqexec login\*(aq login=\*(aqexec login\*(aq
nameref=\*(aqtypeset -n\*(aq
nohup=\*(aqnohup \*(aq nohup=\*(aqnohup \*(aq
r=\*(aqfc \-e \-\*(aq r=\*(aqfc \-e \-\*(aq
stop=\*(aqkill \-STOP\*(aq stop=\*(aqkill \-STOP\*(aq
@ -1261,6 +1262,18 @@ of the string value of parameter
The number of elements in the array The number of elements in the array
.Ar name . .Ar name .
.Pp .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 [*]}
.It Pf ${! Ns Ar name Ns [@]} .It Pf ${! Ns Ar name Ns [@]}
The names of indices (keys) in the array The names of indices (keys) in the array
@ -4110,7 +4123,7 @@ A command that exits with a zero value.
.Pp .Pp
.It Xo .It Xo
.Ic typeset .Ic typeset
.Oo Op Ic +\-alprtUux .Oo Op Ic +\-alpnrtUux
.Op Fl L Ns Op Ar n .Op Fl L Ns Op Ar n
.Op Fl R Ns Op Ar n .Op Fl R Ns Op Ar n
.Op Fl Z 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 when used with the
.Fl i .Fl i
option.) 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 .It Fl p
Print complete Print complete
.Ic typeset .Ic typeset

6
sh.h
View File

@ -134,7 +134,7 @@
#endif #endif
#ifdef EXTERN #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 #endif
#define MKSH_VERSION "R39 2009/08/30" #define MKSH_VERSION "R39 2009/08/30"
@ -906,6 +906,7 @@ struct tbl { /* table item */
#define EXPRINEVAL BIT(23) /* contents currently being evaluated */ #define EXPRINEVAL BIT(23) /* contents currently being evaluated */
#define EXPRLVALUE BIT(24) /* useable as lvalue (temp flag) */ #define EXPRLVALUE BIT(24) /* useable as lvalue (temp flag) */
#define AINDEX BIT(25) /* array index >0 = ua.index filled in */ #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 */ /* flag bits used for taliases/builtins/aliases/keywords/functions */
#define KEEPASN BIT(8) /* keep command assignments (eg, var=x cmd) */ #define KEEPASN BIT(8) /* keep command assignments (eg, var=x cmd) */
#define FINUSE BIT(9) /* function being executed */ #define FINUSE BIT(9) /* function being executed */
@ -919,6 +920,9 @@ struct tbl { /* table item */
#define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL|\ #define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL|\
LCASEV|UCASEV_AL|INT_U|INT_L) LCASEV|UCASEV_AL|INT_U|INT_L)
#define arrayindex(vp) ((unsigned long)((vp)->flag & AINDEX ? \
(vp)->ua.index : 0))
/* command types */ /* command types */
#define CNONE 0 /* undefined */ #define CNONE 0 /* undefined */
#define CSHELL 1 /* built-in */ #define CSHELL 1 /* built-in */

65
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #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 * Variables
@ -47,6 +47,8 @@ static const char *array_index_calc(const char *, bool *, uint32_t *);
static int rnd_get(void); static int rnd_get(void);
static void rnd_set(unsigned long); static void rnd_set(unsigned long);
uint8_t set_refflag = 0;
/* /*
* create a new block for function calls and simple commands * create a new block for function calls and simple commands
* assume caller has allocated and set up e->loc * 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 /* 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. * the basename of the array.
*/ */
static const char * static const char *
@ -143,9 +145,39 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
{ {
const char *p; const char *p;
int len; int len;
char *ap = NULL;
*arrayp = false; *arrayp = false;
redo_from_ref:
p = skip_varname(n, false); 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))) { if (p != n && *p == '[' && (len = array_ref_len(p))) {
char *sub, *tmp; char *sub, *tmp;
mksh_ari_t rval; mksh_ari_t rval;
@ -646,6 +678,9 @@ typeset(const char *var, Tflag set, Tflag clr, int field, int base)
if (*val == '[') { if (*val == '[') {
int len; int len;
if (set_refflag)
errorf("%s: reference variable cannot be an array",
var);
len = array_ref_len(val); len = array_ref_len(val);
if (len == 0) if (len == 0)
return (NULL); 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) : vp = (set&LOCAL) ? local(tvar, (set & LOCAL_COPY) ? true : false) :
global(tvar); 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); set &= ~(LOCAL|LOCAL_COPY);
vpbase = (vp->flag & ARRAY) ? global(arrayname(var)) : vp; 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 /* 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 * argument if there is no legal name, returns a pointer to the terminating
* null if whole string is legal). * NUL if whole string is legal).
*/ */
const char * const char *
skip_varname(const char *s, int aok) skip_varname(const char *s, int aok)
@ -1240,7 +1295,7 @@ arraysearch(struct tbl *vp, uint32_t val)
struct tbl *prev, *curr, *new; struct tbl *prev, *curr, *new;
size_t len; size_t len;
vp->flag |= ARRAY|DEFINED; vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC;
/* The table entry is always [0] */ /* The table entry is always [0] */
if (val == 0) if (val == 0)
return (vp); return (vp);