15155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: var.c,v 1.34 2007/10/15 02:16:35 deraadt Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Thorsten Glaser <tg@mirbsd.org> 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 75155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 85155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if defined(__OpenBSD__) 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include <sys/sysctl.h> 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra__RCSID("$MirOS: src/bin/mksh/var.c,v 1.132 2011/09/07 15:24:22 tg Exp $"); 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/*- 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Variables 335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * WARNING: unreadable code, needs a rewrite 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if (flag&INTEGER), val.i contains integer value, and type contains base. 375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * otherwise, (val.s + type) contains string value. 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if (flag&EXPORT), val.s contains "name=value" for E-Z exporting. 395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct tbl vtemp; 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct table specials; 4303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic uint32_t lcg_state = 5381; 4403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char *formatstr(struct tbl *, const char *); 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void exportprep(struct tbl *, const char *); 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int special(const char *); 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void unspecial(const char *); 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void getspec(struct tbl *); 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void setspec(struct tbl *); 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void unsetspec(struct tbl *); 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int getint(struct tbl *, mksh_ari_t *, bool); 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char *array_index_calc(const char *, bool *, uint32_t *); 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * create a new block for function calls and simple commands 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assume caller has allocated and set up e->loc 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querunewblock(void) 615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const char *empty[] = { null }; 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l = alloc(sizeof(struct block), ATEMP); 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->flags = 0; 6703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* TODO: could use e->area (l->area => l->areap) */ 6803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ainit(&l->area); 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!e->loc) { 705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = 0; 715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv = empty; 725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argc = e->loc->argc; 745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->argv = e->loc->argv; 755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->exit = l->error = NULL; 7703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(&l->area, &l->vars, 0); 7803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(&l->area, &l->funs, 0); 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru l->next = e->loc; 805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru e->loc = l; 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pop a block handling special variables 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querupopblock(void) 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t i; 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **vpp = l->vars.tbls, *vq; 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* pop block */ 9403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra e->loc = l->next; 9503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 9603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 1 << (l->vars.tshift); 9703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (--i >= 0) 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp = *vpp++) != NULL && (vp->flag&SPECIAL)) { 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq = global(vp->name))->flag & ISSET) 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsetspec(vq); 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (l->flags & BF_DOGETOPTS) 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_opt = l->getopts_state; 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afreeall(&l->area); 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(l, ATEMP); 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* called by main() to initialise variable data structures */ 1115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_DEFNS 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruenum var_specs { 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_ENUMS 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru V_MAX 1185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* this is biased with -1 relative to VARSPEC_ENUMS */ 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * const initvar_names[] = { 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define VARSPEC_ITEMS 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "var_spec.h" 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinitvar(void) 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i = 0; 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ktinit(APERM, &specials, 13303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* currently 12 specials -> 80% of 16 (2^4) */ 13403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 4); 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i < V_MAX - 1) { 1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktenter(&specials, initvar_names[i], 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hash(initvar_names[i])); 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->flag = DEFINED|ISSET; 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp->type = ++i; 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* common code for several functions below */ 14403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastatic struct block * 14503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravarsearch(struct block *l, struct tbl **vpp, const char *vn, uint32_t h) 14603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 14703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register struct tbl *vp; 14803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 14903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (l) { 15003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch_loop: 15103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((vp = ktsearch(&l->vars, vn, h)) != NULL) 15203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto varsearch_out; 15303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (l->next != NULL) { 15403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l = l->next; 15503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra goto varsearch_loop; 15603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 15703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 15803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp = NULL; 15903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch_out: 16003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra *vpp = vp; 16103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (l); 16203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 16303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 16403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 16503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Used to calculate an array index for global()/local(). Sets *arrayp 16603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to true if this is an array, sets *valp to the array index, returns 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the basename of the array. 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const char * 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarray_index_calc(const char *n, bool *arrayp, uint32_t *valp) 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 17303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *ap = NULL; 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *arrayp = false; 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru redo_from_ref: 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = skip_varname(n, false); 17903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (set_refflag == SRF_NOP && (p != n) && ksh_isalphx(n[0])) { 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *vn; 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(vn, n, p - n, ATEMP); 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check if this is a reference */ 18503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch(e->loc, &vp, vn, hash(vn)); 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vn, ATEMP); 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp && (vp->flag & (DEFINED|ASSOC|ARRAY)) == 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (DEFINED|ASSOC)) { 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *cp; 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* gotcha! */ 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cp = shf_smprintf("%s%s", str_val(vp), p); 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(ap, ATEMP); 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = ap = cp; 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto redo_from_ref; 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p != n && *p == '[' && (len = array_ref_len(p))) { 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *sub, *tmp; 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t rval; 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 20303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* calculate the value of the subscript */ 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *arrayp = true; 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(tmp, p + 1, len - 2, ATEMP); 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sub = substitute(tmp, 0); 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, ATEMP); 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(n, n, p - n, ATEMP); 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(sub, &rval, KSH_UNWIND_ERROR, true); 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *valp = (uint32_t)rval; 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(sub, ATEMP); 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (n); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for variable, if not found create globally. 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruglobal(const char *n) 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c; 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool array; 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h, val; 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check to see if this is an array */ 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = array_index_calc(n, &array, &val); 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru h = hash(n); 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = n[0]; 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalphx(c)) { 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorf("bad substitution"); 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = &vtemp; 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = DEFINED; 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *vp->name = c; 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(c)) { 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = 0; ksh_isdigit(*n); n++) 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = c*10 + *n-'0'; 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c <= l->argc) 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, l->argv[c], KSH_RETURN_ERROR); 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= RDONLY; 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= RDONLY; 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n[1] != '\0') 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ISSET|INTEGER; 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (c) { 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '$': 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = kshpid; 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '!': 25803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if no job, expand to nothing */ 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->val.i = j_async()) == 0) 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ISSET|INTEGER); 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = exstat; 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '#': 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = l->argc; 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '-': 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~INTEGER; 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.s = getoptions(); 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ISSET|INTEGER); 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 27703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra l = varsearch(e->loc, &vp, n, h); 27803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vp != NULL) 27903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (array ? arraysearch(vp, val) : vp); 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = ktenter(&l->vars, n, h); 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = arraysearch(vp, val); 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= DEFINED; 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (special(n)) 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for local variable, if not found create locally. 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querulocal(const char *n, bool copy) 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l = e->loc; 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool array; 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h, val; 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 30003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* check to see if this is an array */ 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = array_index_calc(n, &array, &val); 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru h = hash(n); 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isalphx(*n)) { 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = &vtemp; 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = DEFINED|RDONLY; 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = ktenter(&l->vars, n, h); 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (copy && !(vp->flag & DEFINED)) { 31203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra struct tbl *vq; 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 31403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch(l->next, &vq, n, h); 31503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq != NULL) { 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= vq->flag & 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (EXPORT | INTEGER | RDONLY | LJUST | RJUST | 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ZEROFIL | LCASEV | UCASEV_AL | INT_U | INT_L); 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vq->flag & INTEGER) 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = vq->type; 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field = vq->u2.field; 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (array) 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp = arraysearch(vp, val); 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= DEFINED; 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (special(n)) 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* get variable string value */ 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar * 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustr_val(struct tbl *vp) 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&SPECIAL)) 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getspec(vp); 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag&ISSET)) 34103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* special to dollar() */ 34203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = null; 34303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (!(vp->flag&INTEGER)) 34403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* string source */ 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = vp->val.s + vp->type; 34603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else { 34703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* integer source */ 34803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mksh_uari_t n; 34903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra int base; 35003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /** 35103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * worst case number length is when base == 2: 35203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * 1 (minus) + 2 (base, up to 36) + 1 ('#') + 35303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * number of bits in the mksh_uari_t + 1 (NUL) 35403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char strbuf[1 + 2 + 1 + 8 * sizeof(mksh_uari_t) + 1]; 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *digits = (vp->flag & UCASEV_AL) ? 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru digits_uc : digits_lc; 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = strbuf + sizeof(strbuf); 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & INT_U) 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = vp->val.u; 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = (vp->val.i < 0) ? -vp->val.i : vp->val.i; 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = (vp->type == 0) ? 10 : vp->type; 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 36603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (base == 1 && n == 0) 36703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra base = 2; 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base == 1) { 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t sz = 1; 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *(s = strbuf) = '1'; 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[1] = '#'; 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!UTFMODE || ((n & 0xFF80) == 0xEF80)) 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* OPTU-16 -> raw octet */ 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[2] = n & 0xFF; 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sz = utf_wctomb(s + 2, n); 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s[2 + sz] = '\0'; 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '\0'; 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[n % base]; 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n /= base; 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (n != 0); 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base != 10) { 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '#'; 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[base % 10]; 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base >= 10) 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = digits[base / 10]; 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag & INT_U) && vp->val.i < 0) 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *--s = '-'; 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 39403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vp->flag & (RJUST|LJUST)) 39503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* case already dealt with */ 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = formatstr(vp, s); 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(s, s, ATEMP); 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set variable to string value */ 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetstr(struct tbl *vq, const char *s, int error_ok) 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *salloc = NULL; 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int no_ro_check = error_ok & 0x4; 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru error_ok &= ~0x4; 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag & RDONLY) && !no_ro_check) { 41203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra warningf(true, "%s: %s", vq->name, "is read only"); 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!error_ok) 41403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorfxz(2); 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 41703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(vq->flag&INTEGER)) { 41803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* string dest */ 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&ALLOC)) { 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* debugging */ 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s >= vq->val.s && 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s <= vq->val.s + strlen(vq->val.s)) 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_errorf( 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "setstr: %s=%s: assigning to self", 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->name, s); 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vq->val.s, vq->areap); 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag &= ~(ISSET|ALLOC); 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->type = 0; 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s && (vq->flag & (UCASEV_AL|LCASEV|LJUST|RJUST))) 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = salloc = formatstr(vq, s); 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&EXPORT)) 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exportprep(vq, s); 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(vq->val.s, s, vq->areap); 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ALLOC; 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 43803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 43903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* integer dest */ 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!v_evaluate(vq, s, error_ok, true)) 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET; 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&SPECIAL)) 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(salloc, ATEMP); 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set variable to integer */ 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetint(struct tbl *vq, mksh_ari_t n) 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vq->flag&INTEGER)) { 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp = &vtemp; 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = (ISSET|INTEGER); 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = 0; 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->areap = ATEMP; 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->val.i = n; 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vq, str_val(vp), KSH_RETURN_ERROR); 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->val.i = n; 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET; 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vq->flag&SPECIAL)) 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetint(struct tbl *vp, mksh_ari_t *nump, bool arith) 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int c, base, neg; 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool have_base = false; 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t num; 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag&SPECIAL) 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getspec(vp); 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX is it possible for ISSET to be set and val.s to be 0? */ 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vp->flag&ISSET) || (!(vp->flag&INTEGER) && vp->val.s == NULL)) 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag&INTEGER) { 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *nump = vp->val.i; 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp->type); 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = vp->val.s + vp->type; 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = 10; 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = 0; 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru neg = 0; 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (arith && *s == '0' && *(s+1)) { 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*s == 'x' || *s == 'X') { 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = 16; 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (vp->flag & ZEROFIL) { 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*s == '0') 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = 8; 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru have_base = true; 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (c = *s++; c ; c = *s++) { 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '-') { 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru neg++; 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (c == '#') { 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = (int)num; 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (have_base || base < 1 || base > 36) 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base == 1) { 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned int wc; 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!UTFMODE) 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wc = *(unsigned char *)s; 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (utf_mbtowc(&wc, s) == (size_t)-1) 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* OPTU-8 -> OPTU-16 */ 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (with a twist: 1#\uEF80 converts 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the same as 1#\x80 does, thus is 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * not round-tripping correctly XXX) 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wc = 0xEF00 + *(unsigned char *)s; 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *nump = (mksh_ari_t)wc; 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = 0; 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru have_base = true; 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru continue; 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (ksh_isdigit(c)) 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c -= '0'; 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ksh_islower(c)) 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c -= 'a' - 10; 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (ksh_isupper(c)) 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c -= 'A' - 10; 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c < 0 || c >= base) 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = num * base + c; 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (neg) 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru num = -num; 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *nump = num; 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (base); 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 54703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 54803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * convert variable vq to integer variable, setting its value from vp 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (vq and vp may be the same) 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetint_v(struct tbl *vq, struct tbl *vp, bool arith) 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int base; 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t num; 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((base = getint(vp, &num, arith)) == -1) 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 55903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setint_n(vq, num); 56003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vq->type == 0) 56103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default base */ 56203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = base; 56303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (vq); 56403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 56503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 56603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* convert variable vq to integer variable, setting its value to num */ 56703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 56803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasetint_n(struct tbl *vq, mksh_ari_t num) 56903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(vq->flag & INTEGER) && (vq->flag & ALLOC)) { 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag &= ~ALLOC; 57203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vq->type = 0; 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vq->val.s, vq->areap); 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->val.i = num; 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq->flag |= ISSET|INTEGER; 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vq->flag&SPECIAL) 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setspec(vq); 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char * 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruformatstr(struct tbl *vp, const char *s) 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int olen, nlen; 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *q; 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t psiz; 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 58803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra olen = (int)utf_mbswidth(s); 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & (RJUST|LJUST)) { 59103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!vp->u2.field) 59203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* default field width */ 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field = olen; 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nlen = vp->u2.field; 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nlen = olen; 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = alloc((psiz = nlen * /* MB_LEN_MAX */ 3 + 1), ATEMP); 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & (RJUST|LJUST)) { 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int slen = olen, i = 0; 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & RJUST) { 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *qq = s; 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n = 0; 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (i < slen) 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i += utf_widthadj(qq, &qq); 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* strip trailing spaces (AT&T uses qq[-1] == ' ') */ 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (qq > s && ksh_isspace(qq[-1])) { 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --qq; 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru --slen; 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ZEROFIL && vp->flag & INTEGER) { 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s[1] == '#') 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 2; 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (s[2] == '#') 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 3; 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->u2.field <= n) 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = 0; 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n) { 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p, s, n); 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += n; 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (slen > vp->u2.field) 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru slen -= utf_widthadj(s, &s); 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->u2.field - slen) 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memset(p + n, (vp->flag & ZEROFIL) ? '0' : ' ', 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field - slen); 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru slen -= n; 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(p + vp->u2.field - slen, 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru psiz - (vp->u2.field - slen), 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "%.*s", slen, s); 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* strip leading spaces/zeros */ 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (ksh_isspace(*s)) 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ZEROFIL) 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*s == '0') 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s++; 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_snprintf(p, nlen + 1, "%-*.*s", 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u2.field, vp->u2.field, s); 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(p, s, strlen(s) + 1); 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & UCASEV_AL) { 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (q = p; *q; q++) 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *q = ksh_toupper(*q); 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (vp->flag & LCASEV) { 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (q = p; *q; q++) 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *q = ksh_tolower(*q); 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * make vp->val.s be "name=value" for quick exporting. 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruexportprep(struct tbl *vp, const char *val) 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *op = (vp->flag&ALLOC) ? vp->val.s : NULL; 66603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t namelen, vallen; 66703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 66803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra namelen = strlen(vp->name); 66903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vallen = strlen(val) + 1; 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ALLOC; 67203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* since name+val are both in memory this can go unchecked */ 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp = alloc(namelen + 1 + vallen, vp->areap); 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(vp->val.s = xp, vp->name, namelen); 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += namelen; 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp++ = '='; 67703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* offset to value */ 67803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp->type = xp - vp->val.s; 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(xp, val, vallen); 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (op != NULL) 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(op, vp->areap); 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 68503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * lookup variable (according to (set&LOCAL)), set its attributes 68603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * (INTEGER, RDONLY, EXPORT, TRACE, LJUST, RJUST, ZEROFIL, LCASEV, 68703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * UCASEV_AL), and optionally set its value if an assignment. 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustruct tbl * 69003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condratypeset(const char *var, uint32_t set, uint32_t clr, int field, int base) 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp; 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vpbase, *t; 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *tvar; 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *val; 69603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t len; 69703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool vappend = false; 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check for valid variable name, search for value */ 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = skip_varname(var, false); 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == var) 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mkssert(var != NULL); 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mkssert(*var != 0); 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*val == '[') { 70603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (set_refflag != SRF_NOP) 70703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s", var, 70803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra "reference variable can't be an array"); 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = array_ref_len(val); 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (len == 0) 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 71203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 71303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * IMPORT is only used when the shell starts up and is 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * setting up its environment. Allow only simple array 71503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * references at this time since parameter/command 71603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * substitution is preformed on the [expression] which 71703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * would be a major security hole. 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set & IMPORT) { 72003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t i; 72103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 1; i < len - 1; i++) 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ksh_isdigit(val[i])) 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val += len; 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 72803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (val[0] == '=' || (val[0] == '+' && val[1] == '=')) { 72903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strndupx(tvar, var, val - var, ATEMP); 73003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (*val++ == '+') { 73103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ++val; 73203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vappend = true; 73303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 73403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else { 73503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* importing from original environment: must have an = */ 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set & IMPORT) 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(tvar, var, ATEMP); 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = NULL; 74003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* handle foo[*] => foo (whole array) mapping for R39b */ 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = strlen(tvar); 74203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (len > 3 && tvar[len - 3] == '[' && tvar[len - 2] == '*' && 74303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tvar[len - 1] == ']') 74403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tvar[len - 3] = '\0'; 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 74703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (set_refflag == SRF_ENABLE) { 74803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra const char *qval; 74903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 75003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* bail out on 'nameref foo+=bar' */ 75103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vappend) 75203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorfz(); 75303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* find value if variable already exists */ 75403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if ((qval = val) == NULL) { 75503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra varsearch(e->loc, &vp, tvar, hash(tvar)); 75603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vp != NULL) 75703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra qval = str_val(vp); 75803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 75903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* silently ignore 'nameref foo=foo' */ 76003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (qval != NULL && !strcmp(qval, tvar)) { 76103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(tvar, ATEMP); 76203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (&vtemp); 76303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 76403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 76503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 76603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* prevent typeset from creating a local PATH/ENV/SHELL */ 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FRESTRICTED) && (strcmp(tvar, "PATH") == 0 || 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strcmp(tvar, "ENV") == 0 || strcmp(tvar, "SHELL") == 0)) 76903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s", tvar, "restricted"); 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 77103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp = (set&LOCAL) ? local(tvar, tobool(set & LOCAL_COPY)) : 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru global(tvar); 77303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (set_refflag == SRF_DISABLE && (vp->flag & (ARRAY|ASSOC)) == ASSOC) 7745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~ASSOC; 77503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra else if (set_refflag == SRF_ENABLE) { 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ARRAY) { 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *a, *tmp; 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 77903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up entire array */ 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (a = vp->u.array; a; ) { 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmp = a; 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru a = a->u.array; 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmp->flag & ALLOC) 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp->val.s, tmp->areap); 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, tmp->areap); 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u.array = NULL; 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~ARRAY; 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= ASSOC; 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru set &= ~(LOCAL|LOCAL_COPY); 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vpbase = (vp->flag & ARRAY) ? global(arrayname(var)) : vp; 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 79703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 79803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * only allow export flag to be set; AT&T ksh allows any 79903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * attribute to be changed which means it can be truncated or 80003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * modified (-L/-R/-Z/-i) 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vpbase->flag&RDONLY) && 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (val || clr || (set & ~EXPORT))) 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX check calls - is error here ok by POSIX? */ 80503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorfx(2, "%s: %s", tvar, "is read only"); 8065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tvar, ATEMP); 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* most calls are with set/clr == 0 */ 8095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set | clr) { 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool ok = true; 8115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 81203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 81303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * XXX if x[0] isn't set, there will be problems: need 81403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to have one copy of attributes for arrays... 8155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (t = vpbase; t; t = t->u.array) { 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool fake_assign; 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s = NULL; 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *free_me = NULL; 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fake_assign = (t->flag & ISSET) && (!val || t != vp) && 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((set & (UCASEV_AL|LCASEV|LJUST|RJUST|ZEROFIL)) || 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((t->flag & INTEGER) && (clr & INTEGER)) || 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!(t->flag & INTEGER) && (set & INTEGER))); 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fake_assign) { 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & INTEGER) { 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(t); 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru free_me = NULL; 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = t->val.s + t->type; 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru free_me = (t->flag & ALLOC) ? t->val.s : 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru NULL; 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ALLOC; 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(t->flag & INTEGER) && (set & INTEGER)) { 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = 0; 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ALLOC; 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag = (t->flag | set) & ~clr; 84103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 84203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Don't change base if assignment is to be 84303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * done, in case assignment fails. 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((set & INTEGER) && base > 0 && (!val || t != vp)) 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = base; 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (set & (LJUST|RJUST|ZEROFIL)) 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->u2.field = field; 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fake_assign) { 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!setstr(t, s, KSH_RETURN_ERROR)) { 85103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 85203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Somewhat arbitrary action 85303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * here: zap contents of 85403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * variable, but keep the flag 85503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * settings. 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ok = false; 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & INTEGER) 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~ISSET; 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (t->flag & ALLOC) 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(t->val.s, t->areap); 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->flag &= ~(ISSET|ALLOC); 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru t->type = 0; 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (free_me) 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(free_me, t->areap); 8695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!ok) 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errorfz(); 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val != NULL) { 87603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *tval; 87703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 87803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (vappend) { 87903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tval = shf_smprintf("%s%s", str_val(vp), val); 88003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra val = tval; 88103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } else 88203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tval = NULL; 88303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag&INTEGER) { 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do not zero base before assignment */ 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_UNWIND_ERROR | 0x4); 88703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* done after assignment to override default */ 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base > 0) 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->type = base; 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail (readonly check already done) */ 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_RETURN_ERROR | 0x4); 89303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 89403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (tval != NULL) 89503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(tval, ATEMP); 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* only x[0] is ever exported, so use vpbase */ 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vpbase->flag&EXPORT) && !(vpbase->flag&INTEGER) && 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vpbase->type == 0) 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exportprep(vpbase, (vpbase->flag&ISSET) ? vpbase->val.s : null); 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/** 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Unset a variable. The flags can be: 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * |1 = tear down entire array 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * |2 = keep attributes, only unset content 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunset(struct tbl *vp, int flags) 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ALLOC) 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(vp->val.s, vp->areap); 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag & ARRAY) && (flags & 1)) { 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *a, *tmp; 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 91903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* free up entire array */ 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (a = vp->u.array; a; ) { 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmp = a; 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru a = a->u.array; 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmp->flag & ALLOC) 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp->val.s, tmp->areap); 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmp, tmp->areap); 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->u.array = NULL; 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & 2) { 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(ALLOC|ISSET); 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 93303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* if foo[0] is being unset, the remainder of the array is kept... */ 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= SPECIAL | ((flags & 1) ? 0 : ARRAY|DEFINED); 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & SPECIAL) 93603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* responsible for 'unspecial'ing var */ 93703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra unsetspec(vp); 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 94003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 94103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Return a pointer to the first char past a legal variable name 94203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * (returns the argument if there is no legal name, returns a pointer to 94303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * the terminating NUL if whole string is legal). 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char * 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruskip_varname(const char *s, int aok) 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 94803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t alen; 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s && ksh_isalphx(*s)) { 9515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*++s && ksh_isalnux(*s)) 9525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (aok && *s == '[' && (alen = array_ref_len(s))) 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += alen; 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Return a pointer to the first character past any legal variable name */ 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruconst char * 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruskip_wdvarname(const char *s, 96203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* skip array de-reference? */ 96303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra bool aok) 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s[0] == CHAR && ksh_isalphx(s[1])) { 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru do { 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s += 2; 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } while (s[0] == CHAR && ksh_isalnux(s[1])); 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (aok && s[0] == CHAR && s[1] == '[') { 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* skip possible array de-reference */ 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = s; 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char c; 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int depth = 0; 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 97503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (/* CONSTCOND */ 1) { 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p[0] != CHAR) 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru c = p[1]; 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p += 2; 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (c == ']' && --depth == 0) { 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = p; 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s); 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Check if coded string s is a variable name */ 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 99403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrais_wdvarname(const char *s, bool aok) 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = skip_wdvarname(s, aok); 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p != s && p[0] == EOS); 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Check if coded string s is a variable assignment */ 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruis_wdvarassign(const char *s) 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p = skip_wdvarname(s, true); 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 100703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (p != s && p[0] == CHAR && 100803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra (p[1] == '=' || (p[1] == '+' && p[2] == CHAR && p[3] == '='))); 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Make the exported environment from the exported names in the dictionary. 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar ** 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumakenv(void) 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 101703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ssize_t i; 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l; 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPtrV denv; 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, **vpp; 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPinit(denv, 64); 102303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (l = e->loc; l != NULL; l = l->next) { 102403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vpp = l->vars.tbls; 102503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = 1 << (l->vars.tshift); 102603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra while (--i >= 0) 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp = *vpp++) != NULL && 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (vp->flag&(ISSET|EXPORT)) == (ISSET|EXPORT)) { 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct block *l2; 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp2; 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru uint32_t h = hash(vp->name); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* unexport any redefined instances */ 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (l2 = l->next; l2 != NULL; l2 = l2->next) { 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp2 = ktsearch(&l2->vars, vp->name, h); 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp2 != NULL) 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp2->flag &= ~EXPORT; 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&INTEGER)) { 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* integer to string */ 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *val; 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru val = str_val(vp); 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~(INTEGER|RDONLY|SPECIAL); 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* setstr can't fail here */ 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vp, val, KSH_RETURN_ERROR); 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(denv, vp->val.s); 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 104903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XPput(denv, NULL); 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return ((char **)XPclose(denv)); 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * handle special variables with side effects - PATH, SECONDS. 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Test if name is a special parameter */ 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruspecial(const char *name) 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&specials, name, hash(name)); 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (tp && (tp->flag & ISSET) ? tp->type : V_NONE); 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Make a variable non-special */ 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunspecial(const char *name) 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *tp; 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tp = ktsearch(&specials, name, hash(name)); 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tp) 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ktdelete(tp); 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic time_t seconds; /* time SECONDS last set */ 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int user_lineno; /* what user set $LINENO to */ 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugetspec(struct tbl *vp) 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru register mksh_ari_t i; 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int st; 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((st = special(vp->name))) { 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * On start up the value of SECONDS is used before 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it has been set - don't do anything in this case 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (see initcoms[] in main.c). 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (vp->flag & ISSET) { 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval tv; 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gettimeofday(&tv, NULL); 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = tv.tv_sec - seconds; 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this is the same Linear Congruential PRNG as Borland 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * C/C++ allegedly uses in its built-in rand() function 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 110803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = ((lcg_state = 22695477 * lcg_state + 1) >> 16) & 0x7FFF; 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_HISTSIZE: 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = histsize; 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_OPTIND: 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = user_opt.uoptind; 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = current_lineno + user_lineno; 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_COLUMNS: 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Do NOT export COLUMNS/LINES. Many applications 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * check COLUMNS/LINES before checking ws.ws_col/row, 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * so if the app is started with C/L in the environ 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and the window is then resized, the app won't 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * see the change cause the environ doesn't change. 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru change_winsz(); 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i = st == V_COLUMNS ? x_cols : x_lins; 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do nothing, do not touch vp at all */ 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~SPECIAL; 113603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra setint_n(vp, i); 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetspec(struct tbl *vp) 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru mksh_ari_t i; 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int st; 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch ((st = special(vp->name))) { 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_PATH: 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (path) 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(path, APERM); 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(vp); 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(path, s, APERM); 115303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clear tracked aliases */ 115403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flushcom(true); 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_IFS: 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setctypes(s = str_val(vp), C_IFS); 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ifs0 = *s; 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_TMPDIR: 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmpdir) { 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmpdir, APERM); 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmpdir = NULL; 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 116503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 116603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Use tmpdir iff it is an absolute path, is writable 116703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * and searchable and is a directory... 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = str_val(vp); 117303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* LINTED use of access */ 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (s[0] == '/' && access(s, W_OK|X_OK) == 0 && 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru stat(s, &statb) == 0 && S_ISDIR(statb.st_mode)) 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(tmpdir, s, APERM); 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 117803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_HISTFILE: 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sethistfile(str_val(vp)); 118203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return; 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* common sub-cases */ 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_OPTIND: 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_HISTSIZE: 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_COLUMNS: 11895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 11925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 119303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 11945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag &= ~SPECIAL; 119503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (getint(vp, &i, false) == -1) { 119603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra s = str_val(vp); 119703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (st != V_RANDOM) 119803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorf("%s: %s: %s", vp->name, "bad number", s); 119903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra i = hash(s); 120003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 12015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag |= SPECIAL; 12025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru default: 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do nothing, do not touch vp at all */ 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* process the singular parts of the common cases */ 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (st) { 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_OPTIND: 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getopts_reset((int)i); 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_HISTSIZE: 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sethistsize((int)i); 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_COLUMNS: 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i >= MIN_COLS) 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = i; 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINES: 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i >= MIN_LINS) 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_lins = i; 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * mksh R39d+ no longer has the traditional repeatability 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of $RANDOM sequences, but always retains state 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 123003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra rndset((long)i); 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct timeval tv; 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gettimeofday(&tv, NULL); 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru seconds = tv.tv_sec - i; 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* The -1 is because line numbering starts at 1. */ 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru user_lineno = (unsigned int)i - current_lineno - 1; 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 124403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 124503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra ksh_tmout = i >= 0 ? i : 0; 124603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra break; 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruunsetspec(struct tbl *vp) 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (special(vp->name)) { 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_PATH: 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (path) 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(path, APERM); 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(path, def_path, APERM); 125803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* clear tracked aliases */ 125903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra flushcom(true); 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_IFS: 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setctypes(" \t\n", C_IFS); 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ifs0 = ' '; 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_TMPDIR: 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* should not become unspecial */ 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tmpdir) { 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(tmpdir, APERM); 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tmpdir = NULL; 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_LINENO: 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_RANDOM: 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case V_SECONDS: 127503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra case V_TMOUT: 127603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* AT&T ksh leaves previous value in place */ 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unspecial(vp->name); 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * AT&T ksh man page says OPTIND, OPTARG and _ lose special 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * meaning, but OPTARG does not (still set by getopts) and _ is 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * also still set in various places. Don't know what AT&T does 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * for HISTSIZE, HISTFILE. Unsetting these in AT&T ksh does not 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * loose the 'specialness': IFS, COLUMNS, PATH, TMPDIR 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Search for (and possibly create) a table entry starting with 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * vp, indexed by val. 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 129403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrastruct tbl * 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarraysearch(struct tbl *vp, uint32_t val) 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *prev, *curr, *news; 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t len; 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vp->flag = (vp->flag | (ARRAY|DEFINED)) & ~ASSOC; 130103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* the table entry is always [0] */ 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (val == 0) 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (vp); 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev = vp; 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru curr = vp->u.array; 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (curr && curr->ua.index < val) { 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev = curr; 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru curr = curr->u.array; 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (curr && curr->ua.index == val) { 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (curr->flag&ISSET) 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (curr); 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news = curr; 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news = NULL; 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!news) { 131703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra len = strlen(vp->name); 131803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra checkoktoadd(len, 1 + offsetof(struct tbl, name[0])); 131903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra news = alloc(offsetof(struct tbl, name[0]) + ++len, vp->areap); 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(news->name, vp->name, len); 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->flag = (vp->flag & ~(ALLOC|DEFINED|ISSET|SPECIAL)) | AINDEX; 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->type = vp->type; 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->areap = vp->areap; 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->u2.field = vp->u2.field; 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->ua.index = val; 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 132803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (curr != news) { 132903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* not reusing old array entry */ 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru prev->u.array = news; 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news->u.array = curr; 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (news); 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 133603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra/* 133703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * Return the length of an array reference (eg, [1+2]) - cp is assumed 133803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * to point to the open bracket. Returns 0 if there is no matching 133903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * closing bracket. 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 134103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrasize_t 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarray_ref_len(const char *cp) 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *s = cp; 134503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char c; 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int depth = 0; 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((c = *s++) && (c != ']' || --depth)) 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (c == '[') 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru depth++; 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!c) 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (s - cp); 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Make a copy of the base of an array name 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar * 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruarrayname(const char *str) 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *rv; 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p = cstrchr(str, '[')) == 0) 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Shouldn't happen, but why worry? */ 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(rv, str, ATEMP); 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(rv, str, p - str, ATEMP); 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* set (or overwrite, if reset) the array variable var to the values in vals */ 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querumksh_uari_t 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruset_array(const char *var, bool reset, const char **vals) 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct tbl *vp, *vq; 137903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra mksh_uari_t i = 0, j = 0; 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *ccp; 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 138203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra char *cp = NULL; 138303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra size_t n; 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* to get local array, use "typeset foo; set -A foo" */ 138703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#ifndef MKSH_SMALL 138803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra n = strlen(var); 138903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (n > 0 && var[n - 1] == '+') { 139003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* append mode */ 139103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra reset = false; 139203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra strndupx(cp, var, n - 1, ATEMP); 139303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 139403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define CPORVAR (cp ? cp : var) 139503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 139603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#define CPORVAR var 139703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 139803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra vp = global(CPORVAR); 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Note: AT&T ksh allows set -A but not set +A of a read-only var */ 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((vp->flag&RDONLY)) 140203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra errorfx(2, "%s: %s", CPORVAR, "is read only"); 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* This code is quite non-optimal */ 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (reset) 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* trash existing values and attributes */ 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unset(vp, 1); 140703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 140803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * TODO: would be nice for assignment to completely succeed or 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * completely fail. Only really effects integer arrays: 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * evaluation of some of vals[] may fail... 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 141303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (cp != NULL) { 141403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* find out where to set when appending */ 141503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra for (vq = vp; vq; vq = vq->u.array) { 141603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (!(vq->flag & ISSET)) 141703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra continue; 141803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra if (arrayindex(vq) >= j) 141903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra j = arrayindex(vq) + 1; 142003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 142103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra afree(cp, ATEMP); 142203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra } 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((ccp = vals[i])) { 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MKSH_SMALL 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == '[') { 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int level = 0; 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (*ccp) { 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == ']' && --level == 0) 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == '[') 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++level; 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++ccp; 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*ccp == ']' && level == 0 && ccp[1] == '=') { 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strndupx(cp, vals[i] + 1, ccp - (vals[i] + 1), 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ATEMP); 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru evaluate(substitute(cp, 0), (mksh_ari_t *)&j, 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru KSH_UNWIND_ERROR, true); 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(cp, ATEMP); 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ccp += 2; 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ccp = vals[i]; 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru vq = arraysearch(vp, j); 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* would be nice to deal with errors here... (see above) */ 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(vq, ccp, KSH_RETURN_ERROR); 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru i++; 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru j++; 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (i); 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchange_winsz(void) 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_lins < 0) { 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* first time initialisation */ 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef TIOCGWINSZ 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tty_fd < 0) 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* non-FTALKING, try to get an fd anyway */ 146603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra tty_init(true, false); 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = -1; 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef TIOCGWINSZ 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* check if window size has changed */ 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (tty_fd >= 0) { 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct winsize ws; 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ioctl(tty_fd, TIOCGWINSZ, &ws) >= 0) { 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ws.ws_col) 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = ws.ws_col; 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ws.ws_row) 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_lins = ws.ws_row; 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* bounds check for sane values, use defaults otherwise */ 14865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_cols < MIN_COLS) 14875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_cols = 80; 14885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (x_lins < MIN_LINS) 14895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru x_lins = 24; 14905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifdef SIGWINCH 14925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru got_winch = 0; 14935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 14945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruuint32_t 149703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrahash(const void *s) 14985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 149903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 150003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 150103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATInit(h); 150203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATUpdateString(h, s); 150303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATFinish(h); 150403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra return (h); 150503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra} 150603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 150703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condravoid 150803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condrarndset(long v) 150903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra{ 151003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra register uint32_t h; 151103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 151203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATInit(h); 151303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); 151403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATUpdateMem(h, &v, sizeof(v)); 151503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra 151603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB) 151703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra /* 151803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * either we have very chap entropy get and push available, 151903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * with malloc() pulling in this code already anyway, or the 152003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra * user requested us to use the old functions 152103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra */ 152203ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = h; 152303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZAATFinish(lcg_state); 152403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#if defined(arc4random_pushb_fast) 152503ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra arc4random_pushb_fast(&lcg_state, sizeof(lcg_state)); 152603ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = arc4random(); 152703ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#else 152803ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state)); 152903ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 153003ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); 153103ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra#endif 15325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 153303ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra NZAATFinish(h); 153403ebf06f4e1112a0e9533b93062d169232c4cbfeGeremy Condra lcg_state = h; 15355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1536