|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.