xref: /onnv-gate/usr/src/ucbcmd/sed/sed1.c (revision 640:acd8cb5618b4)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*640Sbasabi /*
23*640Sbasabi  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*640Sbasabi  * Use is subject to license terms.
25*640Sbasabi  */
26*640Sbasabi 
270Sstevel@tonic-gate /*	Copyright (c) 1984 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
31*640Sbasabi #pragma ident	"%Z%%M%	%I%	%E% SMI"
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <stdio.h>
340Sstevel@tonic-gate #include <sys/types.h>
350Sstevel@tonic-gate #include <sys/stat.h>
360Sstevel@tonic-gate #include <fcntl.h>
370Sstevel@tonic-gate #include "sed.h"
380Sstevel@tonic-gate #include <regexp.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate union reptr     *abuf[ABUFSIZE+1];
410Sstevel@tonic-gate union reptr **aptr;
420Sstevel@tonic-gate char    ibuf[BUFSIZ];
430Sstevel@tonic-gate char    *cbp;
440Sstevel@tonic-gate char    *ebp;
450Sstevel@tonic-gate char    genbuf[LBSIZE+1];
460Sstevel@tonic-gate char	*lcomend;
470Sstevel@tonic-gate int     dolflag;
480Sstevel@tonic-gate int     sflag;
490Sstevel@tonic-gate int     jflag;
500Sstevel@tonic-gate int     delflag;
510Sstevel@tonic-gate long long lnum;
520Sstevel@tonic-gate char    holdsp[LBSIZE+1];
530Sstevel@tonic-gate char    *spend;
540Sstevel@tonic-gate char    *hspend;
550Sstevel@tonic-gate int     nflag;
560Sstevel@tonic-gate long long tlno[NLINES];
570Sstevel@tonic-gate int     f;
580Sstevel@tonic-gate char	*ifname;
590Sstevel@tonic-gate int	numpass;
600Sstevel@tonic-gate union reptr     *pending;
610Sstevel@tonic-gate char	*trans[040]  = {
620Sstevel@tonic-gate 	"\\01",
630Sstevel@tonic-gate 	"\\02",
640Sstevel@tonic-gate 	"\\03",
650Sstevel@tonic-gate 	"\\04",
660Sstevel@tonic-gate 	"\\05",
670Sstevel@tonic-gate 	"\\06",
680Sstevel@tonic-gate 	"\\07",
690Sstevel@tonic-gate 	"-<",
700Sstevel@tonic-gate 	"->",
710Sstevel@tonic-gate 	"\n",
720Sstevel@tonic-gate 	"\\13",
730Sstevel@tonic-gate 	"\\14",
740Sstevel@tonic-gate 	"\\15",
750Sstevel@tonic-gate 	"\\16",
760Sstevel@tonic-gate 	"\\17",
770Sstevel@tonic-gate 	"\\20",
780Sstevel@tonic-gate 	"\\21",
790Sstevel@tonic-gate 	"\\22",
800Sstevel@tonic-gate 	"\\23",
810Sstevel@tonic-gate 	"\\24",
820Sstevel@tonic-gate 	"\\25",
830Sstevel@tonic-gate 	"\\26",
840Sstevel@tonic-gate 	"\\27",
850Sstevel@tonic-gate 	"\\30",
860Sstevel@tonic-gate 	"\\31",
870Sstevel@tonic-gate 	"\\32",
880Sstevel@tonic-gate 	"\\33",
890Sstevel@tonic-gate 	"\\34",
900Sstevel@tonic-gate 	"\\35",
910Sstevel@tonic-gate 	"\\36",
920Sstevel@tonic-gate 	"\\37"
930Sstevel@tonic-gate };
940Sstevel@tonic-gate char	rub[] = {"\\177"};
950Sstevel@tonic-gate 
960Sstevel@tonic-gate extern char TMMES[];
970Sstevel@tonic-gate 
98*640Sbasabi static int match(char *expbuf, int gf);
99*640Sbasabi static int substitute(union reptr *ipc);
100*640Sbasabi static void dosub(char *rhsbuf, int n);
101*640Sbasabi static void command(union reptr *ipc);
102*640Sbasabi static void arout(void);
103*640Sbasabi 
104*640Sbasabi void
execute(char * file)105*640Sbasabi execute(char *file)
1060Sstevel@tonic-gate {
107*640Sbasabi 	char *p1, *p2;
108*640Sbasabi 	union reptr	*ipc;
1090Sstevel@tonic-gate 	int	c;
1100Sstevel@tonic-gate 	char	*execp;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	if (file) {
1130Sstevel@tonic-gate 		if ((f = open(file, 0)) < 0) {
1140Sstevel@tonic-gate 			(void) fprintf(stderr, "sed: ");
1150Sstevel@tonic-gate 			perror(file);
1160Sstevel@tonic-gate 		}
1170Sstevel@tonic-gate 		ifname = file;
1180Sstevel@tonic-gate 	} else {
1190Sstevel@tonic-gate 		f = 0;
1200Sstevel@tonic-gate 		ifname = "standard input";
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	ebp = ibuf;
1240Sstevel@tonic-gate 	cbp = ibuf;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 	if(pending) {
1270Sstevel@tonic-gate 		ipc = pending;
1280Sstevel@tonic-gate 		pending = 0;
1290Sstevel@tonic-gate 		goto yes;
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	for(;;) {
1330Sstevel@tonic-gate 		if((execp = gline(linebuf)) == 0) {
1340Sstevel@tonic-gate 			(void) close(f);
1350Sstevel@tonic-gate 			return;
1360Sstevel@tonic-gate 		}
1370Sstevel@tonic-gate 		spend = execp;
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate 		for(ipc = ptrspace; ipc->r1.command; ) {
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 			p1 = ipc->r1.ad1;
1420Sstevel@tonic-gate 			p2 = ipc->r1.ad2;
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate 			if(p1) {
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate 				if(ipc->r1.inar) {
1470Sstevel@tonic-gate 					if(*p2 == CEND) {
1480Sstevel@tonic-gate 						p1 = 0;
1490Sstevel@tonic-gate 					} else if(*p2 == CLNUM) {
1500Sstevel@tonic-gate 						c = (unsigned char)p2[1];
1510Sstevel@tonic-gate 						if(lnum > tlno[c]) {
1520Sstevel@tonic-gate 							ipc->r1.inar = 0;
1530Sstevel@tonic-gate 							if(ipc->r1.negfl)
1540Sstevel@tonic-gate 								goto yes;
1550Sstevel@tonic-gate 							ipc++;
1560Sstevel@tonic-gate 							continue;
1570Sstevel@tonic-gate 						}
1580Sstevel@tonic-gate 						if(lnum == tlno[c]) {
1590Sstevel@tonic-gate 							ipc->r1.inar = 0;
1600Sstevel@tonic-gate 						}
1610Sstevel@tonic-gate 					} else if(match(p2, 0)) {
1620Sstevel@tonic-gate 						ipc->r1.inar = 0;
1630Sstevel@tonic-gate 					}
1640Sstevel@tonic-gate 				} else if(*p1 == CEND) {
1650Sstevel@tonic-gate 					if(!dolflag) {
1660Sstevel@tonic-gate 						if(ipc->r1.negfl)
1670Sstevel@tonic-gate 							goto yes;
1680Sstevel@tonic-gate 						ipc++;
1690Sstevel@tonic-gate 						continue;
1700Sstevel@tonic-gate 					}
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 				} else if(*p1 == CLNUM) {
1730Sstevel@tonic-gate 					c = (unsigned char)p1[1];
1740Sstevel@tonic-gate 					if(lnum != tlno[c]) {
1750Sstevel@tonic-gate 						if(ipc->r1.negfl)
1760Sstevel@tonic-gate 							goto yes;
1770Sstevel@tonic-gate 						ipc++;
1780Sstevel@tonic-gate 						continue;
1790Sstevel@tonic-gate 					}
1800Sstevel@tonic-gate 					if(p2)
1810Sstevel@tonic-gate 						ipc->r1.inar = 1;
1820Sstevel@tonic-gate 				} else if(match(p1, 0)) {
1830Sstevel@tonic-gate 					if(p2)
1840Sstevel@tonic-gate 						ipc->r1.inar = 1;
1850Sstevel@tonic-gate 				} else {
1860Sstevel@tonic-gate 					if(ipc->r1.negfl)
1870Sstevel@tonic-gate 						goto yes;
1880Sstevel@tonic-gate 					ipc++;
1890Sstevel@tonic-gate 					continue;
1900Sstevel@tonic-gate 				}
1910Sstevel@tonic-gate 			}
1920Sstevel@tonic-gate 
1930Sstevel@tonic-gate 			if(ipc->r1.negfl) {
1940Sstevel@tonic-gate 				ipc++;
1950Sstevel@tonic-gate 				continue;
1960Sstevel@tonic-gate 			}
1970Sstevel@tonic-gate 	yes:
1980Sstevel@tonic-gate 			command(ipc);
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 			if(delflag)
2010Sstevel@tonic-gate 				break;
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 			if(jflag) {
2040Sstevel@tonic-gate 				jflag = 0;
2050Sstevel@tonic-gate 				if((ipc = ipc->r2.lb1) == 0) {
2060Sstevel@tonic-gate 					ipc = ptrspace;
2070Sstevel@tonic-gate 					break;
2080Sstevel@tonic-gate 				}
2090Sstevel@tonic-gate 			} else
2100Sstevel@tonic-gate 				ipc++;
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate 		}
2130Sstevel@tonic-gate 		if(!nflag && !delflag) {
2140Sstevel@tonic-gate 			for(p1 = linebuf; p1 < spend; p1++)
2150Sstevel@tonic-gate 				(void) putc(*p1, stdout);
2160Sstevel@tonic-gate 			(void) putc('\n', stdout);
2170Sstevel@tonic-gate 		}
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 		if(aptr > abuf) {
2200Sstevel@tonic-gate 			arout();
2210Sstevel@tonic-gate 		}
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 		delflag = 0;
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate 	}
2260Sstevel@tonic-gate }
227*640Sbasabi 
228*640Sbasabi static int
match(char * expbuf,int gf)229*640Sbasabi match(char *expbuf, int gf)
2300Sstevel@tonic-gate {
231*640Sbasabi 	char   *p1;
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate 	if(gf) {
2340Sstevel@tonic-gate 		if(*expbuf)	return(0);
2350Sstevel@tonic-gate 		locs = p1 = loc2;
2360Sstevel@tonic-gate 	} else {
2370Sstevel@tonic-gate 		p1 = linebuf;
2380Sstevel@tonic-gate 		locs = 0;
2390Sstevel@tonic-gate 	}
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 	circf = *expbuf++;
2420Sstevel@tonic-gate 	return(step(p1, expbuf));
2430Sstevel@tonic-gate }
2440Sstevel@tonic-gate 
245*640Sbasabi static int
substitute(union reptr * ipc)246*640Sbasabi substitute(union reptr *ipc)
2470Sstevel@tonic-gate {
2480Sstevel@tonic-gate 	if(match(ipc->r1.re1, 0) == 0)	return(0);
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate 	numpass = 0;
2510Sstevel@tonic-gate 	sflag = 0;		/* Flags if any substitution was made */
2520Sstevel@tonic-gate 	dosub(ipc->r1.rhs, ipc->r1.gfl);
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	if(ipc->r1.gfl) {
2550Sstevel@tonic-gate 		while(*loc2) {
2560Sstevel@tonic-gate 			if(match(ipc->r1.re1, 1) == 0) break;
2570Sstevel@tonic-gate 			dosub(ipc->r1.rhs, ipc->r1.gfl);
2580Sstevel@tonic-gate 		}
2590Sstevel@tonic-gate 	}
2600Sstevel@tonic-gate 	return(sflag);
2610Sstevel@tonic-gate }
2620Sstevel@tonic-gate 
263*640Sbasabi static void
dosub(char * rhsbuf,int n)264*640Sbasabi dosub(char *rhsbuf, int n)
2650Sstevel@tonic-gate {
266*640Sbasabi 	char *lp, *sp, *rp;
2670Sstevel@tonic-gate 	int c;
2680Sstevel@tonic-gate 
2690Sstevel@tonic-gate 	if(n > 0 && n < 999)
2700Sstevel@tonic-gate 		{numpass++;
2710Sstevel@tonic-gate 		if(n != numpass) return;
2720Sstevel@tonic-gate 		}
2730Sstevel@tonic-gate 	sflag = 1;
2740Sstevel@tonic-gate 	lp = linebuf;
2750Sstevel@tonic-gate 	sp = genbuf;
2760Sstevel@tonic-gate 	rp = rhsbuf;
2770Sstevel@tonic-gate 	while (lp < loc1)
2780Sstevel@tonic-gate 		*sp++ = *lp++;
2790Sstevel@tonic-gate 	while(c = *rp++) {
2800Sstevel@tonic-gate 		if (c == '&')
2810Sstevel@tonic-gate 			sp = place(sp, loc1, loc2);
2820Sstevel@tonic-gate 		else if (c == '\\') {
2830Sstevel@tonic-gate 			c = *rp++;
2840Sstevel@tonic-gate 			if (c >= '1' && c < NBRA+'1')
2850Sstevel@tonic-gate 				sp = place(sp, braslist[c-'1'], braelist[c-'1']);
2860Sstevel@tonic-gate 			else
2870Sstevel@tonic-gate 				*sp++ = c;
2880Sstevel@tonic-gate   		} else
2890Sstevel@tonic-gate 			*sp++ = c;
2900Sstevel@tonic-gate 		if (sp == &genbuf[LBSIZE+1]) {
2910Sstevel@tonic-gate 			(void) fprintf(stderr, "Output line too long.\n");
2920Sstevel@tonic-gate 			*--sp = '\0';
2930Sstevel@tonic-gate 			goto out;
2940Sstevel@tonic-gate 		}
2950Sstevel@tonic-gate 	}
2960Sstevel@tonic-gate 	lp = loc2;
2970Sstevel@tonic-gate 	loc2 = sp - genbuf + linebuf;
2980Sstevel@tonic-gate 	while(*sp++ = *lp++)
2990Sstevel@tonic-gate 		if (sp == &genbuf[LBSIZE+1]) {
3000Sstevel@tonic-gate 			(void) fprintf(stderr, "Output line too long.\n");
3010Sstevel@tonic-gate 			*--sp = '\0';
3020Sstevel@tonic-gate 			break;
3030Sstevel@tonic-gate 		}
3040Sstevel@tonic-gate out:
3050Sstevel@tonic-gate 	lp = linebuf;
3060Sstevel@tonic-gate 	sp = genbuf;
3070Sstevel@tonic-gate 	while (*lp++ = *sp++);
3080Sstevel@tonic-gate 	spend = lp-1;
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate 
place(asp,al1,al2)3110Sstevel@tonic-gate char	*place(asp, al1, al2)
3120Sstevel@tonic-gate char	*asp, *al1, *al2;
3130Sstevel@tonic-gate {
314*640Sbasabi 	char *sp, *l1, *l2;
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate 	sp = asp;
3170Sstevel@tonic-gate 	l1 = al1;
3180Sstevel@tonic-gate 	l2 = al2;
3190Sstevel@tonic-gate 	while (l1 < l2) {
3200Sstevel@tonic-gate 		*sp++ = *l1++;
3210Sstevel@tonic-gate 		if (sp == &genbuf[LBSIZE+1])
3220Sstevel@tonic-gate 			break;
3230Sstevel@tonic-gate 	}
3240Sstevel@tonic-gate 	return(sp);
3250Sstevel@tonic-gate }
3260Sstevel@tonic-gate 
327*640Sbasabi static void
command(union reptr * ipc)328*640Sbasabi command(union reptr *ipc)
3290Sstevel@tonic-gate {
330*640Sbasabi 	int	i;
331*640Sbasabi 	char   *p1, *p2, *p3;
3320Sstevel@tonic-gate 	char	*execp;
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate 	switch(ipc->r1.command) {
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate 		case ACOM:
3380Sstevel@tonic-gate 			if(aptr >= &abuf[ABUFSIZE]) {
3390Sstevel@tonic-gate 				(void) fprintf(stderr, "Too many appends or reads after line %lld\n",
3400Sstevel@tonic-gate 					lnum);
3410Sstevel@tonic-gate 			} else {
3420Sstevel@tonic-gate 				*aptr++ = ipc;
3430Sstevel@tonic-gate 				*aptr = 0;
3440Sstevel@tonic-gate 			}
3450Sstevel@tonic-gate 			break;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 		case CCOM:
3480Sstevel@tonic-gate 			delflag = 1;
3490Sstevel@tonic-gate 			if(!ipc->r1.inar || dolflag) {
3500Sstevel@tonic-gate 				for(p1 = ipc->r1.re1; *p1; )
3510Sstevel@tonic-gate 					(void) putc(*p1++, stdout);
3520Sstevel@tonic-gate 				(void) putc('\n', stdout);
3530Sstevel@tonic-gate 			}
3540Sstevel@tonic-gate 			break;
3550Sstevel@tonic-gate 		case DCOM:
3560Sstevel@tonic-gate 			delflag++;
3570Sstevel@tonic-gate 			break;
3580Sstevel@tonic-gate 		case CDCOM:
3590Sstevel@tonic-gate 			p1 = p2 = linebuf;
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 			while(*p1 != '\n') {
3620Sstevel@tonic-gate 				if(*p1++ == 0) {
3630Sstevel@tonic-gate 					delflag++;
3640Sstevel@tonic-gate 					return;
3650Sstevel@tonic-gate 				}
3660Sstevel@tonic-gate 			}
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 			p1++;
3690Sstevel@tonic-gate 			while(*p2++ = *p1++);
3700Sstevel@tonic-gate 			spend = p2-1;
3710Sstevel@tonic-gate 			jflag++;
3720Sstevel@tonic-gate 			break;
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 		case EQCOM:
3750Sstevel@tonic-gate 			(void) fprintf(stdout, "%lld\n", lnum);
3760Sstevel@tonic-gate 			break;
3770Sstevel@tonic-gate 
3780Sstevel@tonic-gate 		case GCOM:
3790Sstevel@tonic-gate 			p1 = linebuf;
3800Sstevel@tonic-gate 			p2 = holdsp;
3810Sstevel@tonic-gate 			while(*p1++ = *p2++);
3820Sstevel@tonic-gate 			spend = p1-1;
3830Sstevel@tonic-gate 			break;
3840Sstevel@tonic-gate 
3850Sstevel@tonic-gate 		case CGCOM:
3860Sstevel@tonic-gate 			*spend++ = '\n';
3870Sstevel@tonic-gate 			p1 = spend;
3880Sstevel@tonic-gate 			p2 = holdsp;
3890Sstevel@tonic-gate 			do {
3900Sstevel@tonic-gate 				if (p1 == &linebuf[LBSIZE+1]) {
3910Sstevel@tonic-gate 					(void) fprintf(stderr, "Output line too long.\n");
3920Sstevel@tonic-gate 					*--p1 = '\0';
3930Sstevel@tonic-gate 				}
3940Sstevel@tonic-gate 			} while(*p1++ = *p2++);
3950Sstevel@tonic-gate 			spend = p1-1;
3960Sstevel@tonic-gate 			break;
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 		case HCOM:
3990Sstevel@tonic-gate 			p1 = holdsp;
4000Sstevel@tonic-gate 			p2 = linebuf;
4010Sstevel@tonic-gate 			while(*p1++ = *p2++);
4020Sstevel@tonic-gate 			hspend = p1-1;
4030Sstevel@tonic-gate 			break;
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate 		case CHCOM:
4060Sstevel@tonic-gate 			*hspend++ = '\n';
4070Sstevel@tonic-gate 			p1 = hspend;
4080Sstevel@tonic-gate 			p2 = linebuf;
4090Sstevel@tonic-gate 			do {
4100Sstevel@tonic-gate 				if (p1 == &holdsp[LBSIZE+1]) {
4110Sstevel@tonic-gate 					(void) fprintf(stderr, "Hold space overflowed.\n");
4120Sstevel@tonic-gate 					*--p1 = '\0';
4130Sstevel@tonic-gate 				}
4140Sstevel@tonic-gate 			} while(*p1++ = *p2++);
4150Sstevel@tonic-gate 			hspend = p1-1;
4160Sstevel@tonic-gate 			break;
4170Sstevel@tonic-gate 
4180Sstevel@tonic-gate 		case ICOM:
4190Sstevel@tonic-gate 			for(p1 = ipc->r1.re1; *p1; )
4200Sstevel@tonic-gate 				(void) putc(*p1++, stdout);
4210Sstevel@tonic-gate 			(void) putc('\n', stdout);
4220Sstevel@tonic-gate 			break;
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 		case BCOM:
4250Sstevel@tonic-gate 			jflag = 1;
4260Sstevel@tonic-gate 			break;
4270Sstevel@tonic-gate 
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 		case LCOM:
4300Sstevel@tonic-gate 			p1 = linebuf;
4310Sstevel@tonic-gate 			p2 = genbuf;
4320Sstevel@tonic-gate 			genbuf[72] = 0;
4330Sstevel@tonic-gate 			while(*p1)
4340Sstevel@tonic-gate 				if((unsigned char)*p1 >= 040) {
4350Sstevel@tonic-gate 					if(*p1 == 0177) {
4360Sstevel@tonic-gate 						p3 = rub;
4370Sstevel@tonic-gate 						while(*p2++ = *p3++)
4380Sstevel@tonic-gate 							if(p2 >= lcomend) {
4390Sstevel@tonic-gate 								*p2 = '\\';
4400Sstevel@tonic-gate 								(void) fprintf(stdout, "%s\n", genbuf);
4410Sstevel@tonic-gate 								p2 = genbuf;
4420Sstevel@tonic-gate 							}
4430Sstevel@tonic-gate 						p2--;
4440Sstevel@tonic-gate 						p1++;
4450Sstevel@tonic-gate 						continue;
4460Sstevel@tonic-gate 					}
4470Sstevel@tonic-gate 					if(!isprint(*p1 & 0377)) {
4480Sstevel@tonic-gate 						*p2++ = '\\';
4490Sstevel@tonic-gate 						if(p2 >= lcomend) {
4500Sstevel@tonic-gate 							*p2 = '\\';
4510Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4520Sstevel@tonic-gate 							p2 = genbuf;
4530Sstevel@tonic-gate 						}
4540Sstevel@tonic-gate 						*p2++ = (*p1 >> 6) + '0';
4550Sstevel@tonic-gate 						if(p2 >= lcomend) {
4560Sstevel@tonic-gate 							*p2 = '\\';
4570Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4580Sstevel@tonic-gate 							p2 = genbuf;
4590Sstevel@tonic-gate 						}
4600Sstevel@tonic-gate 						*p2++ = ((*p1 >> 3) & 07) + '0';
4610Sstevel@tonic-gate 						if(p2 >= lcomend) {
4620Sstevel@tonic-gate 							*p2 = '\\';
4630Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4640Sstevel@tonic-gate 							p2 = genbuf;
4650Sstevel@tonic-gate 						}
4660Sstevel@tonic-gate 						*p2++ = (*p1++ & 07) + '0';
4670Sstevel@tonic-gate 						if(p2 >= lcomend) {
4680Sstevel@tonic-gate 							*p2 = '\\';
4690Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4700Sstevel@tonic-gate 							p2 = genbuf;
4710Sstevel@tonic-gate 						}
4720Sstevel@tonic-gate 					} else {
4730Sstevel@tonic-gate 						*p2++ = *p1++;
4740Sstevel@tonic-gate 						if(p2 >= lcomend) {
4750Sstevel@tonic-gate 							*p2 = '\\';
4760Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4770Sstevel@tonic-gate 							p2 = genbuf;
4780Sstevel@tonic-gate 						}
4790Sstevel@tonic-gate 					}
4800Sstevel@tonic-gate 				} else {
4810Sstevel@tonic-gate 					p3 = trans[(unsigned char)*p1-1];
4820Sstevel@tonic-gate 					while(*p2++ = *p3++)
4830Sstevel@tonic-gate 						if(p2 >= lcomend) {
4840Sstevel@tonic-gate 							*p2 = '\\';
4850Sstevel@tonic-gate 							(void) fprintf(stdout, "%s\n", genbuf);
4860Sstevel@tonic-gate 							p2 = genbuf;
4870Sstevel@tonic-gate 						}
4880Sstevel@tonic-gate 					p2--;
4890Sstevel@tonic-gate 					p1++;
4900Sstevel@tonic-gate 				}
4910Sstevel@tonic-gate 			*p2 = 0;
4920Sstevel@tonic-gate 			(void) fprintf(stdout, "%s\n", genbuf);
4930Sstevel@tonic-gate 			break;
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate 		case NCOM:
4960Sstevel@tonic-gate 			if(!nflag) {
4970Sstevel@tonic-gate 				for(p1 = linebuf; p1 < spend; p1++)
4980Sstevel@tonic-gate 					(void) putc(*p1, stdout);
4990Sstevel@tonic-gate 				(void) putc('\n', stdout);
5000Sstevel@tonic-gate 			}
5010Sstevel@tonic-gate 
5020Sstevel@tonic-gate 			if(aptr > abuf)
5030Sstevel@tonic-gate 				arout();
5040Sstevel@tonic-gate 			if((execp = gline(linebuf)) == 0) {
5050Sstevel@tonic-gate 				pending = ipc;
5060Sstevel@tonic-gate 				delflag = 1;
5070Sstevel@tonic-gate 				break;
5080Sstevel@tonic-gate 			}
5090Sstevel@tonic-gate 			spend = execp;
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate 			break;
5120Sstevel@tonic-gate 		case CNCOM:
5130Sstevel@tonic-gate 			if(aptr > abuf)
5140Sstevel@tonic-gate 				arout();
5150Sstevel@tonic-gate 			*spend++ = '\n';
5160Sstevel@tonic-gate 			if((execp = gline(spend)) == 0) {
5170Sstevel@tonic-gate 				pending = ipc;
5180Sstevel@tonic-gate 				delflag = 1;
5190Sstevel@tonic-gate 				break;
5200Sstevel@tonic-gate 			}
5210Sstevel@tonic-gate 			spend = execp;
5220Sstevel@tonic-gate 			break;
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 		case PCOM:
5250Sstevel@tonic-gate 			for(p1 = linebuf; p1 < spend; p1++)
5260Sstevel@tonic-gate 				(void) putc(*p1, stdout);
5270Sstevel@tonic-gate 			(void) putc('\n', stdout);
5280Sstevel@tonic-gate 			break;
5290Sstevel@tonic-gate 		case CPCOM:
5300Sstevel@tonic-gate 	cpcom:
5310Sstevel@tonic-gate 			for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
5320Sstevel@tonic-gate 				(void) putc(*p1++, stdout);
5330Sstevel@tonic-gate 			(void) putc('\n', stdout);
5340Sstevel@tonic-gate 			break;
5350Sstevel@tonic-gate 
5360Sstevel@tonic-gate 		case QCOM:
5370Sstevel@tonic-gate 			if(!nflag) {
5380Sstevel@tonic-gate 				for(p1 = linebuf; p1 < spend; p1++)
5390Sstevel@tonic-gate 					(void) putc(*p1, stdout);
5400Sstevel@tonic-gate 				(void) putc('\n', stdout);
5410Sstevel@tonic-gate 			}
5420Sstevel@tonic-gate 			if(aptr > abuf) arout();
5430Sstevel@tonic-gate 			(void) fclose(stdout);
5440Sstevel@tonic-gate 			exit(0);
5450Sstevel@tonic-gate 		case RCOM:
5460Sstevel@tonic-gate 			if(aptr >= &abuf[ABUFSIZE]) {
5470Sstevel@tonic-gate 				(void) fprintf(stderr, "Too many appends or reads after line %lld\n",
5480Sstevel@tonic-gate 					lnum);
5490Sstevel@tonic-gate 			} else {
5500Sstevel@tonic-gate 				*aptr++ = ipc;
5510Sstevel@tonic-gate 				*aptr = 0;
5520Sstevel@tonic-gate 			}
5530Sstevel@tonic-gate 			break;
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate 		case SCOM:
5560Sstevel@tonic-gate 			i = substitute(ipc);
5570Sstevel@tonic-gate 			if(ipc->r1.pfl && nflag && i)
5580Sstevel@tonic-gate 				if(ipc->r1.pfl == 1) {
5590Sstevel@tonic-gate 					for(p1 = linebuf; p1 < spend; p1++)
5600Sstevel@tonic-gate 						(void) putc(*p1, stdout);
5610Sstevel@tonic-gate 					(void) putc('\n', stdout);
5620Sstevel@tonic-gate 				}
5630Sstevel@tonic-gate 				else
5640Sstevel@tonic-gate 					goto cpcom;
5650Sstevel@tonic-gate 			if(i && ipc->r1.fcode)
5660Sstevel@tonic-gate 				goto wcom;
5670Sstevel@tonic-gate 			break;
5680Sstevel@tonic-gate 
5690Sstevel@tonic-gate 		case TCOM:
5700Sstevel@tonic-gate 			if(sflag == 0)  break;
5710Sstevel@tonic-gate 			sflag = 0;
5720Sstevel@tonic-gate 			jflag = 1;
5730Sstevel@tonic-gate 			break;
5740Sstevel@tonic-gate 
5750Sstevel@tonic-gate 		wcom:
5760Sstevel@tonic-gate 		case WCOM:
5770Sstevel@tonic-gate 			(void) fprintf(ipc->r1.fcode, "%s\n", linebuf);
5780Sstevel@tonic-gate 			(void) fflush(ipc->r1.fcode);
5790Sstevel@tonic-gate 			break;
5800Sstevel@tonic-gate 		case XCOM:
5810Sstevel@tonic-gate 			p1 = linebuf;
5820Sstevel@tonic-gate 			p2 = genbuf;
5830Sstevel@tonic-gate 			while(*p2++ = *p1++);
5840Sstevel@tonic-gate 			p1 = holdsp;
5850Sstevel@tonic-gate 			p2 = linebuf;
5860Sstevel@tonic-gate 			while(*p2++ = *p1++);
5870Sstevel@tonic-gate 			spend = p2 - 1;
5880Sstevel@tonic-gate 			p1 = genbuf;
5890Sstevel@tonic-gate 			p2 = holdsp;
5900Sstevel@tonic-gate 			while(*p2++ = *p1++);
5910Sstevel@tonic-gate 			hspend = p2 - 1;
5920Sstevel@tonic-gate 			break;
5930Sstevel@tonic-gate 
5940Sstevel@tonic-gate 		case YCOM:
5950Sstevel@tonic-gate 			p1 = linebuf;
5960Sstevel@tonic-gate 			p2 = ipc->r1.re1;
5970Sstevel@tonic-gate 			while(*p1 = p2[(unsigned char)*p1])	p1++;
5980Sstevel@tonic-gate 			break;
5990Sstevel@tonic-gate 	}
6000Sstevel@tonic-gate 
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate 
gline(addr)6030Sstevel@tonic-gate char	*gline(addr)
6040Sstevel@tonic-gate char	*addr;
6050Sstevel@tonic-gate {
606*640Sbasabi 	char   *p1, *p2;
607*640Sbasabi 	int	c;
6080Sstevel@tonic-gate 	sflag = 0;
6090Sstevel@tonic-gate 	p1 = addr;
6100Sstevel@tonic-gate 	p2 = cbp;
6110Sstevel@tonic-gate 	for (;;) {
6120Sstevel@tonic-gate 		if (p2 >= ebp) {
6130Sstevel@tonic-gate 			if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) {
6140Sstevel@tonic-gate 				return(0);
6150Sstevel@tonic-gate 			}
6160Sstevel@tonic-gate 			if(c < 0) {
6170Sstevel@tonic-gate 				(void) fprintf(stderr, "sed: error reading ");
6180Sstevel@tonic-gate 				perror(ifname);
6190Sstevel@tonic-gate 				exit(2);
6200Sstevel@tonic-gate 			}
6210Sstevel@tonic-gate 			p2 = ibuf;
6220Sstevel@tonic-gate 			ebp = ibuf+c;
6230Sstevel@tonic-gate 		}
6240Sstevel@tonic-gate 		if ((c = *p2++) == '\n') {
6250Sstevel@tonic-gate 			if(p2 >=  ebp) {
6260Sstevel@tonic-gate 				if(f < 0 || (c = read(f, ibuf, BUFSIZ)) == 0) {
6270Sstevel@tonic-gate 					if(f >= 0) {
6280Sstevel@tonic-gate 						(void) close(f);
6290Sstevel@tonic-gate 						f = -1;
6300Sstevel@tonic-gate 					}
6310Sstevel@tonic-gate 					if(eargc == 0)
6320Sstevel@tonic-gate 							dolflag = 1;
6330Sstevel@tonic-gate 				}
6340Sstevel@tonic-gate 				if(c < 0) {
6350Sstevel@tonic-gate 					(void) fprintf(stderr, "sed: error reading ");
6360Sstevel@tonic-gate 					perror(ifname);
6370Sstevel@tonic-gate 					exit(2);
6380Sstevel@tonic-gate 				}
6390Sstevel@tonic-gate 
6400Sstevel@tonic-gate 				p2 = ibuf;
6410Sstevel@tonic-gate 				ebp = ibuf + c;
6420Sstevel@tonic-gate 			}
6430Sstevel@tonic-gate 			break;
6440Sstevel@tonic-gate 		}
6450Sstevel@tonic-gate 		if(c)
6460Sstevel@tonic-gate 		if(p1 < &linebuf[LBSIZE])
6470Sstevel@tonic-gate 			*p1++ = c;
6480Sstevel@tonic-gate 	}
6490Sstevel@tonic-gate 	lnum++;
6500Sstevel@tonic-gate 	*p1 = 0;
6510Sstevel@tonic-gate 	cbp = p2;
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 	return(p1);
6540Sstevel@tonic-gate }
6550Sstevel@tonic-gate 
comple(x1,ep,x3,x4)6560Sstevel@tonic-gate char *comple(x1, ep, x3, x4)
6570Sstevel@tonic-gate char *x1, *x3;
6580Sstevel@tonic-gate char x4;
659*640Sbasabi char *ep;
6600Sstevel@tonic-gate {
661*640Sbasabi 	char *p;
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	p = compile(x1, ep + 1, x3, x4);
6640Sstevel@tonic-gate 	if(p == ep + 1)
6650Sstevel@tonic-gate 		return(ep);
6660Sstevel@tonic-gate 	*ep = circf;
6670Sstevel@tonic-gate 	return(p);
6680Sstevel@tonic-gate }
6690Sstevel@tonic-gate 
670*640Sbasabi int
regerr(int err)671*640Sbasabi regerr(int err)
6720Sstevel@tonic-gate {
6730Sstevel@tonic-gate 	switch(err) {
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate 	case 11:
6760Sstevel@tonic-gate 		comperr("Range endpoint too large: %s");
6770Sstevel@tonic-gate 		break;
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 	case 16:
6800Sstevel@tonic-gate 		comperr("Bad number: %s");
6810Sstevel@tonic-gate 		break;
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 	case 25:
6840Sstevel@tonic-gate 		comperr("``\\digit'' out of range: %s");
6850Sstevel@tonic-gate 		break;
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate 	case 36:
6880Sstevel@tonic-gate 		comperr("Illegal or missing delimiter: %s");
6890Sstevel@tonic-gate 		break;
6900Sstevel@tonic-gate 
6910Sstevel@tonic-gate 	case 41:
6920Sstevel@tonic-gate 		comperr("No remembered search string: %s");
6930Sstevel@tonic-gate 		break;
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	case 42:
6960Sstevel@tonic-gate 		comperr("\\( \\) imbalance: %s");
6970Sstevel@tonic-gate 		break;
6980Sstevel@tonic-gate 
6990Sstevel@tonic-gate 	case 43:
7000Sstevel@tonic-gate 		comperr("Too many \\(: %s");
7010Sstevel@tonic-gate 		break;
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 	case 44:
7040Sstevel@tonic-gate 		comperr("More than 2 numbers given in \\{ \\}: %s");
7050Sstevel@tonic-gate 		break;
7060Sstevel@tonic-gate 
7070Sstevel@tonic-gate 	case 45:
7080Sstevel@tonic-gate 		comperr("} expected after \\: %s");
7090Sstevel@tonic-gate 		break;
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 	case 46:
7120Sstevel@tonic-gate 		comperr("First number exceeds second in \\{ \\}: %s");
7130Sstevel@tonic-gate 		break;
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate 	case 49:
7160Sstevel@tonic-gate 		comperr("[ ] imbalance: %s");
7170Sstevel@tonic-gate 		break;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate 	case 50:
7200Sstevel@tonic-gate 		comperr(TMMES);
7210Sstevel@tonic-gate 		break;
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 	default:
7240Sstevel@tonic-gate 		(void) fprintf(stderr, "Unknown regexp error code %d: %s\n",
7250Sstevel@tonic-gate 		    err, linebuf);
7260Sstevel@tonic-gate 		exit(2);
7270Sstevel@tonic-gate 		break;
7280Sstevel@tonic-gate 	}
729*640Sbasabi 	return (0);
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate 
732*640Sbasabi static void
arout(void)733*640Sbasabi arout(void)
7340Sstevel@tonic-gate {
735*640Sbasabi 	char   *p1;
7360Sstevel@tonic-gate 	FILE	*fi;
7370Sstevel@tonic-gate 	char	c;
7380Sstevel@tonic-gate 	int	t;
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 	aptr = abuf - 1;
7410Sstevel@tonic-gate 	while(*++aptr) {
7420Sstevel@tonic-gate 		if((*aptr)->r1.command == ACOM) {
7430Sstevel@tonic-gate 			for(p1 = (*aptr)->r1.re1; *p1; )
7440Sstevel@tonic-gate 				(void) putc(*p1++, stdout);
7450Sstevel@tonic-gate 			(void) putc('\n', stdout);
7460Sstevel@tonic-gate 		} else {
7470Sstevel@tonic-gate 			if((fi = fopen((*aptr)->r1.re1, "r")) == NULL)
7480Sstevel@tonic-gate 				continue;
7490Sstevel@tonic-gate 			while((t = getc(fi)) != EOF) {
7500Sstevel@tonic-gate 				c = t;
7510Sstevel@tonic-gate 				(void) putc(c, stdout);
7520Sstevel@tonic-gate 			}
7530Sstevel@tonic-gate 			(void) fclose(fi);
7540Sstevel@tonic-gate 		}
7550Sstevel@tonic-gate 	}
7560Sstevel@tonic-gate 	aptr = abuf;
7570Sstevel@tonic-gate 	*aptr = 0;
7580Sstevel@tonic-gate }
759