mod_export void makezleparams(int ro) { struct zleparam *zp; for(zp = zleparams; zp->name; zp++) { Param pm = createparam(zp->name, (zp->type |PM_SPECIAL|PM_REMOVABLE| PM_LOCAL|(ro ? PM_READONLY : 0))); if (!pm) pm = (Param) paramtab->getnode(paramtab, zp->name); DPUTS(!pm, "param not set in makezleparams"); pm->level = locallevel + 1; pm->u.data = zp->data; switch(PM_TYPE(zp->type)) { case PM_SCALAR: pm->gsu.s = zp->gsu; break; case PM_ARRAY: pm->gsu.a = (GsuArray)zp->gsu; break; case PM_INTEGER: pm->gsu.i = (GsuInteger)zp->gsu; pm->base = 10; break; } if ((zp->type & PM_UNSET) && (zmod.flags & MOD_MULT)) pm->node.flags &= ~PM_UNSET; } }
static void addcompparams(struct compparam *cp, Param *pp) { for (; cp->name; cp++, pp++) { Param pm = createparam(cp->name, cp->type |PM_SPECIAL|PM_REMOVABLE|PM_LOCAL); if (!pm) pm = (Param) paramtab->getnode(paramtab, cp->name); DPUTS(!pm, "param not set in addcompparams"); *pp = pm; pm->level = locallevel + 1; if ((pm->u.data = cp->var)) { switch(PM_TYPE(cp->type)) { case PM_SCALAR: pm->gsu.s = &compvarscalar_gsu; break; case PM_INTEGER: pm->gsu.i = &compvarinteger_gsu; pm->base = 10; break; case PM_ARRAY: pm->gsu.a = &compvararray_gsu; break; } } else { pm->gsu.s = cp->gsu; } } }
static int is_private(Param pm) { switch (PM_TYPE(pm->node.flags)) { case PM_SCALAR: if (!pm->gsu.s || pm->gsu.s->unsetfn != pps_unsetfn) return 0; break; case PM_INTEGER: if (!pm->gsu.i || pm->gsu.i->unsetfn != ppi_unsetfn) return 0; break; case PM_EFLOAT: case PM_FFLOAT: if (!pm->gsu.f || pm->gsu.f->unsetfn != ppf_unsetfn) return 0; break; case PM_ARRAY: if (!pm->gsu.a || pm->gsu.a->unsetfn != ppa_unsetfn) return 0; break; case PM_HASHED: if (!pm->gsu.h || pm->gsu.h->unsetfn != pph_unsetfn) return 0; break; default: /* error */ return 0; } return 1; }
static void makeprivate(HashNode hn, UNUSED(int flags)) { Param pm = (Param)hn; if (pm->level == locallevel) { if (pm->ename || (pm->node.flags & PM_NORESTORE) || (pm->old && (pm->old->level == locallevel - 1 || ((pm->node.flags & (PM_SPECIAL|PM_REMOVABLE)) == PM_SPECIAL && /* typeset_single() line 2300 discards PM_REMOVABLE -- why? */ !is_private(pm->old))))) { zwarnnam("private", "can't change scope of existing param: %s", pm->node.nam); makeprivate_error = 1; return; } struct gsu_closure *gsu = zhalloc(sizeof(struct gsu_closure)); switch (PM_TYPE(pm->node.flags)) { case PM_SCALAR: gsu->g = (void *)(pm->gsu.s); gsu->u.s = scalar_private_gsu; pm->gsu.s = (GsuScalar)gsu; break; case PM_INTEGER: gsu->g = (void *)(pm->gsu.i); gsu->u.i = integer_private_gsu; pm->gsu.i = (GsuInteger)gsu; break; case PM_EFLOAT: case PM_FFLOAT: gsu->g = (void *)(pm->gsu.f); gsu->u.f = float_private_gsu; pm->gsu.f = (GsuFloat)gsu; break; case PM_ARRAY: gsu->g = (void *)(pm->gsu.a); gsu->u.a = array_private_gsu; pm->gsu.a = (GsuArray)gsu; break; case PM_HASHED: gsu->g = (void *)(pm->gsu.h); gsu->u.h = hash_private_gsu; pm->gsu.h = (GsuHash)gsu; break; default: makeprivate_error = 1; break; } /* PM_HIDE so new parameters in deeper scopes do not shadow */ pm->node.flags |= (PM_HIDE|PM_SPECIAL|PM_REMOVABLE); pm->level -= 1; } }
static void compunsetfn(Param pm, int exp) { if (exp) { if (pm->u.data) { if (PM_TYPE(pm->node.flags) == PM_SCALAR) { zsfree(*((char **) pm->u.data)); *((char **) pm->u.data) = ztrdup(""); } else if (PM_TYPE(pm->node.flags) == PM_ARRAY) { freearray(*((char ***) pm->u.data)); *((char ***) pm->u.data) = zshcalloc(sizeof(char *)); } else if (PM_TYPE(pm->node.flags) == PM_HASHED) { deleteparamtable(pm->u.hash); pm->u.hash = NULL; } } } else if (PM_TYPE(pm->node.flags) == PM_HASHED) { Param *p; int i; deletehashtable(pm->u.hash); pm->u.hash = NULL; for (p = compkpms, i = CP_KEYPARAMS; i--; p++) *p = NULL; } if (!exp) { Param *p; int i; for (p = comprpms, i = CP_REALPARAMS; i; p++, i--) if (*p == pm) { *p = NULL; break; } } }
static int bin_vared(char *name, char **args, Options ops, UNUSED(int func)) { char *s, *t, *ova = varedarg; struct value vbuf; Value v; Param pm = 0; int ifl; int type = PM_SCALAR, obreaks = breaks, haso = 0, oSHTTY = 0; char *p1, *p2, *main_keymapname, *vicmd_keymapname, *init, *finish; Keymap main_keymapsave = NULL, vicmd_keymapsave = NULL; FILE *oshout = NULL; if ((interact && unset(USEZLE)) || !strcmp(term, "emacs")) { zwarnnam(name, "ZLE not enabled"); return 1; } if (zleactive) { zwarnnam(name, "ZLE cannot be used recursively (yet)"); return 1; } if (OPT_ISSET(ops,'A')) { if (OPT_ISSET(ops, 'a')) { zwarnnam(name, "specify only one of -a and -A"); return 1; } type = PM_HASHED; } else if (OPT_ISSET(ops,'a')) type = PM_ARRAY; p1 = OPT_ARG_SAFE(ops,'p'); p2 = OPT_ARG_SAFE(ops,'r'); main_keymapname = OPT_ARG_SAFE(ops,'M'); vicmd_keymapname = OPT_ARG_SAFE(ops,'m'); init = OPT_ARG_SAFE(ops,'i'); finish = OPT_ARG_SAFE(ops,'f'); if (type != PM_SCALAR && !OPT_ISSET(ops,'c')) { zwarnnam(name, "-%s ignored", type == PM_ARRAY ? "a" : "A"); } /* handle non-existent parameter */ s = args[0]; queue_signals(); v = fetchvalue(&vbuf, &s, (!OPT_ISSET(ops,'c') || type == PM_SCALAR), SCANPM_WANTKEYS|SCANPM_WANTVALS|SCANPM_MATCHMANY); if (!v && !OPT_ISSET(ops,'c')) { unqueue_signals(); zwarnnam(name, "no such variable: %s", args[0]); return 1; } else if (v) { if (*s) { zwarnnam(name, "not an identifier: `%s'", args[0]); return 1; } if (v->isarr) { /* Array: check for separators and quote them. */ char **arr = getarrvalue(v), **aptr, **tmparr, **tptr; tptr = tmparr = (char **)zhalloc(sizeof(char *)*(arrlen(arr)+1)); for (aptr = arr; *aptr; aptr++) { int sepcount = 0, clen; convchar_t c; /* * See if this word contains a separator character * or backslash */ MB_METACHARINIT(); for (t = *aptr; *t; ) { if (*t == '\\') { t++; sepcount++; } else { t += MB_METACHARLENCONV(t, &c); if (WC_ZISTYPE(c, ISEP)) sepcount++; } } if (sepcount) { /* Yes, so allocate enough space to quote it. */ char *newstr, *nptr; newstr = zhalloc(strlen(*aptr)+sepcount+1); /* Go through string quoting separators */ MB_METACHARINIT(); for (t = *aptr, nptr = newstr; *t; ) { if (*t == '\\') { *nptr++ = '\\'; *nptr++ = *t++; } else { clen = MB_METACHARLENCONV(t, &c); if (WC_ZISTYPE(c, ISEP)) *nptr++ = '\\'; while (clen--) *nptr++ = *t++; } } *nptr = '\0'; /* Stick this into the array of words to join up */ *tptr++ = newstr; } else *tptr++ = *aptr; /* No, keep original array element */ } *tptr = NULL; s = sepjoin(tmparr, NULL, 0); } else { s = ztrdup(getstrvalue(v)); } unqueue_signals(); } else if (*s) { unqueue_signals(); zwarnnam(name, "invalid parameter name: %s", args[0]); return 1; } else { unqueue_signals(); s = ztrdup(s); } if (SHTTY == -1 || OPT_ISSET(ops,'t')) { /* need to open /dev/tty specially */ oSHTTY = SHTTY; if ((SHTTY = open(OPT_ISSET(ops,'t') ? OPT_ARG(ops,'t') : "/dev/tty", O_RDWR|O_NOCTTY)) == -1) { zwarnnam(name, "can't access terminal"); zsfree(s); return 1; } if (!isatty(SHTTY)) { zwarnnam(name, "%s: not a terminal", OPT_ARG(ops,'t')); close(SHTTY); SHTTY = oSHTTY; zsfree(s); return 1; } oshout = shout; init_shout(); haso = 1; } /* edit the parameter value */ zpushnode(bufstack, s); if (main_keymapname && savekeymap(name, "main", main_keymapname, &main_keymapsave)) main_keymapname = NULL; if (vicmd_keymapname && savekeymap(name, "vicmd", vicmd_keymapname, &vicmd_keymapsave)) vicmd_keymapname = NULL; varedarg = *args; ifl = isfirstln; if (OPT_ISSET(ops,'h')) hbegin(2); isfirstln = OPT_ISSET(ops,'e'); t = zleread(&p1, &p2, OPT_ISSET(ops,'h') ? ZLRF_HISTORY : 0, ZLCON_VARED, init ? init : "zle-line-init", finish ? finish : "zle-line-finish"); if (OPT_ISSET(ops,'h')) hend(NULL); isfirstln = ifl; varedarg = ova; restorekeymap(name, "main", main_keymapname, main_keymapsave); restorekeymap(name, "vicmd", vicmd_keymapname, vicmd_keymapsave); if (haso) { fclose(shout); /* close(SHTTY) */ shout = oshout; SHTTY = oSHTTY; } if (!t || errflag) { /* error in editing */ errflag &= ~ERRFLAG_ERROR; breaks = obreaks; if (t) zsfree(t); return 1; } /* strip off trailing newline, if any */ if (t[strlen(t) - 1] == '\n') t[strlen(t) - 1] = '\0'; /* final assignment of parameter value */ if (OPT_ISSET(ops,'c')) { unsetparam(args[0]); createparam(args[0], type); } queue_signals(); pm = (Param) paramtab->getnode(paramtab, args[0]); if (pm && (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED))) { char **a; /* * Use spacesplit with fourth argument 1: identify quoted separators, * and unquote. This duplicates the string, so we still need to free. */ a = spacesplit(t, 1, 0, 1); zsfree(t); if (PM_TYPE(pm->node.flags) == PM_ARRAY) setaparam(args[0], a); else sethparam(args[0], a); } else setsparam(args[0], t); unqueue_signals(); return 0; }
static mnumber setmathvar(struct mathvalue *mvp, mnumber v) { Param pm; if (mvp->pval) { /* * This value may have been hanging around for a while. * Be ultra-paranoid in checking the variable is still valid. */ char *s = mvp->lval, *ptr; Param pm; DPUTS(!mvp->lval, "no variable name but variable value in math"); if ((ptr = strchr(s, '['))) s = dupstrpfx(s, ptr - s); pm = (Param) paramtab->getnode(paramtab, s); if (pm == mvp->pval->pm) { if (noeval) return v; setnumvalue(mvp->pval, v); return v; } /* Different parameter, start again from scratch */ mvp->pval = NULL; } if (!mvp->lval) { zerr("lvalue required"); v.type = MN_INTEGER; v.u.l = 0; return v; } if (noeval) return v; untokenize(mvp->lval); pm = setnparam(mvp->lval, v); if (pm) { /* * If we are performing an assignment, we return the * number with the same type as the parameter we are * assigning to, in the spirit of the way assignments * in C work. Note this was a change to long-standing * zsh behaviour. */ switch (PM_TYPE(pm->node.flags)) { case PM_INTEGER: if (v.type != MN_INTEGER) { v.u.l = (zlong)v.u.d; v.type = MN_INTEGER; } break; case PM_EFLOAT: case PM_FFLOAT: if (v.type != MN_FLOAT) { v.u.d = (double)v.u.l; v.type = MN_FLOAT; } break; } } return v; }
void printparamnode(HashNode hn, int printflags) { #ifdef ZSH_64_BIT_TYPE static char llbuf[DIGBUFSIZE]; #endif Param p = (Param) hn; char *t, **u; if (p->flags & PM_UNSET) return; /* Print the attributes of the parameter */ if (printflags & PRINT_TYPE) { if (p->flags & PM_INTEGER) printf("integer "); if (p->flags & PM_ARRAY) printf("array "); if (p->flags & PM_LEFT) printf("left justified %d ", p->ct); if (p->flags & PM_RIGHT_B) printf("right justified %d ", p->ct); if (p->flags & PM_RIGHT_Z) printf("zero filled %d ", p->ct); if (p->flags & PM_LOWER) printf("lowercase "); if (p->flags & PM_UPPER) printf("uppercase "); if (p->flags & PM_READONLY) printf("readonly "); if (p->flags & PM_TAGGED) printf("tagged "); if (p->flags & PM_EXPORTED) printf("exported "); } if (printflags & PRINT_NAMEONLY) { zputs(p->nam, stdout); putchar('\n'); return; } /* How the value is displayed depends * * on the type of the parameter */ quotedzputs(p->nam, stdout); putchar('='); switch (PM_TYPE(p->flags)) { case PM_SCALAR: /* string: simple output */ if (p->gets.cfn && (t = p->gets.cfn(p))) quotedzputs(t, stdout); putchar('\n'); break; case PM_INTEGER: /* integer */ #ifdef ZSH_64_BIT_TYPE convbase(llbuf, p->gets.ifn(p), 0); puts(llbuf); #else printf("%ld\n", p->gets.ifn(p)); #endif break; case PM_ARRAY: /* array */ putchar('('); u = p->gets.afn(p); if(*u) { quotedzputs(*u++, stdout); while (*u) { putchar(' '); quotedzputs(*u++, stdout); } } printf(")\n"); break; } }