home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / csh / sh.set.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  7KB  |  517 lines

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