1*10805Ssam /* macro.c 4.2 83/02/09 */ 26695Smckusick 36695Smckusick # 46695Smckusick /* 56695Smckusick * UNIX shell 66695Smckusick * 76695Smckusick * S. R. Bourne 86695Smckusick * Bell Telephone Laboratories 96695Smckusick * 106695Smckusick */ 116695Smckusick 126695Smckusick #include "defs.h" 136695Smckusick #include "sym.h" 146695Smckusick 156695Smckusick LOCAL CHAR quote; /* used locally */ 166695Smckusick LOCAL CHAR quoted; /* used locally */ 176695Smckusick 186695Smckusick 196695Smckusick 206695Smckusick LOCAL STRING copyto(endch) 216695Smckusick REG CHAR endch; 226695Smckusick { 236695Smckusick REG CHAR c; 246695Smckusick 256695Smckusick WHILE (c=getch(endch))!=endch ANDF c 266695Smckusick DO pushstak(c|quote) OD 276695Smckusick zerostak(); 286695Smckusick IF c!=endch THEN error(badsub) FI 296695Smckusick } 306695Smckusick 316695Smckusick LOCAL skipto(endch) 326695Smckusick REG CHAR endch; 336695Smckusick { 346695Smckusick /* skip chars up to } */ 356695Smckusick REG CHAR c; 366695Smckusick WHILE (c=readc()) ANDF c!=endch 376695Smckusick DO SWITCH c IN 386695Smckusick 396695Smckusick case SQUOTE: skipto(SQUOTE); break; 406695Smckusick 416695Smckusick case DQUOTE: skipto(DQUOTE); break; 426695Smckusick 436695Smckusick case DOLLAR: IF readc()==BRACE 446695Smckusick THEN skipto('}'); 456695Smckusick FI 466695Smckusick ENDSW 476695Smckusick OD 486695Smckusick IF c!=endch THEN error(badsub) FI 496695Smckusick } 506695Smckusick 516695Smckusick LOCAL getch(endch) 526695Smckusick CHAR endch; 536695Smckusick { 546695Smckusick REG CHAR d; 556695Smckusick 566695Smckusick retry: 576695Smckusick d=readc(); 586695Smckusick IF !subchar(d) 596695Smckusick THEN return(d); 606695Smckusick FI 616695Smckusick IF d==DOLLAR 626695Smckusick THEN REG INT c; 636695Smckusick IF (c=readc(), dolchar(c)) 646695Smckusick THEN NAMPTR n=NIL; 656695Smckusick INT dolg=0; 666695Smckusick BOOL bra; 676695Smckusick REG STRING argp, v; 686695Smckusick CHAR idb[2]; 696695Smckusick STRING id=idb; 706695Smckusick 716695Smckusick IF bra=(c==BRACE) THEN c=readc() FI 726695Smckusick IF letter(c) 736695Smckusick THEN argp=relstak(); 746695Smckusick WHILE alphanum(c) DO pushstak(c); c=readc() OD 756695Smckusick zerostak(); 766695Smckusick n=lookup(absstak(argp)); setstak(argp); 776695Smckusick v = n->namval; id = n->namid; 786695Smckusick peekc = c|MARK;; 796695Smckusick ELIF digchar(c) 806695Smckusick THEN *id=c; idb[1]=0; 816695Smckusick IF astchar(c) 826695Smckusick THEN dolg=1; c='1'; 836695Smckusick FI 846695Smckusick c -= '0'; 856695Smckusick v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0)); 866695Smckusick ELIF c=='$' 876695Smckusick THEN v=pidadr; 886695Smckusick ELIF c=='!' 896695Smckusick THEN v=pcsadr; 906695Smckusick ELIF c=='#' 916695Smckusick THEN v=dolladr; 926695Smckusick ELIF c=='?' 936695Smckusick THEN v=exitadr; 946695Smckusick ELIF c=='-' 956695Smckusick THEN v=flagadr; 966695Smckusick ELIF bra THEN error(badsub); 976695Smckusick ELSE goto retry; 986695Smckusick FI 996695Smckusick c = readc(); 1006695Smckusick IF !defchar(c) ANDF bra 1016695Smckusick THEN error(badsub); 1026695Smckusick FI 1036695Smckusick argp=0; 1046695Smckusick IF bra 1056695Smckusick THEN IF c!='}' 1066695Smckusick THEN argp=relstak(); 1076695Smckusick IF (v==0)NEQ(setchar(c)) 1086695Smckusick THEN copyto('}'); 1096695Smckusick ELSE skipto('}'); 1106695Smckusick FI 1116695Smckusick argp=absstak(argp); 1126695Smckusick FI 1136695Smckusick ELSE peekc = c|MARK; c = 0; 1146695Smckusick FI 1156695Smckusick IF v 1166695Smckusick THEN IF c!='+' 1176695Smckusick THEN LOOP WHILE c = *v++ 1186695Smckusick DO pushstak(c|quote); OD 1196695Smckusick IF dolg==0 ORF (++dolg>dolc) 1206695Smckusick THEN break; 1216695Smckusick ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0)); 1226695Smckusick FI 1236695Smckusick POOL 1246695Smckusick FI 1256695Smckusick ELIF argp 1266695Smckusick THEN IF c=='?' 1276695Smckusick THEN failed(id,*argp?argp:badparam); 1286695Smckusick ELIF c=='=' 1296695Smckusick THEN IF n 1306695Smckusick THEN assign(n,argp); 1316695Smckusick ELSE error(badsub); 1326695Smckusick FI 1336695Smckusick FI 1346695Smckusick ELIF flags&setflg 1356695Smckusick THEN failed(id,badparam); 1366695Smckusick FI 1376695Smckusick goto retry; 1386695Smckusick ELSE peekc=c|MARK; 1396695Smckusick FI 1406695Smckusick ELIF d==endch 1416695Smckusick THEN return(d); 1426695Smckusick ELIF d==SQUOTE 1436695Smckusick THEN comsubst(); goto retry; 1446695Smckusick ELIF d==DQUOTE 1456695Smckusick THEN quoted++; quote^=QUOTE; goto retry; 1466695Smckusick FI 1476695Smckusick return(d); 1486695Smckusick } 1496695Smckusick 1506695Smckusick STRING macro(as) 1516695Smckusick STRING as; 1526695Smckusick { 1536695Smckusick /* Strip "" and do $ substitution 1546695Smckusick * Leaves result on top of stack 1556695Smckusick */ 1566695Smckusick REG BOOL savqu =quoted; 1576695Smckusick REG CHAR savq = quote; 1586695Smckusick FILEHDR fb; 1596695Smckusick 1606695Smckusick push(&fb); estabf(as); 1616695Smckusick usestak(); 1626695Smckusick quote=0; quoted=0; 1636695Smckusick copyto(0); 1646695Smckusick pop(); 1656695Smckusick IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI 1666695Smckusick quote=savq; quoted=savqu; 1676695Smckusick return(fixstak()); 1686695Smckusick } 1696695Smckusick 1706695Smckusick LOCAL comsubst() 1716695Smckusick { 1726695Smckusick /* command substn */ 1736695Smckusick FILEBLK cb; 1746695Smckusick REG CHAR d; 1756695Smckusick REG STKPTR savptr = fixstak(); 1766695Smckusick 1776695Smckusick usestak(); 1786695Smckusick WHILE (d=readc())!=SQUOTE ANDF d 1796695Smckusick DO pushstak(d) OD 1806695Smckusick 1816695Smckusick BEGIN 1826695Smckusick REG STRING argc; 1836695Smckusick trim(argc=fixstak()); 1846695Smckusick push(&cb); estabf(argc); 1856695Smckusick END 1866695Smckusick BEGIN 1876695Smckusick REG TREPTR t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG)); 1886695Smckusick INT pv[2]; 1896695Smckusick 1906695Smckusick /* this is done like this so that the pipe 1916695Smckusick * is open only when needed 1926695Smckusick */ 1936695Smckusick chkpipe(pv); 1946695Smckusick initf(pv[INPIPE]); 1956695Smckusick execute(t, 0, 0, pv); 1966695Smckusick close(pv[OTPIPE]); 1976695Smckusick END 1986695Smckusick tdystak(savptr); staktop=movstr(savptr,stakbot); 199*10805Ssam WHILE d=readc() DO locstak(); pushstak(d|quote) OD 2006695Smckusick await(0); 2016695Smckusick WHILE stakbot!=staktop 2026695Smckusick DO IF (*--staktop&STRIP)!=NL 2036695Smckusick THEN ++staktop; break; 2046695Smckusick FI 2056695Smckusick OD 2066695Smckusick pop(); 2076695Smckusick } 2086695Smckusick 2096695Smckusick #define CPYSIZ 512 2106695Smckusick 2116695Smckusick subst(in,ot) 2126695Smckusick INT in, ot; 2136695Smckusick { 2146695Smckusick REG CHAR c; 2156695Smckusick FILEBLK fb; 2166695Smckusick REG INT count=CPYSIZ; 2176695Smckusick 2186695Smckusick push(&fb); initf(in); 2196695Smckusick /* DQUOTE used to stop it from quoting */ 2206695Smckusick WHILE c=(getch(DQUOTE)&STRIP) 2216695Smckusick DO pushstak(c); 2226695Smckusick IF --count == 0 2236695Smckusick THEN flush(ot); count=CPYSIZ; 2246695Smckusick FI 2256695Smckusick OD 2266695Smckusick flush(ot); 2276695Smckusick pop(); 2286695Smckusick } 2296695Smckusick 2306695Smckusick LOCAL flush(ot) 2316695Smckusick { 2326695Smckusick write(ot,stakbot,staktop-stakbot); 2336695Smckusick IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI 2346695Smckusick staktop=stakbot; 2356695Smckusick } 236