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.func.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  12KB  |  767 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #include "sh.h"
  3.  
  4. /*
  5.  * C shell
  6.  */
  7.  
  8. struct biltins *
  9. isbfunc(cp)
  10.     register char *cp;
  11. {
  12.     register char *dp;
  13.     register struct biltins *bp;
  14.  
  15.     if (lastchr(cp) == ':')
  16.         return ((struct biltins *) 1);
  17.     for (bp = bfunc; dp = bp->bname; bp++) {
  18.         if (dp[0] == cp[0] && eq(dp, cp))
  19.             return (bp);
  20.         if (dp[0] > cp[0])
  21.             break;
  22.     }
  23.     return (0);
  24. }
  25.  
  26. func(t)
  27.     register struct command *t;
  28. {
  29.     register struct biltins *bp;
  30.     int i;
  31.  
  32.     bp = bfunc;
  33.     if (lastchr(t->t_dcom[0]) == ':') {
  34.         xechoit(t->t_dcom);
  35.         if (!eq(t->t_dcom[0], ":") && t->t_dcom[1])
  36.             error("No args on labels");
  37.         return (1);
  38.     }
  39.     bp = isbfunc(t->t_dcom[0]);
  40.     if (bp == 0)
  41.         return (0);
  42.     /* timed builtins must go in background if output is pipe, or &'ed */
  43.     if (eq(bp->bname, "time"))
  44.         if ((t->t_dflg & FAND) || (t->t_dflg & FPOU))
  45.             return (0);
  46.     if (eq(bp->bname, "nohup") && t->t_dcom[1])
  47.         return (0);
  48.     xechoit(t->t_dcom);
  49.     setname(bp->bname);
  50.     i = blklen(t->t_dcom) - 1;
  51.     if (i < bp->minargs)
  52.         bferr("Too few arguments");
  53.     if (i > bp->maxargs)
  54.         bferr("Too many arguments");
  55.     i = (*bp->bfunct)(t->t_dcom, t);
  56.     /* time and nice may not do their deeds, all others guarantee too */
  57.     return (eq(bp->bname, "time") || eq(bp->bname, "nice") ? i : 1);
  58. }
  59.  
  60. doonintr(v)
  61.     char **v;
  62. {
  63.     register char *cp;
  64.     register char *vv = v[1];
  65.  
  66.     if (parintr == SIG_IGN)
  67.         return;
  68.     if (setintr && intty)
  69.         bferr("Can't from terminal");
  70.     cp = gointr, gointr = 0, xfree(cp);
  71.     if (vv == 0) {
  72.         signal(SIGINT, setintr ? SIG_IGN : SIG_DFL);
  73.         gointr = 0;
  74.     } else if (eq((vv = strip(vv)), "-")) {
  75.         signal(SIGINT, SIG_IGN);
  76.         gointr = "-";
  77.     } else {
  78.         gointr = savestr(vv);
  79.         signal(SIGINT, pintr);
  80.     }
  81. }
  82.  
  83. donohup()
  84. {
  85.  
  86.     if (intty)
  87.         bferr("Can't from terminal");
  88.     if (setintr == 0) {
  89.         signal(SIGHUP, SIG_IGN);
  90. #ifdef CC
  91.         submit(getpid());
  92. #endif
  93.     }
  94. }
  95.  
  96. dozip()
  97. {
  98.  
  99.     ;
  100. }
  101.  
  102. chngd(vp)
  103.     register char **vp;
  104. {
  105.     register int i;
  106.     register char *dp;
  107.  
  108.     vp++;
  109.     dp = *vp;
  110.     if (dp)
  111.         dp = globone(dp);
  112.     else {
  113.         dp = value("home");
  114.         if (*dp == 0)
  115.             bferr("No home");
  116.     }
  117.     i = chdir(dp);
  118.     if (*vp)
  119.         xfree(dp);
  120.     if (i < 0)
  121.         Perror(dp);
  122. }
  123.  
  124. prvars()
  125. {
  126.  
  127.     plist(&shvhed);
  128. }
  129.  
  130. doalias(v)
  131.     register char **v;
  132. {
  133.     register struct varent *vp;
  134.     register char *p;
  135.  
  136.     v++;
  137.     p = *v++;
  138.     if (p == 0)
  139.         plist(&aliases);
  140.     else if (*v == 0) {
  141.         vp = adrof1(strip(p), &aliases);
  142.         if (vp)
  143.             blkpr(vp->vec), printf("\n");
  144.     } else {
  145.         if (eq(p, "alias") || eq(p, "unalias")) {
  146.             setname(p);
  147.             bferr("Too dangerous to alias that");
  148.         }
  149.         set1(strip(p), saveblk(v), &aliases);
  150.     }
  151. }
  152.  
  153. unalias(v)
  154.     char **v;
  155. {
  156.  
  157.     unset1(v, &aliases);
  158. }
  159.  
  160. dologout()
  161. {
  162.  
  163.     islogin();
  164.     goodbye();
  165. }
  166.  
  167. islogin()
  168. {
  169.  
  170.     if (loginsh)
  171.         return;
  172.     error("Not login shell");
  173. }
  174.  
  175. doif(v, kp)
  176.     char **v;
  177.     struct command *kp;
  178. {
  179.     register int i;
  180.     register char **vv;
  181.  
  182.     v++;
  183.     i = exp(&v);
  184.     vv = v;
  185.     if (*vv && eq(*vv, "then")) {
  186.         vv++;
  187.         if (*vv)
  188.             bferr("Improper then");
  189.         setname("then");
  190.         /*
  191.          * If expression was zero, then scan to else,
  192.          * otherwise just fall into following code.
  193.          */
  194.         if (!i)
  195.             search(ZIF, 0);
  196.         return;
  197.     }
  198.     /*
  199.      * Simple command attached to this if.
  200.      * Left shift the node in this tree, munging it
  201.      * so we can reexecute it.
  202.      */
  203.     if (i) {
  204.         lshift(kp->t_dcom, vv - kp->t_dcom);
  205.         reexecute(kp);
  206.         donefds();
  207.     }
  208. }
  209.  
  210. /*
  211.  * Reexecute a command, being careful not
  212.  * to redo i/o redirection, which is already set up.
  213.  */
  214. reexecute(kp)
  215.     register struct command *kp;
  216. {
  217.  
  218.     kp->t_dflg = FREDO;
  219.     execute(kp);
  220. }
  221.  
  222. doelse()
  223. {
  224.  
  225.     search(ZELSE, 0);
  226. }
  227.  
  228. dogoto(v)
  229.     char **v;
  230. {
  231.     register struct whyle *wp;
  232.     char *lp;
  233.  
  234.     /*
  235.      * While we still can, locate any unknown ends of existing loops.
  236.      * This obscure code is the WORST result of the fact that we
  237.      * don't really parse.
  238.      */
  239.     for (wp = whyles; wp; wp = wp->w_next)
  240.         if (wp->w_end == 0)
  241.             wp->w_end = search(ZBREAK, 0);
  242.         else
  243.             bseek(wp->w_end);
  244.     search(ZGOTO, 0, lp = globone(v[1]));
  245.     xfree(lp);
  246.     /*
  247.      * Eliminate loops which were exited.
  248.      */
  249.     wfree();
  250. }
  251.  
  252. doswitch(v)
  253.     register char **v;
  254. {
  255.     register char *cp, *lp;
  256.  
  257.     v++;
  258.     if (!*v || *(*v++) != '(')
  259.         goto syntax;
  260.     cp = **v == ')' ? "" : *v++;
  261.     if (*(*v++) != ')')
  262.         v--;
  263.     if (*v)
  264. syntax:
  265.         error("Syntax error");
  266.     search(ZSWITCH, 0, lp = globone(cp));
  267.     xfree(lp);
  268. }
  269.  
  270. dobreak()
  271. {
  272.  
  273.     if (whyles)
  274.         toend();
  275.     else
  276.         bferr("Not in while/foreach");
  277. }
  278.  
  279. doexit(v)
  280.     char **v;
  281. {
  282.  
  283.     /*
  284.      * Don't DEMAND parentheses here either.
  285.      */
  286.     v++;
  287.     if (*v) {
  288.         set("status", putn(exp(&v)));
  289.         if (*v)
  290.             bferr("Expression syntax");
  291.     }
  292.     btoeof();
  293.     if (intty)
  294.         close(SHIN);
  295. }
  296.  
  297. doforeach(v)
  298.     register char **v;
  299. {
  300.     register char *cp;
  301.     register struct whyle *nwp;
  302.  
  303.     v++;
  304.     cp = strip(*v);
  305.     while (*cp && letter(*cp))
  306.         cp++;
  307.     if (*cp || strlen(*v) >= 20)
  308.         bferr("Invalid variable");
  309.     cp = *v++;
  310.     if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
  311.         bferr("Words not ()'ed");
  312.     v++;
  313.     gflag = 0, rscan(v, tglob);
  314.     v = glob(v);
  315.     if (v == 0)
  316.         bferr("No match");
  317.     nwp = (struct whyle *) calloc(1, sizeof *nwp);
  318.     nwp->w_fe = nwp->w_fe0 = v; gargv = 0;
  319.     nwp->w_start = btell();
  320.     nwp->w_fename = savestr(cp);
  321.     nwp->w_next = whyles;
  322.     whyles = nwp;
  323.     /*
  324.      * Pre-read the loop so as to be more
  325.      * comprehensible to a terminal user.
  326.      */
  327.     if (intty)
  328.         preread();
  329.     doagain();
  330. }
  331.  
  332. dowhile(v)
  333.     char **v;
  334. {
  335.     register int status;
  336.     register bool again = whyles != 0 && whyles->w_start == lineloc;
  337.  
  338.     v++;
  339.     /*
  340.      * Implement prereading here also, taking care not to
  341.      * evaluate the expression before the loop has been read up
  342.      * from a terminal.
  343.      */
  344.     if (intty && !again)
  345.         status = !exp0(&v, 1);
  346.     else
  347.         status = !exp(&v);
  348.     if (*v)
  349.         bferr("Expression syntax");
  350.     if (!again) {
  351.         register struct whyle *nwp = (struct whyle *) calloc(1, sizeof (*nwp));
  352.  
  353.         nwp->w_start = lineloc;
  354.         nwp->w_end = 0;
  355.         nwp->w_next = whyles;
  356.         whyles = nwp;
  357.         if (intty) {
  358.             /*
  359.              * The tty preread
  360.              */
  361.             preread();
  362.             doagain();
  363.             return;
  364.         }
  365.     }
  366.     if (status)
  367.         /* We ain't gonna loop no more, no more! */
  368.         toend();
  369. }
  370.  
  371. preread()
  372. {
  373.     register int (*oldint)();
  374.  
  375.     whyles->w_end = -1;
  376.     if (setintr)
  377.         oldint = signal(SIGINT, pintr);
  378.     search(ZBREAK, 0);
  379.     if (setintr)
  380.         signal(SIGINT, oldint);
  381.     whyles->w_end = btell();
  382. }
  383.  
  384. doend()
  385. {
  386.  
  387.     if (!whyles)
  388.         bferr("Not in while/foreach");
  389.     whyles->w_end = btell();
  390.     doagain();
  391. }
  392.  
  393. docontin()
  394. {
  395.  
  396.     if (!whyles)
  397.         bferr("Not in while/foreach");
  398.     doagain();
  399. }
  400.  
  401. doagain()
  402. {
  403.  
  404.     /* Repeating a while is simple */
  405.     if (whyles->w_fename == 0) {
  406.         bseek(whyles->w_start);
  407.         return;
  408.     }
  409.     /*
  410.      * The foreach variable list actually has a spurious word
  411.      * ")" at the end of the w_fe list.  Thus we are at the
  412.      * of the list if one word beyond this is 0.
  413.      */
  414.     if (!whyles->w_fe[1]) {
  415.         dobreak();
  416.         return;
  417.     }
  418.     set(whyles->w_fename, savestr(*whyles->w_fe++));
  419.     bseek(whyles->w_start);
  420. }
  421.  
  422. dorepeat(v, kp)
  423.     char **v;
  424.     struct command *kp;
  425. {
  426.     register int i;
  427.     register int (*saveintr)();
  428.  
  429.     i = getn(v[1]);
  430.     if (setintr)
  431.         saveintr = signal(SIGINT, SIG_IGN);
  432.     lshift(v, 2);
  433.     while (i > 0) {
  434.         if (setintr)
  435.             signal(SIGINT, pintr);
  436.         reexecute(kp);
  437.         --i;
  438.     }
  439.     donefds();
  440.     if (setintr)
  441.         signal(SIGINT, saveintr);
  442. }
  443.  
  444. doswbrk()
  445. {
  446.  
  447.     search(ZBRKSW, 0);
  448. }
  449.  
  450. srchx(cp)
  451.     register char *cp;
  452. {
  453.     register struct srch *sp;
  454.  
  455.     for (sp = srchn; sp->s_name; sp++)
  456.         if (eq(cp, sp->s_name))
  457.             return (sp->s_value);
  458.     return (-1);
  459. }
  460.  
  461. char    Stype;
  462. char    *Sgoal;
  463.  
  464. /*VARARGS2*/
  465. search(type, level, goal)
  466.     int type;
  467.     register int level;
  468.     char *goal;
  469. {
  470.     char wordbuf[BUFSIZ];
  471.     register char *aword = wordbuf;
  472.     register char *cp;
  473.  
  474.     Stype = type; Sgoal = goal;
  475.     if (type == ZGOTO)
  476.         bseek(0l);
  477.     do {
  478.         if (intty && fseekp == feobp)
  479.             printf("? "), flush();
  480.         aword[0] = 0, getword(aword);
  481.         switch (srchx(aword)) {
  482.  
  483.         case ZELSE:
  484.             if (level == 0 && type == ZIF)
  485.                 return;
  486.             break;
  487.  
  488.         case ZIF:
  489.             while (getword(aword))
  490.                 continue;
  491.             if ((type == ZIF || type == ZELSE) && eq(aword, "then"))
  492.                 level++;
  493.             break;
  494.  
  495.         case ZENDIF:
  496.             if (type == ZIF || type == ZELSE)
  497.                 level--;
  498.             break;
  499.  
  500.         case ZFOREACH:
  501.         case ZWHILE:
  502.             if (type == ZBREAK)
  503.                 level++;
  504.             break;
  505.  
  506.         case ZEND:
  507.             if (type == ZBREAK)
  508.                 level--;
  509.             break;
  510.  
  511.         case ZSWITCH:
  512.             if (type == ZSWITCH || type == ZBRKSW)
  513.                 level++;
  514.             break;
  515.  
  516.         case ZENDSW:
  517.             if (type == ZSWITCH || type == ZBRKSW)
  518.                 level--;
  519.             break;
  520.  
  521.         case ZLABEL:
  522.             if (type == ZGOTO && getword(aword) && eq(aword, goal))
  523.                 level = -1;
  524.             break;
  525.  
  526.         default:
  527.             if (type != ZGOTO && (type != ZSWITCH || level != 0))
  528.                 break;
  529.             if (lastchr(aword) != ':')
  530.                 break;
  531.             aword[strlen(aword) - 1] = 0;
  532.             if (type == ZGOTO && eq(aword, goal) || type == ZSWITCH && eq(aword, "default"))
  533.                 level = -1;
  534.             break;
  535.  
  536.         case ZCASE:
  537.             if (type != ZSWITCH || level != 0)
  538.                 break;
  539.             getword(aword);
  540.             if (lastchr(aword) == ':')
  541.                 aword[strlen(aword) - 1] = 0;
  542.             cp = strip(Dfix1(aword));
  543.             if (Gmatch(goal, cp))
  544.                 level = -1;
  545.             xfree(cp);
  546.             break;
  547.  
  548.         case ZDEFAULT:
  549.             if (type == ZSWITCH && level == 0)
  550.                 level = -1;
  551.             break;
  552.         }
  553.         getword(0);
  554.     } while (level >= 0);
  555. }
  556.  
  557. getword(wp)
  558.     register char *wp;
  559. {
  560.     register int found = 0;
  561.     register int c, d;
  562.  
  563.     c = readc(1);
  564.     d = 0;
  565.     do {
  566.         while (c == ' ' || c == '\t')
  567.             c = readc(1);
  568.         if (c < 0)
  569.             goto past;
  570.         if (c == '\n') {
  571.             if (wp)
  572.                 break;
  573.             return (0);
  574.         }
  575.         unreadc(c);
  576.         found = 1;
  577.         do {
  578.             c = readc(1);
  579.             if (c == '\\' && (c = readc(1)) == '\n')
  580.                 c = ' ';
  581.             if (any(c, "'\""))
  582.                 if (d == 0)
  583.                     d = c;
  584.                 else if (d == c)
  585.                     d = 0;
  586.             if (c < 0)
  587.                 goto past;
  588.             if (wp)
  589.                 *wp++ = c;
  590.         } while ((d || c != ' ' && c != '\t') && c != '\n');
  591.     } while (wp == 0);
  592.     unreadc(c);
  593.     if (found)
  594.         *--wp = 0;
  595.     return (found);
  596.  
  597. past:
  598.     switch (Stype) {
  599.  
  600.     case ZIF:
  601.         bferr("then/endif not found");
  602.  
  603.     case ZELSE:
  604.         bferr("endif not found");
  605.  
  606.     case ZBRKSW:
  607.     case ZSWITCH:
  608.         bferr("endsw not found");
  609.  
  610.     case ZBREAK:
  611.         bferr("end not found");
  612.  
  613.     case ZGOTO:
  614.         setname(Sgoal);
  615.         bferr("label not found");
  616.     }
  617.     /*NOTREACHED*/
  618. }
  619.  
  620. toend()
  621. {
  622.  
  623.     if (whyles->w_end == 0) {
  624.         search(ZBREAK, 0);
  625.         whyles->w_end = btell() - 1;
  626.     } else
  627.         bseek(whyles->w_end);
  628.     wfree();
  629. }
  630.  
  631. wfree()
  632. {
  633.     long o = btell();
  634.  
  635.     while (whyles) {
  636.         register struct whyle *wp = whyles;
  637.         register struct whyle *nwp = wp->w_next;
  638.  
  639.         if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end))
  640.             break;
  641.         if (wp->w_fe0)
  642.             blkfree(wp->w_fe0);
  643.         if (wp->w_fename)
  644.             xfree(wp->w_fename);
  645.         xfree(wp);
  646.         whyles = nwp;
  647.     }
  648. }
  649.  
  650. doecho(v)
  651.     char **v;
  652. {
  653.  
  654.     echo(' ', v);
  655. }
  656.  
  657. doglob(v)
  658.     char **v;
  659. {
  660.  
  661.     echo(0, v);
  662.     flush();
  663. }
  664.  
  665. echo(sep, v)
  666.     char sep;
  667.     register char **v;
  668. {
  669.     register char *cp;
  670.     int (*saveintr)();
  671.     if (setintr)
  672.         saveintr = signal(SIGINT, pintr);
  673.  
  674.     v++;
  675.     if (*v == 0)
  676.         return;
  677.     gflag = 0; rscan(v, tglob);
  678.     if (gflag) {
  679.         v = glob(v);
  680.         if (v == 0)
  681.             bferr("No match");
  682.     } else
  683.         scan(v, trim);
  684.     while (cp = *v++) {
  685.         register int c;
  686.  
  687.         while (c = *cp++) {
  688.             if (sep == ' ' && *cp && c == '\\') {
  689.                 c = *cp++;
  690.                 if (c == 'c') {
  691.                     flush();
  692.                     return;
  693.                 } else if (c == 'n')
  694.                     c = '\n';
  695.                 else
  696.                     putchar('\\');
  697.             }
  698.             putchar(c | QUOTE);
  699.         }
  700.         if (*v)
  701.             putchar(sep | QUOTE);
  702.     }
  703.     if (sep)
  704.         putchar('\n');
  705.     if (setintr)
  706.         signal(SIGINT, saveintr);
  707.     if (gargv)
  708.         blkfree(gargv), gargv = 0;
  709. }
  710.  
  711. #ifndef    V6
  712. char    **environ;
  713.  
  714. dosetenv(v)
  715.     register char **v;
  716. {
  717.     char *lp = globone(v[2]);
  718.  
  719.     setenv(v[1], lp);
  720.     xfree(lp);
  721. }
  722.  
  723. setenv(name, value)
  724.     char *name, *value;
  725. {
  726.     register char **ep = environ;
  727.     register char *cp, *dp;
  728.     char *blk[2], **oep = ep;
  729.  
  730.     for (; *ep; ep++) {
  731.         for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
  732.             continue;
  733.         if (*cp != 0 || *dp != '=')
  734.             continue;
  735.         cp = strspl("=", value);
  736.         xfree(*ep);
  737.         *ep = strspl(name, cp);
  738.         xfree(cp);
  739.         return;
  740.     }
  741.     blk[0] = strspl(name, "="); blk[1] = 0;
  742.     environ = blkspl(environ, blk);
  743.     xfree(oep);
  744.     setenv(name, value);
  745. }
  746.  
  747. doumask(v)
  748.     register char **v;
  749. {
  750.     register char *cp = v[1];
  751.     register int i;
  752.  
  753.     if (cp == 0) {
  754.         i = umask(0);
  755.         umask(i);
  756.         printf("%o\n", i);
  757.         return;
  758.     }
  759.     i = 0;
  760.     while (digit(*cp) && *cp != '8' && *cp != '9')
  761.         i = i * 8 + *cp++ - '0';
  762.     if (*cp || i < 0 || i > 0777)
  763.         bferr("Improper mask");
  764.     umask(i);
  765. }
  766. #endif
  767.