home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / bin / csh / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-19  |  13.7 KB  |  699 lines

  1. /*-
  2.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)parse.c    5.12 (Berkeley) 7/19/91";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #if __STDC__
  42. # include <stdarg.h>
  43. #else
  44. # include <varargs.h>
  45. #endif
  46.  
  47. #include "csh.h"
  48. #include "extern.h"
  49.  
  50. static void     asyntax __P((struct wordent *, struct wordent *));
  51. static void     asyn0 __P((struct wordent *, struct wordent *));
  52. static void     asyn3 __P((struct wordent *, struct wordent *));
  53. static struct wordent 
  54.         *freenod __P((struct wordent *, struct wordent *));
  55. static struct command 
  56.         *syn0 __P((struct wordent *, struct wordent *, int));
  57. static struct command 
  58.         *syn1 __P((struct wordent *, struct wordent *, int));
  59. static struct command 
  60.         *syn1a __P((struct wordent *, struct wordent *, int));
  61. static struct command 
  62.         *syn1b __P((struct wordent *, struct wordent *, int));
  63. static struct command 
  64.         *syn2 __P((struct wordent *, struct wordent *, int));
  65. static struct command 
  66.         *syn3 __P((struct wordent *, struct wordent *, int));
  67.  
  68. #define ALEFT    21        /* max of 20 alias expansions     */
  69. #define HLEFT    11        /* max of 10 history expansions     */
  70. /*
  71.  * Perform aliasing on the word list lex
  72.  * Do a (very rudimentary) parse to separate into commands.
  73.  * If word 0 of a command has an alias, do it.
  74.  * Repeat a maximum of 20 times.
  75.  */
  76. static int aleft;
  77. extern int hleft;
  78. void
  79. alias(lex)
  80.     register struct wordent *lex;
  81. {
  82.     jmp_buf osetexit;
  83.  
  84.     aleft = ALEFT;
  85.     hleft = HLEFT;
  86.     getexit(osetexit);
  87.     (void) setexit();
  88.     if (haderr) {
  89.     resexit(osetexit);
  90.     reset();
  91.     }
  92.     if (--aleft == 0)
  93.     stderror(ERR_ALIASLOOP);
  94.     asyntax(lex->next, lex);
  95.     resexit(osetexit);
  96. }
  97.  
  98. static void
  99. asyntax(p1, p2)
  100.     register struct wordent *p1, *p2;
  101. {
  102.     while (p1 != p2)
  103.     if (any(";&\n", p1->word[0]))
  104.         p1 = p1->next;
  105.     else {
  106.         asyn0(p1, p2);
  107.         return;
  108.     }
  109. }
  110.  
  111. static void
  112. asyn0(p1, p2)
  113.     struct wordent *p1;
  114.     register struct wordent *p2;
  115. {
  116.     register struct wordent *p;
  117.     register int l = 0;
  118.  
  119.     for (p = p1; p != p2; p = p->next)
  120.     switch (p->word[0]) {
  121.  
  122.     case '(':
  123.         l++;
  124.         continue;
  125.  
  126.     case ')':
  127.         l--;
  128.         if (l < 0)
  129.         stderror(ERR_TOOMANYRP);
  130.         continue;
  131.  
  132.     case '>':
  133.         if (p->next != p2 && eq(p->next->word, STRand))
  134.         p = p->next;
  135.         continue;
  136.  
  137.     case '&':
  138.     case '|':
  139.     case ';':
  140.     case '\n':
  141.         if (l != 0)
  142.         continue;
  143.         asyn3(p1, p);
  144.         asyntax(p->next, p2);
  145.         return;
  146.     }
  147.     if (l == 0)
  148.     asyn3(p1, p2);
  149. }
  150.  
  151. static void
  152. asyn3(p1, p2)
  153.     struct wordent *p1;
  154.     register struct wordent *p2;
  155. {
  156.     register struct varent *ap;
  157.     struct wordent alout;
  158.     register bool redid;
  159.  
  160.     if (p1 == p2)
  161.     return;
  162.     if (p1->word[0] == '(') {
  163.     for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
  164.         if (p2 == p1)
  165.         return;
  166.     if (p2 == p1->next)
  167.         return;
  168.     asyn0(p1->next, p2);
  169.     return;
  170.     }
  171.     ap = adrof1(p1->word, &aliases);
  172.     if (ap == 0)
  173.     return;
  174.     alhistp = p1->prev;
  175.     alhistt = p2;
  176.     alvec = ap->vec;
  177.     redid = lex(&alout);
  178.     alhistp = alhistt = 0;
  179.     alvec = 0;
  180.     if (seterr) {
  181.     freelex(&alout);
  182.     stderror(ERR_OLD);
  183.     }
  184.     if (p1->word[0] && eq(p1->word, alout.next->word)) {
  185.     Char   *cp = alout.next->word;
  186.  
  187.     alout.next->word = Strspl(STRQNULL, cp);
  188.     xfree((ptr_t) cp);
  189.     }
  190.     p1 = freenod(p1, redid ? p2 : p1->next);
  191.     if (alout.next != &alout) {
  192.     p1->next->prev = alout.prev->prev;
  193.     alout.prev->prev->next = p1->next;
  194.     alout.next->prev = p1;
  195.     p1->next = alout.next;
  196.     xfree((ptr_t) alout.prev->word);
  197.     xfree((ptr_t) (alout.prev));
  198.     }
  199.     reset();            /* throw! */
  200. }
  201.  
  202. static struct wordent *
  203. freenod(p1, p2)
  204.     register struct wordent *p1, *p2;
  205. {
  206.     register struct wordent *retp = p1->prev;
  207.  
  208.     while (p1 != p2) {
  209.     xfree((ptr_t) p1->word);
  210.     p1 = p1->next;
  211.     xfree((ptr_t) (p1->prev));
  212.     }
  213.     retp->next = p2;
  214.     p2->prev = retp;
  215.     return (retp);
  216. }
  217.  
  218. #define    PHERE    1
  219. #define    PIN    2
  220. #define    POUT    4
  221. #define    PERR    8
  222.  
  223. /*
  224.  * syntax
  225.  *    empty
  226.  *    syn0
  227.  */
  228. struct command *
  229. syntax(p1, p2, flags)
  230.     register struct wordent *p1, *p2;
  231.     int     flags;
  232. {
  233.  
  234.     while (p1 != p2)
  235.     if (any(";&\n", p1->word[0]))
  236.         p1 = p1->next;
  237.     else
  238.         return (syn0(p1, p2, flags));
  239.     return (0);
  240. }
  241.  
  242. /*
  243.  * syn0
  244.  *    syn1
  245.  *    syn1 & syntax
  246.  */
  247. static struct command *
  248. syn0(p1, p2, flags)
  249.     struct wordent *p1, *p2;
  250.     int     flags;
  251. {
  252.     register struct wordent *p;
  253.     register struct command *t, *t1;
  254.     int     l;
  255.  
  256.     l = 0;
  257.     for (p = p1; p != p2; p = p->next)
  258.     switch (p->word[0]) {
  259.  
  260.     case '(':
  261.         l++;
  262.         continue;
  263.  
  264.     case ')':
  265.         l--;
  266.         if (l < 0)
  267.         seterror(ERR_TOOMANYRP);
  268.         continue;
  269.  
  270.     case '|':
  271.         if (p->word[1] == '|')
  272.         continue;
  273.         /* fall into ... */
  274.  
  275.     case '>':
  276.         if (p->next != p2 && eq(p->next->word, STRand))
  277.         p = p->next;
  278.         continue;
  279.  
  280.     case '&':
  281.         if (l != 0)
  282.         break;
  283.         if (p->word[1] == '&')
  284.         continue;
  285.         t1 = syn1(p1, p, flags);
  286.         if (t1->t_dtyp == NODE_LIST ||
  287.         t1->t_dtyp == NODE_AND ||
  288.         t1->t_dtyp == NODE_OR) {
  289.         t = (struct command *) xcalloc(1, sizeof(*t));
  290.         t->t_dtyp = NODE_PAREN;
  291.         t->t_dflg = F_AMPERSAND | F_NOINTERRUPT;
  292.         t->t_dspr = t1;
  293.         t1 = t;
  294.         }
  295.         else
  296.         t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT;
  297.         t = (struct command *) xcalloc(1, sizeof(*t));
  298.         t->t_dtyp = NODE_LIST;
  299.         t->t_dflg = 0;
  300.         t->t_dcar = t1;
  301.         t->t_dcdr = syntax(p, p2, flags);
  302.         return (t);
  303.     }
  304.     if (l == 0)
  305.     return (syn1(p1, p2, flags));
  306.     seterror(ERR_TOOMANYLP);
  307.     return (0);
  308. }
  309.  
  310. /*
  311.  * syn1
  312.  *    syn1a
  313.  *    syn1a ; syntax
  314.  */
  315. static struct command *
  316. syn1(p1, p2, flags)
  317.     struct wordent *p1, *p2;
  318.     int     flags;
  319. {
  320.     register struct wordent *p;
  321.     register struct command *t;
  322.     int     l;
  323.  
  324.     l = 0;
  325.     for (p = p1; p != p2; p = p->next)
  326.     switch (p->word[0]) {
  327.  
  328.     case '(':
  329.         l++;
  330.         continue;
  331.  
  332.     case ')':
  333.         l--;
  334.         continue;
  335.  
  336.     case ';':
  337.     case '\n':
  338.         if (l != 0)
  339.         break;
  340.         t = (struct command *) xcalloc(1, sizeof(*t));
  341.         t->t_dtyp = NODE_LIST;
  342.         t->t_dcar = syn1a(p1, p, flags);
  343.         t->t_dcdr = syntax(p->next, p2, flags);
  344.         if (t->t_dcdr == 0)
  345.         t->t_dcdr = t->t_dcar, t->t_dcar = 0;
  346.         return (t);
  347.     }
  348.     return (syn1a(p1, p2, flags));
  349. }
  350.  
  351. /*
  352.  * syn1a
  353.  *    syn1b
  354.  *    syn1b || syn1a
  355.  */
  356. static struct command *
  357. syn1a(p1, p2, flags)
  358.     struct wordent *p1, *p2;
  359.     int     flags;
  360. {
  361.     register struct wordent *p;
  362.     register struct command *t;
  363.     register int l = 0;
  364.  
  365.     for (p = p1; p != p2; p = p->next)
  366.     switch (p->word[0]) {
  367.  
  368.     case '(':
  369.         l++;
  370.         continue;
  371.  
  372.     case ')':
  373.         l--;
  374.         continue;
  375.  
  376.     case '|':
  377.         if (p->word[1] != '|')
  378.         continue;
  379.         if (l == 0) {
  380.         t = (struct command *) xcalloc(1, sizeof(*t));
  381.         t->t_dtyp = NODE_OR;
  382.         t->t_dcar = syn1b(p1, p, flags);
  383.         t->t_dcdr = syn1a(p->next, p2, flags);
  384.         t->t_dflg = 0;
  385.         return (t);
  386.         }
  387.         continue;
  388.     }
  389.     return (syn1b(p1, p2, flags));
  390. }
  391.  
  392. /*
  393.  * syn1b
  394.  *    syn2
  395.  *    syn2 && syn1b
  396.  */
  397. static struct command *
  398. syn1b(p1, p2, flags)
  399.     struct wordent *p1, *p2;
  400.     int     flags;
  401. {
  402.     register struct wordent *p;
  403.     register struct command *t;
  404.     register int l = 0;
  405.  
  406.     for (p = p1; p != p2; p = p->next)
  407.     switch (p->word[0]) {
  408.  
  409.     case '(':
  410.         l++;
  411.         continue;
  412.  
  413.     case ')':
  414.         l--;
  415.         continue;
  416.  
  417.     case '&':
  418.         if (p->word[1] == '&' && l == 0) {
  419.         t = (struct command *) xcalloc(1, sizeof(*t));
  420.         t->t_dtyp = NODE_AND;
  421.         t->t_dcar = syn2(p1, p, flags);
  422.         t->t_dcdr = syn1b(p->next, p2, flags);
  423.         t->t_dflg = 0;
  424.         return (t);
  425.         }
  426.         continue;
  427.     }
  428.     return (syn2(p1, p2, flags));
  429. }
  430.  
  431. /*
  432.  * syn2
  433.  *    syn3
  434.  *    syn3 | syn2
  435.  *    syn3 |& syn2
  436.  */
  437. static struct command *
  438. syn2(p1, p2, flags)
  439.     struct wordent *p1, *p2;
  440.     int     flags;
  441. {
  442.     register struct wordent *p, *pn;
  443.     register struct command *t;
  444.     register int l = 0;
  445.     int     f;
  446.  
  447.     for (p = p1; p != p2; p = p->next)
  448.     switch (p->word[0]) {
  449.  
  450.     case '(':
  451.         l++;
  452.         continue;
  453.  
  454.     case ')':
  455.         l--;
  456.         continue;
  457.  
  458.     case '|':
  459.         if (l != 0)
  460.         continue;
  461.         t = (struct command *) xcalloc(1, sizeof(*t));
  462.         f = flags | POUT;
  463.         pn = p->next;
  464.         if (pn != p2 && pn->word[0] == '&') {
  465.         f |= PERR;
  466.         t->t_dflg |= F_STDERR;
  467.         }
  468.         t->t_dtyp = NODE_PIPE;
  469.         t->t_dcar = syn3(p1, p, f);
  470.         if (pn != p2 && pn->word[0] == '&')
  471.         p = pn;
  472.         t->t_dcdr = syn2(p->next, p2, flags | PIN);
  473.         return (t);
  474.     }
  475.     return (syn3(p1, p2, flags));
  476. }
  477.  
  478. static char RELPAR[] = {'<', '>', '(', ')', '\0'};
  479.  
  480. /*
  481.  * syn3
  482.  *    ( syn0 ) [ < in  ] [ > out ]
  483.  *    word word* [ < in ] [ > out ]
  484.  *    KEYWORD ( word* ) word* [ < in ] [ > out ]
  485.  *
  486.  *    KEYWORD = (@ exit foreach if set switch test while)
  487.  */
  488. static struct command *
  489. syn3(p1, p2, flags)
  490.     struct wordent *p1, *p2;
  491.     int     flags;
  492. {
  493.     register struct wordent *p;
  494.     struct wordent *lp, *rp;
  495.     register struct command *t;
  496.     register int l;
  497.     Char  **av;
  498.     int     n, c;
  499.     bool    specp = 0;
  500.  
  501.     if (p1 != p2) {
  502.     p = p1;
  503. again:
  504.     switch (srchx(p->word)) {
  505.  
  506.     case T_ELSE:
  507.         p = p->next;
  508.         if (p != p2)
  509.         goto again;
  510.         break;
  511.  
  512.     case T_EXIT:
  513.     case T_FOREACH:
  514.     case T_IF:
  515.     case T_LET:
  516.     case T_SET:
  517.     case T_SWITCH:
  518.     case T_WHILE:
  519.         specp = 1;
  520.         break;
  521.     }
  522.     }
  523.     n = 0;
  524.     l = 0;
  525.     for (p = p1; p != p2; p = p->next)
  526.     switch (p->word[0]) {
  527.  
  528.     case '(':
  529.         if (specp)
  530.         n++;
  531.         l++;
  532.         continue;
  533.  
  534.     case ')':
  535.         if (specp)
  536.         n++;
  537.         l--;
  538.         continue;
  539.  
  540.     case '>':
  541.     case '<':
  542.         if (l != 0) {
  543.         if (specp)
  544.             n++;
  545.         continue;
  546.         }
  547.         if (p->next == p2)
  548.         continue;
  549.         if (any(RELPAR, p->next->word[0]))
  550.         continue;
  551.         n--;
  552.         continue;
  553.  
  554.     default:
  555.         if (!specp && l != 0)
  556.         continue;
  557.         n++;
  558.         continue;
  559.     }
  560.     if (n < 0)
  561.     n = 0;
  562.     t = (struct command *) xcalloc(1, sizeof(*t));
  563.     av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **));
  564.     t->t_dcom = av;
  565.     n = 0;
  566.     if (p2->word[0] == ')')
  567.     t->t_dflg = F_NOFORK;
  568.     lp = 0;
  569.     rp = 0;
  570.     l = 0;
  571.     for (p = p1; p != p2; p = p->next) {
  572.     c = p->word[0];
  573.     switch (c) {
  574.  
  575.     case '(':
  576.         if (l == 0) {
  577.         if (lp != 0 && !specp)
  578.             seterror(ERR_BADPLP);
  579.         lp = p->next;
  580.         }
  581.         l++;
  582.         goto savep;
  583.  
  584.     case ')':
  585.         l--;
  586.         if (l == 0)
  587.         rp = p;
  588.         goto savep;
  589.  
  590.     case '>':
  591.         if (l != 0)
  592.         goto savep;
  593.         if (p->word[1] == '>')
  594.         t->t_dflg |= F_APPEND;
  595.         if (p->next != p2 && eq(p->next->word, STRand)) {
  596.         t->t_dflg |= F_STDERR, p = p->next;
  597.         if (flags & (POUT | PERR)) {
  598.             seterror(ERR_OUTRED);
  599.             continue;
  600.         }
  601.         }
  602.         if (p->next != p2 && eq(p->next->word, STRbang))
  603.         t->t_dflg |= F_OVERWRITE, p = p->next;
  604.         if (p->next == p2) {
  605.         seterror(ERR_MISRED);
  606.         continue;
  607.         }
  608.         p = p->next;
  609.         if (any(RELPAR, p->word[0])) {
  610.         seterror(ERR_MISRED);
  611.         continue;
  612.         }
  613.         if ((flags & POUT) && (flags & PERR) == 0 || t->t_drit)
  614.         seterror(ERR_OUTRED);
  615.         else
  616.         t->t_drit = Strsave(p->word);
  617.         continue;
  618.  
  619.     case '<':
  620.         if (l != 0)
  621.         goto savep;
  622.         if (p->word[1] == '<')
  623.         t->t_dflg |= F_READ;
  624.         if (p->next == p2) {
  625.         seterror(ERR_MISRED);
  626.         continue;
  627.         }
  628.         p = p->next;
  629.         if (any(RELPAR, p->word[0])) {
  630.         seterror(ERR_MISRED);
  631.         continue;
  632.         }
  633.         if ((flags & PHERE) && (t->t_dflg & F_READ))
  634.         seterror(ERR_REDPAR);
  635.         else if ((flags & PIN) || t->t_dlef)
  636.         seterror(ERR_INRED);
  637.         else
  638.         t->t_dlef = Strsave(p->word);
  639.         continue;
  640.  
  641.     savep:
  642.         if (!specp)
  643.         continue;
  644.     default:
  645.         if (l != 0 && !specp)
  646.         continue;
  647.         if (seterr == 0)
  648.         av[n] = Strsave(p->word);
  649.         n++;
  650.         continue;
  651.     }
  652.     }
  653.     if (lp != 0 && !specp) {
  654.     if (n != 0)
  655.         seterror(ERR_BADPLPS);
  656.     t->t_dtyp = NODE_PAREN;
  657.     t->t_dspr = syn0(lp, rp, PHERE);
  658.     }
  659.     else {
  660.     if (n == 0)
  661.         seterror(ERR_NULLCOM);
  662.     t->t_dtyp = NODE_COMMAND;
  663.     }
  664.     return (t);
  665. }
  666.  
  667. void
  668. freesyn(t)
  669.     register struct command *t;
  670. {
  671.     register Char **v;
  672.  
  673.     if (t == 0)
  674.     return;
  675.     switch (t->t_dtyp) {
  676.  
  677.     case NODE_COMMAND:
  678.     for (v = t->t_dcom; *v; v++)
  679.         xfree((ptr_t) * v);
  680.     xfree((ptr_t) (t->t_dcom));
  681.     xfree((ptr_t) t->t_dlef);
  682.     xfree((ptr_t) t->t_drit);
  683.     break;
  684.     case NODE_PAREN:
  685.     freesyn(t->t_dspr);
  686.     xfree((ptr_t) t->t_dlef);
  687.     xfree((ptr_t) t->t_drit);
  688.     break;
  689.  
  690.     case NODE_AND:
  691.     case NODE_OR:
  692.     case NODE_PIPE:
  693.     case NODE_LIST:
  694.     freesyn(t->t_dcar), freesyn(t->t_dcdr);
  695.     break;
  696.     }
  697.     xfree((ptr_t) t);
  698. }
  699.