1fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes/* $OpenBSD: var.c,v 1.44 2015/09/10 11:37:42 jca Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 4c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 5fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes * 2011, 2012, 2013, 2014, 2015, 2016 6fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes * mirabilos <m@mirbsd.org> 75155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 85155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 25737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#include "mirhash.h" 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(__OpenBSD__) 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include <sys/sysctl.h> 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes__RCSID("$MirOS: src/bin/mksh/var.c,v 1.197 2016/01/14 22:49:33 tg Exp $"); 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Variables 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * WARNING: unreadable code, needs a rewrite 375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if (flag&INTEGER), val.i contains integer value, and type contains base. 395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * otherwise, (val.s + type) contains string value. 405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if (flag&EXPORT), val.s contains "name=value" for E-Z exporting. 415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct table specials; 44737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesstatic uint32_t lcg_state = 5381, qh_state = 4711; 45737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes/* may only be set by typeset() just before call to array_index_calc() */ 46737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesstatic enum namerefflag innermost_refflag = SRF_NOP; 4703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char *formatstr(struct tbl *, const char *); 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void exportprep(struct tbl *, const char *); 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int special(const char *); 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void unspecial(const char *); 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void getspec(struct tbl *); 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void setspec(struct tbl *); 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void unsetspec(struct tbl *); 55811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserstatic int getint(struct tbl *, mksh_ari_u *, bool); 565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *array_index_calc(const char *, bool *, uint32_t *); 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * create a new block for function calls and simple commands 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume caller has allocated and set up e->loc 615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunewblock(void) 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *empty[] = { null }; 675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l = alloc(sizeof(struct block), ATEMP); 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->flags = 0; 7003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* TODO: could use e->area (l->area => l->areap) */ 7103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&l->area); 725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!e->loc) { 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = 0; 745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv = empty; 755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = e->loc->argc; 775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv = e->loc->argv; 785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->exit = l->error = NULL; 8003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(&l->area, &l->vars, 0); 8103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(&l->area, &l->funs, 0); 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->next = e->loc; 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc = l; 845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pop a block handling special variables 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupopblock(void) 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t i; 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **vpp = l->vars.tbls, *vq; 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop block */ 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra e->loc = l->next; 9803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 9903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 1 << (l->vars.tshift); 10003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (--i >= 0) 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) { 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq = global(vp->name))->flag & ISSET) 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsetspec(vq); 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (l->flags & BF_DOGETOPTS) 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt = l->getopts_state; 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afreeall(&l->area); 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(l, ATEMP); 1115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* called by main() to initialise variable data structures */ 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_DEFNS 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruenum var_specs { 1185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_ENUMS 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru V_MAX 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* this is biased with -1 relative to VARSPEC_ENUMS */ 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * const initvar_names[] = { 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_ITEMS 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinitvar(void) 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i = 0; 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &specials, 136c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* currently 14 specials: 75% of 32 = 2^5 */ 137c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 5); 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i < V_MAX - 1) { 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktenter(&specials, initvar_names[i], 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hash(initvar_names[i])); 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->flag = DEFINED|ISSET; 1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->type = ++i; 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 146c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser/* common code for several functions below and c_typeset() */ 147c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserstruct block * 14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravarsearch(struct block *l, struct tbl **vpp, const char *vn, uint32_t h) 14903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 15003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register struct tbl *vp; 15103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 15203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (l) { 15303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch_loop: 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((vp = ktsearch(&l->vars, vn, h)) != NULL) 15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto varsearch_out; 15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (l->next != NULL) { 15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l = l->next; 15803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto varsearch_loop; 15903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 16003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp = NULL; 16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch_out: 16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *vpp = vp; 16403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (l); 16503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 16603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 16703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 16803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Used to calculate an array index for global()/local(). Sets *arrayp 16903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to true if this is an array, sets *valp to the array index, returns 170737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * the basename of the array. May only be called from global()/local() 171737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * and must be their first callee. 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarray_index_calc(const char *n, bool *arrayp, uint32_t *valp) 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 17703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *ap = NULL; 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *arrayp = false; 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru redo_from_ref: 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = skip_varname(n, false); 183737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (innermost_refflag == SRF_NOP && (p != n) && ksh_isalphx(n[0])) { 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *vn; 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(vn, n, p - n, ATEMP); 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check if this is a reference */ 18903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch(e->loc, &vp, vn, hash(vn)); 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vn, ATEMP); 191737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (vp && (vp->flag & (DEFINED | ASSOC | ARRAY)) == 192737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes (DEFINED | ASSOC)) { 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* gotcha! */ 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = shf_smprintf("%s%s", str_val(vp), p); 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap, ATEMP); 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = ap = cp; 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto redo_from_ref; 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 202737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes innermost_refflag = SRF_NOP; 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p != n && *p == '[' && (len = array_ref_len(p))) { 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sub, *tmp; 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t rval; 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 20803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* calculate the value of the subscript */ 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *arrayp = true; 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(tmp, p + 1, len - 2, ATEMP); 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sub = substitute(tmp, 0); 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(n, n, p - n, ATEMP); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(sub, &rval, KSH_UNWIND_ERROR, true); 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *valp = (uint32_t)rval; 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(sub, ATEMP); 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (n); 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 221fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes#define vn vname.ro 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for variable, if not found create globally. 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruglobal(const char *n) 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 229fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes union mksh_cchack vname; 230fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes struct block *l = e->loc; 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool array; 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h, val; 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 235737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 236737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * check to see if this is an array; 237737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * dereference namerefs; must come first 238737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 239fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes vn = array_index_calc(n, &array, &val); 240fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes h = hash(vn); 241fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes c = (unsigned char)vn[0]; 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalphx(c)) { 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("bad substitution"); 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = &vtemp; 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = DEFINED; 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *vp->name = c; 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(c)) { 251fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (getn(vn, &c) && (c <= l->argc)) 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, l->argv[c], KSH_RETURN_ERROR); 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= RDONLY; 255fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes goto out; 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= RDONLY; 258fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (vn[1] != '\0') 259fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes goto out; 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ISSET|INTEGER; 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = kshpid; 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '!': 26603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if no job, expand to nothing */ 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->val.i = j_async()) == 0) 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ISSET|INTEGER); 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 271c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->val.i = exstat & 0xFF; 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '#': 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = l->argc; 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '-': 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~INTEGER; 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.s = getoptions(); 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ISSET|INTEGER); 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 283fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes goto out; 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 285fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes l = varsearch(e->loc, &vp, vn, h); 286fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (vp != NULL) { 287fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (array) 288fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes vp = arraysearch(vp, val); 289fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes goto out; 290fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes } 291fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes vp = ktenter(&l->vars, vn, h); 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = arraysearch(vp, val); 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= DEFINED; 295fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (special(vn)) 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 297fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes out: 298fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes last_lookup_was_array = array; 299fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (vn != n) 300fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(vname.rw, ATEMP); 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for local variable, if not found create locally. 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querulocal(const char *n, bool copy) 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 311fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes union mksh_cchack vname; 312fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes struct block *l = e->loc; 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool array; 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h, val; 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 316737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 317737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * check to see if this is an array; 318737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * dereference namerefs; must come first 319737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 320fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes vn = array_index_calc(n, &array, &val); 321fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes h = hash(vn); 322fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (!ksh_isalphx(*vn)) { 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = &vtemp; 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = DEFINED|RDONLY; 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 327fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes goto out; 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 329fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes vp = ktenter(&l->vars, vn, h); 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (copy && !(vp->flag & DEFINED)) { 33103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct tbl *vq; 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 333fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes varsearch(l->next, &vq, vn, h); 33403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq != NULL) { 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= vq->flag & 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (EXPORT | INTEGER | RDONLY | LJUST | RJUST | 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ZEROFIL | LCASEV | UCASEV_AL | INT_U | INT_L); 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vq->flag & INTEGER) 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = vq->type; 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field = vq->u2.field; 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = arraysearch(vp, val); 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= DEFINED; 346fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (special(vn)) 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 348fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes out: 349fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes last_lookup_was_array = array; 350fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (vn != n) 351fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(vname.rw, ATEMP); 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 354fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes#undef vn 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* get variable string value */ 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar * 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustr_val(struct tbl *vp) 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&SPECIAL)) 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getspec(vp); 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag&ISSET)) 36503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* special to dollar() */ 36603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = null; 36703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (!(vp->flag&INTEGER)) 36803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* string source */ 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = vp->val.s + vp->type; 37003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else { 37103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* integer source */ 37203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mksh_uari_t n; 373811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser unsigned int base; 37403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /** 37503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * worst case number length is when base == 2: 37603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * 1 (minus) + 2 (base, up to 36) + 1 ('#') + 37703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * number of bits in the mksh_uari_t + 1 (NUL) 37803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char strbuf[1 + 2 + 1 + 8 * sizeof(mksh_uari_t) + 1]; 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *digits = (vp->flag & UCASEV_AL) ? 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru digits_uc : digits_lc; 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = strbuf + sizeof(strbuf); 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & INT_U) 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = vp->val.u; 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 387811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser n = (vp->val.i < 0) ? -vp->val.u : vp->val.u; 388811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser base = (vp->type == 0) ? 10U : (unsigned int)vp->type; 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 39003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (base == 1 && n == 0) 39103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra base = 2; 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base == 1) { 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t sz = 1; 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *(s = strbuf) = '1'; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[1] = '#'; 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!UTFMODE || ((n & 0xFF80) == 0xEF80)) 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* OPTU-16 -> raw octet */ 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[2] = n & 0xFF; 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sz = utf_wctomb(s + 2, n); 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[2 + sz] = '\0'; 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '\0'; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[n % base]; 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n /= base; 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (n != 0); 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base != 10) { 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '#'; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[base % 10]; 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base >= 10) 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[base / 10]; 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag & INT_U) && vp->val.i < 0) 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '-'; 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 41803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vp->flag & (RJUST|LJUST)) 41903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* case already dealt with */ 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = formatstr(vp, s); 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(s, s, ATEMP); 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set variable to string value */ 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetstr(struct tbl *vq, const char *s, int error_ok) 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *salloc = NULL; 432c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser bool no_ro_check = tobool(error_ok & 0x4); 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru error_ok &= ~0x4; 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag & RDONLY) && !no_ro_check) { 436c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser warningf(true, "read-only: %s", vq->name); 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!error_ok) 43803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorfxz(2); 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 44103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(vq->flag&INTEGER)) { 44203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* string dest */ 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&ALLOC)) { 444c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#ifndef MKSH_SMALL 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* debugging */ 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s >= vq->val.s && 447c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser s <= vq->val.s + strlen(vq->val.s)) { 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_errorf( 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "setstr: %s=%s: assigning to self", 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->name, s); 451c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 452c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vq->val.s, vq->areap); 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag &= ~(ISSET|ALLOC); 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->type = 0; 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST))) 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = salloc = formatstr(vq, s); 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&EXPORT)) 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exportprep(vq, s); 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(vq->val.s, s, vq->areap); 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ALLOC; 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 46503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 46603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* integer dest */ 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!v_evaluate(vq, s, error_ok, true)) 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET; 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&SPECIAL)) 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(salloc, ATEMP); 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set variable to integer */ 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetint(struct tbl *vq, mksh_ari_t n) 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vq->flag&INTEGER)) { 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp = &vtemp; 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = (ISSET|INTEGER); 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = n; 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vq, str_val(vp), KSH_RETURN_ERROR); 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->val.i = n; 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET; 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&SPECIAL)) 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 497811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glasergetint(struct tbl *vp, mksh_ari_u *nump, bool arith) 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 499b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes mksh_uari_t c, num = 0, base = 10; 500c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *s; 501811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser bool have_base = false, neg = false; 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 503b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (vp->flag & SPECIAL) 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getspec(vp); 505811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* XXX is it possible for ISSET to be set and val.s to be NULL? */ 506b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (!(vp->flag & ISSET) || (!(vp->flag & INTEGER) && vp->val.s == NULL)) 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 508b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (vp->flag & INTEGER) { 509811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser nump->i = vp->val.i; 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp->type); 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = vp->val.s + vp->type; 513b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes 514b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes do { 515b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes c = (unsigned char)*s++; 516b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } while (ksh_isspace(c)); 517b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes 518b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes switch (c) { 519b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes case '-': 520b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes neg = true; 521b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* FALLTHROUGH */ 522b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes case '+': 523b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes c = (unsigned char)*s++; 524b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes break; 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 526b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes 527b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (c == '0' && arith) { 52896b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (ksh_eq(s[0], 'X', 'x')) { 529b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* interpret as hexadecimal */ 530b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes base = 16; 531b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes ++s; 532b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes goto getint_c_style_base; 533b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } else if (Flag(FPOSIX) && ksh_isdigit(s[0]) && 534b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes !(vp->flag & ZEROFIL)) { 535b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* interpret as octal (deprecated) */ 536b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes base = 8; 537b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes getint_c_style_base: 538b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes have_base = true; 539b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes c = (unsigned char)*s++; 540b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } 541c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 542b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes 543b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes do { 544b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (c == '#') { 545b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* ksh-style base determination */ 546b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (have_base || num < 1) 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 548811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if ((base = num) == 1) { 549b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* mksh-specific extension */ 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned int wc; 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!UTFMODE) 553c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser wc = *(const unsigned char *)s; 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (utf_mbtowc(&wc, s) == (size_t)-1) 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* OPTU-8 -> OPTU-16 */ 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (with a twist: 1#\uEF80 converts 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the same as 1#\x80 does, thus is 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * not round-tripping correctly XXX) 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 561c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser wc = 0xEF00 + *(const unsigned char *)s; 562811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser nump->u = (mksh_uari_t)wc; 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 564b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } else if (base > 36) 56596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes base = 10; 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = 0; 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru have_base = true; 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 569b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } 570b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes if (ksh_isdigit(c)) 57196b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes c = ksh_numdig(c); 57296b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes else if (ksh_isupper(c)) 57396b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes c = ksh_numuc(c) + 10; 57496b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes else if (ksh_islower(c)) 57596b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes c = ksh_numlc(c) + 10; 57696b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes else 57796b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes return (-1); 578811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (c >= base) 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 580b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes /* handle overflow as truncation */ 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = num * base + c; 582b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes } while ((c = (unsigned char)*s++)); 583b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes 584811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (neg) 585811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num = -num; 586811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser nump->u = num; 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (base); 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 59003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 59103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * convert variable vq to integer variable, setting its value from vp 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (vq and vp may be the same) 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetint_v(struct tbl *vq, struct tbl *vp, bool arith) 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int base; 598811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser mksh_ari_u num; 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((base = getint(vp, &num, arith)) == -1) 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 602811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser setint_n(vq, num.i, 0); 60303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq->type == 0) 60403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default base */ 60503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = base; 60603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (vq); 60703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 60803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 60903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* convert variable vq to integer variable, setting its value to num */ 61003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 611c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasersetint_n(struct tbl *vq, mksh_ari_t num, int newbase) 61203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vq->flag & INTEGER) && (vq->flag & ALLOC)) { 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag &= ~ALLOC; 61503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = 0; 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vq->val.s, vq->areap); 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->val.i = num; 619c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (newbase != 0) 620c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vq->type = newbase; 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET|INTEGER; 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vq->flag&SPECIAL) 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruformatstr(struct tbl *vp, const char *s) 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int olen, nlen; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *q; 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t psiz; 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 63303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra olen = (int)utf_mbswidth(s); 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & (RJUST|LJUST)) { 63603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!vp->u2.field) 63703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default field width */ 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field = olen; 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nlen = vp->u2.field; 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nlen = olen; 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP); 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & (RJUST|LJUST)) { 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int slen = olen, i = 0; 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & RJUST) { 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *qq = s; 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n = 0; 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i < slen) 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i += utf_widthadj(qq, &qq); 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* strip trailing spaces (AT&T uses qq[-1] == ' ') */ 6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (qq > s && ksh_isspace(qq[-1])) { 6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --qq; 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --slen; 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ZEROFIL && vp->flag & INTEGER) { 659c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (!s[0] || !s[1]) 660c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser goto uhm_no; 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s[1] == '#') 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 2; 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (s[2] == '#') 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 3; 665c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser uhm_no: 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->u2.field <= n) 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 0; 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n) { 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p, s, n); 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += n; 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (slen > vp->u2.field) 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru slen -= utf_widthadj(s, &s); 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->u2.field - slen) 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(p + n, (vp->flag & ZEROFIL) ? '0' : ' ', 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field - slen); 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru slen -= n; 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(p + vp->u2.field - slen, 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru psiz - (vp->u2.field - slen), 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "%.*s", slen, s); 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* strip leading spaces/zeros */ 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (ksh_isspace(*s)) 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ZEROFIL) 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*s == '0') 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(p, nlen + 1, "%-*.*s", 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field, vp->u2.field, s); 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p, s, strlen(s) + 1); 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & UCASEV_AL) { 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (q = p; *q; q++) 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *q = ksh_toupper(*q); 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (vp->flag & LCASEV) { 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (q = p; *q; q++) 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *q = ksh_tolower(*q); 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * make vp->val.s be "name=value" for quick exporting. 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruexportprep(struct tbl *vp, const char *val) 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *op = (vp->flag&ALLOC) ? vp->val.s : NULL; 71403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t namelen, vallen; 71503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 71603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra namelen = strlen(vp->name); 71703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vallen = strlen(val) + 1; 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ALLOC; 72003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* since name+val are both in memory this can go unchecked */ 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp = alloc(namelen + 1 + vallen, vp->areap); 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(vp->val.s = xp, vp->name, namelen); 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += namelen; 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp++ = '='; 72503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* offset to value */ 72603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->type = xp - vp->val.s; 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(xp, val, vallen); 728fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(op, vp->areap); 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 73203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * lookup variable (according to (set&LOCAL)), set its attributes 73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, LCASEV, 73403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * UCASEV_AL), and optionally set its value if an assignment. 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 73703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condratypeset(const char *var, uint32_t set, uint32_t clr, int field, int base) 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vpbase, *t; 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tvar; 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *val; 74303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 74403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool vappend = false; 745737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes enum namerefflag new_refflag = SRF_NOP; 746737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 747737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if ((set & (ARRAY | ASSOC)) == ASSOC) { 748737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes new_refflag = SRF_ENABLE; 749737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes set &= ~(ARRAY | ASSOC); 750737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 751737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if ((clr & (ARRAY | ASSOC)) == ASSOC) { 752737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes new_refflag = SRF_DISABLE; 753737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes clr &= ~(ARRAY | ASSOC); 754737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for valid variable name, search for value */ 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = skip_varname(var, false); 758811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (val == var) { 759811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* no variable name given */ 760811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser return (NULL); 761811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser } 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*val == '[') { 763737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (new_refflag != SRF_NOP) 76403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s", var, 76503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "reference variable can't be an array"); 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = array_ref_len(val); 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (len == 0) 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 76903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 77003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * IMPORT is only used when the shell starts up and is 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * setting up its environment. Allow only simple array 77203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * references at this time since parameter/command 773c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * substitution is performed on the [expression] which 77403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * would be a major security hole. 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set & IMPORT) { 77703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t i; 77803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 1; i < len - 1; i++) 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(val[i])) 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val += len; 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 78556b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes if (val[0] == '=') { 78603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strndupx(tvar, var, val - var, ATEMP); 78756b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes ++val; 78856b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } else if (set & IMPORT) { 78956b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes /* environment invalid variable name or no assignment */ 79056b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes return (NULL); 79156b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } else if (val[0] == '+' && val[1] == '=') { 79256b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes strndupx(tvar, var, val - var, ATEMP); 79356b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes val += 2; 79456b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes vappend = true; 79556b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } else if (val[0] != '\0') { 79656b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes /* other invalid variable names (not from environment) */ 797c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (NULL); 79803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 799c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* just varname with no value part nor equals sign */ 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(tvar, var, ATEMP); 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = NULL; 80203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* handle foo[*] => foo (whole array) mapping for R39b */ 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = strlen(tvar); 80403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (len > 3 && tvar[len - 3] == '[' && tvar[len - 2] == '*' && 80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tvar[len - 1] == ']') 80603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tvar[len - 3] = '\0'; 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 809737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (new_refflag == SRF_ENABLE) { 810737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes const char *qval, *ccp; 81103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* bail out on 'nameref foo+=bar' */ 81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vappend) 814737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes errorf("appending not allowed for nameref"); 81503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* find value if variable already exists */ 81603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((qval = val) == NULL) { 81703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch(e->loc, &vp, tvar, hash(tvar)); 818f7f795644b6b1016c35b09d88c52f427473b3baeElliott Hughes if (vp == NULL) 819f7f795644b6b1016c35b09d88c52f427473b3baeElliott Hughes goto nameref_empty; 820f7f795644b6b1016c35b09d88c52f427473b3baeElliott Hughes qval = str_val(vp); 82103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 822737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* check target value for being a valid variable name */ 823737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes ccp = skip_varname(qval, false); 82456b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes if (ccp == qval) { 82556b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes if (ksh_isdigit(qval[0])) { 82656b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes int c; 82756b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes 82856b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes if (getn(qval, &c)) 82956b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes goto nameref_rhs_checked; 83056b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } else if (qval[1] == '\0') switch (qval[0]) { 83156b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes case '$': 83256b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes case '!': 83356b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes case '?': 83456b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes case '#': 83556b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes case '-': 83656b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes goto nameref_rhs_checked; 83756b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } 838f7f795644b6b1016c35b09d88c52f427473b3baeElliott Hughes nameref_empty: 839737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes errorf("%s: %s", var, "empty nameref target"); 84056b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes } 841737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes len = (*ccp == '[') ? array_ref_len(ccp) : 0; 842737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (ccp[len]) { 843737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* 844737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * works for cases "no array", "valid array with 845737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * junk after it" and "invalid array"; in the 846737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * latter case, len is also 0 and points to '[' 847737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes */ 848737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes errorf("%s: %s", qval, 849737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes "nameref target not a valid parameter name"); 850737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } 85156b517d46cdf4f6ccd6b62b207110e2afc3db30bElliott Hughes nameref_rhs_checked: 852811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser /* prevent nameref loops */ 853811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser while (qval) { 854811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (!strcmp(qval, tvar)) 855811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser errorf("%s: %s", qval, 856811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser "expression recurses on parameter"); 857811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser varsearch(e->loc, &vp, qval, hash(qval)); 858811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser qval = NULL; 859737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (vp && ((vp->flag & (ARRAY | ASSOC)) == ASSOC)) 860811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser qval = str_val(vp); 86103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 86203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 86303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 86403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* prevent typeset from creating a local PATH/ENV/SHELL */ 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FRESTRICTED) && (strcmp(tvar, "PATH") == 0 || 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0)) 86703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s", tvar, "restricted"); 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 869737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes innermost_refflag = new_refflag; 870737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes vp = (set & LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) : 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru global(tvar); 872737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if (new_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC) 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~ASSOC; 874737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes else if (new_refflag == SRF_ENABLE) { 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ARRAY) { 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *a, *tmp; 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 87803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up entire array */ 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (a = vp->u.array; a; ) { 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmp = a; 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru a = a->u.array; 8825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmp->flag & ALLOC) 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp->val.s, tmp->areap); 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, tmp->areap); 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u.array = NULL; 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~ARRAY; 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ASSOC; 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set &= ~(LOCAL|LOCAL_COPY); 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 894737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes vpbase = (vp->flag & ARRAY) ? global(arrayname(tvar)) : vp; 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 89603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 89703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * only allow export flag to be set; AT&T ksh allows any 89803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * attribute to be changed which means it can be truncated or 89903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * modified (-L/-R/-Z/-i) 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 901737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes if ((vpbase->flag & RDONLY) && 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (val || clr || (set & ~EXPORT))) 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX check calls - is error here ok by POSIX? */ 904c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorfx(2, "read-only: %s", tvar); 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tvar, ATEMP); 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* most calls are with set/clr == 0 */ 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set | clr) { 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ok = true; 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 91103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 91203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * XXX if x[0] isn't set, there will be problems: need 91303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to have one copy of attributes for arrays... 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (t = vpbase; t; t = t->u.array) { 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool fake_assign; 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s = NULL; 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *free_me = NULL; 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fake_assign = (t->flag & ISSET) && (!val || t != vp) && 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((set & (UCASEV_AL|LCASEV|LJUST|RJUST|ZEROFIL)) || 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((t->flag & INTEGER) && (clr & INTEGER)) || 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!(t->flag & INTEGER) && (set & INTEGER))); 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fake_assign) { 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & INTEGER) { 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(t); 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru free_me = NULL; 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = t->val.s + t->type; 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru free_me = (t->flag & ALLOC) ? t->val.s : 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL; 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ALLOC; 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t->flag & INTEGER) && (set & INTEGER)) { 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = 0; 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ALLOC; 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag = (t->flag | set) & ~clr; 94003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 94103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Don't change base if assignment is to be 94203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * done, in case assignment fails. 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((set & INTEGER) && base > 0 && (!val || t != vp)) 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = base; 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set & (LJUST|RJUST|ZEROFIL)) 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->u2.field = field; 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fake_assign) { 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setstr(t, s, KSH_RETURN_ERROR)) { 95003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 95103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Somewhat arbitrary action 95203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * here: zap contents of 95303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * variable, but keep the flag 95403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * settings. 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ok = false; 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & INTEGER) 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ISSET; 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & ALLOC) 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(t->val.s, t->areap); 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~(ISSET|ALLOC); 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = 0; 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 966fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(free_me, t->areap); 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ok) 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorfz(); 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val != NULL) { 97403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *tval; 97503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 97603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vappend) { 97703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tval = shf_smprintf("%s%s", str_val(vp), val); 97803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra val = tval; 97903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 98003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tval = NULL; 98103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag&INTEGER) { 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do not zero base before assignment */ 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_UNWIND_ERROR | 0x4); 98503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* done after assignment to override default */ 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base > 0) 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = base; 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail (readonly check already done) */ 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_RETURN_ERROR | 0x4); 99103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 992fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(tval, ATEMP); 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* only x[0] is ever exported, so use vpbase */ 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) && 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vpbase->type == 0) 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exportprep(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null); 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/** 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Unset a variable. The flags can be: 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * |1 = tear down entire array 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * |2 = keep attributes, only unset content 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunset(struct tbl *vp, int flags) 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ALLOC) 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vp->val.s, vp->areap); 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag & ARRAY) && (flags & 1)) { 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *a, *tmp; 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 101603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up entire array */ 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (a = vp->u.array; a; ) { 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmp = a; 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru a = a->u.array; 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmp->flag & ALLOC) 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp->val.s, tmp->areap); 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, tmp->areap); 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u.array = NULL; 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & 2) { 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ALLOC|ISSET); 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 103003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if foo[0] is being unset, the remainder of the array is kept... */ 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= SPECIAL | ((flags & 1) ? 0 : ARRAY|DEFINED); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & SPECIAL) 103303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* responsible for 'unspecial'ing var */ 103403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unsetspec(vp); 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 103703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 103803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Return a pointer to the first char past a legal variable name 103903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * (returns the argument if there is no legal name, returns a pointer to 104003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the terminating NUL if whole string is legal). 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char * 1043737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesskip_varname(const char *s, bool aok) 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 104503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t alen; 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s && ksh_isalphx(*s)) { 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++s && ksh_isalnux(*s)) 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (aok && *s == '[' && (alen = array_ref_len(s))) 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += alen; 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Return a pointer to the first character past any legal variable name */ 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char * 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruskip_wdvarname(const char *s, 105903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip array de-reference? */ 106003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool aok) 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s[0] == CHAR && ksh_isalphx(s[1])) { 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += 2; 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (s[0] == CHAR && ksh_isalnux(s[1])); 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (aok && s[0] == CHAR && s[1] == '[') { 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* skip possible array de-reference */ 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = s; 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char c; 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int depth = 0; 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 107203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p[0] != CHAR) 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = p[1]; 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p += 2; 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ']' && --depth == 0) { 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = p; 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Check if coded string s is a variable name */ 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 109103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrais_wdvarname(const char *s, bool aok) 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = skip_wdvarname(s, aok); 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p != s && p[0] == EOS); 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Check if coded string s is a variable assignment */ 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruis_wdvarassign(const char *s) 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = skip_wdvarname(s, true); 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 110403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (p != s && p[0] == CHAR && 110503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (p[1] == '=' || (p[1] == '+' && p[2] == CHAR && p[3] == '='))); 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Make the exported environment from the exported names in the dictionary. 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar ** 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumakenv(void) 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 111403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t i; 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPtrV denv; 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **vpp; 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(denv, 64); 112003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (l = e->loc; l != NULL; l = l->next) { 112103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vpp = l->vars.tbls; 112203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 1 << (l->vars.tshift); 112303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (--i >= 0) 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp = *vpp++) != NULL && 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) { 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l2; 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp2; 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = hash(vp->name); 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unexport any redefined instances */ 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l2 = l->next; l2 != NULL; l2 = l2->next) { 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp2 = ktsearch(&l2->vars, vp->name, h); 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp2 != NULL) 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp2->flag &= ~EXPORT; 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&INTEGER)) { 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* integer to string */ 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *val; 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = str_val(vp); 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(INTEGER|RDONLY|SPECIAL); 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_RETURN_ERROR); 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(denv, vp->val.s); 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 114650012061ca3ad8e8a7f88c72130a5e22d797897eElliott Hughes if (l->flags & BF_STOPENV) 114750012061ca3ad8e8a7f88c72130a5e22d797897eElliott Hughes break; 114803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(denv, NULL); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((char **)XPclose(denv)); 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * handle special variables with side effects - PATH, SECONDS. 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Test if name is a special parameter */ 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruspecial(const char *name) 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&specials, name, hash(name)); 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tp && (tp->flag & ISSET) ? tp->type : V_NONE); 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Make a variable non-special */ 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunspecial(const char *name) 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&specials, name, hash(name)); 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp) 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ktdelete(tp); 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic time_t seconds; /* time SECONDS last set */ 1179b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughesstatic mksh_uari_t user_lineno; /* what user set $LINENO to */ 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetspec(struct tbl *vp) 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1184811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser mksh_ari_u num; 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int st; 1186c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser struct timeval tv; 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((st = special(vp->name))) { 1189c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_COLUMNS: 1190c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_LINES: 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 1192c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * Do NOT export COLUMNS/LINES. Many applications 1193c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * check COLUMNS/LINES before checking ws.ws_col/row, 1194c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * so if the app is started with C/L in the environ 1195c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * and the window is then resized, the app won't 1196c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * see the change cause the environ doesn't change. 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1198c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (got_winch) 1199c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser change_winsz(); 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1201c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1202c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser switch (st) { 1203c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_BASHPID: 1204811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.u = (mksh_uari_t)procpid; 1205c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 1206c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_COLUMNS: 1207811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = x_cols; 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_HISTSIZE: 1210811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = histsize; 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 1213b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes num.u = (mksh_uari_t)current_lineno + user_lineno; 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 1216811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = x_lins; 1217c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 1218c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_EPOCHREALTIME: { 1219c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 10(%u) + 1(.) + 6 + NUL */ 1220c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser char buf[18]; 1221c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 1222c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->flag &= ~SPECIAL; 1223c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 1224c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser shf_snprintf(buf, sizeof(buf), "%u.%06u", 1225c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser (unsigned)tv.tv_sec, (unsigned)tv.tv_usec); 1226c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setstr(vp, buf, KSH_RETURN_ERROR | 0x4); 1227c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->flag |= SPECIAL; 1228c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 1229c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1230c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_OPTIND: 1231811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = user_opt.uoptind; 1232c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 1233c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_RANDOM: 1234811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = rndget(); 1235c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 1236c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_SECONDS: 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 1238c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * On start up the value of SECONDS is used before 1239c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * it has been set - don't do anything in this case 1240c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * (see initcoms[] in main.c). 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1242c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (vp->flag & ISSET) { 1243c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 1244811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.i = tv.tv_sec - seconds; 1245c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } else 1246c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do nothing, do not touch vp at all */ 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~SPECIAL; 1253811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser setint_n(vp, num.i, 0); 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetspec(struct tbl *vp) 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1260811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser mksh_ari_u num; 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int st; 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((st = special(vp->name))) { 1265c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#if HAVE_PERSISTENT_HISTORY 1266c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_HISTFILE: 1267c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser sethistfile(str_val(vp)); 1268c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 1269c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser#endif 1270c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_IFS: 1271c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setctypes(s = str_val(vp), C_IFS); 1272c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ifs0 = *s; 1273c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_PATH: 1275fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(path, APERM); 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(vp); 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(path, s, APERM); 127803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clear tracked aliases */ 127903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flushcom(true); 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_TMPDIR: 1282fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(tmpdir, APERM); 1283fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes tmpdir = NULL; 128403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 128503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Use tmpdir iff it is an absolute path, is writable 128603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * and searchable and is a directory... 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(vp); 129203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 129396b43632c2aa206ac1ec0eb70b34847d58d52633Elliott Hughes if (mksh_abspath(s) && access(s, W_OK|X_OK) == 0 && 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru stat(s, &statb) == 0 && S_ISDIR(statb.st_mode)) 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(tmpdir, s, APERM); 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 129703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* common sub-cases */ 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_COLUMNS: 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 1301c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (vp->flag & IMPORT) { 1302c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* do not touch */ 1303c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser unspecial(vp->name); 1304c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp->flag &= ~SPECIAL; 1305c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return; 1306c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 1307c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* FALLTHROUGH */ 1308c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_HISTSIZE: 1309c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_LINENO: 1310c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_OPTIND: 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 131303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~SPECIAL; 1315811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (getint(vp, &num, false) == -1) { 131603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = str_val(vp); 131703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (st != V_RANDOM) 131803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s: %s", vp->name, "bad number", s); 1319811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser num.u = hash(s); 132003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do nothing, do not touch vp at all */ 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process the singular parts of the common cases */ 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (st) { 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_COLUMNS: 1332811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (num.i >= MIN_COLS) 1333811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser x_cols = num.i; 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1335c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_HISTSIZE: 1336811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser sethistsize(num.i); 1337c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 1338c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_LINENO: 1339c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* The -1 is because line numbering starts at 1. */ 1340b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes user_lineno = num.u - (mksh_uari_t)current_lineno - 1; 1341c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 1343811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser if (num.i >= MIN_LINS) 1344811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser x_lins = num.i; 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1346c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_OPTIND: 1347811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser getopts_reset((int)num.i); 1348c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * mksh R39d+ no longer has the traditional repeatability 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of $RANDOM sequences, but always retains state 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1354811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser rndset((unsigned long)num.u); 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval tv; 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1360c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser mksh_TIME(tv); 1361811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser seconds = tv.tv_sec - num.i; 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 136403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 1365811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaser ksh_tmout = num.i >= 0 ? num.i : 0; 136603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunsetspec(struct tbl *vp) 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1373c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 1374c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * AT&T ksh man page says OPTIND, OPTARG and _ lose special 1375c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * meaning, but OPTARG does not (still set by getopts) and _ is 1376c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * also still set in various places. Don't know what AT&T does 1377c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * for HISTSIZE, HISTFILE. Unsetting these in AT&T ksh does not 1378c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * loose the 'specialness': IFS, COLUMNS, PATH, TMPDIR 1379c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 1380c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (special(vp->name)) { 1382b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes#if HAVE_PERSISTENT_HISTORY 1383b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes case V_HISTFILE: 1384b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes sethistfile(NULL); 1385b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes return; 1386b27ce95e41e941ad22b3dc392d8328251d3a057eElliott Hughes#endif 1387c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser case V_IFS: 1388c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser setctypes(TC_IFSWS, C_IFS); 1389c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ifs0 = ' '; 1390c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser break; 13915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_PATH: 1392fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes afree(path, APERM); 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(path, def_path, APERM); 139403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clear tracked aliases */ 139503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flushcom(true); 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_TMPDIR: 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* should not become unspecial */ 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmpdir) { 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmpdir, APERM); 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmpdir = NULL; 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 140703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 140803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh leaves previous value in place */ 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unspecial(vp->name); 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for (and possibly create) a table entry starting with 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * vp, indexed by val. 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 141803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct tbl * 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarraysearch(struct tbl *vp, uint32_t val) 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *prev, *curr, *news; 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t len; 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1424737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes vp->flag = (vp->flag | (ARRAY | DEFINED)) & ~ASSOC; 142503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* the table entry is always [0] */ 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == 0) 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev = vp; 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru curr = vp->u.array; 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (curr && curr->ua.index < val) { 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev = curr; 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru curr = curr->u.array; 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (curr && curr->ua.index == val) { 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (curr->flag&ISSET) 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (curr); 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news = curr; 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news = NULL; 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!news) { 144103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra len = strlen(vp->name); 144203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra checkoktoadd(len, 1 + offsetof(struct tbl, name[0])); 144303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra news = alloc(offsetof(struct tbl, name[0]) + ++len, vp->areap); 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(news->name, vp->name, len); 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX; 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->type = vp->type; 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->areap = vp->areap; 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->u2.field = vp->u2.field; 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->ua.index = val; 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 145203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (curr != news) { 145303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not reusing old array entry */ 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev->u.array = news; 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->u.array = curr; 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (news); 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 146003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 146103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Return the length of an array reference (eg, [1+2]) - cp is assumed 146203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to point to the open bracket. Returns 0 if there is no matching 146303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * closing bracket. 1464737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * 1465737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes * XXX this should parse the actual arithmetic syntax 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 146703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasize_t 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarray_ref_len(const char *cp) 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s = cp; 147103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c; 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int depth = 0; 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s++) && (c != ']' || --depth)) 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!c) 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s - cp); 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Make a copy of the base of an array name 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar * 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarrayname(const char *str) 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *rv; 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1491fc0307d88e2ab13777f102dc63c0d1c968dc8bb2Elliott Hughes if (!(p = cstrchr(str, '['))) 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Shouldn't happen, but why worry? */ 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(rv, str, ATEMP); 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(rv, str, p - str, ATEMP); 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set (or overwrite, if reset) the array variable var to the values in vals */ 15015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumksh_uari_t 15025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_array(const char *var, bool reset, const char **vals) 15035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 15045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, *vq; 150503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mksh_uari_t i = 0, j = 0; 1506c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser const char *ccp = var; 150703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp = NULL; 150803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t n; 15095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1510c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* to get local array, use "local foo; set -A foo" */ 151103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n = strlen(var); 151203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (n > 0 && var[n - 1] == '+') { 151303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* append mode */ 151403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra reset = false; 151503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strndupx(cp, var, n - 1, ATEMP); 1516c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser ccp = cp; 151703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 1518c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser vp = global(ccp); 15195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note: AT&T ksh allows set -A but not set +A of a read-only var */ 15215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) 1522c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser errorfx(2, "read-only: %s", ccp); 15235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This code is quite non-optimal */ 1524c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (reset) { 15255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trash existing values and attributes */ 15265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset(vp, 1); 1527c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* allocate-by-access the [0] element to keep in scope */ 1528c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser arraysearch(vp, 0); 1529c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser } 153003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 153103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * TODO: would be nice for assignment to completely succeed or 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * completely fail. Only really effects integer arrays: 15335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * evaluation of some of vals[] may fail... 15345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 153503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cp != NULL) { 153603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* find out where to set when appending */ 153703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (vq = vp; vq; vq = vq->u.array) { 153803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(vq->flag & ISSET)) 153903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 154003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (arrayindex(vq) >= j) 154103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra j = arrayindex(vq) + 1; 154203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 154303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 154403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 15455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((ccp = vals[i])) { 1546737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#if 0 /* temporarily taken out due to regression */ 15475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == '[') { 15485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int level = 0; 15495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*ccp) { 15515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == ']' && --level == 0) 15525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 15535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == '[') 15545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++level; 15555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++ccp; 15565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == ']' && level == 0 && ccp[1] == '=') { 15585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(cp, vals[i] + 1, ccp - (vals[i] + 1), 15595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ATEMP); 15605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(substitute(cp, 0), (mksh_ari_t *)&j, 15615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru KSH_UNWIND_ERROR, true); 15625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp, ATEMP); 15635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ccp += 2; 15645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 15655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ccp = vals[i]; 15665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1567737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#endif 15685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq = arraysearch(vp, j); 15705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* would be nice to deal with errors here... (see above) */ 15715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vq, ccp, KSH_RETURN_ERROR); 15725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i++; 15735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j++; 15745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 15775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 15785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 15805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchange_winsz(void) 15815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1582737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes struct timeval tv; 1583737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1584737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes mksh_TIME(tv); 1585737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_mem(qh_state, &tv, sizeof(tv)); 1586737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 15875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef TIOCGWINSZ 15885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check if window size has changed */ 1589c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser if (tty_init_fd() < 2) { 15905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct winsize ws; 15915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 15925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ioctl(tty_fd, TIOCGWINSZ, &ws) >= 0) { 15935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ws.ws_col) 15945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = ws.ws_col; 15955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ws.ws_row) 15965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_lins = ws.ws_row; 15975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 15995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 16005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* bounds check for sane values, use defaults otherwise */ 16025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_cols < MIN_COLS) 16035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = 80; 16045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_lins < MIN_LINS) 16055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_lins = 24; 16065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 16085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru got_winch = 0; 16095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 16105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 16115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 16125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruuint32_t 161303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrahash(const void *s) 16145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 161503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 161603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 1617737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHInit(h); 1618737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateStr_reg(h, s); 1619737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(h); 1620737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes return (h); 1621737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes} 1622737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1623737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesuint32_t 1624737fdce098f804459a925438e48dd711c31bbc9eElliott Hugheschvt_rndsetup(const void *bp, size_t sz) 1625737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes{ 1626737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes register uint32_t h; 1627737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1628737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* use LCG as seed but try to get them to deviate immediately */ 1629737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes h = lcg_state; 1630737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes (void)rndget(); 1631737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(h); 1632737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* variation through pid, ppid, and the works */ 1633737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(h, &rndsetupstate, sizeof(rndsetupstate)); 1634737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* some variation, some possibly entropy, depending on OE */ 1635737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(h, bp, sz); 1636737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* mix them all up */ 1637737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(h); 1638737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 163903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (h); 164003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 164103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 1642c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glasermksh_ari_t 1643c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaserrndget(void) 1644c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser{ 1645c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser /* 1646c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * this is the same Linear Congruential PRNG as Borland 1647c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser * C/C++ allegedly uses in its built-in rand() function 1648c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser */ 1649c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser return (((lcg_state = 22695477 * lcg_state + 1) >> 16) & 0x7FFF); 1650c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser} 1651c2dc5def5e2273bb1d78b4ba032a3903dd0f980cThorsten Glaser 165203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 1653811a575c0f6a5ef00a921d14c1830ef5ae1bd796Thorsten Glaserrndset(unsigned long v) 165403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 165503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 1656737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB) 1657737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes register uint32_t t; 1658737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#endif 1659737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes struct { 1660737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes struct timeval tv; 1661737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes void *sp; 1662737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes uint32_t qh; 1663737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes pid_t pp; 1664737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes short r; 1665737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes } z; 1666737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1667737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#ifdef DEBUG 1668737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes /* clear the allocated space, for valgrind */ 1669737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes memset(&z, 0, sizeof(z)); 1670737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#endif 167103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 1672737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes h = lcg_state; 1673737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(h); 1674737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(h, &v, sizeof(v)); 1675737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1676737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes mksh_TIME(z.tv); 1677737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes z.sp = &lcg_state; 1678737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes z.pp = procpid; 1679737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes z.r = (short)rndget(); 168003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 168103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB) 1682737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes t = qh_state; 1683737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(t); 1684737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes z.qh = (t & 0xFFFF8000) | rndget(); 1685737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes lcg_state = (t << 15) | rndget(); 168603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 168703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * either we have very chap entropy get and push available, 168803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * with malloc() pulling in this code already anyway, or the 168903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * user requested us to use the old functions 169003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 1691737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes t = h; 1692737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(t, &lcg_state, sizeof(lcg_state)); 1693737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(t); 1694737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes lcg_state = t; 169503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(arc4random_pushb_fast) 169603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra arc4random_pushb_fast(&lcg_state, sizeof(lcg_state)); 169703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = arc4random(); 169803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 169903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state)); 170003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 1701737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(h, &lcg_state, sizeof(lcg_state)); 1702737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes#else 1703737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes z.qh = qh_state; 170403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 17055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1706737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateMem_reg(h, &z, sizeof(z)); 1707737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHFinish_reg(h); 170803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = h; 17095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1710737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1711737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesvoid 1712737fdce098f804459a925438e48dd711c31bbc9eElliott Hughesrndpush(const void *s) 1713737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes{ 1714737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes register uint32_t h = qh_state; 1715737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes 1716737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateStr_reg(h, s); 1717737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes BAFHUpdateOctet_reg(h, 0); 1718737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes qh_state = h; 1719737fdce098f804459a925438e48dd711c31bbc9eElliott Hughes} 1720