1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 7*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate /* 10*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 11*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement 12*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 13*7c478bd9Sstevel@tonic-gate */ 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate #include "sh.h" 18*7c478bd9Sstevel@tonic-gate #include "sh.tconst.h" 19*7c478bd9Sstevel@tonic-gate extern didchdir; 20*7c478bd9Sstevel@tonic-gate 21*7c478bd9Sstevel@tonic-gate /* 22*7c478bd9Sstevel@tonic-gate * C Shell 23*7c478bd9Sstevel@tonic-gate */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate doset(v) 26*7c478bd9Sstevel@tonic-gate register tchar **v; 27*7c478bd9Sstevel@tonic-gate { 28*7c478bd9Sstevel@tonic-gate register tchar *p; 29*7c478bd9Sstevel@tonic-gate tchar *vp, op; 30*7c478bd9Sstevel@tonic-gate tchar **vecp; 31*7c478bd9Sstevel@tonic-gate bool hadsub; 32*7c478bd9Sstevel@tonic-gate int subscr; 33*7c478bd9Sstevel@tonic-gate tchar *retp; 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #ifdef TRACE 36*7c478bd9Sstevel@tonic-gate tprintf("TRACE- doset()\n"); 37*7c478bd9Sstevel@tonic-gate #endif 38*7c478bd9Sstevel@tonic-gate v++; 39*7c478bd9Sstevel@tonic-gate p = *v++; 40*7c478bd9Sstevel@tonic-gate if (p == 0) { 41*7c478bd9Sstevel@tonic-gate prvars(); 42*7c478bd9Sstevel@tonic-gate return; 43*7c478bd9Sstevel@tonic-gate } 44*7c478bd9Sstevel@tonic-gate do { 45*7c478bd9Sstevel@tonic-gate hadsub = 0; 46*7c478bd9Sstevel@tonic-gate /* 47*7c478bd9Sstevel@tonic-gate * check for proper variable syntax 48*7c478bd9Sstevel@tonic-gate * must be alphanumeric, start with a letter and 49*7c478bd9Sstevel@tonic-gate * be at most 20 characters 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate for (vp = p; alnum(*p); p++) 52*7c478bd9Sstevel@tonic-gate continue; 53*7c478bd9Sstevel@tonic-gate if (vp == p || !letter(*vp)) 54*7c478bd9Sstevel@tonic-gate goto setsyn; 55*7c478bd9Sstevel@tonic-gate if ( (p - vp) > MAX_VAR_LEN ) 56*7c478bd9Sstevel@tonic-gate bferr("Variable name too long"); 57*7c478bd9Sstevel@tonic-gate if (*p == '[') { 58*7c478bd9Sstevel@tonic-gate hadsub++; 59*7c478bd9Sstevel@tonic-gate p = getinx(p, &subscr); 60*7c478bd9Sstevel@tonic-gate } 61*7c478bd9Sstevel@tonic-gate if (op = *p) { 62*7c478bd9Sstevel@tonic-gate *p++ = 0; 63*7c478bd9Sstevel@tonic-gate if (*p == 0 && *v && **v == '(') 64*7c478bd9Sstevel@tonic-gate p = *v++; 65*7c478bd9Sstevel@tonic-gate } else if (*v && eq(*v, S_EQ/*"="*/)) { 66*7c478bd9Sstevel@tonic-gate op = '=', v++; 67*7c478bd9Sstevel@tonic-gate if (*v) 68*7c478bd9Sstevel@tonic-gate p = *v++; 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate if (op && op != '=') 71*7c478bd9Sstevel@tonic-gate setsyn: 72*7c478bd9Sstevel@tonic-gate bferr("Syntax error"); 73*7c478bd9Sstevel@tonic-gate if (eq(p, S_LPAR/*"("*/)) { 74*7c478bd9Sstevel@tonic-gate register tchar **e = v; 75*7c478bd9Sstevel@tonic-gate 76*7c478bd9Sstevel@tonic-gate if (hadsub) 77*7c478bd9Sstevel@tonic-gate goto setsyn; 78*7c478bd9Sstevel@tonic-gate for (;;) { 79*7c478bd9Sstevel@tonic-gate if (!*e) 80*7c478bd9Sstevel@tonic-gate bferr("Missing )"); 81*7c478bd9Sstevel@tonic-gate if (**e == ')') 82*7c478bd9Sstevel@tonic-gate break; 83*7c478bd9Sstevel@tonic-gate e++; 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate p = *e; 86*7c478bd9Sstevel@tonic-gate *e = 0; 87*7c478bd9Sstevel@tonic-gate vecp = saveblk(v); 88*7c478bd9Sstevel@tonic-gate set1(vp, vecp, &shvhed); 89*7c478bd9Sstevel@tonic-gate *e = p; 90*7c478bd9Sstevel@tonic-gate v = e + 1; 91*7c478bd9Sstevel@tonic-gate } else if (hadsub) { 92*7c478bd9Sstevel@tonic-gate retp = savestr(p); 93*7c478bd9Sstevel@tonic-gate asx(vp, subscr, retp); 94*7c478bd9Sstevel@tonic-gate xfree(retp); 95*7c478bd9Sstevel@tonic-gate retp = 0; 96*7c478bd9Sstevel@tonic-gate } else 97*7c478bd9Sstevel@tonic-gate set(vp, savestr(p)); 98*7c478bd9Sstevel@tonic-gate if (eq(vp, S_path/*"path"*/)) { 99*7c478bd9Sstevel@tonic-gate exportpath(adrof(S_path/*"path"*/)->vec); 100*7c478bd9Sstevel@tonic-gate dohash(xhash); 101*7c478bd9Sstevel@tonic-gate } else if (eq(vp, S_histchars/*"histchars"*/)) { 102*7c478bd9Sstevel@tonic-gate register tchar *p = value(S_histchars/*"histchars"*/); 103*7c478bd9Sstevel@tonic-gate HIST = *p++; 104*7c478bd9Sstevel@tonic-gate HISTSUB = *p; 105*7c478bd9Sstevel@tonic-gate } else if (eq(vp, S_user/*"user"*/)) 106*7c478bd9Sstevel@tonic-gate local_setenv(S_USER/*"USER"*/, value(vp)); 107*7c478bd9Sstevel@tonic-gate else if (eq(vp, S_term/*"term"*/)) 108*7c478bd9Sstevel@tonic-gate local_setenv(S_TERM/*"TERM"*/, value(vp)); 109*7c478bd9Sstevel@tonic-gate else if (eq(vp, S_home/*"home"*/)) 110*7c478bd9Sstevel@tonic-gate local_setenv(S_HOME/*"HOME"*/, value(vp)); 111*7c478bd9Sstevel@tonic-gate #ifdef FILEC 112*7c478bd9Sstevel@tonic-gate else if (eq(vp, S_filec/*"filec"*/)) 113*7c478bd9Sstevel@tonic-gate filec = 1; 114*7c478bd9Sstevel@tonic-gate else if (eq(vp, S_cdpath/*"cdpath"*/)) 115*7c478bd9Sstevel@tonic-gate dohash(xhash2); 116*7c478bd9Sstevel@tonic-gate #endif 117*7c478bd9Sstevel@tonic-gate } while (p = *v++); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate tchar * 121*7c478bd9Sstevel@tonic-gate getinx(cp, ip) 122*7c478bd9Sstevel@tonic-gate register tchar *cp; 123*7c478bd9Sstevel@tonic-gate register int *ip; 124*7c478bd9Sstevel@tonic-gate { 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate #ifdef TRACE 127*7c478bd9Sstevel@tonic-gate tprintf("TRACE- getinx()\n"); 128*7c478bd9Sstevel@tonic-gate #endif 129*7c478bd9Sstevel@tonic-gate *ip = 0; 130*7c478bd9Sstevel@tonic-gate *cp++ = 0; 131*7c478bd9Sstevel@tonic-gate while (*cp && digit(*cp)) 132*7c478bd9Sstevel@tonic-gate *ip = *ip * 10 + *cp++ - '0'; 133*7c478bd9Sstevel@tonic-gate if (*cp++ != ']') 134*7c478bd9Sstevel@tonic-gate bferr("Subscript error"); 135*7c478bd9Sstevel@tonic-gate return (cp); 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate asx(vp, subscr, p) 139*7c478bd9Sstevel@tonic-gate tchar *vp; 140*7c478bd9Sstevel@tonic-gate int subscr; 141*7c478bd9Sstevel@tonic-gate tchar *p; 142*7c478bd9Sstevel@tonic-gate { 143*7c478bd9Sstevel@tonic-gate register struct varent *v = getvx(vp, subscr); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate #ifdef TRACE 146*7c478bd9Sstevel@tonic-gate tprintf("TRACE- asx()\n"); 147*7c478bd9Sstevel@tonic-gate #endif 148*7c478bd9Sstevel@tonic-gate xfree(v->vec[subscr - 1]); 149*7c478bd9Sstevel@tonic-gate v->vec[subscr - 1] = globone(p); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate struct varent * 153*7c478bd9Sstevel@tonic-gate getvx(vp, subscr) 154*7c478bd9Sstevel@tonic-gate tchar *vp; 155*7c478bd9Sstevel@tonic-gate { 156*7c478bd9Sstevel@tonic-gate register struct varent *v = adrof(vp); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate #ifdef TRACE 159*7c478bd9Sstevel@tonic-gate tprintf("TRACE- getvx()\n"); 160*7c478bd9Sstevel@tonic-gate #endif 161*7c478bd9Sstevel@tonic-gate if (v == 0) 162*7c478bd9Sstevel@tonic-gate udvar(vp); 163*7c478bd9Sstevel@tonic-gate if (subscr < 1 || subscr > blklen(v->vec)) 164*7c478bd9Sstevel@tonic-gate bferr("Subscript out of range"); 165*7c478bd9Sstevel@tonic-gate return (v); 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate tchar plusplus[2] = { '1', 0 }; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate dolet(v) 171*7c478bd9Sstevel@tonic-gate tchar **v; 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate register tchar *p; 174*7c478bd9Sstevel@tonic-gate tchar *vp, c, op; 175*7c478bd9Sstevel@tonic-gate bool hadsub; 176*7c478bd9Sstevel@tonic-gate int subscr; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate v++; 179*7c478bd9Sstevel@tonic-gate p = *v++; 180*7c478bd9Sstevel@tonic-gate if (p == 0) { 181*7c478bd9Sstevel@tonic-gate prvars(); 182*7c478bd9Sstevel@tonic-gate return; 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate do { 185*7c478bd9Sstevel@tonic-gate hadsub = 0; 186*7c478bd9Sstevel@tonic-gate for (vp = p; alnum(*p); p++) 187*7c478bd9Sstevel@tonic-gate continue; 188*7c478bd9Sstevel@tonic-gate if (vp == p || !letter(*vp)) 189*7c478bd9Sstevel@tonic-gate goto letsyn; 190*7c478bd9Sstevel@tonic-gate if (*p == '[') { 191*7c478bd9Sstevel@tonic-gate hadsub++; 192*7c478bd9Sstevel@tonic-gate p = getinx(p, &subscr); 193*7c478bd9Sstevel@tonic-gate } 194*7c478bd9Sstevel@tonic-gate if (*p == 0 && *v) 195*7c478bd9Sstevel@tonic-gate p = *v++; 196*7c478bd9Sstevel@tonic-gate if (op = *p) 197*7c478bd9Sstevel@tonic-gate *p++ = 0; 198*7c478bd9Sstevel@tonic-gate else 199*7c478bd9Sstevel@tonic-gate goto letsyn; 200*7c478bd9Sstevel@tonic-gate vp = savestr(vp); 201*7c478bd9Sstevel@tonic-gate if (op == '=') { 202*7c478bd9Sstevel@tonic-gate c = '='; 203*7c478bd9Sstevel@tonic-gate p = xset(p, &v); 204*7c478bd9Sstevel@tonic-gate } else { 205*7c478bd9Sstevel@tonic-gate c = *p++; 206*7c478bd9Sstevel@tonic-gate /* if (any(c, "+-")) { */ 207*7c478bd9Sstevel@tonic-gate if (c == '+' || c == '-') { 208*7c478bd9Sstevel@tonic-gate if (c != op || *p) 209*7c478bd9Sstevel@tonic-gate goto letsyn; 210*7c478bd9Sstevel@tonic-gate p = plusplus; 211*7c478bd9Sstevel@tonic-gate } else { 212*7c478bd9Sstevel@tonic-gate /*if (any(op, "<>")) {*/ 213*7c478bd9Sstevel@tonic-gate if (op == '<' || op == '>') { 214*7c478bd9Sstevel@tonic-gate if (c != op) 215*7c478bd9Sstevel@tonic-gate goto letsyn; 216*7c478bd9Sstevel@tonic-gate c = *p++; 217*7c478bd9Sstevel@tonic-gate letsyn: 218*7c478bd9Sstevel@tonic-gate bferr("Syntax error"); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate if (c != '=') 221*7c478bd9Sstevel@tonic-gate goto letsyn; 222*7c478bd9Sstevel@tonic-gate p = xset(p, &v); 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate if (op == '=') 226*7c478bd9Sstevel@tonic-gate if (hadsub) 227*7c478bd9Sstevel@tonic-gate asx(vp, subscr, p); 228*7c478bd9Sstevel@tonic-gate else 229*7c478bd9Sstevel@tonic-gate set(vp, p); 230*7c478bd9Sstevel@tonic-gate else 231*7c478bd9Sstevel@tonic-gate if (hadsub) 232*7c478bd9Sstevel@tonic-gate #ifndef V6 233*7c478bd9Sstevel@tonic-gate /* avoid bug in vax CC */ 234*7c478bd9Sstevel@tonic-gate { 235*7c478bd9Sstevel@tonic-gate struct varent *gv = getvx(vp, subscr); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate asx(vp, subscr, operate(op, gv->vec[subscr - 1], p)); 238*7c478bd9Sstevel@tonic-gate } 239*7c478bd9Sstevel@tonic-gate #else 240*7c478bd9Sstevel@tonic-gate asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p)); 241*7c478bd9Sstevel@tonic-gate #endif 242*7c478bd9Sstevel@tonic-gate else 243*7c478bd9Sstevel@tonic-gate set(vp, operate(op, value(vp), p)); 244*7c478bd9Sstevel@tonic-gate if (eq(vp, S_path/*"path"*/)) { 245*7c478bd9Sstevel@tonic-gate exportpath(adrof(S_path/*"path"*/)->vec); 246*7c478bd9Sstevel@tonic-gate dohash(xhash); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate if (eq(vp, S_cdpath/*"cdpath"*/)) 250*7c478bd9Sstevel@tonic-gate dohash(xhash2); 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate XFREE(vp) 253*7c478bd9Sstevel@tonic-gate if (c != '=') 254*7c478bd9Sstevel@tonic-gate XFREE(p) 255*7c478bd9Sstevel@tonic-gate } while (p = *v++); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate tchar * 259*7c478bd9Sstevel@tonic-gate xset(cp, vp) 260*7c478bd9Sstevel@tonic-gate tchar *cp, ***vp; 261*7c478bd9Sstevel@tonic-gate { 262*7c478bd9Sstevel@tonic-gate register tchar *dp; 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate #ifdef TRACE 265*7c478bd9Sstevel@tonic-gate tprintf("TRACE- xset()\n"); 266*7c478bd9Sstevel@tonic-gate #endif 267*7c478bd9Sstevel@tonic-gate if (*cp) { 268*7c478bd9Sstevel@tonic-gate dp = savestr(cp); 269*7c478bd9Sstevel@tonic-gate --(*vp); 270*7c478bd9Sstevel@tonic-gate xfree(**vp); 271*7c478bd9Sstevel@tonic-gate **vp = dp; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate return (putn(exp(vp))); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate tchar * 277*7c478bd9Sstevel@tonic-gate operate(op, vp, p) 278*7c478bd9Sstevel@tonic-gate tchar op, *vp, *p; 279*7c478bd9Sstevel@tonic-gate { 280*7c478bd9Sstevel@tonic-gate tchar opr[2]; 281*7c478bd9Sstevel@tonic-gate tchar *vec[5]; 282*7c478bd9Sstevel@tonic-gate register tchar **v = vec; 283*7c478bd9Sstevel@tonic-gate tchar **vecp = v; 284*7c478bd9Sstevel@tonic-gate register int i; 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate if (op != '=') { 287*7c478bd9Sstevel@tonic-gate if (*vp) 288*7c478bd9Sstevel@tonic-gate *v++ = vp; 289*7c478bd9Sstevel@tonic-gate opr[0] = op; 290*7c478bd9Sstevel@tonic-gate opr[1] = 0; 291*7c478bd9Sstevel@tonic-gate *v++ = opr; 292*7c478bd9Sstevel@tonic-gate if (op == '<' || op == '>') 293*7c478bd9Sstevel@tonic-gate *v++ = opr; 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate *v++ = p; 296*7c478bd9Sstevel@tonic-gate *v++ = 0; 297*7c478bd9Sstevel@tonic-gate i = exp(&vecp); 298*7c478bd9Sstevel@tonic-gate if (*vecp) 299*7c478bd9Sstevel@tonic-gate bferr("Expression syntax"); 300*7c478bd9Sstevel@tonic-gate return (putn(i)); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate static tchar *putp; 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate tchar * 306*7c478bd9Sstevel@tonic-gate putn(n) 307*7c478bd9Sstevel@tonic-gate register int n; 308*7c478bd9Sstevel@tonic-gate { 309*7c478bd9Sstevel@tonic-gate static tchar number[15]; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate #ifdef TRACE 312*7c478bd9Sstevel@tonic-gate tprintf("TRACE- putn()\n"); 313*7c478bd9Sstevel@tonic-gate #endif 314*7c478bd9Sstevel@tonic-gate putp = number; 315*7c478bd9Sstevel@tonic-gate if (n < 0) { 316*7c478bd9Sstevel@tonic-gate n = -n; 317*7c478bd9Sstevel@tonic-gate *putp++ = '-'; 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate if (sizeof (int) == 2 && n == -32768) { 320*7c478bd9Sstevel@tonic-gate *putp++ = '3'; 321*7c478bd9Sstevel@tonic-gate n = 2768; 322*7c478bd9Sstevel@tonic-gate #ifdef pdp11 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate #else 325*7c478bd9Sstevel@tonic-gate } else if (sizeof (int) == 4 && n == 0x80000000) { 326*7c478bd9Sstevel@tonic-gate *putp++ = '2'; 327*7c478bd9Sstevel@tonic-gate n = 147483648; 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate #endif 330*7c478bd9Sstevel@tonic-gate putn1(n); 331*7c478bd9Sstevel@tonic-gate *putp = 0; 332*7c478bd9Sstevel@tonic-gate return (savestr(number)); 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate putn1(n) 336*7c478bd9Sstevel@tonic-gate register int n; 337*7c478bd9Sstevel@tonic-gate { 338*7c478bd9Sstevel@tonic-gate #ifdef TRACE 339*7c478bd9Sstevel@tonic-gate tprintf("TRACE- putn1()\n"); 340*7c478bd9Sstevel@tonic-gate #endif 341*7c478bd9Sstevel@tonic-gate if (n > 9) 342*7c478bd9Sstevel@tonic-gate putn1(n / 10); 343*7c478bd9Sstevel@tonic-gate *putp++ = n % 10 + '0'; 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate getn(cp) 347*7c478bd9Sstevel@tonic-gate register tchar *cp; 348*7c478bd9Sstevel@tonic-gate { 349*7c478bd9Sstevel@tonic-gate register int n; 350*7c478bd9Sstevel@tonic-gate int sign; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate #ifdef TRACE 353*7c478bd9Sstevel@tonic-gate tprintf("TRACE- getn()\n"); 354*7c478bd9Sstevel@tonic-gate #endif 355*7c478bd9Sstevel@tonic-gate sign = 0; 356*7c478bd9Sstevel@tonic-gate if (cp[0] == '+' && cp[1]) 357*7c478bd9Sstevel@tonic-gate cp++; 358*7c478bd9Sstevel@tonic-gate if (*cp == '-') { 359*7c478bd9Sstevel@tonic-gate sign++; 360*7c478bd9Sstevel@tonic-gate cp++; 361*7c478bd9Sstevel@tonic-gate if (!digit(*cp)) 362*7c478bd9Sstevel@tonic-gate goto badnum; 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate n = 0; 365*7c478bd9Sstevel@tonic-gate while (digit(*cp)) 366*7c478bd9Sstevel@tonic-gate n = n * 10 + *cp++ - '0'; 367*7c478bd9Sstevel@tonic-gate if (*cp) 368*7c478bd9Sstevel@tonic-gate goto badnum; 369*7c478bd9Sstevel@tonic-gate return (sign ? -n : n); 370*7c478bd9Sstevel@tonic-gate badnum: 371*7c478bd9Sstevel@tonic-gate bferr("Badly formed number"); 372*7c478bd9Sstevel@tonic-gate return (0); 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate tchar * 376*7c478bd9Sstevel@tonic-gate value1(var, head) 377*7c478bd9Sstevel@tonic-gate tchar *var; 378*7c478bd9Sstevel@tonic-gate struct varent *head; 379*7c478bd9Sstevel@tonic-gate { 380*7c478bd9Sstevel@tonic-gate register struct varent *vp; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate #ifdef TRACE 383*7c478bd9Sstevel@tonic-gate tprintf("TRACE- value1()\n"); 384*7c478bd9Sstevel@tonic-gate #endif 385*7c478bd9Sstevel@tonic-gate vp = adrof1(var, head); 386*7c478bd9Sstevel@tonic-gate return (vp == 0 || vp->vec[0] == 0 ? S_/*""*/ : vp->vec[0]); 387*7c478bd9Sstevel@tonic-gate } 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate struct varent * 390*7c478bd9Sstevel@tonic-gate madrof(pat, vp) 391*7c478bd9Sstevel@tonic-gate tchar *pat; 392*7c478bd9Sstevel@tonic-gate register struct varent *vp; 393*7c478bd9Sstevel@tonic-gate { 394*7c478bd9Sstevel@tonic-gate register struct varent *vp1; 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate #ifdef TRACE 397*7c478bd9Sstevel@tonic-gate tprintf("TRACE- madrof()\n"); 398*7c478bd9Sstevel@tonic-gate #endif 399*7c478bd9Sstevel@tonic-gate for (; vp; vp = vp->v_right) { 400*7c478bd9Sstevel@tonic-gate if (vp->v_left && (vp1 = madrof(pat, vp->v_left))) 401*7c478bd9Sstevel@tonic-gate return vp1; 402*7c478bd9Sstevel@tonic-gate if (Gmatch(vp->v_name, pat)) 403*7c478bd9Sstevel@tonic-gate return vp; 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate return vp; 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate struct varent * 409*7c478bd9Sstevel@tonic-gate adrof1(name, v) 410*7c478bd9Sstevel@tonic-gate register tchar *name; 411*7c478bd9Sstevel@tonic-gate register struct varent *v; 412*7c478bd9Sstevel@tonic-gate { 413*7c478bd9Sstevel@tonic-gate register cmp; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate #ifdef TRACE 416*7c478bd9Sstevel@tonic-gate tprintf("TRACE- adrof1()\n"); 417*7c478bd9Sstevel@tonic-gate #endif 418*7c478bd9Sstevel@tonic-gate v = v->v_left; 419*7c478bd9Sstevel@tonic-gate while (v && ((cmp = *name - *v->v_name) || 420*7c478bd9Sstevel@tonic-gate (cmp = strcmp_(name, v->v_name)))) 421*7c478bd9Sstevel@tonic-gate if (cmp < 0) 422*7c478bd9Sstevel@tonic-gate v = v->v_left; 423*7c478bd9Sstevel@tonic-gate else 424*7c478bd9Sstevel@tonic-gate v = v->v_right; 425*7c478bd9Sstevel@tonic-gate return v; 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate /* 429*7c478bd9Sstevel@tonic-gate * The caller is responsible for putting value in a safe place 430*7c478bd9Sstevel@tonic-gate */ 431*7c478bd9Sstevel@tonic-gate set(var, val) 432*7c478bd9Sstevel@tonic-gate tchar *var, *val; 433*7c478bd9Sstevel@tonic-gate { 434*7c478bd9Sstevel@tonic-gate register tchar **vec = (tchar **) xalloc(2 * sizeof (tchar **)); 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate #ifdef TRACE 437*7c478bd9Sstevel@tonic-gate tprintf("TRACE- set()\n"); 438*7c478bd9Sstevel@tonic-gate #endif 439*7c478bd9Sstevel@tonic-gate vec[0] = onlyread(val) ? savestr(val) : val; 440*7c478bd9Sstevel@tonic-gate vec[1] = 0; 441*7c478bd9Sstevel@tonic-gate set1(var, vec, &shvhed); 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate set1(var, vec, head) 445*7c478bd9Sstevel@tonic-gate tchar *var, **vec; 446*7c478bd9Sstevel@tonic-gate struct varent *head; 447*7c478bd9Sstevel@tonic-gate { 448*7c478bd9Sstevel@tonic-gate register tchar **oldv = vec; 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate #ifdef TRACE 451*7c478bd9Sstevel@tonic-gate tprintf("TRACE- set1()\n"); 452*7c478bd9Sstevel@tonic-gate #endif 453*7c478bd9Sstevel@tonic-gate gflag = 0; 454*7c478bd9Sstevel@tonic-gate /* If setting cwd variable via "set cwd=/tmp/something" 455*7c478bd9Sstevel@tonic-gate * then do globbing. But if we are setting the cwd 456*7c478bd9Sstevel@tonic-gate * becuz of a cd, chdir, pushd, popd, do not do globbing. 457*7c478bd9Sstevel@tonic-gate */ 458*7c478bd9Sstevel@tonic-gate if ( (!(eq(var,S_cwd))) || (eq(var,S_cwd) && (didchdir == 0)) ) 459*7c478bd9Sstevel@tonic-gate { 460*7c478bd9Sstevel@tonic-gate tglob(oldv); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate if (gflag) { 463*7c478bd9Sstevel@tonic-gate vec = glob(oldv); 464*7c478bd9Sstevel@tonic-gate if (vec == 0) { 465*7c478bd9Sstevel@tonic-gate bferr("No match"); 466*7c478bd9Sstevel@tonic-gate blkfree(oldv); 467*7c478bd9Sstevel@tonic-gate return; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate blkfree(oldv); 470*7c478bd9Sstevel@tonic-gate gargv = 0; 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate setq(var, vec, head); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate setq(name, vec, p) 476*7c478bd9Sstevel@tonic-gate tchar *name, **vec; 477*7c478bd9Sstevel@tonic-gate register struct varent *p; 478*7c478bd9Sstevel@tonic-gate { 479*7c478bd9Sstevel@tonic-gate register struct varent *c; 480*7c478bd9Sstevel@tonic-gate register f; 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate #ifdef TRACE 483*7c478bd9Sstevel@tonic-gate tprintf("TRACE- setq()\n"); 484*7c478bd9Sstevel@tonic-gate #endif 485*7c478bd9Sstevel@tonic-gate f = 0; /* tree hangs off the header's left link */ 486*7c478bd9Sstevel@tonic-gate while (c = p->v_link[f]) { 487*7c478bd9Sstevel@tonic-gate if ((f = *name - *c->v_name) == 0 && 488*7c478bd9Sstevel@tonic-gate (f = strcmp_(name, c->v_name)) == 0) { 489*7c478bd9Sstevel@tonic-gate blkfree(c->vec); 490*7c478bd9Sstevel@tonic-gate goto found; 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate p = c; 493*7c478bd9Sstevel@tonic-gate f = f > 0; 494*7c478bd9Sstevel@tonic-gate } 495*7c478bd9Sstevel@tonic-gate p->v_link[f] = c = (struct varent *)xalloc(sizeof (struct varent)); 496*7c478bd9Sstevel@tonic-gate c->v_name = savestr(name); 497*7c478bd9Sstevel@tonic-gate c->v_bal = 0; 498*7c478bd9Sstevel@tonic-gate c->v_left = c->v_right = 0; 499*7c478bd9Sstevel@tonic-gate c->v_parent = p; 500*7c478bd9Sstevel@tonic-gate balance(p, f, 0); 501*7c478bd9Sstevel@tonic-gate found: 502*7c478bd9Sstevel@tonic-gate trim(c->vec = vec); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate unset(v) 506*7c478bd9Sstevel@tonic-gate tchar *v[]; 507*7c478bd9Sstevel@tonic-gate { 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate #ifdef TRACE 510*7c478bd9Sstevel@tonic-gate tprintf("TRACE- unset()\n"); 511*7c478bd9Sstevel@tonic-gate #endif 512*7c478bd9Sstevel@tonic-gate unset1(v, &shvhed); 513*7c478bd9Sstevel@tonic-gate if (adrof(S_histchars/*"histchars"*/) == 0) { 514*7c478bd9Sstevel@tonic-gate HIST = '!'; 515*7c478bd9Sstevel@tonic-gate HISTSUB = '^'; 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate #ifdef FILEC 518*7c478bd9Sstevel@tonic-gate if (adrof(S_filec/*"filec"*/) == 0) 519*7c478bd9Sstevel@tonic-gate filec = 0; 520*7c478bd9Sstevel@tonic-gate #endif 521*7c478bd9Sstevel@tonic-gate } 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate unset1(v, head) 524*7c478bd9Sstevel@tonic-gate register tchar *v[]; 525*7c478bd9Sstevel@tonic-gate struct varent *head; 526*7c478bd9Sstevel@tonic-gate { 527*7c478bd9Sstevel@tonic-gate register struct varent *vp; 528*7c478bd9Sstevel@tonic-gate register int cnt; 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate #ifdef TRACE 531*7c478bd9Sstevel@tonic-gate tprintf("TRACE- unset1()\n"); 532*7c478bd9Sstevel@tonic-gate #endif 533*7c478bd9Sstevel@tonic-gate while (*++v) { 534*7c478bd9Sstevel@tonic-gate cnt = 0; 535*7c478bd9Sstevel@tonic-gate while (vp = madrof(*v, head->v_left)) 536*7c478bd9Sstevel@tonic-gate unsetv1(vp), cnt++; 537*7c478bd9Sstevel@tonic-gate if (cnt == 0) 538*7c478bd9Sstevel@tonic-gate setname(*v); 539*7c478bd9Sstevel@tonic-gate } 540*7c478bd9Sstevel@tonic-gate } 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate unsetv(var) 543*7c478bd9Sstevel@tonic-gate tchar *var; 544*7c478bd9Sstevel@tonic-gate { 545*7c478bd9Sstevel@tonic-gate register struct varent *vp; 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate #ifdef TRACE 548*7c478bd9Sstevel@tonic-gate tprintf("TRACE- unsetv()\n"); 549*7c478bd9Sstevel@tonic-gate #endif 550*7c478bd9Sstevel@tonic-gate if ((vp = adrof1(var, &shvhed)) == 0) 551*7c478bd9Sstevel@tonic-gate udvar(var); 552*7c478bd9Sstevel@tonic-gate unsetv1(vp); 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate unsetv1(p) 556*7c478bd9Sstevel@tonic-gate register struct varent *p; 557*7c478bd9Sstevel@tonic-gate { 558*7c478bd9Sstevel@tonic-gate register struct varent *c, *pp; 559*7c478bd9Sstevel@tonic-gate register f; 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate #ifdef TRACE 562*7c478bd9Sstevel@tonic-gate tprintf("TRACE- unsetv1()\n"); 563*7c478bd9Sstevel@tonic-gate #endif 564*7c478bd9Sstevel@tonic-gate /* 565*7c478bd9Sstevel@tonic-gate * Free associated memory first to avoid complications. 566*7c478bd9Sstevel@tonic-gate */ 567*7c478bd9Sstevel@tonic-gate blkfree(p->vec); 568*7c478bd9Sstevel@tonic-gate XFREE(p->v_name); 569*7c478bd9Sstevel@tonic-gate /* 570*7c478bd9Sstevel@tonic-gate * If p is missing one child, then we can move the other 571*7c478bd9Sstevel@tonic-gate * into where p is. Otherwise, we find the predecessor 572*7c478bd9Sstevel@tonic-gate * of p, which is guaranteed to have no right child, copy 573*7c478bd9Sstevel@tonic-gate * it into p, and move it's left child into it. 574*7c478bd9Sstevel@tonic-gate */ 575*7c478bd9Sstevel@tonic-gate if (p->v_right == 0) 576*7c478bd9Sstevel@tonic-gate c = p->v_left; 577*7c478bd9Sstevel@tonic-gate else if (p->v_left == 0) 578*7c478bd9Sstevel@tonic-gate c = p->v_right; 579*7c478bd9Sstevel@tonic-gate else { 580*7c478bd9Sstevel@tonic-gate for (c = p->v_left; c->v_right; c = c->v_right) 581*7c478bd9Sstevel@tonic-gate ; 582*7c478bd9Sstevel@tonic-gate p->v_name = c->v_name; 583*7c478bd9Sstevel@tonic-gate p->vec = c->vec; 584*7c478bd9Sstevel@tonic-gate p = c; 585*7c478bd9Sstevel@tonic-gate c = p->v_left; 586*7c478bd9Sstevel@tonic-gate } 587*7c478bd9Sstevel@tonic-gate /* 588*7c478bd9Sstevel@tonic-gate * Move c into where p is. 589*7c478bd9Sstevel@tonic-gate */ 590*7c478bd9Sstevel@tonic-gate pp = p->v_parent; 591*7c478bd9Sstevel@tonic-gate f = pp->v_right == p; 592*7c478bd9Sstevel@tonic-gate if (pp->v_link[f] = c) 593*7c478bd9Sstevel@tonic-gate c->v_parent = pp; 594*7c478bd9Sstevel@tonic-gate /* 595*7c478bd9Sstevel@tonic-gate * Free the deleted node, and rebalance. 596*7c478bd9Sstevel@tonic-gate */ 597*7c478bd9Sstevel@tonic-gate XFREE( (tchar *)p); 598*7c478bd9Sstevel@tonic-gate balance(pp, f, 1); 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate setNS(cp) 602*7c478bd9Sstevel@tonic-gate tchar *cp; 603*7c478bd9Sstevel@tonic-gate { 604*7c478bd9Sstevel@tonic-gate #ifdef TRACE 605*7c478bd9Sstevel@tonic-gate tprintf("TRACE- setNS()\n"); 606*7c478bd9Sstevel@tonic-gate #endif 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate set(cp, S_/*""*/); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate shift(v) 612*7c478bd9Sstevel@tonic-gate register tchar **v; 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate register struct varent *argv; 615*7c478bd9Sstevel@tonic-gate register tchar *name; 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate #ifdef TRACE 618*7c478bd9Sstevel@tonic-gate tprintf("TRACE- shift()\n"); 619*7c478bd9Sstevel@tonic-gate #endif 620*7c478bd9Sstevel@tonic-gate v++; 621*7c478bd9Sstevel@tonic-gate name = *v; 622*7c478bd9Sstevel@tonic-gate if (name == 0) 623*7c478bd9Sstevel@tonic-gate name = S_argv/*"argv"*/; 624*7c478bd9Sstevel@tonic-gate else 625*7c478bd9Sstevel@tonic-gate (void) strip(name); 626*7c478bd9Sstevel@tonic-gate argv = adrof(name); 627*7c478bd9Sstevel@tonic-gate if (argv == 0) 628*7c478bd9Sstevel@tonic-gate udvar(name); 629*7c478bd9Sstevel@tonic-gate if (argv->vec[0] == 0) 630*7c478bd9Sstevel@tonic-gate bferr("No more words"); 631*7c478bd9Sstevel@tonic-gate lshift(argv->vec, 1); 632*7c478bd9Sstevel@tonic-gate } 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate exportpath(val) 635*7c478bd9Sstevel@tonic-gate tchar **val; 636*7c478bd9Sstevel@tonic-gate { 637*7c478bd9Sstevel@tonic-gate tchar exppath[PATHSIZ]; 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate #ifdef TRACE 640*7c478bd9Sstevel@tonic-gate tprintf("TRACE- exportpath()\n"); 641*7c478bd9Sstevel@tonic-gate #endif 642*7c478bd9Sstevel@tonic-gate exppath[0] = 0; 643*7c478bd9Sstevel@tonic-gate if (val) 644*7c478bd9Sstevel@tonic-gate while (*val) { 645*7c478bd9Sstevel@tonic-gate if (strlen_(*val) + strlen_(exppath) + 2 > PATHSIZ) { 646*7c478bd9Sstevel@tonic-gate printf("Warning: ridiculously long PATH truncated\n"); 647*7c478bd9Sstevel@tonic-gate break; 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate (void) strcat_(exppath, *val++); 650*7c478bd9Sstevel@tonic-gate if (*val == 0 || eq(*val, S_RPAR/*")"*/)) 651*7c478bd9Sstevel@tonic-gate break; 652*7c478bd9Sstevel@tonic-gate (void) strcat_(exppath, S_COLON/*":"*/); 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate local_setenv(S_PATH/*"PATH"*/, exppath); 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate /* macros to do single rotations on node p */ 658*7c478bd9Sstevel@tonic-gate #define rright(p) (\ 659*7c478bd9Sstevel@tonic-gate t = (p)->v_left,\ 660*7c478bd9Sstevel@tonic-gate (t)->v_parent = (p)->v_parent,\ 661*7c478bd9Sstevel@tonic-gate ((p)->v_left = t->v_right) ? (t->v_right->v_parent = (p)) : 0,\ 662*7c478bd9Sstevel@tonic-gate (t->v_right = (p))->v_parent = t,\ 663*7c478bd9Sstevel@tonic-gate (p) = t) 664*7c478bd9Sstevel@tonic-gate #define rleft(p) (\ 665*7c478bd9Sstevel@tonic-gate t = (p)->v_right,\ 666*7c478bd9Sstevel@tonic-gate (t)->v_parent = (p)->v_parent,\ 667*7c478bd9Sstevel@tonic-gate ((p)->v_right = t->v_left) ? (t->v_left->v_parent = (p)) : 0,\ 668*7c478bd9Sstevel@tonic-gate (t->v_left = (p))->v_parent = t,\ 669*7c478bd9Sstevel@tonic-gate (p) = t) 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate /* 672*7c478bd9Sstevel@tonic-gate * Rebalance a tree, starting at p and up. 673*7c478bd9Sstevel@tonic-gate * F == 0 means we've come from p's left child. 674*7c478bd9Sstevel@tonic-gate * D == 1 means we've just done a delete, otherwise an insert. 675*7c478bd9Sstevel@tonic-gate */ 676*7c478bd9Sstevel@tonic-gate balance(p, f, d) 677*7c478bd9Sstevel@tonic-gate register struct varent *p; 678*7c478bd9Sstevel@tonic-gate register f; 679*7c478bd9Sstevel@tonic-gate { 680*7c478bd9Sstevel@tonic-gate register struct varent *pp; 681*7c478bd9Sstevel@tonic-gate register struct varent *t; /* used by the rotate macros */ 682*7c478bd9Sstevel@tonic-gate register ff; 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate #ifdef TRACE 685*7c478bd9Sstevel@tonic-gate tprintf("TRACE- balance()\n"); 686*7c478bd9Sstevel@tonic-gate #endif 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * Ok, from here on, p is the node we're operating on; 689*7c478bd9Sstevel@tonic-gate * pp is it's parent; f is the branch of p from which we have come; 690*7c478bd9Sstevel@tonic-gate * ff is the branch of pp which is p. 691*7c478bd9Sstevel@tonic-gate */ 692*7c478bd9Sstevel@tonic-gate for (; pp = p->v_parent; p = pp, f = ff) { 693*7c478bd9Sstevel@tonic-gate ff = pp->v_right == p; 694*7c478bd9Sstevel@tonic-gate if (f ^ d) { /* right heavy */ 695*7c478bd9Sstevel@tonic-gate switch (p->v_bal) { 696*7c478bd9Sstevel@tonic-gate case -1: /* was left heavy */ 697*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 698*7c478bd9Sstevel@tonic-gate break; 699*7c478bd9Sstevel@tonic-gate case 0: /* was balanced */ 700*7c478bd9Sstevel@tonic-gate p->v_bal = 1; 701*7c478bd9Sstevel@tonic-gate break; 702*7c478bd9Sstevel@tonic-gate case 1: /* was already right heavy */ 703*7c478bd9Sstevel@tonic-gate switch (p->v_right->v_bal) { 704*7c478bd9Sstevel@tonic-gate case 1: /* sigle rotate */ 705*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rleft(p); 706*7c478bd9Sstevel@tonic-gate p->v_left->v_bal = 0; 707*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 708*7c478bd9Sstevel@tonic-gate break; 709*7c478bd9Sstevel@tonic-gate case 0: /* single rotate */ 710*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rleft(p); 711*7c478bd9Sstevel@tonic-gate p->v_left->v_bal = 1; 712*7c478bd9Sstevel@tonic-gate p->v_bal = -1; 713*7c478bd9Sstevel@tonic-gate break; 714*7c478bd9Sstevel@tonic-gate case -1: /* double rotate */ 715*7c478bd9Sstevel@tonic-gate rright(p->v_right); 716*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rleft(p); 717*7c478bd9Sstevel@tonic-gate p->v_left->v_bal = 718*7c478bd9Sstevel@tonic-gate p->v_bal < 1 ? 0 : -1; 719*7c478bd9Sstevel@tonic-gate p->v_right->v_bal = 720*7c478bd9Sstevel@tonic-gate p->v_bal > -1 ? 0 : 1; 721*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 722*7c478bd9Sstevel@tonic-gate break; 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate break; 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate } else { /* left heavy */ 727*7c478bd9Sstevel@tonic-gate switch (p->v_bal) { 728*7c478bd9Sstevel@tonic-gate case 1: /* was right heavy */ 729*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 730*7c478bd9Sstevel@tonic-gate break; 731*7c478bd9Sstevel@tonic-gate case 0: /* was balanced */ 732*7c478bd9Sstevel@tonic-gate p->v_bal = -1; 733*7c478bd9Sstevel@tonic-gate break; 734*7c478bd9Sstevel@tonic-gate case -1: /* was already left heavy */ 735*7c478bd9Sstevel@tonic-gate switch (p->v_left->v_bal) { 736*7c478bd9Sstevel@tonic-gate case -1: /* single rotate */ 737*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rright(p); 738*7c478bd9Sstevel@tonic-gate p->v_right->v_bal = 0; 739*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 740*7c478bd9Sstevel@tonic-gate break; 741*7c478bd9Sstevel@tonic-gate case 0: /* signle rotate */ 742*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rright(p); 743*7c478bd9Sstevel@tonic-gate p->v_right->v_bal = -1; 744*7c478bd9Sstevel@tonic-gate p->v_bal = 1; 745*7c478bd9Sstevel@tonic-gate break; 746*7c478bd9Sstevel@tonic-gate case 1: /* double rotate */ 747*7c478bd9Sstevel@tonic-gate rleft(p->v_left); 748*7c478bd9Sstevel@tonic-gate pp->v_link[ff] = rright(p); 749*7c478bd9Sstevel@tonic-gate p->v_left->v_bal = 750*7c478bd9Sstevel@tonic-gate p->v_bal < 1 ? 0 : -1; 751*7c478bd9Sstevel@tonic-gate p->v_right->v_bal = 752*7c478bd9Sstevel@tonic-gate p->v_bal > -1 ? 0 : 1; 753*7c478bd9Sstevel@tonic-gate p->v_bal = 0; 754*7c478bd9Sstevel@tonic-gate break; 755*7c478bd9Sstevel@tonic-gate } 756*7c478bd9Sstevel@tonic-gate break; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate /* 760*7c478bd9Sstevel@tonic-gate * If from insert, then we terminate when p is balanced. 761*7c478bd9Sstevel@tonic-gate * If from delete, then we terminate when p is unbalanced. 762*7c478bd9Sstevel@tonic-gate */ 763*7c478bd9Sstevel@tonic-gate if ((p->v_bal == 0) ^ d) 764*7c478bd9Sstevel@tonic-gate break; 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate } 767*7c478bd9Sstevel@tonic-gate 768*7c478bd9Sstevel@tonic-gate plist(p) 769*7c478bd9Sstevel@tonic-gate register struct varent *p; 770*7c478bd9Sstevel@tonic-gate { 771*7c478bd9Sstevel@tonic-gate register struct varent *c; 772*7c478bd9Sstevel@tonic-gate register len; 773*7c478bd9Sstevel@tonic-gate 774*7c478bd9Sstevel@tonic-gate #ifdef TRACE 775*7c478bd9Sstevel@tonic-gate tprintf("TRACE- plist()\n"); 776*7c478bd9Sstevel@tonic-gate #endif 777*7c478bd9Sstevel@tonic-gate if (setintr) 778*7c478bd9Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT)); 779*7c478bd9Sstevel@tonic-gate for (;;) { 780*7c478bd9Sstevel@tonic-gate while (p->v_left) 781*7c478bd9Sstevel@tonic-gate p = p->v_left; 782*7c478bd9Sstevel@tonic-gate x: 783*7c478bd9Sstevel@tonic-gate if (p->v_parent == 0) /* is it the header? */ 784*7c478bd9Sstevel@tonic-gate return; 785*7c478bd9Sstevel@tonic-gate len = blklen(p->vec); 786*7c478bd9Sstevel@tonic-gate printf("%t", p->v_name); 787*7c478bd9Sstevel@tonic-gate Putchar('\t'); 788*7c478bd9Sstevel@tonic-gate if (len != 1) 789*7c478bd9Sstevel@tonic-gate Putchar('('); 790*7c478bd9Sstevel@tonic-gate blkpr(p->vec); 791*7c478bd9Sstevel@tonic-gate if (len != 1) 792*7c478bd9Sstevel@tonic-gate Putchar(')'); 793*7c478bd9Sstevel@tonic-gate Putchar('\n'); 794*7c478bd9Sstevel@tonic-gate if (p->v_right) { 795*7c478bd9Sstevel@tonic-gate p = p->v_right; 796*7c478bd9Sstevel@tonic-gate continue; 797*7c478bd9Sstevel@tonic-gate } 798*7c478bd9Sstevel@tonic-gate do { 799*7c478bd9Sstevel@tonic-gate c = p; 800*7c478bd9Sstevel@tonic-gate p = p->v_parent; 801*7c478bd9Sstevel@tonic-gate } while (p->v_right == c); 802*7c478bd9Sstevel@tonic-gate goto x; 803*7c478bd9Sstevel@tonic-gate } 804*7c478bd9Sstevel@tonic-gate } 805