home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / sh / macro.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-12  |  4.0 KB  |  234 lines

  1. #
  2. /*
  3.  * UNIX shell
  4.  *
  5.  * S. R. Bourne
  6.  * Bell Telephone Laboratories
  7.  *
  8.  */
  9.  
  10. #include    "defs.h"
  11. #include    "sym.h"
  12.  
  13. LOCAL CHAR    quote;    /* used locally */
  14. LOCAL CHAR    quoted;    /* used locally */
  15.  
  16.  
  17.  
  18. LOCAL STRING    copyto(endch)
  19.     REG CHAR    endch;
  20. {
  21.     REG CHAR    c;
  22.  
  23.     WHILE (c=getch(endch))!=endch ANDF c
  24.     DO pushstak(c|quote) OD
  25.     zerostak();
  26.     IF c!=endch THEN error(badsub) FI
  27. }
  28.  
  29. LOCAL    skipto(endch)
  30.     REG CHAR    endch;
  31. {
  32.     /* skip chars up to } */
  33.     REG CHAR    c;
  34.     WHILE (c=readc()) ANDF c!=endch
  35.     DO    SWITCH c IN
  36.  
  37.         case SQUOTE:    skipto(SQUOTE); break;
  38.  
  39.         case DQUOTE:    skipto(DQUOTE); break;
  40.  
  41.         case DOLLAR:    IF readc()==BRACE
  42.                 THEN    skipto('}');
  43.                 FI
  44.         ENDSW
  45.     OD
  46.     IF c!=endch THEN error(badsub) FI
  47. }
  48.  
  49. LOCAL    getch(endch)
  50.     CHAR        endch;
  51. {
  52.     REG CHAR    d;
  53.  
  54. retry:
  55.     d=readc();
  56.     IF !subchar(d)
  57.     THEN    return(d);
  58.     FI
  59.     IF d==DOLLAR
  60.     THEN    REG INT    c;
  61.         IF (c=readc(), dolchar(c))
  62.         THEN    NAMPTR        n=NIL;
  63.             INT        dolg=0;
  64.             BOOL        bra;
  65.             REG STRING    argp, v;
  66.             CHAR        idb[2];
  67.             STRING        id=idb;
  68.  
  69.             IF bra=(c==BRACE) THEN c=readc() FI
  70.             IF letter(c)
  71.             THEN    argp=relstak();
  72.                 WHILE alphanum(c) DO pushstak(c); c=readc() OD
  73.                 zerostak();
  74.                 n=lookup(absstak(argp)); setstak(argp);
  75.                 v = n->namval; id = n->namid;
  76.                 peekc = c|MARK;;
  77.             ELIF digchar(c)
  78.             THEN    *id=c; idb[1]=0;
  79.                 IF astchar(c)
  80.                 THEN    dolg=1; c='1';
  81.                 FI
  82.                 c -= '0';
  83.                 v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0));
  84.             ELIF c=='$'
  85.             THEN    v=pidadr;
  86.             ELIF c=='!'
  87.             THEN    v=pcsadr;
  88.             ELIF c=='#'
  89.             THEN    v=dolladr;
  90.             ELIF c=='?'
  91.             THEN    v=exitadr;
  92.             ELIF c=='-'
  93.             THEN    v=flagadr;
  94.             ELIF bra THEN error(badsub);
  95.             ELSE    goto retry;
  96.             FI
  97.             c = readc();
  98.             IF !defchar(c) ANDF bra
  99.             THEN    error(badsub);
  100.             FI
  101.             argp=0;
  102.             IF bra
  103.             THEN    IF c!='}'
  104.                 THEN    argp=relstak();
  105.                     IF (v==0)NEQ(setchar(c))
  106.                     THEN    copyto('}');
  107.                     ELSE    skipto('}');
  108.                     FI
  109.                     argp=absstak(argp);
  110.                 FI
  111.             ELSE    peekc = c|MARK; c = 0;
  112.             FI
  113.             IF v
  114.             THEN    IF c!='+'
  115.                 THEN    LOOP WHILE c = *v++
  116.                          DO pushstak(c|quote); OD
  117.                          IF dolg==0 ORF (++dolg>dolc)
  118.                          THEN break;
  119.                          ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0));
  120.                          FI
  121.                     POOL
  122.                 FI
  123.             ELIF argp
  124.             THEN    IF c=='?'
  125.                 THEN    failed(id,*argp?argp:badparam);
  126.                 ELIF c=='='
  127.                 THEN    IF n
  128.                     THEN    assign(n,argp);
  129.                     ELSE    error(badsub);
  130.                     FI
  131.                 FI
  132.             ELIF flags&setflg
  133.             THEN    failed(id,badparam);
  134.             FI
  135.             goto retry;
  136.         ELSE    peekc=c|MARK;
  137.         FI
  138.     ELIF d==endch
  139.     THEN    return(d);
  140.     ELIF d==SQUOTE
  141.     THEN    comsubst(); goto retry;
  142.     ELIF d==DQUOTE
  143.     THEN    quoted++; quote^=QUOTE; goto retry;
  144.     FI
  145.     return(d);
  146. }
  147.  
  148. STRING    macro(as)
  149.     STRING        as;
  150. {
  151.     /* Strip "" and do $ substitution
  152.      * Leaves result on top of stack
  153.      */
  154.     REG BOOL    savqu =quoted;
  155.     REG CHAR    savq = quote;
  156.     FILEHDR        fb;
  157.  
  158.     push(&fb); estabf(as);
  159.     usestak();
  160.     quote=0; quoted=0;
  161.     copyto(0);
  162.     pop();
  163.     IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI
  164.     quote=savq; quoted=savqu;
  165.     return(fixstak());
  166. }
  167.  
  168. LOCAL    comsubst()
  169. {
  170.     /* command substn */
  171.     FILEBLK        cb;
  172.     REG CHAR    d;
  173.     REG STKPTR    savptr = fixstak();
  174.  
  175.     usestak();
  176.     WHILE (d=readc())!=SQUOTE ANDF d
  177.     DO pushstak(d) OD
  178.  
  179.     BEGIN
  180.        REG STRING    argc;
  181.        trim(argc=fixstak());
  182.        push(&cb); estabf(argc);
  183.     END
  184.     BEGIN
  185.        REG TREPTR    t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG));
  186.        INT        pv[2];
  187.  
  188.        /* this is done like this so that the pipe
  189.         * is open only when needed
  190.         */
  191.        chkpipe(pv);
  192.        initf(pv[INPIPE]);
  193.        execute(t, 0, 0, pv);
  194.        close(pv[OTPIPE]);
  195.     END
  196.     tdystak(savptr); staktop=movstr(savptr,stakbot);
  197.     WHILE d=readc() DO pushstak(d|quote) OD
  198.     await(0);
  199.     WHILE stakbot!=staktop
  200.     DO    IF (*--staktop&STRIP)!=NL
  201.         THEN    ++staktop; break;
  202.         FI
  203.     OD
  204.     pop();
  205. }
  206.  
  207. #define CPYSIZ    512
  208.  
  209. subst(in,ot)
  210.     INT        in, ot;
  211. {
  212.     REG CHAR    c;
  213.     FILEBLK        fb;
  214.     REG INT        count=CPYSIZ;
  215.  
  216.     push(&fb); initf(in);
  217.     /* DQUOTE used to stop it from quoting */
  218.     WHILE c=(getch(DQUOTE)&STRIP)
  219.     DO pushstak(c);
  220.        IF --count == 0
  221.        THEN    flush(ot); count=CPYSIZ;
  222.        FI
  223.     OD
  224.     flush(ot);
  225.     pop();
  226. }
  227.  
  228. LOCAL    flush(ot)
  229. {
  230.     write(ot,stakbot,staktop-stakbot);
  231.     IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI
  232.     staktop=stakbot;
  233. }
  234.