1*1305Sbill static char *sccsid = "@(#)set.c 4.1 10/09/80"; 2*1305Sbill 3*1305Sbill #include "sh.h" 4*1305Sbill 5*1305Sbill /* 6*1305Sbill * C Shell 7*1305Sbill */ 8*1305Sbill 9*1305Sbill doset(v) 10*1305Sbill register char **v; 11*1305Sbill { 12*1305Sbill register char *p; 13*1305Sbill char *vp, op; 14*1305Sbill char **vecp; 15*1305Sbill bool hadsub; 16*1305Sbill int subscr; 17*1305Sbill 18*1305Sbill v++; 19*1305Sbill p = *v++; 20*1305Sbill if (p == 0) { 21*1305Sbill prvars(); 22*1305Sbill return; 23*1305Sbill } 24*1305Sbill do { 25*1305Sbill hadsub = 0; 26*1305Sbill for (vp = p; alnum(*p); p++) 27*1305Sbill continue; 28*1305Sbill if (vp == p) 29*1305Sbill goto setsyn; 30*1305Sbill if (*p == '[') { 31*1305Sbill hadsub++; 32*1305Sbill p = getinx(p, &subscr); 33*1305Sbill } 34*1305Sbill if (op = *p) { 35*1305Sbill *p++ = 0; 36*1305Sbill if (*p == 0 && *v && **v == '(') 37*1305Sbill p = *v++; 38*1305Sbill } else if (*v && eq(*v, "=")) { 39*1305Sbill op = '=', v++; 40*1305Sbill if (*v) 41*1305Sbill p = *v++; 42*1305Sbill } 43*1305Sbill if (op && op != '=') 44*1305Sbill setsyn: 45*1305Sbill bferr("Syntax error"); 46*1305Sbill if (eq(p, "(")) { 47*1305Sbill register char **e = v; 48*1305Sbill 49*1305Sbill if (hadsub) 50*1305Sbill goto setsyn; 51*1305Sbill for (;;) { 52*1305Sbill if (!*e) 53*1305Sbill bferr("Missing )"); 54*1305Sbill if (**e == ')') 55*1305Sbill break; 56*1305Sbill e++; 57*1305Sbill } 58*1305Sbill p = *e; 59*1305Sbill *e = 0; 60*1305Sbill vecp = saveblk(v); 61*1305Sbill set1(vp, vecp, &shvhed); 62*1305Sbill *e = p; 63*1305Sbill v = e + 1; 64*1305Sbill } else if (hadsub) 65*1305Sbill asx(vp, subscr, savestr(p)); 66*1305Sbill else 67*1305Sbill set(vp, savestr(p)); 68*1305Sbill if (eq(vp, "path")) { 69*1305Sbill exportpath(adrof("path")->vec); 70*1305Sbill dohash(); 71*1305Sbill } else if (eq(vp, "histchars")) { 72*1305Sbill register char *p = value("histchars"); 73*1305Sbill 74*1305Sbill HIST = *p++; 75*1305Sbill HISTSUB = *p; 76*1305Sbill } else if (eq(vp, "user")) 77*1305Sbill setenv("USER", value(vp)); 78*1305Sbill else if (eq(vp, "term")) 79*1305Sbill setenv("TERM", value(vp)); 80*1305Sbill else if (eq(vp, "home")) 81*1305Sbill setenv("HOME", value(vp)); 82*1305Sbill } while (p = *v++); 83*1305Sbill } 84*1305Sbill 85*1305Sbill char * 86*1305Sbill getinx(cp, ip) 87*1305Sbill register char *cp; 88*1305Sbill register int *ip; 89*1305Sbill { 90*1305Sbill 91*1305Sbill *ip = 0; 92*1305Sbill *cp++ = 0; 93*1305Sbill while (*cp && digit(*cp)) 94*1305Sbill *ip = *ip * 10 + *cp++ - '0'; 95*1305Sbill if (*cp++ != ']') 96*1305Sbill bferr("Subscript error"); 97*1305Sbill return (cp); 98*1305Sbill } 99*1305Sbill 100*1305Sbill asx(vp, subscr, p) 101*1305Sbill char *vp; 102*1305Sbill int subscr; 103*1305Sbill char *p; 104*1305Sbill { 105*1305Sbill register struct varent *v = getvx(vp, subscr); 106*1305Sbill 107*1305Sbill xfree(v->vec[subscr - 1]); 108*1305Sbill v->vec[subscr - 1] = globone(p); 109*1305Sbill } 110*1305Sbill 111*1305Sbill struct varent * 112*1305Sbill getvx(vp, subscr) 113*1305Sbill { 114*1305Sbill register struct varent *v = adrof(vp); 115*1305Sbill 116*1305Sbill if (v == 0) 117*1305Sbill udvar(vp); 118*1305Sbill if (subscr < 1 || subscr > blklen(v->vec)) 119*1305Sbill bferr("Subscript out of range"); 120*1305Sbill return (v); 121*1305Sbill } 122*1305Sbill 123*1305Sbill char plusplus[2] = { '1', 0 }; 124*1305Sbill 125*1305Sbill 126*1305Sbill dolet(v) 127*1305Sbill char **v; 128*1305Sbill { 129*1305Sbill register char *p; 130*1305Sbill char *vp, c, op; 131*1305Sbill bool hadsub; 132*1305Sbill int subscr; 133*1305Sbill 134*1305Sbill v++; 135*1305Sbill p = *v++; 136*1305Sbill if (p == 0) { 137*1305Sbill prvars(); 138*1305Sbill return; 139*1305Sbill } 140*1305Sbill do { 141*1305Sbill hadsub = 0; 142*1305Sbill for (vp = p; letter(*p); p++) 143*1305Sbill continue; 144*1305Sbill if (vp == p) 145*1305Sbill goto letsyn; 146*1305Sbill if (*p == '[') { 147*1305Sbill hadsub++; 148*1305Sbill p = getinx(p, &subscr); 149*1305Sbill } 150*1305Sbill if (*p == 0 && *v) 151*1305Sbill p = *v++; 152*1305Sbill if (op = *p) 153*1305Sbill *p++ = 0; 154*1305Sbill else 155*1305Sbill goto letsyn; 156*1305Sbill vp = savestr(vp); 157*1305Sbill if (op == '=') { 158*1305Sbill c = '='; 159*1305Sbill p = xset(p, &v); 160*1305Sbill } else { 161*1305Sbill c = *p++; 162*1305Sbill if (any(c, "+-")) { 163*1305Sbill if (c != op || *p) 164*1305Sbill goto letsyn; 165*1305Sbill p = plusplus; 166*1305Sbill } else { 167*1305Sbill if (any(op, "<>")) { 168*1305Sbill if (c != op) 169*1305Sbill goto letsyn; 170*1305Sbill c = *p++; 171*1305Sbill letsyn: 172*1305Sbill bferr("Syntax error"); 173*1305Sbill } 174*1305Sbill if (c != '=') 175*1305Sbill goto letsyn; 176*1305Sbill p = xset(p, &v); 177*1305Sbill } 178*1305Sbill } 179*1305Sbill if (op == '=') 180*1305Sbill if (hadsub) 181*1305Sbill asx(vp, subscr, p); 182*1305Sbill else 183*1305Sbill set(vp, p); 184*1305Sbill else 185*1305Sbill if (hadsub) 186*1305Sbill #ifndef V6 187*1305Sbill /* avoid bug in vax CC */ 188*1305Sbill { 189*1305Sbill struct varent *gv = getvx(vp, subscr); 190*1305Sbill 191*1305Sbill asx(vp, subscr, operate(op, gv->vec[subscr - 1], p)); 192*1305Sbill } 193*1305Sbill #else 194*1305Sbill asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p)); 195*1305Sbill #endif 196*1305Sbill else 197*1305Sbill set(vp, operate(op, value(vp), p)); 198*1305Sbill if (strcmp(vp, "path") == 0) 199*1305Sbill dohash(); 200*1305Sbill xfree(vp); 201*1305Sbill if (c != '=') 202*1305Sbill xfree(p); 203*1305Sbill } while (p = *v++); 204*1305Sbill } 205*1305Sbill 206*1305Sbill char * 207*1305Sbill xset(cp, vp) 208*1305Sbill char *cp, ***vp; 209*1305Sbill { 210*1305Sbill register char *dp; 211*1305Sbill 212*1305Sbill if (*cp) { 213*1305Sbill dp = savestr(cp); 214*1305Sbill --(*vp); 215*1305Sbill xfree(**vp); 216*1305Sbill **vp = dp; 217*1305Sbill } 218*1305Sbill return (putn(exp(vp))); 219*1305Sbill } 220*1305Sbill 221*1305Sbill char * 222*1305Sbill operate(op, vp, p) 223*1305Sbill char op, *vp, *p; 224*1305Sbill { 225*1305Sbill char opr[2]; 226*1305Sbill char *vec[5]; 227*1305Sbill register char **v = vec; 228*1305Sbill char **vecp = v; 229*1305Sbill register int i; 230*1305Sbill 231*1305Sbill if (op != '=') { 232*1305Sbill if (*vp) 233*1305Sbill *v++ = vp; 234*1305Sbill opr[0] = op; 235*1305Sbill opr[1] = 0; 236*1305Sbill *v++ = opr; 237*1305Sbill if (op == '<' || op == '>') 238*1305Sbill *v++ = opr; 239*1305Sbill } 240*1305Sbill *v++ = p; 241*1305Sbill *v++ = 0; 242*1305Sbill i = exp(&vecp); 243*1305Sbill if (*vecp) 244*1305Sbill bferr("Expression syntax"); 245*1305Sbill return (putn(i)); 246*1305Sbill } 247*1305Sbill 248*1305Sbill onlyread(cp) 249*1305Sbill char *cp; 250*1305Sbill { 251*1305Sbill extern char end[]; 252*1305Sbill 253*1305Sbill return (cp < end); 254*1305Sbill } 255*1305Sbill 256*1305Sbill xfree(cp) 257*1305Sbill char *cp; 258*1305Sbill { 259*1305Sbill extern char end[]; 260*1305Sbill 261*1305Sbill if (cp >= end && cp < (char *) &cp) 262*1305Sbill cfree(cp); 263*1305Sbill } 264*1305Sbill 265*1305Sbill char * 266*1305Sbill savestr(s) 267*1305Sbill register char *s; 268*1305Sbill { 269*1305Sbill register char *n; 270*1305Sbill 271*1305Sbill if (s == 0) 272*1305Sbill s = ""; 273*1305Sbill strcpy(n = calloc(1, strlen(s) + 1), s); 274*1305Sbill return (n); 275*1305Sbill } 276*1305Sbill 277*1305Sbill static char *putp; 278*1305Sbill 279*1305Sbill char * 280*1305Sbill putn(n) 281*1305Sbill register int n; 282*1305Sbill { 283*1305Sbill static char number[15]; 284*1305Sbill 285*1305Sbill putp = number; 286*1305Sbill if (n < 0) { 287*1305Sbill n = -n; 288*1305Sbill *putp++ = '-'; 289*1305Sbill } 290*1305Sbill if (sizeof (int) == 2 && n == -32768) { 291*1305Sbill *putp++ = '3'; 292*1305Sbill n = 2768; 293*1305Sbill #ifdef pdp11 294*1305Sbill } 295*1305Sbill #else 296*1305Sbill } else if (sizeof (int) == 4 && n == -2147483648) { 297*1305Sbill *putp++ = '2'; 298*1305Sbill n = 147483648; 299*1305Sbill } 300*1305Sbill #endif 301*1305Sbill putn1(n); 302*1305Sbill *putp = 0; 303*1305Sbill return (savestr(number)); 304*1305Sbill } 305*1305Sbill 306*1305Sbill putn1(n) 307*1305Sbill register int n; 308*1305Sbill { 309*1305Sbill if (n > 9) 310*1305Sbill putn1(n / 10); 311*1305Sbill *putp++ = n % 10 + '0'; 312*1305Sbill } 313*1305Sbill 314*1305Sbill getn(cp) 315*1305Sbill register char *cp; 316*1305Sbill { 317*1305Sbill register int n; 318*1305Sbill int sign; 319*1305Sbill 320*1305Sbill sign = 0; 321*1305Sbill if (cp[0] == '+' && cp[1]) 322*1305Sbill cp++; 323*1305Sbill if (*cp == '-') { 324*1305Sbill sign++; 325*1305Sbill cp++; 326*1305Sbill if (!digit(*cp)) 327*1305Sbill goto badnum; 328*1305Sbill } 329*1305Sbill n = 0; 330*1305Sbill while (digit(*cp)) 331*1305Sbill n = n * 10 + *cp++ - '0'; 332*1305Sbill if (*cp) 333*1305Sbill goto badnum; 334*1305Sbill return (sign ? -n : n); 335*1305Sbill badnum: 336*1305Sbill bferr("Badly formed number"); 337*1305Sbill return (0); 338*1305Sbill } 339*1305Sbill 340*1305Sbill char * 341*1305Sbill value(var) 342*1305Sbill char *var; 343*1305Sbill { 344*1305Sbill 345*1305Sbill return (value1(var, &shvhed)); 346*1305Sbill } 347*1305Sbill 348*1305Sbill char * 349*1305Sbill value1(var, head) 350*1305Sbill char *var; 351*1305Sbill struct varent *head; 352*1305Sbill { 353*1305Sbill register struct varent *vp; 354*1305Sbill 355*1305Sbill vp = adrof1(var, head); 356*1305Sbill return (vp == 0 || vp->vec[0] == 0 ? "" : vp->vec[0]); 357*1305Sbill } 358*1305Sbill 359*1305Sbill static struct varent *shprev; 360*1305Sbill 361*1305Sbill struct varent * 362*1305Sbill adrof(var) 363*1305Sbill char *var; 364*1305Sbill { 365*1305Sbill 366*1305Sbill return (adrof1(var, &shvhed)); 367*1305Sbill } 368*1305Sbill 369*1305Sbill struct varent * 370*1305Sbill madrof(pat, head) 371*1305Sbill char *pat; 372*1305Sbill struct varent *head; 373*1305Sbill { 374*1305Sbill register struct varent *vp; 375*1305Sbill 376*1305Sbill shprev = head; 377*1305Sbill for (vp = shprev->link; vp != 0; vp = vp->link) { 378*1305Sbill if (Gmatch(vp->name, pat)) 379*1305Sbill return (vp); 380*1305Sbill shprev = vp; 381*1305Sbill } 382*1305Sbill return (0); 383*1305Sbill } 384*1305Sbill 385*1305Sbill struct varent * 386*1305Sbill adrof1(var, head) 387*1305Sbill char *var; 388*1305Sbill struct varent *head; 389*1305Sbill { 390*1305Sbill register struct varent *vp; 391*1305Sbill int cmp; 392*1305Sbill 393*1305Sbill shprev = head; 394*1305Sbill for (vp = shprev->link; vp != 0; vp = vp->link) { 395*1305Sbill cmp = strcmp(vp->name, var); 396*1305Sbill if (cmp == 0) 397*1305Sbill return (vp); 398*1305Sbill else if (cmp > 0) 399*1305Sbill return (0); 400*1305Sbill shprev = vp; 401*1305Sbill } 402*1305Sbill return (0); 403*1305Sbill } 404*1305Sbill 405*1305Sbill /* 406*1305Sbill * The caller is responsible for putting value in a safe place 407*1305Sbill */ 408*1305Sbill set(var, value) 409*1305Sbill char *var, *value; 410*1305Sbill { 411*1305Sbill register char **vec = (char **) calloc(2, sizeof (char **)); 412*1305Sbill 413*1305Sbill vec[0] = onlyread(value) ? savestr(value) : value; 414*1305Sbill set1(var, vec, &shvhed); 415*1305Sbill } 416*1305Sbill 417*1305Sbill set1(var, vec, head) 418*1305Sbill char *var, **vec; 419*1305Sbill struct varent *head; 420*1305Sbill { 421*1305Sbill 422*1305Sbill register char **oldv = vec; 423*1305Sbill 424*1305Sbill gflag = 0; rscan(oldv, tglob); 425*1305Sbill if (gflag) { 426*1305Sbill vec = glob(oldv); 427*1305Sbill if (vec == 0) { 428*1305Sbill bferr("No match"); 429*1305Sbill blkfree(oldv); 430*1305Sbill return; 431*1305Sbill } 432*1305Sbill blkfree(oldv); 433*1305Sbill gargv = 0; 434*1305Sbill } 435*1305Sbill setq(var, vec, head); 436*1305Sbill } 437*1305Sbill 438*1305Sbill setq(var, vec, head) 439*1305Sbill char *var, **vec; 440*1305Sbill struct varent *head; 441*1305Sbill { 442*1305Sbill register struct varent *vp; 443*1305Sbill 444*1305Sbill vp = adrof1(var, head); 445*1305Sbill if (vp == 0) { 446*1305Sbill vp = (struct varent *) calloc(1, sizeof *vp); 447*1305Sbill vp->name = savestr(var); 448*1305Sbill vp->link = shprev->link; 449*1305Sbill shprev->link = vp; 450*1305Sbill } 451*1305Sbill if (vp->vec) 452*1305Sbill blkfree(vp->vec); 453*1305Sbill scan(vec, trim); 454*1305Sbill vp->vec = vec; 455*1305Sbill } 456*1305Sbill 457*1305Sbill unset(v) 458*1305Sbill register char *v[]; 459*1305Sbill { 460*1305Sbill 461*1305Sbill unset1(v, &shvhed); 462*1305Sbill if (adrof("histchars") == 0) { 463*1305Sbill HIST = '!'; 464*1305Sbill HISTSUB = '^'; 465*1305Sbill } 466*1305Sbill } 467*1305Sbill 468*1305Sbill unset1(v, head) 469*1305Sbill register char *v[]; 470*1305Sbill struct varent *head; 471*1305Sbill { 472*1305Sbill register char *var; 473*1305Sbill register struct varent *vp; 474*1305Sbill register int cnt; 475*1305Sbill 476*1305Sbill v++; 477*1305Sbill while (var = *v++) { 478*1305Sbill cnt = 0; 479*1305Sbill while (vp = madrof(var, head)) 480*1305Sbill unsetv1(vp->name, head), cnt++; 481*1305Sbill if (cnt == 0) 482*1305Sbill setname(var); 483*1305Sbill } 484*1305Sbill } 485*1305Sbill 486*1305Sbill unsetv(var) 487*1305Sbill char *var; 488*1305Sbill { 489*1305Sbill 490*1305Sbill unsetv1(var, &shvhed); 491*1305Sbill } 492*1305Sbill 493*1305Sbill unsetv1(var, head) 494*1305Sbill char *var; 495*1305Sbill struct varent *head; 496*1305Sbill { 497*1305Sbill register struct varent *vp; 498*1305Sbill 499*1305Sbill vp = adrof1(var, head); 500*1305Sbill if (vp == 0) 501*1305Sbill udvar(var); 502*1305Sbill vp = shprev->link; 503*1305Sbill shprev->link = vp->link; 504*1305Sbill blkfree(vp->vec); 505*1305Sbill xfree(vp->name); 506*1305Sbill xfree((char *)vp); 507*1305Sbill } 508*1305Sbill 509*1305Sbill setNS(cp) 510*1305Sbill char *cp; 511*1305Sbill { 512*1305Sbill 513*1305Sbill set(cp, ""); 514*1305Sbill } 515*1305Sbill 516*1305Sbill shift(v) 517*1305Sbill register char **v; 518*1305Sbill { 519*1305Sbill register struct varent *argv; 520*1305Sbill register char *name; 521*1305Sbill 522*1305Sbill v++; 523*1305Sbill name = *v; 524*1305Sbill if (name == 0) 525*1305Sbill name = "argv"; 526*1305Sbill else 527*1305Sbill strip(name); 528*1305Sbill argv = adrof(name); 529*1305Sbill if (argv == 0) 530*1305Sbill udvar(name); 531*1305Sbill if (argv->vec[0] == 0) 532*1305Sbill bferr("No more words"); 533*1305Sbill lshift(argv->vec, 1); 534*1305Sbill } 535*1305Sbill 536*1305Sbill exportpath(val) 537*1305Sbill char **val; 538*1305Sbill { 539*1305Sbill char exppath[BUFSIZ]; 540*1305Sbill register char *dir; 541*1305Sbill 542*1305Sbill exppath[0] = 0; 543*1305Sbill if (val) 544*1305Sbill while (*val) { 545*1305Sbill if (strlen(*val) + strlen(exppath) + 2 > BUFSIZ) { 546*1305Sbill printf("Warning: ridiculously long PATH truncated\n"); 547*1305Sbill break; 548*1305Sbill } 549*1305Sbill strcat(exppath, *val++); 550*1305Sbill if (*val == 0 || eq(*val, ")")) 551*1305Sbill break; 552*1305Sbill strcat(exppath, ":"); 553*1305Sbill } 554*1305Sbill setenv("PATH", exppath); 555*1305Sbill } 556