leak less memory

This commit is contained in:
tg 2016-01-14 20:21:39 +00:00
parent 0a1f594503
commit 5be0ec410e
1 changed files with 37 additions and 24 deletions

61
var.c
View File

@ -2,7 +2,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013, 2014, 2015 * 2011, 2012, 2013, 2014, 2015, 2016
* mirabilos <m@mirbsd.org> * mirabilos <m@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
@ -28,7 +28,7 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.195 2015/10/09 16:11:19 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.196 2016/01/14 20:21:39 tg Exp $");
/*- /*-
* Variables * Variables
@ -218,14 +218,16 @@ array_index_calc(const char *n, bool *arrayp, uint32_t *valp)
return (n); return (n);
} }
#define vn vname.ro
/* /*
* Search for variable, if not found create globally. * Search for variable, if not found create globally.
*/ */
struct tbl * struct tbl *
global(const char *n) global(const char *n)
{ {
struct block *l = e->loc;
struct tbl *vp; struct tbl *vp;
union mksh_cchack vname;
struct block *l = e->loc;
int c; int c;
bool array; bool array;
uint32_t h, val; uint32_t h, val;
@ -234,9 +236,9 @@ global(const char *n)
* check to see if this is an array; * check to see if this is an array;
* dereference namerefs; must come first * dereference namerefs; must come first
*/ */
n = array_index_calc(n, &array, &val); vn = array_index_calc(n, &array, &val);
h = hash(n); h = hash(vn);
c = (unsigned char)n[0]; c = (unsigned char)vn[0];
if (!ksh_isalphx(c)) { if (!ksh_isalphx(c)) {
if (array) if (array)
errorf("bad substitution"); errorf("bad substitution");
@ -246,15 +248,15 @@ global(const char *n)
vp->areap = ATEMP; vp->areap = ATEMP;
*vp->name = c; *vp->name = c;
if (ksh_isdigit(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 can't fail here */
setstr(vp, l->argv[c], KSH_RETURN_ERROR); setstr(vp, l->argv[c], KSH_RETURN_ERROR);
vp->flag |= RDONLY; vp->flag |= RDONLY;
return (vp); goto out;
} }
vp->flag |= RDONLY; vp->flag |= RDONLY;
if (n[1] != '\0') if (vn[1] != '\0')
return (vp); goto out;
vp->flag |= ISSET|INTEGER; vp->flag |= ISSET|INTEGER;
switch (c) { switch (c) {
case '$': case '$':
@ -278,17 +280,23 @@ global(const char *n)
default: default:
vp->flag &= ~(ISSET|INTEGER); vp->flag &= ~(ISSET|INTEGER);
} }
return (vp); goto out;
} }
l = varsearch(e->loc, &vp, n, h); l = varsearch(e->loc, &vp, vn, h);
if (vp != NULL) if (vp != NULL) {
return (array ? arraysearch(vp, val) : vp); if (array)
vp = ktenter(&l->vars, n, h); vp = arraysearch(vp, val);
goto out;
}
vp = ktenter(&l->vars, vn, h);
if (array) if (array)
vp = arraysearch(vp, val); vp = arraysearch(vp, val);
vp->flag |= DEFINED; vp->flag |= DEFINED;
if (special(n)) if (special(vn))
vp->flag |= SPECIAL; vp->flag |= SPECIAL;
out:
if (vn != n)
afree(vname.rw, ATEMP);
return (vp); return (vp);
} }
@ -298,8 +306,9 @@ global(const char *n)
struct tbl * struct tbl *
local(const char *n, bool copy) local(const char *n, bool copy)
{ {
struct block *l = e->loc;
struct tbl *vp; struct tbl *vp;
union mksh_cchack vname;
struct block *l = e->loc;
bool array; bool array;
uint32_t h, val; uint32_t h, val;
@ -307,20 +316,20 @@ local(const char *n, bool copy)
* check to see if this is an array; * check to see if this is an array;
* dereference namerefs; must come first * dereference namerefs; must come first
*/ */
n = array_index_calc(n, &array, &val); vn = array_index_calc(n, &array, &val);
h = hash(n); h = hash(vn);
if (!ksh_isalphx(*n)) { if (!ksh_isalphx(*vn)) {
vp = &vtemp; vp = &vtemp;
vp->flag = DEFINED|RDONLY; vp->flag = DEFINED|RDONLY;
vp->type = 0; vp->type = 0;
vp->areap = ATEMP; vp->areap = ATEMP;
return (vp); goto out;
} }
vp = ktenter(&l->vars, n, h); vp = ktenter(&l->vars, vn, h);
if (copy && !(vp->flag & DEFINED)) { if (copy && !(vp->flag & DEFINED)) {
struct tbl *vq; struct tbl *vq;
varsearch(l->next, &vq, n, h); varsearch(l->next, &vq, vn, h);
if (vq != NULL) { if (vq != NULL) {
vp->flag |= vq->flag & vp->flag |= vq->flag &
(EXPORT | INTEGER | RDONLY | LJUST | RJUST | (EXPORT | INTEGER | RDONLY | LJUST | RJUST |
@ -333,10 +342,14 @@ local(const char *n, bool copy)
if (array) if (array)
vp = arraysearch(vp, val); vp = arraysearch(vp, val);
vp->flag |= DEFINED; vp->flag |= DEFINED;
if (special(n)) if (special(vn))
vp->flag |= SPECIAL; vp->flag |= SPECIAL;
out:
if (vn != n)
afree(vname.rw, ATEMP);
return (vp); return (vp);
} }
#undef vn
/* get variable string value */ /* get variable string value */
char * char *