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