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