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: }

Defined functions

comsubst defined in line 168; used 1 times
copyto defined in line 18; used 3 times
flush defined in line 228; used 2 times
getch defined in line 49; used 2 times
macro defined in line 148; used 4 times
skipto defined in line 29; used 4 times
subst defined in line 209; used 1 times

Defined macros

CPYSIZ defined in line 207; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1102
Valid CSS Valid XHTML 1.0 Strict