/** * Unset a variable. The flags can be: * |1 = tear down entire array * |2 = keep attributes, only unset content */ void unset(struct tbl *vp, int flags) { if (vp->flag & ALLOC) afree(vp->val.s, vp->areap); if ((vp->flag & ARRAY) && (flags & 1)) { 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; } if (flags & 2) { vp->flag &= ~(ALLOC|ISSET); return; } /* if foo[0] is being unset, the remainder of the array is kept... */ vp->flag &= SPECIAL | ((flags & 1) ? 0 : ARRAY|DEFINED); if (vp->flag & SPECIAL) /* responsible for 'unspecial'ing var */ unsetspec(vp); }
/* * pop a block handling special variables */ void popblock() { register struct block *l = e->loc; register struct tbl *vp, **vpp = l->vars.tbls, *vq; register int i; e->loc = l->next; /* pop block */ for (i = l->vars.size; --i >= 0; ) if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) if ((vq = global(vp->name))->flag & ISSET) setspec(vq); else unsetspec(vq); if (l->flags & BF_DOGETOPTS) user_opt = l->getopts_state; afreeall(&l->area); afree(l, ATEMP); }
/* * pop a block handling special variables */ void popblock(void) { ssize_t i; struct block *l = e->loc; struct tbl *vp, **vpp = l->vars.tbls, *vq; /* pop block */ e->loc = l->next; i = 1 << (l->vars.tshift); while (--i >= 0) if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) { if ((vq = global(vp->name))->flag & ISSET) setspec(vq); else unsetspec(vq); } if (l->flags & BF_DOGETOPTS) user_opt = l->getopts_state; afreeall(&l->area); afree(l, ATEMP); }