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.parse.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  10KB  |  622 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "sh.h"
  3.  
  4. /*
  5.  * C shell
  6.  */
  7.  
  8. /*
  9.  * Perform aliasing on the word list lex
  10.  * Do a (very rudimentary) parse to separate into commands.
  11.  * If word 0 of a command has an alias, do it.
  12.  * Repeat a maximum of 20 times.
  13.  */
  14. alias(lex)
  15.     register struct wordent *lex;
  16. {
  17.     int aleft = 21;
  18.     jmp_buf osetexit;
  19.  
  20.     getexit(osetexit);
  21.     setexit();
  22.     if (haderr) {
  23.         resexit(osetexit);
  24.         reset();
  25.     }
  26.     if (--aleft == 0)
  27.         error("Alias loop");
  28.     asyntax(lex->next, lex);
  29.     resexit(osetexit);
  30. }
  31.  
  32. asyntax(p1, p2)
  33.     register struct wordent *p1, *p2;
  34. {
  35.  
  36.     while (p1 != p2)
  37.         if (any(p1->word[0], ";&\n"))
  38.             p1 = p1->next;
  39.         else {
  40.             asyn0(p1, p2);
  41.             return;
  42.         }
  43. }
  44.  
  45. asyn0(p1, p2)
  46.     struct wordent *p1;
  47.     register struct wordent *p2;
  48. {
  49.     register struct wordent *p;
  50.     register int l = 0;
  51.  
  52.     for (p = p1; p != p2; p = p->next)
  53.         switch (p->word[0]) {
  54.  
  55.         case '(':
  56.             l++;
  57.             continue;
  58.  
  59.         case ')':
  60.             l--;
  61.             if (l < 0)
  62.                 error("Too many )'s");
  63.             continue;
  64.  
  65.         case '>':
  66.             if (p->next != p2 && eq(p->next->word, "&"))
  67.                 p = p->next;
  68.             continue;
  69.  
  70.         case '&':
  71.         case '|':
  72.         case ';':
  73.         case '\n':
  74.             if (l != 0)
  75.                 continue;
  76.             asyn3(p1, p);
  77.             asyntax(p->next, p2);
  78.             return;
  79.         }
  80.     if (l == 0)
  81.         asyn3(p1, p2);
  82. }
  83.  
  84. asyn3(p1, p2)
  85.     struct wordent *p1;
  86.     register struct wordent *p2;
  87. {
  88.     register struct varent *ap;
  89.     struct wordent alout;
  90.     register bool redid;
  91.  
  92.     if (p1 == p2)
  93.         return;
  94.     if (p1->word[0] == '(') {
  95.         for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
  96.             if (p2 == p1)
  97.                 return;
  98.         if (p2 == p1->next)
  99.             return;
  100.         asyn0(p1->next, p2);
  101.         return;
  102.     }
  103.     ap = adrof1(p1->word, &aliases);
  104.     if (ap == 0)
  105.         return;
  106.     alhistp = p1->prev;
  107.     alhistt = p2;
  108.     alvec = ap->vec;
  109.     redid = lex(&alout);
  110.     alhistp = alhistt = 0;
  111.     alvec = 0;
  112.     if (err) {
  113.         freelex(&alout);
  114.         error(err);
  115.     }
  116.     if (p1->word[0] && eq(p1->word, alout.next->word)) {
  117.         char *cp = alout.next->word;
  118.  
  119.         alout.next->word = strspl("\200", cp);
  120.         xfree(cp);
  121.     }
  122.     p1 = freenod(p1, redid ? p2 : p1->next);
  123.     if (alout.next != &alout) {
  124.         p1->next->prev = alout.prev->prev;
  125.         alout.prev->prev->next = p1->next;
  126.         alout.next->prev = p1;
  127.         p1->next = alout.next;
  128.         xfree(alout.prev->word);
  129.         xfree(alout.prev);
  130.     }
  131.     reset();        /* throw! */
  132. }
  133.  
  134. struct wordent *
  135. freenod(p1, p2)
  136.     register struct wordent *p1, *p2;
  137. {
  138.     register struct wordent *retp = p1->prev;
  139.  
  140.     while (p1 != p2) {
  141.         xfree(p1->word);
  142.         p1 = p1->next;
  143.         xfree(p1->prev);
  144.     }
  145.     retp->next = p2;
  146.     p2->prev = retp;
  147.     return (retp);
  148. }
  149.  
  150. #define    PHERE    1
  151. #define    PIN    2
  152. #define    POUT    4
  153. #define    PDIAG    8
  154.  
  155. /*
  156.  * syntax
  157.  *    empty
  158.  *    syn0
  159.  */
  160. struct command *
  161. syntax(p1, p2, flags)
  162.     register struct wordent *p1, *p2;
  163.     int flags;
  164. {
  165.  
  166.     while (p1 != p2)
  167.         if (any(p1->word[0], ";&\n"))
  168.             p1 = p1->next;
  169.         else
  170.             return (syn0(p1, p2, flags));
  171.     return (0);
  172. }
  173.  
  174. /*
  175.  * syn0
  176.  *    syn1
  177.  *    syn1 & syntax
  178.  */
  179. struct command *
  180. syn0(p1, p2, flags)
  181.     struct wordent *p1, *p2;
  182.     int flags;
  183. {
  184.     register struct wordent *p;
  185.     register struct command *t, *t1;
  186.     int l;
  187.  
  188.     l = 0;
  189.     for (p = p1; p != p2; p = p->next)
  190.         switch (p->word[0]) {
  191.  
  192.         case '(':
  193.             l++;
  194.             continue;
  195.  
  196.         case ')':
  197.             l--;
  198.             if (l < 0)
  199.                 seterr("Too many )'s");
  200.             continue;
  201.  
  202.         case '|':
  203.             if (p->word[1] == '|')
  204.                 continue;
  205.             /* fall into ... */
  206.  
  207.         case '>':
  208.             if (p->next != p2 && eq(p->next->word, "&"))
  209.                 p = p->next;
  210.             continue;
  211.  
  212.         case '&':
  213.             if (l != 0)
  214.                 break;
  215.             if (p->word[1] == '&')
  216.                 continue;
  217.             t1 = syn1(p1, p, flags);
  218.             if (t1->t_dtyp == TLST) {
  219.                 t = (struct command *) calloc(1, sizeof (*t));
  220.                 t->t_dtyp = TPAR;
  221.                 t->t_dflg = FAND|FPRS|FINT;
  222.                 t->t_dspr = t1;
  223.                 t1 = t;
  224.             } else
  225.                 t1->t_dflg |= FAND|FPRS|FINT;
  226.             t = (struct command *) calloc(1, sizeof (*t));
  227.             t->t_dtyp = TLST;
  228.             t->t_dflg = 0;
  229.             t->t_dcar = t1;
  230.             t->t_dcdr = syntax(p, p2, flags);
  231.             return(t);
  232.         }
  233.     if (l == 0)
  234.         return (syn1(p1, p2, flags));
  235.     seterr("Too many ('s");
  236.     return (0);
  237. }
  238.  
  239. /*
  240.  * syn1
  241.  *    syn1a
  242.  *    syn1a ; syntax
  243.  */
  244. struct command *
  245. syn1(p1, p2, flags)
  246.     struct wordent *p1, *p2;
  247.     int flags;
  248. {
  249.     register struct wordent *p;
  250.     register struct command *t;
  251.     int l;
  252.  
  253.     l = 0;
  254.     for (p = p1; p != p2; p = p->next)
  255.         switch (p->word[0]) {
  256.  
  257.         case '(':
  258.             l++;
  259.             continue;
  260.  
  261.         case ')':
  262.             l--;
  263.             continue;
  264.  
  265.         case ';':
  266.         case '\n':
  267.             if (l != 0)
  268.                 break;
  269.             t = (struct command *) calloc(1, sizeof (*t));
  270.             t->t_dtyp = TLST;
  271.             t->t_dcar = syn1a(p1, p, flags);
  272.             t->t_dcdr = syntax(p->next, p2, flags);
  273.             if (t->t_dcdr == 0)
  274.                 t->t_dcdr = t->t_dcar, t->t_dcar = 0;
  275.             return (t);
  276.         }
  277.     return (syn1a(p1, p2, flags));
  278. }
  279.  
  280. /*
  281.  * syn1a
  282.  *    syn1b
  283.  *    syn1b || syn1a
  284.  */
  285. struct command *
  286. syn1a(p1, p2, flags)
  287.     struct wordent *p1, *p2;
  288.     int flags;
  289. {
  290.     register struct wordent *p;
  291.     register struct command *t;
  292.     register int l = 0;
  293.  
  294.     for (p = p1; p != p2; p = p->next)
  295.         switch (p->word[0]) {
  296.  
  297.         case '(':
  298.             l++;
  299.             continue;
  300.  
  301.         case ')':
  302.             l--;
  303.             continue;
  304.  
  305.         case '|':
  306.             if (p->word[1] != '|')
  307.                 continue;
  308.             if (l == 0) {
  309.                 t = (struct command *) calloc(1, sizeof (*t));
  310.                 t->t_dtyp = TOR;
  311.                 t->t_dcar = syn1b(p1, p, flags);
  312.                 t->t_dcdr = syn1a(p->next, p2, flags);
  313.                 t->t_dflg = 0;
  314.                 return (t);
  315.             }
  316.             continue;
  317.         }
  318.     return (syn1b(p1, p2, flags));
  319. }
  320.  
  321. /*
  322.  * syn1b
  323.  *    syn2
  324.  *    syn2 && syn1b
  325.  */
  326. struct command *
  327. syn1b(p1, p2, flags)
  328.     struct wordent *p1, *p2;
  329.     int flags;
  330. {
  331.     register struct wordent *p;
  332.     register struct command *t;
  333.     register int l = 0;
  334.  
  335.     l = 0;
  336.     for (p = p1; p != p2; p = p->next)
  337.         switch (p->word[0]) {
  338.  
  339.         case '(':
  340.             l++;
  341.             continue;
  342.  
  343.         case ')':
  344.             l--;
  345.             continue;
  346.  
  347.         case '&':
  348.             if (p->word[1] == '&' && l == 0) {
  349.                 t = (struct command *) calloc(1, sizeof (*t));
  350.                 t->t_dtyp = TAND;
  351.                 t->t_dcar = syn2(p1, p, flags);
  352.                 t->t_dcdr = syn1b(p->next, p2, flags);
  353.                 t->t_dflg = 0;
  354.                 return (t);
  355.             }
  356.             continue;
  357.         }
  358.     return (syn2(p1, p2, flags));
  359. }
  360.  
  361. /*
  362.  * syn2
  363.  *    syn3
  364.  *    syn3 | syn2
  365.  *    syn3 |& syn2
  366.  */
  367. struct command *
  368. syn2(p1, p2, flags)
  369.     struct wordent *p1, *p2;
  370.     int flags;
  371. {
  372.     register struct wordent *p, *pn;
  373.     register struct command *t;
  374.     register int l = 0;
  375.     int f;
  376.  
  377.     for (p = p1; p != p2; p = p->next)
  378.         switch (p->word[0]) {
  379.  
  380.         case '(':
  381.             l++;
  382.             continue;
  383.  
  384.         case ')':
  385.             l--;
  386.             continue;
  387.  
  388.         case '|':
  389.             if (l != 0)
  390.                 continue;
  391.             t = (struct command *) calloc(1, sizeof (*t));
  392.             f = flags | POUT;
  393.             pn = p->next;
  394.             if (pn != p2 && pn->word[0] == '&') {
  395.                 f |= PDIAG;
  396.                 t->t_dflg |= FDIAG;
  397.             }
  398.             t->t_dtyp = TFIL;
  399.             t->t_dcar = syn3(p1, p, f);
  400.             if (pn != p2 && pn->word[0] == '&')
  401.                 p = pn;
  402.             t->t_dcdr = syn2(p->next, p2, flags | PIN);
  403.             return (t);
  404.         }
  405.     return (syn3(p1, p2, flags));
  406. }
  407.  
  408. char    *RELPAR =    "<>()";
  409.  
  410. /*
  411.  * syn3
  412.  *    ( syn0 ) [ < in  ] [ > out ]
  413.  *    word word* [ < in ] [ > out ]
  414.  *    KEYWORD ( word* ) word* [ < in ] [ > out ]
  415.  *
  416.  *    KEYWORD = (@ exit foreach if set switch test while)
  417.  */
  418. struct command *
  419. syn3(p1, p2, flags)
  420.     struct wordent *p1, *p2;
  421.     int flags;
  422. {
  423.     register struct wordent *p;
  424.     struct wordent *lp, *rp;
  425.     register struct command *t;
  426.     register int l;
  427.     char **av;
  428.     int n, c;
  429.     bool specp = 0;
  430.  
  431.     if (p1 != p2) {
  432.         p = p1;
  433. again:
  434.         switch (srchx(p->word)) {
  435.  
  436.         case ZELSE:
  437.             p = p->next;
  438.             if (p != p2)
  439.                 goto again;
  440.             break;
  441.  
  442.         case ZEXIT:
  443.         case ZFOREACH:
  444.         case ZIF:
  445.         case ZLET:
  446.         case ZSET:
  447.         case ZSWITCH:
  448.         case ZWHILE:
  449.             specp = 1;
  450.             break;
  451.         }
  452.     }
  453.     n = 0;
  454.     l = 0;
  455.     for (p = p1; p != p2; p = p->next)
  456.         switch (p->word[0]) {
  457.  
  458.         case '(':
  459.             if (specp)
  460.                 n++;
  461.             l++;
  462.             continue;
  463.  
  464.         case ')':
  465.             if (specp)
  466.                 n++;
  467.             l--;
  468.             continue;
  469.  
  470.         case '>':
  471.         case '<':
  472.             if (l != 0) {
  473.                 if (specp)
  474.                     n++;
  475.                 continue;
  476.             }
  477.             if (p->next == p2)
  478.                 continue;
  479.             if (any(p->next->word[0], RELPAR))
  480.                 continue;
  481.             n--;
  482.             continue;
  483.  
  484.         default:
  485.             if (!specp && l != 0)
  486.                 continue;
  487.             n++;
  488.             continue;
  489.         }
  490.     if (n < 0)
  491.         n = 0;
  492.     t = (struct command *) calloc(1, sizeof (*t));
  493.     av = (char **) calloc(n + 1, sizeof (char **));
  494.     t->t_dcom = av;
  495.     n = 0;
  496.     if (p2->word[0] == ')')
  497.         t->t_dflg = FPAR;
  498.     lp = 0;
  499.     rp = 0;
  500.     l = 0;
  501.     for (p = p1; p != p2; p = p->next) {
  502.         c = p->word[0];
  503.         switch (c) {
  504.  
  505.         case '(':
  506.             if (l == 0) {
  507.                 if (lp != 0 && !specp)
  508.                     seterr("Badly placed (");
  509.                 lp = p->next;
  510.             }
  511.             l++;
  512.             goto savep;
  513.  
  514.         case ')':
  515.             l--;
  516.             if (l == 0)
  517.                 rp = p;
  518.             goto savep;
  519.  
  520.         case '>':
  521.             if (l != 0)
  522.                 goto savep;
  523.             if (p->word[1] == '>')
  524.                 t->t_dflg |= FCAT;
  525.             if (p->next != p2 && eq(p->next->word, "&")) {
  526.                 t->t_dflg |= FDIAG, p = p->next;
  527.                 if (flags & (POUT|PDIAG))
  528.                     goto badout;
  529.             }
  530.             if (p->next != p2 && eq(p->next->word, "!"))
  531.                 t->t_dflg |= FANY, p = p->next;
  532.             if (p->next == p2) {
  533. missfile:
  534.                 seterr("Missing name for redirect");
  535.                 continue;
  536.             }
  537.             p = p->next;
  538.             if (any(p->word[0], RELPAR))
  539.                 goto missfile;
  540.             if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
  541. badout:
  542.                 seterr("Ambiguous output redirect");
  543.             else
  544.                 t->t_drit = savestr(p->word);
  545.             continue;
  546.  
  547.         case '<':
  548.             if (l != 0)
  549.                 goto savep;
  550.             if (p->word[1] == '<')
  551.                 t->t_dflg |= FHERE;
  552.             if (p->next == p2)
  553.                 goto missfile;
  554.             p = p->next;
  555.             if (any(p->word[0], RELPAR))
  556.                 goto missfile;
  557.             if ((flags & PHERE) && (t->t_dflg & FHERE))
  558.                 seterr("Can't << within ()'s");
  559.             else if ((flags & PIN) || t->t_dlef)
  560.                 seterr("Ambiguous input redirect");
  561.             else
  562.                 t->t_dlef = savestr(p->word);
  563.             continue;
  564.  
  565. savep:
  566.             if (!specp)
  567.                 continue;
  568.         default:
  569.             if (l != 0 && !specp)
  570.                 continue;
  571.             if (err == 0)
  572.                 av[n] = savestr(p->word);
  573.             n++;
  574.             continue;
  575.         }
  576.     }
  577.     if (lp != 0 && !specp) {
  578.         if (n != 0)
  579.             seterr("Badly placed ()'s");
  580.         t->t_dtyp = TPAR;
  581.         t->t_dspr = syn0(lp, rp, PHERE);
  582.     } else {
  583.         if (n == 0)
  584.             seterr("Invalid null command");
  585.         t->t_dtyp = TCOM;
  586.     }
  587.     return (t);
  588. }
  589.  
  590. freesyn(t)
  591.     register struct command *t;
  592. {
  593.     register char **v;
  594.  
  595.     if (t == 0)
  596.         return;
  597.     switch (t->t_dtyp) {
  598.  
  599.     case TCOM:
  600.         for (v = t->t_dcom; *v; v++)
  601.             xfree(*v);
  602.         xfree(t->t_dcom);
  603.         goto lr;
  604.  
  605.     case TPAR:
  606.         freesyn(t->t_dspr);
  607.         /* fall into ... */
  608.  
  609. lr:
  610.         xfree(t->t_dlef), xfree(t->t_drit);
  611.         break;
  612.  
  613.     case TAND:
  614.     case TOR:
  615.     case TFIL:
  616.     case TLST:
  617.         freesyn(t->t_dcar), freesyn(t->t_dcdr);
  618.         break;
  619.     }
  620.     xfree(t);
  621. }
  622.