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