xref: /plan9/sys/src/cmd/sam/xec.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
13e12c5d1SDavid du Colombier #include "sam.h"
23e12c5d1SDavid du Colombier #include "parse.h"
33e12c5d1SDavid du Colombier 
43e12c5d1SDavid du Colombier int	Glooping;
53e12c5d1SDavid du Colombier int	nest;
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier int	append(File*, Cmd*, Posn);
83e12c5d1SDavid du Colombier int	display(File*);
93e12c5d1SDavid du Colombier void	looper(File*, Cmd*, int);
103e12c5d1SDavid du Colombier void	filelooper(Cmd*, int);
113e12c5d1SDavid du Colombier void	linelooper(File*, Cmd*);
123e12c5d1SDavid du Colombier 
133e12c5d1SDavid du Colombier void
resetxec(void)143e12c5d1SDavid du Colombier resetxec(void)
153e12c5d1SDavid du Colombier {
163e12c5d1SDavid du Colombier 	Glooping = nest = 0;
173e12c5d1SDavid du Colombier }
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier int
cmdexec(File * f,Cmd * cp)203e12c5d1SDavid du Colombier cmdexec(File *f, Cmd *cp)
213e12c5d1SDavid du Colombier {
223e12c5d1SDavid du Colombier 	int i;
233e12c5d1SDavid du Colombier 	Addr *ap;
243e12c5d1SDavid du Colombier 	Address a;
253e12c5d1SDavid du Colombier 
26*7dd7cddfSDavid du Colombier 	if(f && f->unread)
273e12c5d1SDavid du Colombier 		load(f);
283e12c5d1SDavid du Colombier 	if(f==0 && (cp->addr==0 || cp->addr->type!='"') &&
29*7dd7cddfSDavid du Colombier 	    !utfrune("bBnqUXY!", cp->cmdc) &&
303e12c5d1SDavid du Colombier 	    cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext))
313e12c5d1SDavid du Colombier 		error(Enofile);
323e12c5d1SDavid du Colombier 	i = lookup(cp->cmdc);
33*7dd7cddfSDavid du Colombier 	if(i >= 0 && cmdtab[i].defaddr != aNo){
343e12c5d1SDavid du Colombier 		if((ap=cp->addr)==0 && cp->cmdc!='\n'){
353e12c5d1SDavid du Colombier 			cp->addr = ap = newaddr();
363e12c5d1SDavid du Colombier 			ap->type = '.';
373e12c5d1SDavid du Colombier 			if(cmdtab[i].defaddr == aAll)
383e12c5d1SDavid du Colombier 				ap->type = '*';
393e12c5d1SDavid du Colombier 		}else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){
403e12c5d1SDavid du Colombier 			ap->next = newaddr();
413e12c5d1SDavid du Colombier 			ap->next->type = '.';
423e12c5d1SDavid du Colombier 			if(cmdtab[i].defaddr == aAll)
433e12c5d1SDavid du Colombier 				ap->next->type = '*';
443e12c5d1SDavid du Colombier 		}
453e12c5d1SDavid du Colombier 		if(cp->addr){	/* may be false for '\n' (only) */
463e12c5d1SDavid du Colombier 			static Address none = {0,0,0};
473e12c5d1SDavid du Colombier 			if(f)
483e12c5d1SDavid du Colombier 				addr = address(ap, f->dot, 0);
493e12c5d1SDavid du Colombier 			else	/* a " */
503e12c5d1SDavid du Colombier 				addr = address(ap, none, 0);
513e12c5d1SDavid du Colombier 			f = addr.f;
523e12c5d1SDavid du Colombier 		}
533e12c5d1SDavid du Colombier 	}
543e12c5d1SDavid du Colombier 	current(f);
553e12c5d1SDavid du Colombier 	switch(cp->cmdc){
563e12c5d1SDavid du Colombier 	case '{':
573e12c5d1SDavid du Colombier 		a = cp->addr? address(cp->addr, f->dot, 0): f->dot;
583e12c5d1SDavid du Colombier 		for(cp = cp->ccmd; cp; cp = cp->next){
593e12c5d1SDavid du Colombier 			a.f->dot = a;
603e12c5d1SDavid du Colombier 			cmdexec(a.f, cp);
613e12c5d1SDavid du Colombier 		}
623e12c5d1SDavid du Colombier 		break;
633e12c5d1SDavid du Colombier 	default:
643e12c5d1SDavid du Colombier 		i=(*cmdtab[i].fn)(f, cp);
653e12c5d1SDavid du Colombier 		return i;
663e12c5d1SDavid du Colombier 	}
673e12c5d1SDavid du Colombier 	return 1;
683e12c5d1SDavid du Colombier }
693e12c5d1SDavid du Colombier 
703e12c5d1SDavid du Colombier 
713e12c5d1SDavid du Colombier int
a_cmd(File * f,Cmd * cp)723e12c5d1SDavid du Colombier a_cmd(File *f, Cmd *cp)
733e12c5d1SDavid du Colombier {
743e12c5d1SDavid du Colombier 	return append(f, cp, addr.r.p2);
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier int
b_cmd(File * f,Cmd * cp)783e12c5d1SDavid du Colombier b_cmd(File *f, Cmd *cp)
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier 	USED(f);
813e12c5d1SDavid du Colombier 	f = cp->cmdc=='b'? tofile(cp->ctext) : getfile(cp->ctext);
82*7dd7cddfSDavid du Colombier 	if(f->unread)
833e12c5d1SDavid du Colombier 		load(f);
843e12c5d1SDavid du Colombier 	else if(nest == 0)
853e12c5d1SDavid du Colombier 		filename(f);
863e12c5d1SDavid du Colombier 	return TRUE;
873e12c5d1SDavid du Colombier }
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier int
c_cmd(File * f,Cmd * cp)903e12c5d1SDavid du Colombier c_cmd(File *f, Cmd *cp)
913e12c5d1SDavid du Colombier {
92*7dd7cddfSDavid du Colombier 	logdelete(f, addr.r.p1, addr.r.p2);
933e12c5d1SDavid du Colombier 	f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p2;
943e12c5d1SDavid du Colombier 	return append(f, cp, addr.r.p2);
953e12c5d1SDavid du Colombier }
963e12c5d1SDavid du Colombier 
973e12c5d1SDavid du Colombier int
d_cmd(File * f,Cmd * cp)983e12c5d1SDavid du Colombier d_cmd(File *f, Cmd *cp)
993e12c5d1SDavid du Colombier {
1003e12c5d1SDavid du Colombier 	USED(cp);
101*7dd7cddfSDavid du Colombier 	logdelete(f, addr.r.p1, addr.r.p2);
1023e12c5d1SDavid du Colombier 	f->ndot.r.p1 = f->ndot.r.p2 = addr.r.p1;
1033e12c5d1SDavid du Colombier 	return TRUE;
1043e12c5d1SDavid du Colombier }
1053e12c5d1SDavid du Colombier 
1063e12c5d1SDavid du Colombier int
D_cmd(File * f,Cmd * cp)1073e12c5d1SDavid du Colombier D_cmd(File *f, Cmd *cp)
1083e12c5d1SDavid du Colombier {
1093e12c5d1SDavid du Colombier 	closefiles(f, cp->ctext);
1103e12c5d1SDavid du Colombier 	return TRUE;
1113e12c5d1SDavid du Colombier }
1123e12c5d1SDavid du Colombier 
1133e12c5d1SDavid du Colombier int
e_cmd(File * f,Cmd * cp)1143e12c5d1SDavid du Colombier e_cmd(File *f, Cmd *cp)
1153e12c5d1SDavid du Colombier {
1163e12c5d1SDavid du Colombier 	if(getname(f, cp->ctext, cp->cmdc=='e')==0)
1173e12c5d1SDavid du Colombier 		error(Enoname);
1183e12c5d1SDavid du Colombier 	edit(f, cp->cmdc);
1193e12c5d1SDavid du Colombier 	return TRUE;
1203e12c5d1SDavid du Colombier }
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier int
f_cmd(File * f,Cmd * cp)1233e12c5d1SDavid du Colombier f_cmd(File *f, Cmd *cp)
1243e12c5d1SDavid du Colombier {
1253e12c5d1SDavid du Colombier 	getname(f, cp->ctext, TRUE);
1263e12c5d1SDavid du Colombier 	filename(f);
1273e12c5d1SDavid du Colombier 	return TRUE;
1283e12c5d1SDavid du Colombier }
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier int
g_cmd(File * f,Cmd * cp)1313e12c5d1SDavid du Colombier g_cmd(File *f, Cmd *cp)
1323e12c5d1SDavid du Colombier {
1333e12c5d1SDavid du Colombier 	if(f!=addr.f)panic("g_cmd f!=addr.f");
1343e12c5d1SDavid du Colombier 	compile(cp->re);
1353e12c5d1SDavid du Colombier 	if(execute(f, addr.r.p1, addr.r.p2) ^ cp->cmdc=='v'){
1363e12c5d1SDavid du Colombier 		f->dot = addr;
1373e12c5d1SDavid du Colombier 		return cmdexec(f, cp->ccmd);
1383e12c5d1SDavid du Colombier 	}
1393e12c5d1SDavid du Colombier 	return TRUE;
1403e12c5d1SDavid du Colombier }
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier int
i_cmd(File * f,Cmd * cp)1433e12c5d1SDavid du Colombier i_cmd(File *f, Cmd *cp)
1443e12c5d1SDavid du Colombier {
1453e12c5d1SDavid du Colombier 	return append(f, cp, addr.r.p1);
1463e12c5d1SDavid du Colombier }
1473e12c5d1SDavid du Colombier 
1483e12c5d1SDavid du Colombier int
k_cmd(File * f,Cmd * cp)1493e12c5d1SDavid du Colombier k_cmd(File *f, Cmd *cp)
1503e12c5d1SDavid du Colombier {
1513e12c5d1SDavid du Colombier 	USED(cp);
1523e12c5d1SDavid du Colombier 	f->mark = addr.r;
1533e12c5d1SDavid du Colombier 	return TRUE;
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier int
m_cmd(File * f,Cmd * cp)1573e12c5d1SDavid du Colombier m_cmd(File *f, Cmd *cp)
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier 	Address addr2;
1603e12c5d1SDavid du Colombier 
1613e12c5d1SDavid du Colombier 	addr2 = address(cp->caddr, f->dot, 0);
1623e12c5d1SDavid du Colombier 	if(cp->cmdc=='m')
1633e12c5d1SDavid du Colombier 		move(f, addr2);
1643e12c5d1SDavid du Colombier 	else
1653e12c5d1SDavid du Colombier 		copy(f, addr2);
1663e12c5d1SDavid du Colombier 	return TRUE;
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier int
n_cmd(File * f,Cmd * cp)1703e12c5d1SDavid du Colombier n_cmd(File *f, Cmd *cp)
1713e12c5d1SDavid du Colombier {
1723e12c5d1SDavid du Colombier 	int i;
1733e12c5d1SDavid du Colombier 	USED(f);
1743e12c5d1SDavid du Colombier 	USED(cp);
1753e12c5d1SDavid du Colombier 	for(i = 0; i<file.nused; i++){
1763e12c5d1SDavid du Colombier 		if(file.filepptr[i] == cmd)
1773e12c5d1SDavid du Colombier 			continue;
1783e12c5d1SDavid du Colombier 		f = file.filepptr[i];
1793e12c5d1SDavid du Colombier 		Strduplstr(&genstr, &f->name);
1803e12c5d1SDavid du Colombier 		filename(f);
1813e12c5d1SDavid du Colombier 	}
1823e12c5d1SDavid du Colombier 	return TRUE;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier int
p_cmd(File * f,Cmd * cp)1863e12c5d1SDavid du Colombier p_cmd(File *f, Cmd *cp)
1873e12c5d1SDavid du Colombier {
1883e12c5d1SDavid du Colombier 	USED(cp);
1893e12c5d1SDavid du Colombier 	return display(f);
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier 
1923e12c5d1SDavid du Colombier int
q_cmd(File * f,Cmd * cp)1933e12c5d1SDavid du Colombier q_cmd(File *f, Cmd *cp)
1943e12c5d1SDavid du Colombier {
1953e12c5d1SDavid du Colombier 	USED(cp);
1963e12c5d1SDavid du Colombier 	USED(f);
1973e12c5d1SDavid du Colombier 	trytoquit();
1983e12c5d1SDavid du Colombier 	if(downloaded){
1993e12c5d1SDavid du Colombier 		outT0(Hexit);
2003e12c5d1SDavid du Colombier 		return TRUE;
2013e12c5d1SDavid du Colombier 	}
2023e12c5d1SDavid du Colombier 	return FALSE;
2033e12c5d1SDavid du Colombier }
2043e12c5d1SDavid du Colombier 
2053e12c5d1SDavid du Colombier int
s_cmd(File * f,Cmd * cp)2063e12c5d1SDavid du Colombier s_cmd(File *f, Cmd *cp)
2073e12c5d1SDavid du Colombier {
2083e12c5d1SDavid du Colombier 	int i, j, c, n;
2093e12c5d1SDavid du Colombier 	Posn p1, op, didsub = 0, delta = 0;
2103e12c5d1SDavid du Colombier 
2113e12c5d1SDavid du Colombier 	n = cp->num;
2123e12c5d1SDavid du Colombier 	op= -1;
2133e12c5d1SDavid du Colombier 	compile(cp->re);
2143e12c5d1SDavid du Colombier 	for(p1 = addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
2153e12c5d1SDavid du Colombier 		if(sel.p[0].p1==sel.p[0].p2){	/* empty match? */
2163e12c5d1SDavid du Colombier 			if(sel.p[0].p1==op){
2173e12c5d1SDavid du Colombier 				p1++;
2183e12c5d1SDavid du Colombier 				continue;
2193e12c5d1SDavid du Colombier 			}
2203e12c5d1SDavid du Colombier 			p1 = sel.p[0].p2+1;
2213e12c5d1SDavid du Colombier 		}else
2223e12c5d1SDavid du Colombier 			p1 = sel.p[0].p2;
2233e12c5d1SDavid du Colombier 		op = sel.p[0].p2;
2243e12c5d1SDavid du Colombier 		if(--n>0)
2253e12c5d1SDavid du Colombier 			continue;
2263e12c5d1SDavid du Colombier 		Strzero(&genstr);
2273e12c5d1SDavid du Colombier 		for(i = 0; i<cp->ctext->n; i++)
2283e12c5d1SDavid du Colombier 			if((c = cp->ctext->s[i])=='\\' && i<cp->ctext->n-1){
2293e12c5d1SDavid du Colombier 				c = cp->ctext->s[++i];
2303e12c5d1SDavid du Colombier 				if('1'<=c && c<='9') {
2313e12c5d1SDavid du Colombier 					j = c-'0';
2323e12c5d1SDavid du Colombier 					if(sel.p[j].p2-sel.p[j].p1>BLOCKSIZE)
2333e12c5d1SDavid du Colombier 						error(Elongtag);
234*7dd7cddfSDavid du Colombier 					bufread(f, sel.p[j].p1, genbuf, sel.p[j].p2-sel.p[j].p1);
2353e12c5d1SDavid du Colombier 					Strinsert(&genstr, tmprstr(genbuf, (sel.p[j].p2-sel.p[j].p1)), genstr.n);
2363e12c5d1SDavid du Colombier 				}else
2373e12c5d1SDavid du Colombier 				 	Straddc(&genstr, c);
2383e12c5d1SDavid du Colombier 			}else if(c!='&')
2393e12c5d1SDavid du Colombier 				Straddc(&genstr, c);
2403e12c5d1SDavid du Colombier 			else{
2413e12c5d1SDavid du Colombier 				if(sel.p[0].p2-sel.p[0].p1>BLOCKSIZE)
2423e12c5d1SDavid du Colombier 					error(Elongrhs);
243*7dd7cddfSDavid du Colombier 				bufread(f, sel.p[0].p1, genbuf, sel.p[0].p2-sel.p[0].p1);
2443e12c5d1SDavid du Colombier 				Strinsert(&genstr,
2453e12c5d1SDavid du Colombier 					tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)),
2463e12c5d1SDavid du Colombier 					genstr.n);
2473e12c5d1SDavid du Colombier 			}
2483e12c5d1SDavid du Colombier 		if(sel.p[0].p1!=sel.p[0].p2){
249*7dd7cddfSDavid du Colombier 			logdelete(f, sel.p[0].p1, sel.p[0].p2);
2503e12c5d1SDavid du Colombier 			delta-=sel.p[0].p2-sel.p[0].p1;
2513e12c5d1SDavid du Colombier 		}
2523e12c5d1SDavid du Colombier 		if(genstr.n){
253*7dd7cddfSDavid du Colombier 			loginsert(f, sel.p[0].p2, genstr.s, genstr.n);
2543e12c5d1SDavid du Colombier 			delta+=genstr.n;
2553e12c5d1SDavid du Colombier 		}
2563e12c5d1SDavid du Colombier 		didsub = 1;
2573e12c5d1SDavid du Colombier 		if(!cp->flag)
2583e12c5d1SDavid du Colombier 			break;
2593e12c5d1SDavid du Colombier 	}
2603e12c5d1SDavid du Colombier 	if(!didsub && nest==0)
2613e12c5d1SDavid du Colombier 		error(Enosub);
2623e12c5d1SDavid du Colombier 	f->ndot.r.p1 = addr.r.p1, f->ndot.r.p2 = addr.r.p2+delta;
2633e12c5d1SDavid du Colombier 	return TRUE;
2643e12c5d1SDavid du Colombier }
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier int
u_cmd(File * f,Cmd * cp)2673e12c5d1SDavid du Colombier u_cmd(File *f, Cmd *cp)
2683e12c5d1SDavid du Colombier {
2693e12c5d1SDavid du Colombier 	int n;
270*7dd7cddfSDavid du Colombier 
2713e12c5d1SDavid du Colombier 	USED(f);
2723e12c5d1SDavid du Colombier 	USED(cp);
2733e12c5d1SDavid du Colombier 	n = cp->num;
274*7dd7cddfSDavid du Colombier 	if(n >= 0)
275*7dd7cddfSDavid du Colombier 		while(n-- && undo(TRUE))
276*7dd7cddfSDavid du Colombier 			;
277*7dd7cddfSDavid du Colombier 	else
278*7dd7cddfSDavid du Colombier 		while(n++ && undo(FALSE))
279bd389b36SDavid du Colombier 			;
2803e12c5d1SDavid du Colombier 	return TRUE;
2813e12c5d1SDavid du Colombier }
2823e12c5d1SDavid du Colombier 
2833e12c5d1SDavid du Colombier int
w_cmd(File * f,Cmd * cp)2843e12c5d1SDavid du Colombier w_cmd(File *f, Cmd *cp)
2853e12c5d1SDavid du Colombier {
286*7dd7cddfSDavid du Colombier 	int fseq;
287*7dd7cddfSDavid du Colombier 
288*7dd7cddfSDavid du Colombier 	fseq = f->seq;
2893e12c5d1SDavid du Colombier 	if(getname(f, cp->ctext, FALSE)==0)
2903e12c5d1SDavid du Colombier 		error(Enoname);
291*7dd7cddfSDavid du Colombier 	if(fseq == seq)
292*7dd7cddfSDavid du Colombier 		error_s(Ewseq, genc);
2933e12c5d1SDavid du Colombier 	writef(f);
2943e12c5d1SDavid du Colombier 	return TRUE;
2953e12c5d1SDavid du Colombier }
2963e12c5d1SDavid du Colombier 
2973e12c5d1SDavid du Colombier int
x_cmd(File * f,Cmd * cp)2983e12c5d1SDavid du Colombier x_cmd(File *f, Cmd *cp)
2993e12c5d1SDavid du Colombier {
3003e12c5d1SDavid du Colombier 	if(cp->re)
3013e12c5d1SDavid du Colombier 		looper(f, cp, cp->cmdc=='x');
3023e12c5d1SDavid du Colombier 	else
3033e12c5d1SDavid du Colombier 		linelooper(f, cp);
3043e12c5d1SDavid du Colombier 	return TRUE;
3053e12c5d1SDavid du Colombier }
3063e12c5d1SDavid du Colombier 
3073e12c5d1SDavid du Colombier int
X_cmd(File * f,Cmd * cp)3083e12c5d1SDavid du Colombier X_cmd(File *f, Cmd *cp)
3093e12c5d1SDavid du Colombier {
3103e12c5d1SDavid du Colombier 	USED(f);
3113e12c5d1SDavid du Colombier 	filelooper(cp, cp->cmdc=='X');
3123e12c5d1SDavid du Colombier 	return TRUE;
3133e12c5d1SDavid du Colombier }
3143e12c5d1SDavid du Colombier 
3153e12c5d1SDavid du Colombier int
plan9_cmd(File * f,Cmd * cp)3163e12c5d1SDavid du Colombier plan9_cmd(File *f, Cmd *cp)
3173e12c5d1SDavid du Colombier {
3183e12c5d1SDavid du Colombier 	plan9(f, cp->cmdc, cp->ctext, nest);
3193e12c5d1SDavid du Colombier 	return TRUE;
3203e12c5d1SDavid du Colombier }
3213e12c5d1SDavid du Colombier 
3223e12c5d1SDavid du Colombier int
eq_cmd(File * f,Cmd * cp)3233e12c5d1SDavid du Colombier eq_cmd(File *f, Cmd *cp)
3243e12c5d1SDavid du Colombier {
3253e12c5d1SDavid du Colombier 	int charsonly;
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier 	switch(cp->ctext->n){
3283e12c5d1SDavid du Colombier 	case 1:
3293e12c5d1SDavid du Colombier 		charsonly = FALSE;
3303e12c5d1SDavid du Colombier 		break;
3313e12c5d1SDavid du Colombier 	case 2:
3323e12c5d1SDavid du Colombier 		if(cp->ctext->s[0]=='#'){
3333e12c5d1SDavid du Colombier 			charsonly = TRUE;
3343e12c5d1SDavid du Colombier 			break;
3353e12c5d1SDavid du Colombier 		}
3363e12c5d1SDavid du Colombier 	default:
3373e12c5d1SDavid du Colombier 		SET(charsonly);
3383e12c5d1SDavid du Colombier 		error(Enewline);
3393e12c5d1SDavid du Colombier 	}
3403e12c5d1SDavid du Colombier 	printposn(f, charsonly);
3413e12c5d1SDavid du Colombier 	return TRUE;
3423e12c5d1SDavid du Colombier }
3433e12c5d1SDavid du Colombier 
3443e12c5d1SDavid du Colombier int
nl_cmd(File * f,Cmd * cp)3453e12c5d1SDavid du Colombier nl_cmd(File *f, Cmd *cp)
3463e12c5d1SDavid du Colombier {
347*7dd7cddfSDavid du Colombier 	Address a;
348*7dd7cddfSDavid du Colombier 
3493e12c5d1SDavid du Colombier 	if(cp->addr == 0){
3503e12c5d1SDavid du Colombier 		/* First put it on newline boundaries */
3513e12c5d1SDavid du Colombier 		addr = lineaddr((Posn)0, f->dot, -1);
352*7dd7cddfSDavid du Colombier 		a = lineaddr((Posn)0, f->dot, 1);
353*7dd7cddfSDavid du Colombier 		addr.r.p2 = a.r.p2;
3543e12c5d1SDavid du Colombier 		if(addr.r.p1==f->dot.r.p1 && addr.r.p2==f->dot.r.p2)
3553e12c5d1SDavid du Colombier 			addr = lineaddr((Posn)1, f->dot, 1);
3563e12c5d1SDavid du Colombier 		display(f);
3573e12c5d1SDavid du Colombier 	}else if(downloaded)
3583e12c5d1SDavid du Colombier 		moveto(f, addr.r);
3593e12c5d1SDavid du Colombier 	else
3603e12c5d1SDavid du Colombier 		display(f);
3613e12c5d1SDavid du Colombier 	return TRUE;
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier 
3643e12c5d1SDavid du Colombier int
cd_cmd(File * f,Cmd * cp)3653e12c5d1SDavid du Colombier cd_cmd(File *f, Cmd *cp)
3663e12c5d1SDavid du Colombier {
3673e12c5d1SDavid du Colombier 	USED(f);
3683e12c5d1SDavid du Colombier 	cd(cp->ctext);
3693e12c5d1SDavid du Colombier 	return TRUE;
3703e12c5d1SDavid du Colombier }
3713e12c5d1SDavid du Colombier 
3723e12c5d1SDavid du Colombier int
append(File * f,Cmd * cp,Posn p)3733e12c5d1SDavid du Colombier append(File *f, Cmd *cp, Posn p)
3743e12c5d1SDavid du Colombier {
3753e12c5d1SDavid du Colombier 	if(cp->ctext->n>0 && cp->ctext->s[cp->ctext->n-1]==0)
3763e12c5d1SDavid du Colombier 		--cp->ctext->n;
3773e12c5d1SDavid du Colombier 	if(cp->ctext->n>0)
378*7dd7cddfSDavid du Colombier 		loginsert(f, p, cp->ctext->s, cp->ctext->n);
3793e12c5d1SDavid du Colombier 	f->ndot.r.p1 = p;
3803e12c5d1SDavid du Colombier 	f->ndot.r.p2 = p+cp->ctext->n;
3813e12c5d1SDavid du Colombier 	return TRUE;
3823e12c5d1SDavid du Colombier }
3833e12c5d1SDavid du Colombier 
3843e12c5d1SDavid du Colombier int
display(File * f)3853e12c5d1SDavid du Colombier display(File *f)
3863e12c5d1SDavid du Colombier {
3873e12c5d1SDavid du Colombier 	Posn p1, p2;
388*7dd7cddfSDavid du Colombier 	int np;
3893e12c5d1SDavid du Colombier 	char *c;
3903e12c5d1SDavid du Colombier 
3913e12c5d1SDavid du Colombier 	p1 = addr.r.p1;
3923e12c5d1SDavid du Colombier 	p2 = addr.r.p2;
393*7dd7cddfSDavid du Colombier 	if(p2 > f->nc){
394*7dd7cddfSDavid du Colombier 		fprint(2, "bad display addr p1=%ld p2=%ld f->nc=%d\n", p1, p2, f->nc); /*ZZZ should never happen, can remove */
395*7dd7cddfSDavid du Colombier 		p2 = f->nc;
396*7dd7cddfSDavid du Colombier 	}
3973e12c5d1SDavid du Colombier 	while(p1 < p2){
3983e12c5d1SDavid du Colombier 		np = p2-p1;
3993e12c5d1SDavid du Colombier 		if(np>BLOCKSIZE-1)
4003e12c5d1SDavid du Colombier 			np = BLOCKSIZE-1;
401*7dd7cddfSDavid du Colombier 		bufread(f, p1, genbuf, np);
402*7dd7cddfSDavid du Colombier 		genbuf[np] = 0;
403*7dd7cddfSDavid du Colombier 		c = Strtoc(tmprstr(genbuf, np+1));
4043e12c5d1SDavid du Colombier 		if(downloaded)
4053e12c5d1SDavid du Colombier 			termwrite(c);
4063e12c5d1SDavid du Colombier 		else
4073e12c5d1SDavid du Colombier 			Write(1, c, strlen(c));
4083e12c5d1SDavid du Colombier 		free(c);
409*7dd7cddfSDavid du Colombier 		p1 += np;
4103e12c5d1SDavid du Colombier 	}
4113e12c5d1SDavid du Colombier 	f->dot = addr;
4123e12c5d1SDavid du Colombier 	return TRUE;
4133e12c5d1SDavid du Colombier }
4143e12c5d1SDavid du Colombier 
4153e12c5d1SDavid du Colombier void
looper(File * f,Cmd * cp,int xy)4163e12c5d1SDavid du Colombier looper(File *f, Cmd *cp, int xy)
4173e12c5d1SDavid du Colombier {
4183e12c5d1SDavid du Colombier 	Posn p, op;
4193e12c5d1SDavid du Colombier 	Range r;
4203e12c5d1SDavid du Colombier 
4213e12c5d1SDavid du Colombier 	r = addr.r;
4223e12c5d1SDavid du Colombier 	op= xy? -1 : r.p1;
4233e12c5d1SDavid du Colombier 	nest++;
4243e12c5d1SDavid du Colombier 	compile(cp->re);
4253e12c5d1SDavid du Colombier 	for(p = r.p1; p<=r.p2; ){
4263e12c5d1SDavid du Colombier 		if(!execute(f, p, r.p2)){ /* no match, but y should still run */
4273e12c5d1SDavid du Colombier 			if(xy || op>r.p2)
4283e12c5d1SDavid du Colombier 				break;
4293e12c5d1SDavid du Colombier 			f->dot.r.p1 = op, f->dot.r.p2 = r.p2;
4303e12c5d1SDavid du Colombier 			p = r.p2+1;	/* exit next loop */
4313e12c5d1SDavid du Colombier 		}else{
4323e12c5d1SDavid du Colombier 			if(sel.p[0].p1==sel.p[0].p2){	/* empty match? */
4333e12c5d1SDavid du Colombier 				if(sel.p[0].p1==op){
4343e12c5d1SDavid du Colombier 					p++;
4353e12c5d1SDavid du Colombier 					continue;
4363e12c5d1SDavid du Colombier 				}
4373e12c5d1SDavid du Colombier 				p = sel.p[0].p2+1;
4383e12c5d1SDavid du Colombier 			}else
4393e12c5d1SDavid du Colombier 				p = sel.p[0].p2;
4403e12c5d1SDavid du Colombier 			if(xy)
4413e12c5d1SDavid du Colombier 				f->dot.r = sel.p[0];
4423e12c5d1SDavid du Colombier 			else
4433e12c5d1SDavid du Colombier 				f->dot.r.p1 = op, f->dot.r.p2 = sel.p[0].p1;
4443e12c5d1SDavid du Colombier 		}
4453e12c5d1SDavid du Colombier 		op = sel.p[0].p2;
4463e12c5d1SDavid du Colombier 		cmdexec(f, cp->ccmd);
4473e12c5d1SDavid du Colombier 		compile(cp->re);
4483e12c5d1SDavid du Colombier 	}
4493e12c5d1SDavid du Colombier 	--nest;
4503e12c5d1SDavid du Colombier }
4513e12c5d1SDavid du Colombier 
4523e12c5d1SDavid du Colombier void
linelooper(File * f,Cmd * cp)4533e12c5d1SDavid du Colombier linelooper(File *f, Cmd *cp)
4543e12c5d1SDavid du Colombier {
4553e12c5d1SDavid du Colombier 	Posn p;
4563e12c5d1SDavid du Colombier 	Range r, linesel;
457*7dd7cddfSDavid du Colombier 	Address a, a3;
4583e12c5d1SDavid du Colombier 
4593e12c5d1SDavid du Colombier 	nest++;
4603e12c5d1SDavid du Colombier 	r = addr.r;
4613e12c5d1SDavid du Colombier 	a3.f = f;
4623e12c5d1SDavid du Colombier 	a3.r.p1 = a3.r.p2 = r.p1;
4633e12c5d1SDavid du Colombier 	for(p = r.p1; p<r.p2; p = a3.r.p2){
4643e12c5d1SDavid du Colombier 		a3.r.p1 = a3.r.p2;
4653e12c5d1SDavid du Colombier /*pjw		if(p!=r.p1 || (linesel = lineaddr((Posn)0, a3, 1)).r.p2==p)*/
466*7dd7cddfSDavid du Colombier 		if(p!=r.p1 || (a = lineaddr((Posn)0, a3, 1), linesel = a.r, linesel.p2==p)){
467*7dd7cddfSDavid du Colombier 			a = lineaddr((Posn)1, a3, 1);
468*7dd7cddfSDavid du Colombier 			linesel = a.r;
469*7dd7cddfSDavid du Colombier 		}
4703e12c5d1SDavid du Colombier 		if(linesel.p1 >= r.p2)
4713e12c5d1SDavid du Colombier 			break;
4723e12c5d1SDavid du Colombier 		if(linesel.p2 >= r.p2)
4733e12c5d1SDavid du Colombier 			linesel.p2 = r.p2;
4743e12c5d1SDavid du Colombier 		if(linesel.p2 > linesel.p1)
4753e12c5d1SDavid du Colombier 			if(linesel.p1>=a3.r.p2 && linesel.p2>a3.r.p2){
4763e12c5d1SDavid du Colombier 				f->dot.r = linesel;
4773e12c5d1SDavid du Colombier 				cmdexec(f, cp->ccmd);
4783e12c5d1SDavid du Colombier 				a3.r = linesel;
4793e12c5d1SDavid du Colombier 				continue;
4803e12c5d1SDavid du Colombier 			}
4813e12c5d1SDavid du Colombier 		break;
4823e12c5d1SDavid du Colombier 	}
4833e12c5d1SDavid du Colombier 	--nest;
4843e12c5d1SDavid du Colombier }
4853e12c5d1SDavid du Colombier 
4863e12c5d1SDavid du Colombier void
filelooper(Cmd * cp,int XY)4873e12c5d1SDavid du Colombier filelooper(Cmd *cp, int XY)
4883e12c5d1SDavid du Colombier {
4893e12c5d1SDavid du Colombier 	File *f, *cur;
4903e12c5d1SDavid du Colombier 	int i;
4913e12c5d1SDavid du Colombier 
4923e12c5d1SDavid du Colombier 	if(Glooping++)
4933e12c5d1SDavid du Colombier 		error(EnestXY);
4943e12c5d1SDavid du Colombier 	nest++;
4953e12c5d1SDavid du Colombier 	settempfile();
4963e12c5d1SDavid du Colombier 	cur = curfile;
4973e12c5d1SDavid du Colombier 	for(i = 0; i<tempfile.nused; i++){
4983e12c5d1SDavid du Colombier 		f = tempfile.filepptr[i];
4993e12c5d1SDavid du Colombier 		if(f==cmd)
5003e12c5d1SDavid du Colombier 			continue;
5013e12c5d1SDavid du Colombier 		if(cp->re==0 || filematch(f, cp->re)==XY)
5023e12c5d1SDavid du Colombier 			cmdexec(f, cp->ccmd);
5033e12c5d1SDavid du Colombier 	}
5043e12c5d1SDavid du Colombier 	if(cur && whichmenu(cur)>=0)	/* check that cur is still a file */
5053e12c5d1SDavid du Colombier 		current(cur);
5063e12c5d1SDavid du Colombier 	--Glooping;
5073e12c5d1SDavid du Colombier 	--nest;
5083e12c5d1SDavid du Colombier }
509