|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)macro.c 4.4 4/24/88"; ! 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] : (STRING)(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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.