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

Defined functions

comsubst defined in line 172; used 1 times
copyto defined in line 22; used 3 times
flush defined in line 232; used 2 times
getch defined in line 53; used 2 times
macro defined in line 152; used 4 times
skipto defined in line 33; used 4 times
subst defined in line 213; used 1 times

Defined variables

sccsid defined in line 2; never used

Defined macros

CPYSIZ defined in line 211; used 2 times
Last modified: 1983-08-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1349
Valid CSS Valid XHTML 1.0 Strict