xref: /plan9-contrib/sys/src/ape/cmd/sed/sed1.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier #include <stdlib.h>
2*219b2ee8SDavid du Colombier #include <sys/types.h>
3*219b2ee8SDavid du Colombier #include <fcntl.h>
4*219b2ee8SDavid du Colombier #include <unistd.h>
5*219b2ee8SDavid du Colombier #include	<stdio.h>
6*219b2ee8SDavid du Colombier #include "sed.h"
7*219b2ee8SDavid du Colombier 
8*219b2ee8SDavid du Colombier #define Read(f, buf, n)	(fflush(stdout), read(f, buf, n))
9*219b2ee8SDavid du Colombier 
10*219b2ee8SDavid du Colombier void
execute(uchar * file)11*219b2ee8SDavid du Colombier execute(uchar *file)
12*219b2ee8SDavid du Colombier {
13*219b2ee8SDavid du Colombier 	uchar *p1, *p2;
14*219b2ee8SDavid du Colombier 	union reptr	*ipc;
15*219b2ee8SDavid du Colombier 	int	c;
16*219b2ee8SDavid du Colombier 	long	l;
17*219b2ee8SDavid du Colombier 	uchar	*execp;
18*219b2ee8SDavid du Colombier 
19*219b2ee8SDavid du Colombier 	if (file) {
20*219b2ee8SDavid du Colombier 		if ((f = open((char*)file, O_RDONLY)) < 0) {
21*219b2ee8SDavid du Colombier 			fprintf(stderr, "sed: Can't open %s\n", file);
22*219b2ee8SDavid du Colombier 		}
23*219b2ee8SDavid du Colombier 	} else
24*219b2ee8SDavid du Colombier 		f = 0;
25*219b2ee8SDavid du Colombier 
26*219b2ee8SDavid du Colombier 	ebp = ibuf;
27*219b2ee8SDavid du Colombier 	cbp = ibuf;
28*219b2ee8SDavid du Colombier 
29*219b2ee8SDavid du Colombier 	if(pending) {
30*219b2ee8SDavid du Colombier 		ipc = pending;
31*219b2ee8SDavid du Colombier 		pending = 0;
32*219b2ee8SDavid du Colombier 		goto yes;
33*219b2ee8SDavid du Colombier 	}
34*219b2ee8SDavid du Colombier 
35*219b2ee8SDavid du Colombier 	for(;;) {
36*219b2ee8SDavid du Colombier 		if((execp = gline(linebuf)) == badp) {
37*219b2ee8SDavid du Colombier 			close(f);
38*219b2ee8SDavid du Colombier 			return;
39*219b2ee8SDavid du Colombier 		}
40*219b2ee8SDavid du Colombier 		spend = execp;
41*219b2ee8SDavid du Colombier 
42*219b2ee8SDavid du Colombier 		for(ipc = ptrspace; ipc->r1.command; ) {
43*219b2ee8SDavid du Colombier 
44*219b2ee8SDavid du Colombier 			p1 = ipc->r1.ad1;
45*219b2ee8SDavid du Colombier 			p2 = ipc->r1.ad2;
46*219b2ee8SDavid du Colombier 
47*219b2ee8SDavid du Colombier 			if(p1) {
48*219b2ee8SDavid du Colombier 
49*219b2ee8SDavid du Colombier 				if(ipc->r1.inar) {
50*219b2ee8SDavid du Colombier 					if(*p2 == CEND) {
51*219b2ee8SDavid du Colombier 						p1 = 0;
52*219b2ee8SDavid du Colombier 					} else if(*p2 == CLNUM) {
53*219b2ee8SDavid du Colombier 						l = p2[1]&0377
54*219b2ee8SDavid du Colombier 							| ((p2[2]&0377)<<8)
55*219b2ee8SDavid du Colombier 							| ((p2[3]&0377)<<16)
56*219b2ee8SDavid du Colombier 							| ((p2[4]&0377)<<24);
57*219b2ee8SDavid du Colombier 						if(lnum > l) {
58*219b2ee8SDavid du Colombier 							ipc->r1.inar = 0;
59*219b2ee8SDavid du Colombier 							if(ipc->r1.negfl)
60*219b2ee8SDavid du Colombier 								goto yes;
61*219b2ee8SDavid du Colombier 							ipc++;
62*219b2ee8SDavid du Colombier 							continue;
63*219b2ee8SDavid du Colombier 						}
64*219b2ee8SDavid du Colombier 						if(lnum == l) {
65*219b2ee8SDavid du Colombier 							ipc->r1.inar = 0;
66*219b2ee8SDavid du Colombier 						}
67*219b2ee8SDavid du Colombier 					} else if(match(p2, 0)) {
68*219b2ee8SDavid du Colombier 						ipc->r1.inar = 0;
69*219b2ee8SDavid du Colombier 					}
70*219b2ee8SDavid du Colombier 				} else if(*p1 == CEND) {
71*219b2ee8SDavid du Colombier 					if(!dolflag) {
72*219b2ee8SDavid du Colombier 						if(ipc->r1.negfl)
73*219b2ee8SDavid du Colombier 							goto yes;
74*219b2ee8SDavid du Colombier 						ipc++;
75*219b2ee8SDavid du Colombier 						continue;
76*219b2ee8SDavid du Colombier 					}
77*219b2ee8SDavid du Colombier 
78*219b2ee8SDavid du Colombier 				} else if(*p1 == CLNUM) {
79*219b2ee8SDavid du Colombier 					l = p1[1]&0377
80*219b2ee8SDavid du Colombier 						| ((p1[2]&0377)<<8)
81*219b2ee8SDavid du Colombier 						| ((p1[3]&0377)<<16)
82*219b2ee8SDavid du Colombier 						| ((p1[4]&0377)<<24);
83*219b2ee8SDavid du Colombier 					if(lnum != l) {
84*219b2ee8SDavid du Colombier 						if(ipc->r1.negfl)
85*219b2ee8SDavid du Colombier 							goto yes;
86*219b2ee8SDavid du Colombier 						ipc++;
87*219b2ee8SDavid du Colombier 						continue;
88*219b2ee8SDavid du Colombier 					}
89*219b2ee8SDavid du Colombier 					if(p2)
90*219b2ee8SDavid du Colombier 						ipc->r1.inar = 1;
91*219b2ee8SDavid du Colombier 				} else if(match(p1, 0)) {
92*219b2ee8SDavid du Colombier 					if(p2)
93*219b2ee8SDavid du Colombier 						ipc->r1.inar = 1;
94*219b2ee8SDavid du Colombier 				} else {
95*219b2ee8SDavid du Colombier 					if(ipc->r1.negfl)
96*219b2ee8SDavid du Colombier 						goto yes;
97*219b2ee8SDavid du Colombier 					ipc++;
98*219b2ee8SDavid du Colombier 					continue;
99*219b2ee8SDavid du Colombier 				}
100*219b2ee8SDavid du Colombier 			}
101*219b2ee8SDavid du Colombier 
102*219b2ee8SDavid du Colombier 			if(ipc->r1.negfl) {
103*219b2ee8SDavid du Colombier 				ipc++;
104*219b2ee8SDavid du Colombier 				continue;
105*219b2ee8SDavid du Colombier 			}
106*219b2ee8SDavid du Colombier 	yes:
107*219b2ee8SDavid du Colombier 			command(ipc);
108*219b2ee8SDavid du Colombier 
109*219b2ee8SDavid du Colombier 			if(delflag)
110*219b2ee8SDavid du Colombier 				break;
111*219b2ee8SDavid du Colombier 
112*219b2ee8SDavid du Colombier 			if(jflag) {
113*219b2ee8SDavid du Colombier 				jflag = 0;
114*219b2ee8SDavid du Colombier 				if((ipc = ipc->r2.lb1) == 0) {
115*219b2ee8SDavid du Colombier 					ipc = ptrspace;
116*219b2ee8SDavid du Colombier 					break;
117*219b2ee8SDavid du Colombier 				}
118*219b2ee8SDavid du Colombier 			} else
119*219b2ee8SDavid du Colombier 				ipc++;
120*219b2ee8SDavid du Colombier 
121*219b2ee8SDavid du Colombier 		}
122*219b2ee8SDavid du Colombier 		if(!nflag && !delflag) {
123*219b2ee8SDavid du Colombier 			for(p1 = linebuf; p1 < spend; p1++)
124*219b2ee8SDavid du Colombier 				putc(*p1, stdout);
125*219b2ee8SDavid du Colombier 			putc('\n', stdout);
126*219b2ee8SDavid du Colombier 		}
127*219b2ee8SDavid du Colombier 
128*219b2ee8SDavid du Colombier 		if(aptr > abuf) {
129*219b2ee8SDavid du Colombier 			arout();
130*219b2ee8SDavid du Colombier 		}
131*219b2ee8SDavid du Colombier 
132*219b2ee8SDavid du Colombier 		delflag = 0;
133*219b2ee8SDavid du Colombier 
134*219b2ee8SDavid du Colombier 	}
135*219b2ee8SDavid du Colombier }
136*219b2ee8SDavid du Colombier int
match(uchar * expbuf,int gf)137*219b2ee8SDavid du Colombier match(uchar *expbuf, int gf)
138*219b2ee8SDavid du Colombier {
139*219b2ee8SDavid du Colombier 	uchar	*p1, *p2;
140*219b2ee8SDavid du Colombier 	int c;
141*219b2ee8SDavid du Colombier 
142*219b2ee8SDavid du Colombier 	if(gf) {
143*219b2ee8SDavid du Colombier 		if(*expbuf)	return(0);
144*219b2ee8SDavid du Colombier 		p1 = linebuf;
145*219b2ee8SDavid du Colombier 		p2 = genbuf;
146*219b2ee8SDavid du Colombier 		while(*p1++ = *p2++);
147*219b2ee8SDavid du Colombier 		locs = p1 = loc2;
148*219b2ee8SDavid du Colombier 	} else {
149*219b2ee8SDavid du Colombier 		p1 = linebuf;
150*219b2ee8SDavid du Colombier 		locs = 0;
151*219b2ee8SDavid du Colombier 	}
152*219b2ee8SDavid du Colombier 
153*219b2ee8SDavid du Colombier 	p2 = expbuf;
154*219b2ee8SDavid du Colombier 	if(*p2++) {
155*219b2ee8SDavid du Colombier 		loc1 = p1;
156*219b2ee8SDavid du Colombier 		if(*p2 == CCHR && p2[1] != *p1)
157*219b2ee8SDavid du Colombier 			return(0);
158*219b2ee8SDavid du Colombier 		return(advance(p1, p2));
159*219b2ee8SDavid du Colombier 	}
160*219b2ee8SDavid du Colombier 
161*219b2ee8SDavid du Colombier 	/* fast check for first character */
162*219b2ee8SDavid du Colombier 
163*219b2ee8SDavid du Colombier 	if(*p2 == CCHR) {
164*219b2ee8SDavid du Colombier 		c = p2[1];
165*219b2ee8SDavid du Colombier 		do {
166*219b2ee8SDavid du Colombier 			if(*p1 != c)
167*219b2ee8SDavid du Colombier 				continue;
168*219b2ee8SDavid du Colombier 			if(advance(p1, p2)) {
169*219b2ee8SDavid du Colombier 				loc1 = p1;
170*219b2ee8SDavid du Colombier 				return(1);
171*219b2ee8SDavid du Colombier 			}
172*219b2ee8SDavid du Colombier 		} while(*p1++);
173*219b2ee8SDavid du Colombier 		return(0);
174*219b2ee8SDavid du Colombier 	}
175*219b2ee8SDavid du Colombier 
176*219b2ee8SDavid du Colombier 	do {
177*219b2ee8SDavid du Colombier 		if(advance(p1, p2)) {
178*219b2ee8SDavid du Colombier 			loc1 = p1;
179*219b2ee8SDavid du Colombier 			return(1);
180*219b2ee8SDavid du Colombier 		}
181*219b2ee8SDavid du Colombier 	} while(*p1++);
182*219b2ee8SDavid du Colombier 	return(0);
183*219b2ee8SDavid du Colombier }
184*219b2ee8SDavid du Colombier int
advance(uchar * alp,uchar * aep)185*219b2ee8SDavid du Colombier advance(uchar *alp, uchar *aep)
186*219b2ee8SDavid du Colombier {
187*219b2ee8SDavid du Colombier 	uchar *lp, *ep, *curlp;
188*219b2ee8SDavid du Colombier 	uchar	c;
189*219b2ee8SDavid du Colombier 	uchar *bbeg;
190*219b2ee8SDavid du Colombier 	int	ct;
191*219b2ee8SDavid du Colombier 
192*219b2ee8SDavid du Colombier /*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep);	/*DEBUG*/
193*219b2ee8SDavid du Colombier 
194*219b2ee8SDavid du Colombier 	lp = alp;
195*219b2ee8SDavid du Colombier 	ep = aep;
196*219b2ee8SDavid du Colombier 	for (;;) switch (*ep++) {
197*219b2ee8SDavid du Colombier 
198*219b2ee8SDavid du Colombier 	case CCHR:
199*219b2ee8SDavid du Colombier 		if (*ep++ == *lp++)
200*219b2ee8SDavid du Colombier 			continue;
201*219b2ee8SDavid du Colombier 		return(0);
202*219b2ee8SDavid du Colombier 
203*219b2ee8SDavid du Colombier 	case CDOT:
204*219b2ee8SDavid du Colombier 		if (*lp++)
205*219b2ee8SDavid du Colombier 			continue;
206*219b2ee8SDavid du Colombier 		return(0);
207*219b2ee8SDavid du Colombier 
208*219b2ee8SDavid du Colombier 	case CNL:
209*219b2ee8SDavid du Colombier 	case CDOL:
210*219b2ee8SDavid du Colombier 		if (*lp == 0)
211*219b2ee8SDavid du Colombier 			continue;
212*219b2ee8SDavid du Colombier 		return(0);
213*219b2ee8SDavid du Colombier 
214*219b2ee8SDavid du Colombier 	case CEOF:
215*219b2ee8SDavid du Colombier 		loc2 = lp;
216*219b2ee8SDavid du Colombier 		return(1);
217*219b2ee8SDavid du Colombier 
218*219b2ee8SDavid du Colombier 	case CCL:
219*219b2ee8SDavid du Colombier 		c = *lp++;
220*219b2ee8SDavid du Colombier 		if(ep[c>>3] & bittab[c & 07]) {
221*219b2ee8SDavid du Colombier 			ep += 32;
222*219b2ee8SDavid du Colombier 			continue;
223*219b2ee8SDavid du Colombier 		}
224*219b2ee8SDavid du Colombier 		return(0);
225*219b2ee8SDavid du Colombier 
226*219b2ee8SDavid du Colombier 	case CBRA:
227*219b2ee8SDavid du Colombier 		braslist[*ep++] = lp;
228*219b2ee8SDavid du Colombier 		continue;
229*219b2ee8SDavid du Colombier 
230*219b2ee8SDavid du Colombier 	case CKET:
231*219b2ee8SDavid du Colombier 		braelist[*ep++] = lp;
232*219b2ee8SDavid du Colombier 		continue;
233*219b2ee8SDavid du Colombier 
234*219b2ee8SDavid du Colombier 	case CBACK:
235*219b2ee8SDavid du Colombier 		bbeg = braslist[*ep];
236*219b2ee8SDavid du Colombier 		ct = braelist[*ep++] - bbeg;
237*219b2ee8SDavid du Colombier 
238*219b2ee8SDavid du Colombier 		if(ecmp(bbeg, lp, ct)) {
239*219b2ee8SDavid du Colombier 			lp += ct;
240*219b2ee8SDavid du Colombier 			continue;
241*219b2ee8SDavid du Colombier 		}
242*219b2ee8SDavid du Colombier 		return(0);
243*219b2ee8SDavid du Colombier 
244*219b2ee8SDavid du Colombier 	case CBACK|STAR:
245*219b2ee8SDavid du Colombier 		bbeg = braslist[*ep];
246*219b2ee8SDavid du Colombier 		ct = braelist[*ep++] - bbeg;
247*219b2ee8SDavid du Colombier 		curlp = lp;
248*219b2ee8SDavid du Colombier 		while(ecmp(bbeg, lp, ct))
249*219b2ee8SDavid du Colombier 			lp += ct;
250*219b2ee8SDavid du Colombier 
251*219b2ee8SDavid du Colombier 		while(lp >= curlp) {
252*219b2ee8SDavid du Colombier 			if(advance(lp, ep))	return(1);
253*219b2ee8SDavid du Colombier 			lp -= ct;
254*219b2ee8SDavid du Colombier 		}
255*219b2ee8SDavid du Colombier 		return(0);
256*219b2ee8SDavid du Colombier 
257*219b2ee8SDavid du Colombier 
258*219b2ee8SDavid du Colombier 	case CDOT|STAR:
259*219b2ee8SDavid du Colombier 		curlp = lp;
260*219b2ee8SDavid du Colombier 		while (*lp++);
261*219b2ee8SDavid du Colombier 		goto star;
262*219b2ee8SDavid du Colombier 
263*219b2ee8SDavid du Colombier 	case CCHR|STAR:
264*219b2ee8SDavid du Colombier 		curlp = lp;
265*219b2ee8SDavid du Colombier 		while (*lp++ == *ep);
266*219b2ee8SDavid du Colombier 		ep++;
267*219b2ee8SDavid du Colombier 		goto star;
268*219b2ee8SDavid du Colombier 
269*219b2ee8SDavid du Colombier 	case CCL|STAR:
270*219b2ee8SDavid du Colombier 		curlp = lp;
271*219b2ee8SDavid du Colombier 		do {
272*219b2ee8SDavid du Colombier 			c = *lp++;
273*219b2ee8SDavid du Colombier 		} while(ep[c>>3] & bittab[c & 07]);
274*219b2ee8SDavid du Colombier 		ep += 32;
275*219b2ee8SDavid du Colombier 		goto star;
276*219b2ee8SDavid du Colombier 
277*219b2ee8SDavid du Colombier 	star:
278*219b2ee8SDavid du Colombier 		if(--lp == curlp) {
279*219b2ee8SDavid du Colombier 			continue;
280*219b2ee8SDavid du Colombier 		}
281*219b2ee8SDavid du Colombier 
282*219b2ee8SDavid du Colombier 		if(*ep == CCHR) {
283*219b2ee8SDavid du Colombier 			c = ep[1];
284*219b2ee8SDavid du Colombier 			do {
285*219b2ee8SDavid du Colombier 				if(*lp != c)
286*219b2ee8SDavid du Colombier 					continue;
287*219b2ee8SDavid du Colombier 				if(advance(lp, ep))
288*219b2ee8SDavid du Colombier 					return(1);
289*219b2ee8SDavid du Colombier 			} while(lp-- > curlp);
290*219b2ee8SDavid du Colombier 			return(0);
291*219b2ee8SDavid du Colombier 		}
292*219b2ee8SDavid du Colombier 
293*219b2ee8SDavid du Colombier 		if(*ep == CBACK) {
294*219b2ee8SDavid du Colombier 			c = *(braslist[ep[1]]);
295*219b2ee8SDavid du Colombier 			do {
296*219b2ee8SDavid du Colombier 				if(*lp != c)
297*219b2ee8SDavid du Colombier 					continue;
298*219b2ee8SDavid du Colombier 				if(advance(lp, ep))
299*219b2ee8SDavid du Colombier 					return(1);
300*219b2ee8SDavid du Colombier 			} while(lp-- > curlp);
301*219b2ee8SDavid du Colombier 			return(0);
302*219b2ee8SDavid du Colombier 		}
303*219b2ee8SDavid du Colombier 
304*219b2ee8SDavid du Colombier 		do {
305*219b2ee8SDavid du Colombier 			if(lp == locs)	break;
306*219b2ee8SDavid du Colombier 			if (advance(lp, ep))
307*219b2ee8SDavid du Colombier 				return(1);
308*219b2ee8SDavid du Colombier 		} while (lp-- > curlp);
309*219b2ee8SDavid du Colombier 		return(0);
310*219b2ee8SDavid du Colombier 
311*219b2ee8SDavid du Colombier 	default:
312*219b2ee8SDavid du Colombier 		fprintf(stderr, "sed:  RE botch, %o\n", *--ep);
313*219b2ee8SDavid du Colombier 		exit(1);
314*219b2ee8SDavid du Colombier 	}
315*219b2ee8SDavid du Colombier }
316*219b2ee8SDavid du Colombier int
substitute(union reptr * ipc)317*219b2ee8SDavid du Colombier substitute(union reptr *ipc)
318*219b2ee8SDavid du Colombier {
319*219b2ee8SDavid du Colombier 	uchar	*oloc2;
320*219b2ee8SDavid du Colombier 
321*219b2ee8SDavid du Colombier 	if(match(ipc->r1.re1, 0)) {
322*219b2ee8SDavid du Colombier 
323*219b2ee8SDavid du Colombier 		sflag = 1;
324*219b2ee8SDavid du Colombier 		if(!ipc->r1.gfl) {
325*219b2ee8SDavid du Colombier 			dosub(ipc->r1.rhs);
326*219b2ee8SDavid du Colombier 			return(1);
327*219b2ee8SDavid du Colombier 		}
328*219b2ee8SDavid du Colombier 
329*219b2ee8SDavid du Colombier 		oloc2 = NULL;
330*219b2ee8SDavid du Colombier 		do {
331*219b2ee8SDavid du Colombier 			if(oloc2 == loc2) {
332*219b2ee8SDavid du Colombier 				loc2++;
333*219b2ee8SDavid du Colombier 				continue;
334*219b2ee8SDavid du Colombier 			} else {
335*219b2ee8SDavid du Colombier 				dosub(ipc->r1.rhs);
336*219b2ee8SDavid du Colombier 				if(*loc2 == 0)
337*219b2ee8SDavid du Colombier 					break;
338*219b2ee8SDavid du Colombier 				oloc2 = loc2;
339*219b2ee8SDavid du Colombier 			}
340*219b2ee8SDavid du Colombier 		} while(match(ipc->r1.re1, 1));
341*219b2ee8SDavid du Colombier 		return(1);
342*219b2ee8SDavid du Colombier 	}
343*219b2ee8SDavid du Colombier 	return(0);
344*219b2ee8SDavid du Colombier }
345*219b2ee8SDavid du Colombier 
346*219b2ee8SDavid du Colombier void
dosub(uchar * rhsbuf)347*219b2ee8SDavid du Colombier dosub(uchar *rhsbuf)
348*219b2ee8SDavid du Colombier {
349*219b2ee8SDavid du Colombier 	uchar *lp, *sp, *rp;
350*219b2ee8SDavid du Colombier 	int c;
351*219b2ee8SDavid du Colombier 
352*219b2ee8SDavid du Colombier 	lp = linebuf;
353*219b2ee8SDavid du Colombier 	sp = genbuf;
354*219b2ee8SDavid du Colombier 	rp = rhsbuf;
355*219b2ee8SDavid du Colombier 	while (lp < loc1)
356*219b2ee8SDavid du Colombier 		*sp++ = *lp++;
357*219b2ee8SDavid du Colombier 	while(c = *rp++) {
358*219b2ee8SDavid du Colombier 		if (c == '\\') {
359*219b2ee8SDavid du Colombier 			c = *rp++;
360*219b2ee8SDavid du Colombier 			if (c >= '1' && c < NBRA+'1') {
361*219b2ee8SDavid du Colombier 				sp = place(sp, braslist[c-'1'], braelist[c-'1']);
362*219b2ee8SDavid du Colombier 				continue;
363*219b2ee8SDavid du Colombier 			}
364*219b2ee8SDavid du Colombier 		} else if(c == '&') {
365*219b2ee8SDavid du Colombier 				sp = place(sp, loc1, loc2);
366*219b2ee8SDavid du Colombier 				continue;
367*219b2ee8SDavid du Colombier 		}
368*219b2ee8SDavid du Colombier 		*sp++ = c;
369*219b2ee8SDavid du Colombier 		if (sp >= &genbuf[LBSIZE])
370*219b2ee8SDavid du Colombier 			fprintf(stderr, "sed: Output line too long.\n");
371*219b2ee8SDavid du Colombier 	}
372*219b2ee8SDavid du Colombier 	lp = loc2;
373*219b2ee8SDavid du Colombier 	loc2 = sp - genbuf + linebuf;
374*219b2ee8SDavid du Colombier 	while (*sp++ = *lp++)
375*219b2ee8SDavid du Colombier 		if (sp >= &genbuf[LBSIZE]) {
376*219b2ee8SDavid du Colombier 			fprintf(stderr, "sed: Output line too long.\n");
377*219b2ee8SDavid du Colombier 		}
378*219b2ee8SDavid du Colombier 	lp = linebuf;
379*219b2ee8SDavid du Colombier 	sp = genbuf;
380*219b2ee8SDavid du Colombier 	while (*lp++ = *sp++);
381*219b2ee8SDavid du Colombier 	spend = lp-1;
382*219b2ee8SDavid du Colombier }
383*219b2ee8SDavid du Colombier uchar *
place(uchar * asp,uchar * al1,uchar * al2)384*219b2ee8SDavid du Colombier place(uchar *asp, uchar *al1, uchar *al2)
385*219b2ee8SDavid du Colombier {
386*219b2ee8SDavid du Colombier 	uchar *sp, *l1, *l2;
387*219b2ee8SDavid du Colombier 
388*219b2ee8SDavid du Colombier 	sp = asp;
389*219b2ee8SDavid du Colombier 	l1 = al1;
390*219b2ee8SDavid du Colombier 	l2 = al2;
391*219b2ee8SDavid du Colombier 	while (l1 < l2) {
392*219b2ee8SDavid du Colombier 		*sp++ = *l1++;
393*219b2ee8SDavid du Colombier 		if (sp >= &genbuf[LBSIZE])
394*219b2ee8SDavid du Colombier 			fprintf(stderr, "sed: Output line too long.\n");
395*219b2ee8SDavid du Colombier 	}
396*219b2ee8SDavid du Colombier 	return(sp);
397*219b2ee8SDavid du Colombier }
398*219b2ee8SDavid du Colombier 
399*219b2ee8SDavid du Colombier void
command(union reptr * ipc)400*219b2ee8SDavid du Colombier command(union reptr *ipc)
401*219b2ee8SDavid du Colombier {
402*219b2ee8SDavid du Colombier 	int	i;
403*219b2ee8SDavid du Colombier 	uchar	*p1, *p2;
404*219b2ee8SDavid du Colombier 	uchar	*execp;
405*219b2ee8SDavid du Colombier 
406*219b2ee8SDavid du Colombier 
407*219b2ee8SDavid du Colombier 	switch(ipc->r1.command) {
408*219b2ee8SDavid du Colombier 
409*219b2ee8SDavid du Colombier 		case ACOM:
410*219b2ee8SDavid du Colombier 			*aptr++ = ipc;
411*219b2ee8SDavid du Colombier 			if(aptr >= &abuf[ABUFSIZE]) {
412*219b2ee8SDavid du Colombier 				fprintf(stderr, "sed: Too many appends after line %ld\n",
413*219b2ee8SDavid du Colombier 					lnum);
414*219b2ee8SDavid du Colombier 			}
415*219b2ee8SDavid du Colombier 			*aptr = 0;
416*219b2ee8SDavid du Colombier 			break;
417*219b2ee8SDavid du Colombier 
418*219b2ee8SDavid du Colombier 		case CCOM:
419*219b2ee8SDavid du Colombier 			delflag = 1;
420*219b2ee8SDavid du Colombier 			if(!ipc->r1.inar || dolflag) {
421*219b2ee8SDavid du Colombier 				for(p1 = ipc->r1.re1; *p1; )
422*219b2ee8SDavid du Colombier 					putc(*p1++, stdout);
423*219b2ee8SDavid du Colombier 				putc('\n', stdout);
424*219b2ee8SDavid du Colombier 			}
425*219b2ee8SDavid du Colombier 			break;
426*219b2ee8SDavid du Colombier 		case DCOM:
427*219b2ee8SDavid du Colombier 			delflag++;
428*219b2ee8SDavid du Colombier 			break;
429*219b2ee8SDavid du Colombier 		case CDCOM:
430*219b2ee8SDavid du Colombier 			p1 = p2 = linebuf;
431*219b2ee8SDavid du Colombier 
432*219b2ee8SDavid du Colombier 			while(*p1 != '\n') {
433*219b2ee8SDavid du Colombier 				if(*p1++ == 0) {
434*219b2ee8SDavid du Colombier 					delflag++;
435*219b2ee8SDavid du Colombier 					return;
436*219b2ee8SDavid du Colombier 				}
437*219b2ee8SDavid du Colombier 			}
438*219b2ee8SDavid du Colombier 
439*219b2ee8SDavid du Colombier 			p1++;
440*219b2ee8SDavid du Colombier 			while(*p2++ = *p1++);
441*219b2ee8SDavid du Colombier 			spend = p2-1;
442*219b2ee8SDavid du Colombier 			jflag++;
443*219b2ee8SDavid du Colombier 			break;
444*219b2ee8SDavid du Colombier 
445*219b2ee8SDavid du Colombier 		case EQCOM:
446*219b2ee8SDavid du Colombier 			fprintf(stdout, "%ld\n", lnum);
447*219b2ee8SDavid du Colombier 			break;
448*219b2ee8SDavid du Colombier 
449*219b2ee8SDavid du Colombier 		case GCOM:
450*219b2ee8SDavid du Colombier 			p1 = linebuf;
451*219b2ee8SDavid du Colombier 			p2 = holdsp;
452*219b2ee8SDavid du Colombier 			while(*p1++ = *p2++);
453*219b2ee8SDavid du Colombier 			spend = p1-1;
454*219b2ee8SDavid du Colombier 			break;
455*219b2ee8SDavid du Colombier 
456*219b2ee8SDavid du Colombier 		case CGCOM:
457*219b2ee8SDavid du Colombier 			*spend++ = '\n';
458*219b2ee8SDavid du Colombier 			p1 = spend;
459*219b2ee8SDavid du Colombier 			p2 = holdsp;
460*219b2ee8SDavid du Colombier 			while(*p1++ = *p2++)
461*219b2ee8SDavid du Colombier 				if(p1 >= lbend)
462*219b2ee8SDavid du Colombier 					break;
463*219b2ee8SDavid du Colombier 			spend = p1-1;
464*219b2ee8SDavid du Colombier 			break;
465*219b2ee8SDavid du Colombier 
466*219b2ee8SDavid du Colombier 		case HCOM:
467*219b2ee8SDavid du Colombier 			p1 = holdsp;
468*219b2ee8SDavid du Colombier 			p2 = linebuf;
469*219b2ee8SDavid du Colombier 			while(*p1++ = *p2++);
470*219b2ee8SDavid du Colombier 			hspend = p1-1;
471*219b2ee8SDavid du Colombier 			break;
472*219b2ee8SDavid du Colombier 
473*219b2ee8SDavid du Colombier 		case CHCOM:
474*219b2ee8SDavid du Colombier 			*hspend++ = '\n';
475*219b2ee8SDavid du Colombier 			p1 = hspend;
476*219b2ee8SDavid du Colombier 			p2 = linebuf;
477*219b2ee8SDavid du Colombier 			while(*p1++ = *p2++)
478*219b2ee8SDavid du Colombier 				if(p1 >= hend)
479*219b2ee8SDavid du Colombier 					break;
480*219b2ee8SDavid du Colombier 			hspend = p1-1;
481*219b2ee8SDavid du Colombier 			break;
482*219b2ee8SDavid du Colombier 
483*219b2ee8SDavid du Colombier 		case ICOM:
484*219b2ee8SDavid du Colombier 			for(p1 = ipc->r1.re1; *p1; )
485*219b2ee8SDavid du Colombier 				putc(*p1++, stdout);
486*219b2ee8SDavid du Colombier 			putc('\n', stdout);
487*219b2ee8SDavid du Colombier 			break;
488*219b2ee8SDavid du Colombier 
489*219b2ee8SDavid du Colombier 		case BCOM:
490*219b2ee8SDavid du Colombier 			jflag = 1;
491*219b2ee8SDavid du Colombier 			break;
492*219b2ee8SDavid du Colombier 
493*219b2ee8SDavid du Colombier 		case LCOM:
494*219b2ee8SDavid du Colombier 			p1 = linebuf;
495*219b2ee8SDavid du Colombier 			p2 = genbuf;
496*219b2ee8SDavid du Colombier 			while(*p1) {
497*219b2ee8SDavid du Colombier 				p2 = lformat(*p1++ & 0377, p2);
498*219b2ee8SDavid du Colombier 				if(p2>lcomend && *p1) {
499*219b2ee8SDavid du Colombier 					*p2 = 0;
500*219b2ee8SDavid du Colombier 					fprintf(stdout, "%s\\\n", genbuf);
501*219b2ee8SDavid du Colombier 					p2 = genbuf;
502*219b2ee8SDavid du Colombier 				}
503*219b2ee8SDavid du Colombier 			}
504*219b2ee8SDavid du Colombier 			if(p2>genbuf && (p1[-1]==' '||p1[-1]=='\n'))
505*219b2ee8SDavid du Colombier 					p2 = lformat('\n', p2);
506*219b2ee8SDavid du Colombier 			*p2 = 0;
507*219b2ee8SDavid du Colombier 			fprintf(stdout, "%s\n", genbuf);
508*219b2ee8SDavid du Colombier 			break;
509*219b2ee8SDavid du Colombier 
510*219b2ee8SDavid du Colombier 		case NCOM:
511*219b2ee8SDavid du Colombier 			if(!nflag) {
512*219b2ee8SDavid du Colombier 				for(p1 = linebuf; p1 < spend; p1++)
513*219b2ee8SDavid du Colombier 					putc(*p1, stdout);
514*219b2ee8SDavid du Colombier 				putc('\n', stdout);
515*219b2ee8SDavid du Colombier 			}
516*219b2ee8SDavid du Colombier 
517*219b2ee8SDavid du Colombier 			if(aptr > abuf)
518*219b2ee8SDavid du Colombier 				arout();
519*219b2ee8SDavid du Colombier 			if((execp = gline(linebuf)) == badp) {
520*219b2ee8SDavid du Colombier 				pending = ipc;
521*219b2ee8SDavid du Colombier 				delflag = 1;
522*219b2ee8SDavid du Colombier 				break;
523*219b2ee8SDavid du Colombier 			}
524*219b2ee8SDavid du Colombier 			spend = execp;
525*219b2ee8SDavid du Colombier 
526*219b2ee8SDavid du Colombier 			break;
527*219b2ee8SDavid du Colombier 		case CNCOM:
528*219b2ee8SDavid du Colombier 			if(aptr > abuf)
529*219b2ee8SDavid du Colombier 				arout();
530*219b2ee8SDavid du Colombier 			*spend++ = '\n';
531*219b2ee8SDavid du Colombier 			if((execp = gline(spend)) == badp) {
532*219b2ee8SDavid du Colombier 				pending = ipc;
533*219b2ee8SDavid du Colombier 				delflag = 1;
534*219b2ee8SDavid du Colombier 				break;
535*219b2ee8SDavid du Colombier 			}
536*219b2ee8SDavid du Colombier 			spend = execp;
537*219b2ee8SDavid du Colombier 			break;
538*219b2ee8SDavid du Colombier 
539*219b2ee8SDavid du Colombier 		case PCOM:
540*219b2ee8SDavid du Colombier 			for(p1 = linebuf; p1 < spend; p1++)
541*219b2ee8SDavid du Colombier 				putc(*p1, stdout);
542*219b2ee8SDavid du Colombier 			putc('\n', stdout);
543*219b2ee8SDavid du Colombier 			break;
544*219b2ee8SDavid du Colombier 		case CPCOM:
545*219b2ee8SDavid du Colombier 	cpcom:
546*219b2ee8SDavid du Colombier 			for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
547*219b2ee8SDavid du Colombier 				putc(*p1++, stdout);
548*219b2ee8SDavid du Colombier 			putc('\n', stdout);
549*219b2ee8SDavid du Colombier 			break;
550*219b2ee8SDavid du Colombier 
551*219b2ee8SDavid du Colombier 		case QCOM:
552*219b2ee8SDavid du Colombier 			if(!nflag) {
553*219b2ee8SDavid du Colombier 				for(p1 = linebuf; p1 < spend; p1++)
554*219b2ee8SDavid du Colombier 					putc(*p1, stdout);
555*219b2ee8SDavid du Colombier 				putc('\n', stdout);
556*219b2ee8SDavid du Colombier 			}
557*219b2ee8SDavid du Colombier 			if(aptr > abuf)	arout();
558*219b2ee8SDavid du Colombier 			fclose(stdout);
559*219b2ee8SDavid du Colombier 			lseek(f,(long)(cbp-ebp),2);
560*219b2ee8SDavid du Colombier 			exit(0);
561*219b2ee8SDavid du Colombier 		case RCOM:
562*219b2ee8SDavid du Colombier 
563*219b2ee8SDavid du Colombier 			*aptr++ = ipc;
564*219b2ee8SDavid du Colombier 			if(aptr >= &abuf[ABUFSIZE])
565*219b2ee8SDavid du Colombier 				fprintf(stderr, "sed: Too many reads after line%ld\n",
566*219b2ee8SDavid du Colombier 					lnum);
567*219b2ee8SDavid du Colombier 
568*219b2ee8SDavid du Colombier 			*aptr = 0;
569*219b2ee8SDavid du Colombier 
570*219b2ee8SDavid du Colombier 			break;
571*219b2ee8SDavid du Colombier 
572*219b2ee8SDavid du Colombier 		case SCOM:
573*219b2ee8SDavid du Colombier 			i = substitute(ipc);
574*219b2ee8SDavid du Colombier 			if(ipc->r1.pfl && i)
575*219b2ee8SDavid du Colombier 				if(ipc->r1.pfl == 1) {
576*219b2ee8SDavid du Colombier 					for(p1 = linebuf; p1 < spend; p1++)
577*219b2ee8SDavid du Colombier 						putc(*p1, stdout);
578*219b2ee8SDavid du Colombier 					putc('\n', stdout);
579*219b2ee8SDavid du Colombier 				}
580*219b2ee8SDavid du Colombier 				else
581*219b2ee8SDavid du Colombier 					goto cpcom;
582*219b2ee8SDavid du Colombier 			if(i && ipc->r1.fcode)
583*219b2ee8SDavid du Colombier 				goto wcom;
584*219b2ee8SDavid du Colombier 			break;
585*219b2ee8SDavid du Colombier 
586*219b2ee8SDavid du Colombier 		case TCOM:
587*219b2ee8SDavid du Colombier 			if(sflag == 0)	break;
588*219b2ee8SDavid du Colombier 			sflag = 0;
589*219b2ee8SDavid du Colombier 			jflag = 1;
590*219b2ee8SDavid du Colombier 			break;
591*219b2ee8SDavid du Colombier 
592*219b2ee8SDavid du Colombier 		wcom:
593*219b2ee8SDavid du Colombier 		case WCOM:
594*219b2ee8SDavid du Colombier 			fprintf(ipc->r1.fcode, "%s\n", linebuf);
595*219b2ee8SDavid du Colombier 			fflush(ipc->r1.fcode);
596*219b2ee8SDavid du Colombier 			break;
597*219b2ee8SDavid du Colombier 		case XCOM:
598*219b2ee8SDavid du Colombier 			p1 = linebuf;
599*219b2ee8SDavid du Colombier 			p2 = genbuf;
600*219b2ee8SDavid du Colombier 			while(*p2++ = *p1++);
601*219b2ee8SDavid du Colombier 			p1 = holdsp;
602*219b2ee8SDavid du Colombier 			p2 = linebuf;
603*219b2ee8SDavid du Colombier 			while(*p2++ = *p1++);
604*219b2ee8SDavid du Colombier 			spend = p2 - 1;
605*219b2ee8SDavid du Colombier 			p1 = genbuf;
606*219b2ee8SDavid du Colombier 			p2 = holdsp;
607*219b2ee8SDavid du Colombier 			while(*p2++ = *p1++);
608*219b2ee8SDavid du Colombier 			hspend = p2 - 1;
609*219b2ee8SDavid du Colombier 			break;
610*219b2ee8SDavid du Colombier 
611*219b2ee8SDavid du Colombier 		case YCOM:
612*219b2ee8SDavid du Colombier 			p1 = linebuf;
613*219b2ee8SDavid du Colombier 			p2 = ipc->r1.re1;
614*219b2ee8SDavid du Colombier 			while(*p1 = p2[*p1])	p1++;
615*219b2ee8SDavid du Colombier 			break;
616*219b2ee8SDavid du Colombier 	}
617*219b2ee8SDavid du Colombier 
618*219b2ee8SDavid du Colombier }
619*219b2ee8SDavid du Colombier 
620*219b2ee8SDavid du Colombier uchar *
gline(uchar * addr)621*219b2ee8SDavid du Colombier gline(uchar *addr)
622*219b2ee8SDavid du Colombier {
623*219b2ee8SDavid du Colombier 	uchar	*p1, *p2;
624*219b2ee8SDavid du Colombier 	int	c;
625*219b2ee8SDavid du Colombier 	sflag = 0;
626*219b2ee8SDavid du Colombier 	p1 = addr;
627*219b2ee8SDavid du Colombier 	p2 = cbp;
628*219b2ee8SDavid du Colombier 	for (;;) {
629*219b2ee8SDavid du Colombier 		if (p2 >= ebp) {
630*219b2ee8SDavid du Colombier 			if ((c = Read(f, ibuf, 512)) <= 0) {
631*219b2ee8SDavid du Colombier 				return(badp);
632*219b2ee8SDavid du Colombier 			}
633*219b2ee8SDavid du Colombier 			p2 = ibuf;
634*219b2ee8SDavid du Colombier 			ebp = ibuf+c;
635*219b2ee8SDavid du Colombier 		}
636*219b2ee8SDavid du Colombier 		if ((c = *p2++) == '\n') {
637*219b2ee8SDavid du Colombier 			if(p2 >=  ebp) {
638*219b2ee8SDavid du Colombier 				if((c = Read(f, ibuf, 512)) <= 0) {
639*219b2ee8SDavid du Colombier 					close(f);
640*219b2ee8SDavid du Colombier 					if(eargc == 0)
641*219b2ee8SDavid du Colombier 							dolflag = 1;
642*219b2ee8SDavid du Colombier 				}
643*219b2ee8SDavid du Colombier 
644*219b2ee8SDavid du Colombier 				p2 = ibuf;
645*219b2ee8SDavid du Colombier 				ebp = ibuf + c;
646*219b2ee8SDavid du Colombier 			}
647*219b2ee8SDavid du Colombier 			break;
648*219b2ee8SDavid du Colombier 		}
649*219b2ee8SDavid du Colombier 		if(c)
650*219b2ee8SDavid du Colombier 		if(p1 < lbend)
651*219b2ee8SDavid du Colombier 			*p1++ = c;
652*219b2ee8SDavid du Colombier 	}
653*219b2ee8SDavid du Colombier 	lnum++;
654*219b2ee8SDavid du Colombier 	*p1 = 0;
655*219b2ee8SDavid du Colombier 	cbp = p2;
656*219b2ee8SDavid du Colombier 
657*219b2ee8SDavid du Colombier 	return(p1);
658*219b2ee8SDavid du Colombier }
659*219b2ee8SDavid du Colombier int
ecmp(uchar * a,uchar * b,int count)660*219b2ee8SDavid du Colombier ecmp(uchar *a, uchar *b, int count)
661*219b2ee8SDavid du Colombier {
662*219b2ee8SDavid du Colombier 	while(count--)
663*219b2ee8SDavid du Colombier 		if(*a++ != *b++)	return(0);
664*219b2ee8SDavid du Colombier 	return(1);
665*219b2ee8SDavid du Colombier }
666*219b2ee8SDavid du Colombier 
667*219b2ee8SDavid du Colombier void
arout(void)668*219b2ee8SDavid du Colombier arout(void)
669*219b2ee8SDavid du Colombier {
670*219b2ee8SDavid du Colombier 	uchar	*p1;
671*219b2ee8SDavid du Colombier 	FILE	*fi;
672*219b2ee8SDavid du Colombier 	uchar	c;
673*219b2ee8SDavid du Colombier 	int	t;
674*219b2ee8SDavid du Colombier 
675*219b2ee8SDavid du Colombier 	aptr = abuf - 1;
676*219b2ee8SDavid du Colombier 	while(*++aptr) {
677*219b2ee8SDavid du Colombier 		if((*aptr)->r1.command == ACOM) {
678*219b2ee8SDavid du Colombier 			for(p1 = (*aptr)->r1.re1; *p1; )
679*219b2ee8SDavid du Colombier 				putc(*p1++, stdout);
680*219b2ee8SDavid du Colombier 			putc('\n', stdout);
681*219b2ee8SDavid du Colombier 		} else {
682*219b2ee8SDavid du Colombier 			if((fi = fopen((char*)((*aptr)->r1.re1), "r")) == NULL)
683*219b2ee8SDavid du Colombier 				continue;
684*219b2ee8SDavid du Colombier 			while((t = getc(fi)) != EOF) {
685*219b2ee8SDavid du Colombier 				c = t;
686*219b2ee8SDavid du Colombier 				putc(c, stdout);
687*219b2ee8SDavid du Colombier 			}
688*219b2ee8SDavid du Colombier 			fclose(fi);
689*219b2ee8SDavid du Colombier 		}
690*219b2ee8SDavid du Colombier 	}
691*219b2ee8SDavid du Colombier 	aptr = abuf;
692*219b2ee8SDavid du Colombier 	*aptr = 0;
693*219b2ee8SDavid du Colombier }
694*219b2ee8SDavid du Colombier 
695*219b2ee8SDavid du Colombier uchar *
lformat(int c,uchar * p)696*219b2ee8SDavid du Colombier lformat(int c, uchar *p)
697*219b2ee8SDavid du Colombier {
698*219b2ee8SDavid du Colombier 	int trans =
699*219b2ee8SDavid du Colombier 		c=='\b'? 'b':
700*219b2ee8SDavid du Colombier 		c=='\t'? 't':
701*219b2ee8SDavid du Colombier 		c=='\n'? 'n':
702*219b2ee8SDavid du Colombier 		c=='\v'? 'v':
703*219b2ee8SDavid du Colombier 		c=='\f'? 'f':
704*219b2ee8SDavid du Colombier 		c=='\r'? 'r':
705*219b2ee8SDavid du Colombier 		c=='\\'? '\\':
706*219b2ee8SDavid du Colombier 		0;
707*219b2ee8SDavid du Colombier 	if(trans) {
708*219b2ee8SDavid du Colombier 		*p++ = '\\';
709*219b2ee8SDavid du Colombier 		*p++ = trans;
710*219b2ee8SDavid du Colombier 	} else if(c<040 || c>=0177) {
711*219b2ee8SDavid du Colombier 		*p++ = '\\';
712*219b2ee8SDavid du Colombier 		*p++ = ((c>>6)&07) + '0';
713*219b2ee8SDavid du Colombier 		*p++ = ((c>>3)&07) + '0';
714*219b2ee8SDavid du Colombier 		*p++ = (c&07) + '0';
715*219b2ee8SDavid du Colombier 	} else
716*219b2ee8SDavid du Colombier 		*p++ = c;
717*219b2ee8SDavid du Colombier 	return p;
718*219b2ee8SDavid du Colombier }
719*219b2ee8SDavid du Colombier 
720