summaryrefslogtreecommitdiffstats
path: root/src/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/var.c')
-rw-r--r--src/var.c90
1 files changed, 49 insertions, 41 deletions
diff --git a/src/var.c b/src/var.c
index 428192c..d816eb1 100644
--- a/src/var.c
+++ b/src/var.c
@@ -1,9 +1,9 @@
-/* $OpenBSD: var.c,v 1.41 2015/04/17 17:20:41 deraadt Exp $ */
+/* $OpenBSD: var.c,v 1.44 2015/09/10 11:37:42 jca Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- * 2011, 2012, 2013, 2014, 2015
- * Thorsten Glaser <tg@mirbsd.org>
+ * 2011, 2012, 2013, 2014, 2015, 2016
+ * mirabilos <m@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
* are retained or reproduced in an accompanying document, permission
@@ -28,7 +28,7 @@
#include <sys/sysctl.h>
#endif
-__RCSID("$MirOS: src/bin/mksh/var.c,v 1.193 2015/07/10 19:36:38 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/var.c,v 1.197 2016/01/14 22:49:33 tg Exp $");
/*-
* Variables
@@ -218,14 +218,16 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
return (n);
}
+#define vn vname.ro
/*
* Search for variable, if not found create globally.
*/
struct tbl *
global(const char *n)
{
- struct block *l = e->loc;
struct tbl *vp;
+ union mksh_cchack vname;
+ struct block *l = e->loc;
int c;
bool array;
uint32_t h, val;
@@ -234,9 +236,9 @@ global(const char *n)
* check to see if this is an array;
* dereference namerefs; must come first
*/
- n = array_index_calc(n, &array, &val);
- h = hash(n);
- c = (unsigned char)n[0];
+ vn = array_index_calc(n, &array, &val);
+ h = hash(vn);
+ c = (unsigned char)vn[0];
if (!ksh_isalphx(c)) {
if (array)
errorf("bad substitution");
@@ -246,15 +248,15 @@ global(const char *n)
vp->areap = ATEMP;
*vp->name = c;
if (ksh_isdigit(c)) {
- if (getn(n, &c) && (c <= l->argc))
+ if (getn(vn, &c) && (c <= l->argc))
/* setstr can't fail here */
setstr(vp, l->argv[c], KSH_RETURN_ERROR);
vp->flag |= RDONLY;
- return (vp);
+ goto out;
}
vp->flag |= RDONLY;
- if (n[1] != '\0')
- return (vp);
+ if (vn[1] != '\0')
+ goto out;
vp->flag |= ISSET|INTEGER;
switch (c) {
case '$':
@@ -278,17 +280,24 @@ global(const char *n)
default:
vp->flag &= ~(ISSET|INTEGER);
}
- return (vp);
+ goto out;
}
- l = varsearch(e->loc, &vp, n, h);
- if (vp != NULL)
- return (array ? arraysearch(vp, val) : vp);
- vp = ktenter(&l->vars, n, h);
+ l = varsearch(e->loc, &vp, vn, h);
+ if (vp != NULL) {
+ if (array)
+ vp = arraysearch(vp, val);
+ goto out;
+ }
+ vp = ktenter(&l->vars, vn, h);
if (array)
vp = arraysearch(vp, val);
vp->flag |= DEFINED;
- if (special(n))
+ if (special(vn))
vp->flag |= SPECIAL;
+ out:
+ last_lookup_was_array = array;
+ if (vn != n)
+ afree(vname.rw, ATEMP);
return (vp);
}
@@ -298,8 +307,9 @@ global(const char *n)
struct tbl *
local(const char *n, bool copy)
{
- struct block *l = e->loc;
struct tbl *vp;
+ union mksh_cchack vname;
+ struct block *l = e->loc;
bool array;
uint32_t h, val;
@@ -307,20 +317,20 @@ local(const char *n, bool copy)
* check to see if this is an array;
* dereference namerefs; must come first
*/
- n = array_index_calc(n, &array, &val);
- h = hash(n);
- if (!ksh_isalphx(*n)) {
+ vn = array_index_calc(n, &array, &val);
+ h = hash(vn);
+ if (!ksh_isalphx(*vn)) {
vp = &vtemp;
vp->flag = DEFINED|RDONLY;
vp->type = 0;
vp->areap = ATEMP;
- return (vp);
+ goto out;
}
- vp = ktenter(&l->vars, n, h);
+ vp = ktenter(&l->vars, vn, h);
if (copy && !(vp->flag & DEFINED)) {
struct tbl *vq;
- varsearch(l->next, &vq, n, h);
+ varsearch(l->next, &vq, vn, h);
if (vq != NULL) {
vp->flag |= vq->flag &
(EXPORT | INTEGER | RDONLY | LJUST | RJUST |
@@ -333,10 +343,15 @@ local(const char *n, bool copy)
if (array)
vp = arraysearch(vp, val);
vp->flag |= DEFINED;
- if (special(n))
+ if (special(vn))
vp->flag |= SPECIAL;
+ out:
+ last_lookup_was_array = array;
+ if (vn != n)
+ afree(vname.rw, ATEMP);
return (vp);
}
+#undef vn
/* get variable string value */
char *
@@ -710,8 +725,7 @@ exportprep(struct tbl *vp, const char *val)
/* offset to value */
vp->type = xp - vp->val.s;
memcpy(xp, val, vallen);
- if (op != NULL)
- afree(op, vp->areap);
+ afree(op, vp->areap);
}
/*
@@ -949,8 +963,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
t->type = 0;
}
}
- if (free_me)
- afree(free_me, t->areap);
+ afree(free_me, t->areap);
}
}
if (!ok)
@@ -976,8 +989,7 @@ typeset(const char *var, uint32_t set, uint32_t clr, int field, int base)
/* setstr can't fail (readonly check already done) */
setstr(vp, val, KSH_RETURN_ERROR | 0x4);
- if (tval != NULL)
- afree(tval, ATEMP);
+ afree(tval, ATEMP);
}
/* only x[0] is ever exported, so use vpbase */
@@ -1260,18 +1272,15 @@ setspec(struct tbl *vp)
ifs0 = *s;
return;
case V_PATH:
- if (path)
- afree(path, APERM);
+ afree(path, APERM);
s = str_val(vp);
strdupx(path, s, APERM);
/* clear tracked aliases */
flushcom(true);
return;
case V_TMPDIR:
- if (tmpdir) {
- afree(tmpdir, APERM);
- tmpdir = NULL;
- }
+ afree(tmpdir, APERM);
+ tmpdir = NULL;
/*
* Use tmpdir iff it is an absolute path, is writable
* and searchable and is a directory...
@@ -1380,8 +1389,7 @@ unsetspec(struct tbl *vp)
ifs0 = ' ';
break;
case V_PATH:
- if (path)
- afree(path, APERM);
+ afree(path, APERM);
strdupx(path, def_path, APERM);
/* clear tracked aliases */
flushcom(true);
@@ -1480,7 +1488,7 @@ arrayname(const char *str)
const char *p;
char *rv;
- if ((p = cstrchr(str, '[')) == 0)
+ if (!(p = cstrchr(str, '[')))
/* Shouldn't happen, but why worry? */
strdupx(rv, str, ATEMP);
else