/*
 * sed -- stream  editor
 *
 *
 */
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <regexp.h>

enum {
	DEPTH		= 20,		/* max nesting depth of {} */
	MAXCMDS		= 512,		/* max sed commands */
	ADDSIZE		= 10000,	/* size of add & read buffer */
	MAXADDS		= 20,		/* max pending adds and reads */
	LBSIZE		= 8192,		/* input line size */
	LABSIZE		= 50,		/* max label name size */
	MAXSUB		= 10,		/* max number of sub reg exp */
	MAXFILES	= 120		/* max output files */
};
	/* An address is a line #, a R.E., "$", a reference to the last
	 * R.E., or nothing.
	 */
typedef struct	{
	enum {
		A_NONE,
		A_DOL,
		A_LINE,
		A_RE,
		A_LAST
	}type;
	union {
		long line;		/* Line # */
		Reprog *rp;		/* Compiled R.E. */
	} u;
} Addr;

typedef struct	SEDCOM {
	Addr	ad1;			/* optional start address */
	Addr	ad2;			/* optional end address */
	union {
		Reprog	*re1;		/* compiled R.E. */
		Rune	*text;		/* added text or file name */
		struct	SEDCOM	*lb1;	/* destination command of branch */
	} u;
	Rune	*rhs;			/* Right-hand side of substitution */
	Biobuf*	fcode;			/* File ID for read and write */
	char	command;		/* command code -see below */
	char	gfl;			/* 'Global' flag for substitutions */
	char	pfl;			/* 'print' flag for substitutions */
	char	active;			/* 1 => data between start and end */
	char	negfl;			/* negation flag */
} SedCom;

	/* Command Codes for field SedCom.command */
#define ACOM	01
#define BCOM	020
#define CCOM	02
#define	CDCOM	025
#define	CNCOM	022
#define COCOM	017
#define	CPCOM	023
#define DCOM	03
#define ECOM	015
#define EQCOM	013
#define FCOM	016
#define GCOM	027
#define CGCOM	030
#define HCOM	031
#define CHCOM	032
#define ICOM	04
#define LCOM	05
#define NCOM	012
#define PCOM	010
#define QCOM	011
#define RCOM	06
#define SCOM	07
#define TCOM	021
#define WCOM	014
#define	CWCOM	024
#define	YCOM	026
#define XCOM	033

	
typedef struct label {			/* Label symbol table */
	Rune	asc[9];			/* Label name */
	SedCom	*chain;
	SedCom	*address;		/* Command associated with label */
} Label;

typedef	struct	FILE_CACHE {		/* Data file control block */
	struct FILE_CACHE *next;	/* Forward Link */
	char 		  *name;	/* Name of file */
} FileCache;

SedCom pspace[MAXCMDS];			/* Command storage */
SedCom *pend = pspace+MAXCMDS;		/* End of command storage */
SedCom *rep = pspace;			/* Current fill point */

Reprog	*lastre = 0;			/* Last regular expression */
Resub	subexp[MAXSUB];			/* sub-patterns of pattern match*/

Rune	addspace[ADDSIZE];		/* Buffer for a, c, & i commands */
Rune	*addend = addspace+ADDSIZE;

SedCom	*abuf[MAXADDS];			/* Queue of pending adds & reads */
SedCom	**aptr = abuf;

struct {				/* Sed program input control block */
	enum PTYPE 			/* Either on command line or in file */
		{ P_ARG,
		  P_FILE
		} type;
	union PCTL {			/* Pointer to data */
		Biobuf	*bp;
		char	*curr;
	} pctl;
} prog;

Rune	genbuf[LBSIZE];			/* Miscellaneous buffer */

FileCache	*fhead = 0;		/* Head of File Cache Chain */
FileCache	*ftail = 0;		/* Tail of File Cache Chain */

Rune	*loc1;				/* Start of pattern match */
Rune	*loc2;				/* End of pattern match */
Rune	seof;				/* Pattern delimiter char */

Rune	linebuf[LBSIZE+1];		/* Input data buffer */
Rune	*lbend = linebuf+LBSIZE;	/* End of buffer */
Rune	*spend = linebuf;			/* End of input data */
Rune	*cp;				/* Current scan point in linebuf */

Rune	holdsp[LBSIZE+1];		/* Hold buffer */
Rune	*hend = holdsp+LBSIZE;		/* End of hold buffer */
Rune	*hspend = holdsp;		/* End of hold data */

int	nflag;				/* Command line flags */
int	gflag;
int	lflag;

int	dolflag;			/* Set when at true EOF */
int	sflag;				/* Set when substitution done */
int	jflag;				/* Set when jump required */
int	delflag;			/* Delete current line when set */

long	lnum = 0;			/* Input line count */

char	fname[MAXFILES][40];		/* File name cache */
Biobuf	*fcode[MAXFILES];		/* File ID cache */
int	nfiles = 0;			/* Cache fill point */

Biobuf	fout;				/* Output stream */
Biobuf	bstdin;				/* Default input */
Biobuf*	f = 0;				/* Input data */

Label	ltab[LABSIZE];			/* Label name symbol table */
Label	*labend = ltab+LABSIZE;		/* End of label table */
Label	*lab = ltab+1;			/* Current Fill point */

int	depth = 0;			/* {} stack pointer */

Rune	bad;				/* Dummy err ptr reference */
Rune	*badp = &bad;


char	CGMES[]	 = 	"Command garbled: %S";
char	TMMES[]	 = 	"Too much text: %S";
char	LTL[]	 = 	"Label too long: %S";
char	AD0MES[] =	"No addresses allowed: %S";
char	AD1MES[] =	"Only one address allowed: %S";

void	address(Addr *);
void	arout(void);
int	cmp(char *, char *);
int	rcmp(Rune *, Rune *);
void	command(SedCom *);
Reprog	*compile(void);
Rune	*compsub(Rune *, Rune *);
void	dechain(void);
void	dosub(Rune *);
int	ecmp(Rune *, Rune *, int);
void	enroll(char *);
void	errexit(void);
int	executable(SedCom *);
void	execute(void);
void	fcomp(void);
long	getrune(void);
Rune	*gline(Rune *);
int	match(Reprog *, Rune *);
void	newfile(enum PTYPE, char *);
int 	opendata(void);
Biobuf	*open_file(char *);
Rune	*place(Rune *, Rune *, Rune *);
void	quit(char *, char *);
int	rline(Rune *, Rune *);
Label	*search(Label *);
int	substitute(SedCom *);
char	*text(char *);
Rune	*stext(Rune *, Rune *);
int	ycomp(SedCom *);
char *	trans(int c);
void	putline(Biobuf *bp, Rune *buf, int n);

void
main(int argc, char **argv)
{
	int	compfl;

	lnum = 0;
	Binit(&fout, 1, OWRITE);
	fcode[nfiles++] = &fout;
	compfl = 0;

	if(argc == 1)
		exits(0);
	ARGBEGIN{
		case 'n':
			nflag++;
			continue;
		case 'f':
			if(argc <= 1)
				quit("no pattern-file", 0);
			newfile(P_FILE, ARGF());
			fcomp();
			compfl = 1;
			continue;
		case 'e':
			if (argc <= 1)
				quit("missing pattern", 0);
			newfile(P_ARG, ARGF());
			fcomp();
			compfl = 1;
			continue;
		case 'g':
			gflag++;
			continue;
		case 'l':
			lflag++;
			continue;
		default:
			fprint(2, "sed: Unknown flag: %c\n", ARGC());
			continue;
	} ARGEND

	if(compfl == 0) {
		if (--argc < 0)
			quit("missing pattern", 0);
		newfile(P_ARG, *argv++);
		fcomp();
	}

	if(depth)
		quit("Too many {'s", 0);

	ltab[0].address = rep;

	dechain();

	if(argc <= 0)
		enroll(0);		/* Add stdin to cache */
	else while(--argc >= 0) {
		enroll(*argv++);
	}
	execute();
	exits(0);
}
void
fcomp(void)
{
	Rune	*tp;
	SedCom	*pt, *pt1;
	int	i;
	Label	*lpt;

	static Rune	*p = addspace;
	static SedCom	**cmpend[DEPTH];	/* stack of {} operations */

	while (rline(linebuf, lbend) >= 0) {
		cp = linebuf;
comploop:
		while(*cp == ' ' || *cp == '\t')
			cp++;
		if(*cp == '\0' || *cp == '#')
			continue;
		if(*cp == ';') {
			cp++;
			goto comploop;
		}

		address(&rep->ad1);
		if (rep->ad1.type != A_NONE) {
			if (rep->ad1.type == A_LAST) {
				if (!lastre)
					quit("First RE may not be null", 0);
				rep->ad1.type = A_RE;
				rep->ad1.u.rp = lastre;
			}
			if(*cp == ',' || *cp == ';') {
				cp++;
				address(&rep->ad2);
				if (rep->ad2.type == A_LAST) {
					rep->ad1.type = A_RE;
					rep->ad2.u.rp = lastre;
				}
			} else
				rep->ad2.type = A_NONE;
		}
		while(*cp == ' ' || *cp == '\t')
			cp++;

swit:
		switch(*cp++) {

			default:
				quit("Unrecognized command: %S", (char *)linebuf);

			case '!':
				rep->negfl = 1;
				goto swit;

			case '{':
				rep->command = BCOM;
				rep->negfl = !(rep->negfl);
				cmpend[depth++] = &rep->u.lb1;
				if(++rep >= pend)
					quit("Too many commands: %S", (char *) linebuf);
				if(*cp == '\0')	continue;
				goto comploop;

			case '}':
				if(rep->ad1.type != A_NONE)
					quit(AD0MES, (char *) linebuf);
				if(--depth < 0)
					quit("Too many }'s", 0);
				*cmpend[depth] = rep;
				if(*cp == 0)	continue;
				goto comploop;

			case '=':
				rep->command = EQCOM;
				if(rep->ad2.type != A_NONE)
					quit(AD1MES, (char *) linebuf);
				break;

			case ':':
				if(rep->ad1.type != A_NONE)
					quit(AD0MES, (char *) linebuf);

				while(*cp == ' ')
					cp++;
				tp = lab->asc;
				while (*cp && *cp != ';' && *cp != ' ' && *cp != '\t' && *cp != '#') {
					*tp++ = *cp++;
					if(tp >= &(lab->asc[8]))
						quit(LTL, (char *) linebuf);
				}
				*tp = '\0';

				if(lpt = search(lab)) {
					if(lpt->address)
						quit("Duplicate labels: %S", (char *) linebuf);
				} else {
					lab->chain = 0;
					lpt = lab;
					if(++lab >= labend)
						quit("Too many labels: %S", (char *) linebuf);
				}
				lpt->address = rep;
				if (*cp == '#')
					continue;
				rep--;			/* reuse this slot */
				break;

			case 'a':
				rep->command = ACOM;
				if(rep->ad2.type != A_NONE)
					quit(AD1MES, (char *) linebuf);
				if(*cp == '\\')	cp++;
				if(*cp++ != '\n')
					quit(CGMES, (char *) linebuf);
				rep->u.text = p;
				p = stext(p, addend);
				break;
			case 'c':
				rep->command = CCOM;
				if(*cp == '\\')	cp++;
				if(*cp++ != '\n')
					quit(CGMES, (char *) linebuf);
				rep->u.text = p;
				p = stext(p, addend);
				break;
			case 'i':
				rep->command = ICOM;
				if(rep->ad2.type != A_NONE)
					quit(AD1MES, (char *) linebuf);
				if(*cp == '\\')	cp++;
				if(*cp++ != '\n')
					quit(CGMES, (char *) linebuf);
				rep->u.text = p;
				p = stext(p, addend);
				break;

			case 'g':
				rep->command = GCOM;
				break;

			case 'G':
				rep->command = CGCOM;
				break;

			case 'h':
				rep->command = HCOM;
				break;

			case 'H':
				rep->command = CHCOM;
				break;

			case 't':
				rep->command = TCOM;
				goto jtcommon;

			case 'b':
				rep->command = BCOM;
jtcommon:
				while(*cp == ' ')cp++;
				if(*cp == '\0') {
					if(pt = ltab[0].chain) {
						while(pt1 = pt->u.lb1)
							pt = pt1;
						pt->u.lb1 = rep;
					} else
						ltab[0].chain = rep;
					break;
				}
				tp = lab->asc;
				while((*tp++ = *cp++))
					if(tp >= &(lab->asc[8]))
						quit(LTL, (char *) linebuf);
				cp--;
				tp[-1] = '\0';

				if(lpt = search(lab)) {
					if(lpt->address) {
						rep->u.lb1 = lpt->address;
					} else {
						pt = lpt->chain;
						while(pt1 = pt->u.lb1)
							pt = pt1;
						pt->u.lb1 = rep;
					}
				} else {
					lab->chain = rep;
					lab->address = 0;
					if(++lab >= labend)
						quit("Too many labels: %S",
							(char *) linebuf);
				}
				break;

			case 'n':
				rep->command = NCOM;
				break;

			case 'N':
				rep->command = CNCOM;
				break;

			case 'p':
				rep->command = PCOM;
				break;

			case 'P':
				rep->command = CPCOM;
				break;

			case 'r':
				rep->command = RCOM;
				if(rep->ad2.type != A_NONE)
					quit(AD1MES, (char *) linebuf);
				if(*cp++ != ' ')
					quit(CGMES, (char *) linebuf);
				rep->u.text = p;
				p = stext(p, addend);
				break;

			case 'd':
				rep->command = DCOM;
				break;

			case 'D':
				rep->command = CDCOM;
				rep->u.lb1 = pspace;
				break;

			case 'q':
				rep->command = QCOM;
				if(rep->ad2.type != A_NONE)
					quit(AD1MES, (char *) linebuf);
				break;

			case 'l':
				rep->command = LCOM;
				break;

			case 's':
				rep->command = SCOM;
				seof = *cp++;
				if ((rep->u.re1 = compile()) == 0) {
					if(!lastre)
						quit("First RE may not be null.", 0);
					rep->u.re1 = lastre;
				}
				rep->rhs = p;
				if((p = compsub(p, addend)) == 0)
					quit(CGMES, (char *) linebuf);
				if(*cp == 'g') {
					cp++;
					rep->gfl++;
				} else if(gflag)
					rep->gfl++;

				if(*cp == 'p') {
					cp++;
					rep->pfl = 1;
				}

				if(*cp == 'P') {
					cp++;
					rep->pfl = 2;
				}

				if(*cp == 'w') {
					cp++;
					if(*cp++ !=  ' ')
						quit(CGMES, (char *) linebuf);
					text(fname[nfiles]);
					for(i = nfiles - 1; i >= 0; i--)
						if(cmp(fname[nfiles],fname[i]) == 0) {
							rep->fcode = fcode[i];
							goto done;
						}
					if(nfiles >= MAXFILES)
						quit("Too many files in w commands 1", 0);
					rep->fcode = open_file(fname[nfiles]);
				}
				break;

			case 'w':
				rep->command = WCOM;
				if(*cp++ != ' ')
					quit(CGMES, (char *) linebuf);
				text(fname[nfiles]);
				for(i = nfiles - 1; i >= 0; i--)
					if(cmp(fname[nfiles], fname[i]) == 0) {
						rep->fcode = fcode[i];
						goto done;
					}
				if(nfiles >= MAXFILES){
					fprint(2, "sed: Too many files in w commands 2 \n");
					fprint(2, "nfiles = %d; MAXF = %d\n", nfiles, MAXFILES);
					errexit();
				}
				rep->fcode = open_file(fname[nfiles]);
				break;

			case 'x':
				rep->command = XCOM;
				break;

			case 'y':
				rep->command = YCOM;
				seof = *cp++;
				if (ycomp(rep) == 0)
					quit(CGMES, (char *) linebuf);
				break;

		}
done:
		if(++rep >= pend)
			quit("Too many commands, last: %S", (char *) linebuf);

		if(*cp++ != '\0') {
			if(cp[-1] == ';')
				goto comploop;
			quit(CGMES, (char *) linebuf);
		}

	}
}

Biobuf *
open_file(char *name)
{
	Biobuf *bp;
	int fd;

	if ((bp = malloc(sizeof(Biobuf))) == 0)
		quit("Out of memory", 0);
	if ((fd = open(name, OWRITE)) < 0 &&
		(fd = create(name, OWRITE, 0666)) < 0)
			quit("Cannot create %s", name);
	Binit(bp, fd, OWRITE);
	Bseek(bp, 0, 2);
	fcode[nfiles++] = bp;
	return bp;
}

Rune	*
compsub(Rune *rhs, Rune *end)
{
	Rune	r;

	while ((r = *cp++) != '\0') {
		if(r == '\\') {
			if (rhs < end)
				*rhs++ = 0xFFFF;
			else
				return 0;
			r = *cp++;
			if(r == 'n')
				r = '\n';
		} else {
			if(r == seof) {
				if (rhs < end)
					*rhs++ = '\0';
				else
					return 0;
				return rhs;
			}
		}
		if (rhs < end)
			*rhs++ = r;
		else	
			return 0;

	}
	return 0;
}

Reprog *
compile(void)
{
	Rune c;
	char *ep;
	char expbuf[512];

	if((c = *cp++) == seof)		/* '//' */
		return 0;
	ep = expbuf;
	do {
		if (c == 0 || c == '\n')
			quit(TMMES, (char *) linebuf);
		if (c == '\\') {
			if (ep >= expbuf+sizeof(expbuf))
				quit(TMMES, (char *) linebuf);
			ep += runetochar(ep, &c);
			if ((c = *cp++) == 'n')
				c = '\n';
		}
		if (ep >= expbuf+sizeof(expbuf))
			quit(TMMES, (char *) linebuf);
		ep += runetochar(ep, &c);
	} while ((c = *cp++) != seof);
	*ep = 0;
	return lastre = regcomp(expbuf);
}

void
regerror(char *s)
{
	USED(s);
	quit(CGMES, (char *) linebuf);
}

void
newfile(enum PTYPE type, char *name)
{
	if (type == P_ARG)
		prog.pctl.curr = name;
	else if ((prog.pctl.bp = Bopen(name, OREAD)) == 0)
		quit("Cannot open pattern-file: %s\n", name);
	prog.type = type;
}

int
rline(Rune *buf, Rune *end)
{
	long c;
	Rune r;

	while ((c = getrune()) >= 0) {
		r = c;
		if (r == '\\') {
			if (buf <= end)
				*buf++ = r;
			if ((c = getrune()) < 0)
				break;
			r = c;
		} else if (r == '\n') {
			*buf = '\0';
			return(1);
		}
		if (buf <= end)
			*buf++ = r;
	}
	*buf = '\0';
	return(-1);
}

long
getrune(void)
{
	char *p;
	long c;
	Rune r;

	if (prog.type == P_ARG) {
		if ((p = prog.pctl.curr) != 0) {
			if (*p) {
				prog.pctl.curr += chartorune(&r, p);
				c = r;
			} else {
				c = '\n';	/* fake an end-of-line */
				prog.pctl.curr = 0;
			}
		} else 
			c = -1;
	} else if ((c = Bgetrune(prog.pctl.bp)) < 0)
			Bterm(prog.pctl.bp);
	return c;
}

void
address(Addr *ap)
{
	int c;
	long	lno;

	if((c = *cp++) == '$')
		ap->type = A_DOL;
	else if(c == '/') {
		seof = c;
		if (ap->u.rp = compile())
			ap->type = A_RE;
		else
			ap->type = A_LAST;
	}
	else if (c >= '0' && c <= '9') {
		lno = c-'0';
		while ((c = *cp) >= '0' && c <= '9')
			lno = lno*10 + *cp++-'0';
		if(!lno)
			quit("line number 0 is illegal",0);
		ap->type = A_LINE;
		ap->u.line = lno;
	}
	else {
		cp--;
		ap->type = A_NONE;
	}
}

int
cmp(char *a, char *b)		/* compare characters */
{
	while(*a == *b++)
		if (*a == '\0')
			return(0);
		else a++;
	return(1);
}

int
rcmp(Rune *a, Rune *b)		/* compare runes */
{
	while(*a == *b++)
		if (*a == '\0')
			return(0);
		else a++;
	return(1);
}

char *
text(char *p)		/* extract character string */
{
	Rune	r;

	while(*cp == '\t' || *cp == ' ')
			cp++;
	while (*cp) {
		if ((r = *cp++) == '\\')
			if ((r = *cp++) == 0)
				break;;
		if (r == '\n')
			while (*cp == '\t' || *cp == ' ')
					cp++;
		p += runetochar(p, &r);
	}
	*p++ = '\0';
	return p;
}

Rune *
stext(Rune *p, Rune *end)		/* extract rune string */
{
	while(*cp == '\t' || *cp == ' ')
		cp++;
	while (*cp) {
		if (*cp == '\\')
			if (*++cp == 0)
				break;
		if (p >= end-1)
			quit(TMMES, (char *) linebuf);
		if ((*p++ = *cp++) == '\n')
			while(*cp == '\t' || *cp == ' ')
					cp++;
	}
	*p++ = 0;
	return p;
}


Label *
search (Label *ptr)
{
	Label	*rp;

	for (rp = ltab; rp < ptr; rp++)
		if(rcmp(rp->asc, ptr->asc) == 0)
			return(rp);
	return(0);
}

void
dechain(void)
{
	Label	*lptr;
	SedCom	*rptr, *trptr;

	for(lptr = ltab; lptr < lab; lptr++) {

		if(lptr->address == 0)
			quit("Undefined label: %S", (char *) lptr->asc);

		if(lptr->chain) {
			rptr = lptr->chain;
			while(trptr = rptr->u.lb1) {
				rptr->u.lb1 = lptr->address;
				rptr = trptr;
			}
			rptr->u.lb1 = lptr->address;
		}
	}
}

int
ycomp(SedCom *r)
{
	int 	i;
	Rune	*rp;
	Rune	c, *tsp, highc;
	Rune	*sp;

	highc = 0;
	for(tsp = cp; *tsp != seof; tsp++) {
		if(*tsp == '\\')
			tsp++;
		if(*tsp == '\n' || *tsp == '\0')
			return(0);
		if (*tsp > highc) highc = *tsp;
	}
	tsp++;
	if ((rp = r->u.text = (Rune *) malloc(sizeof(Rune)*(highc+2))) == 0)
		quit("Out of memory", 0);
	*rp++ = highc;				/* save upper bound */
	for (i = 0; i <= highc; i++)
		rp[i] = i;
	sp = cp;
	while((c = *sp++) != seof) {
		if(c == '\\' && *sp == 'n') {
			sp++;
			c = '\n';
		}
		if((rp[c] = *tsp++) == '\\' && *tsp == 'n') {
			rp[c] = '\n';
			tsp++;
		}
		if(rp[c] == seof || rp[c] == '\0') {
			free(r->u.re1);
			r->u.re1 = 0;
			return(0);
		}
	}
	if(*tsp != seof) {
		free(r->u.re1);
		r->u.re1 = 0;
		return(0);
	}
	cp = tsp+1;
	return(1);
}

void
execute(void)
{
	SedCom	*ipc;

	while (spend = gline(linebuf)){
		for(ipc = pspace; ipc->command; ) {
			if (!executable(ipc)) {
				ipc++;
				continue;
			}
			command(ipc);

			if(delflag)
				break;
			if(jflag) {
				jflag = 0;
				if((ipc = ipc->u.lb1) == 0)
					break;
			} else
				ipc++;

		}
		if(!nflag && !delflag)
			putline(&fout, linebuf, spend-linebuf);
		if(aptr > abuf) {
			arout();
		}
		delflag = 0;
	}
}
	/* determine if a statement should be applied to an input line */
int
executable(SedCom *ipc)
{
	if (ipc->active) {	/* Addr1 satisfied - accept until Addr2 */
		if (ipc->active == 1)		/* Second line */
			ipc->active = 2;
		switch(ipc->ad2.type) {
			case A_NONE:	/* No second addr; use first */
				ipc->active = 0;
				break;
			case A_DOL:	/* Accept everything */
				return !ipc->negfl;
			case A_LINE:	/* Line at end of range? */
				if (lnum <= ipc->ad2.u.line) {
					if (ipc->ad2.u.line == lnum)
						ipc->active = 0;
					return !ipc->negfl;
				}
				ipc->active = 0;	/* out of range */
				return ipc->negfl;
			case A_RE:	/* Check for matching R.E. */
				if (match(ipc->ad2.u.rp, linebuf))
					ipc->active = 0;
				return !ipc->negfl;
			default:		/* internal error */
				quit("Internal error", 0);
		}
	}
	switch (ipc->ad1.type) {	/* Check first address */
		case A_NONE:			/* Everything matches */
			return !ipc->negfl;
		case A_DOL:			/* Only last line */
			if (dolflag)
				return !ipc->negfl;
			break;
		case A_LINE:			/* Check line number */
			if (ipc->ad1.u.line == lnum) {
				ipc->active = 1;	/* In range */
				return !ipc->negfl;
			}
			break;
		case A_RE:			/* Check R.E. */
			if (match(ipc->ad1.u.rp, linebuf)) {
				ipc->active = 1;	/* In range */
				return !ipc->negfl;
			}
			break;
		default:
			quit("Internal error", 0);
	}
	return ipc->negfl;
}

int
match(Reprog *pattern, Rune *buf)
{
	if (!pattern)
		return 0;
	subexp[0].s.rsp = buf; 
	subexp[0].e.rep = 0;
	if (rregexec(pattern, linebuf, subexp, MAXSUB) > 0) {
		loc1 = subexp[0].s.rsp;
		loc2 = subexp[0].e.rep;
		return 1;
	}
	loc1 = loc2 = 0;
	return 0;
}

int
substitute(SedCom *ipc)
{
	int len;

	if(!match(ipc->u.re1, linebuf))
		return 0;

	/*
	 * we have at least one match.  some patterns, e.g. '$' or '^', can
	 * produce zero-length matches, so during a global substitute we
	 * must bump to the character after a zero-length match to keep from looping.
	 */
	sflag = 1;
	if(ipc->gfl == 0)		/* single substitution */
		dosub(ipc->rhs);
	else
	do{				/* global substitution */
		len = loc2-loc1;	/* length of match */
		dosub(ipc->rhs);	/* dosub moves loc2 */
		if(*loc2 == 0)		/* end of string */
			break;
		if(len == 0)		/* zero-length R.E. match */
			loc2++;		/* bump over zero-length match */
		if(*loc2 == 0)		/* end of string */
			break;
	} while(match(ipc->u.re1, loc2));
	return 1;
}

void
dosub(Rune *rhsbuf)
{
	Rune *lp, *sp;
	Rune *rp;
	int c, n;

	lp = linebuf;
	sp = genbuf;
	rp = rhsbuf;
	while (lp < loc1)
		*sp++ = *lp++;
	while(c = *rp++) {
		if (c == '&') {
			sp = place(sp, loc1, loc2);
			continue;
		}
		if (c == 0xFFFF && (c = *rp++) >= '1' && c < MAXSUB+'0') {
			n = c-'0';
			if (subexp[n].s.rsp && subexp[n].e.rep) {
				sp = place(sp, subexp[n].s.rsp, subexp[n].e.rep);
				continue;
			}
			else {
				fprint(2, "sed: Invalid back reference \\%d\n",n);
				errexit();
			}
		}
		*sp++ = c;
		if (sp >= &genbuf[LBSIZE])
			fprint(2, "sed: Output line too long.\n");
	}
	lp = loc2;
	loc2 = sp - genbuf + linebuf;
	while (*sp++ = *lp++)
		if (sp >= &genbuf[LBSIZE])
			fprint(2, "sed: Output line too long.\n");
	lp = linebuf;
	sp = genbuf;
	while (*lp++ = *sp++)
		;
	spend = lp-1;
}

Rune *
place(Rune *sp, Rune *l1, Rune *l2)
{
	while (l1 < l2) {
		*sp++ = *l1++;
		if (sp >= &genbuf[LBSIZE])
			fprint(2, "sed: Output line too long.\n");
	}
	return(sp);
}

char *
trans(int c)
{
	static char buf[] = "\\x0000";
	static char hex[] = "0123456789abcdef";

	switch(c) {
		case '\b':
			return "\\b";
		case '\n':
			return "\\n";
		case '\r':
			return "\\r";
		case '\t':
			return "\\t";
		case '\\':
			return "\\\\";
	}
	buf[2] = hex[(c>>12)&0xF];
	buf[3] = hex[(c>>8)&0xF];
	buf[4] = hex[(c>>4)&0xF];
	buf[5] = hex[c&0xF];
	return buf;
}

void
command(SedCom *ipc)
{
	int	i, c;
	Rune	*p1, *p2;
	char	*ucp;
	Rune	*rp;
	Rune	*execp;

	switch(ipc->command) {

		case ACOM:
			*aptr++ = ipc;
			if(aptr >= abuf+MAXADDS) {
				quit("sed: Too many appends after line %ld\n",
					(char *) lnum);
			}
			*aptr = 0;
			break;
		case CCOM:
			delflag = 1;
			if(ipc->active == 1) {
				for(rp = ipc->u.text; *rp; rp++)
					Bputrune(&fout, *rp);
				Bputc(&fout, '\n');
			}
			break;
		case DCOM:
			delflag++;
			break;
		case CDCOM:
			p1 = p2 = linebuf;
			while(*p1 != '\n') {
				if(*p1++ == 0) {
					delflag++;
					return;
				}
			}
			p1++;
			while(*p2++ = *p1++)
				;
			spend = p2-1;
			jflag++;
			break;
		case EQCOM:
			Bprint(&fout, "%ld\n", lnum);
			break;
		case GCOM:
			p1 = linebuf;
			p2 = holdsp;
			while(*p1++ = *p2++)
				;
			spend = p1-1;
			break;
		case CGCOM:
			*spend++ = '\n';
			p1 = spend;
			p2 = holdsp;
			while(*p1++ = *p2++)
				if(p1 >= lbend)
					break;
			spend = p1-1;
			break;
		case HCOM:
			p1 = holdsp;
			p2 = linebuf;
			while(*p1++ = *p2++);
			hspend = p1-1;
			break;
		case CHCOM:
			*hspend++ = '\n';
			p1 = hspend;
			p2 = linebuf;
			while(*p1++ = *p2++)
				if(p1 >= hend)
					break;
			hspend = p1-1;
			break;
		case ICOM:
			for(rp = ipc->u.text; *rp; rp++)
				Bputrune(&fout, *rp);
			Bputc(&fout, '\n');
			break;
		case BCOM:
			jflag = 1;
			break;
		case LCOM:
			c = 0;
			for (i = 0, rp = linebuf; *rp; rp++) {
				c = *rp;
				if(c >= 0x20 && c < 0x7F && c != '\\') {
					Bputc(&fout, c);
					if(i++ > 71) {
						Bprint(&fout, "\\\n");
						i = 0;
					}
				} else {
					for (ucp = trans(*rp); *ucp; ucp++){
						c = *ucp;
						Bputc(&fout, c);
						if(i++ > 71) {
							Bprint(&fout, "\\\n");
							i = 0;
						}
					}
				}
			}
			if(c == ' ')
				Bprint(&fout, "\\n");
			Bputc(&fout, '\n');
			break;
		case NCOM:
			if(!nflag)
				putline(&fout, linebuf, spend-linebuf);

			if(aptr > abuf)
				arout();
			if((execp = gline(linebuf)) == 0) {
				delflag = 1;
				break;
			}
			spend = execp;
			break;
		case CNCOM:
			if(aptr > abuf)
				arout();
			*spend++ = '\n';
			if((execp = gline(spend)) == 0) {
				delflag = 1;
				break;
			}
			spend = execp;
			break;
		case PCOM:
			putline(&fout, linebuf, spend-linebuf);
			break;
		case CPCOM:
	cpcom:
			for(rp = linebuf; *rp && *rp != '\n'; rp++)
				Bputc(&fout, *rp);
			Bputc(&fout, '\n');
			break;
		case QCOM:
			if(!nflag)
				putline(&fout, linebuf, spend-linebuf);
			if(aptr > abuf)
				arout();
			exits(0);
		case RCOM:
			*aptr++ = ipc;
			if(aptr >= &abuf[MAXADDS])
				quit("sed: Too many reads after line %ld\n",
					(char *) lnum);
			*aptr = 0;
			break;
		case SCOM:
			i = substitute(ipc);
			if(i && ipc->pfl)
				if(ipc->pfl == 1)
					putline(&fout, linebuf, spend-linebuf);
				else
					goto cpcom;
			if(i && ipc->fcode)
				goto wcom;
			break;

		case TCOM:
			if(sflag == 0)	break;
			sflag = 0;
			jflag = 1;
			break;

		wcom:
		case WCOM:
			putline(ipc->fcode,linebuf, spend-linebuf);
			break;
		case XCOM:
			p1 = linebuf;
			p2 = genbuf;
			while(*p2++ = *p1++);
			p1 = holdsp;
			p2 = linebuf;
			while(*p2++ = *p1++);
			spend = p2 - 1;
			p1 = genbuf;
			p2 = holdsp;
			while(*p2++ = *p1++);
			hspend = p2 - 1;
			break;
		case YCOM:
			p1 = linebuf;
			p2 = ipc->u.text;
			for (i = *p2++;	*p1; p1++){
				if (*p1 <= i) *p1 = p2[*p1];
			}
			break;
	}

}

void
putline(Biobuf *bp, Rune *buf, int n)
{
	while (n--)
		Bputrune(bp, *buf++);
	Bputc(bp, '\n');
	if(lflag)
		Bflush(bp);
}

int
ecmp(Rune *a, Rune *b, int count)
{
	while(count--)
		if(*a++ != *b++)	return(0);
	return(1);
}

void
arout(void)
{
	Rune	*p1;
	Biobuf	*fi;
	int	c;
	char	*s;
	char	buf[128];

	for (aptr = abuf; *aptr; aptr++) {
		if((*aptr)->command == ACOM) {
			for(p1 = (*aptr)->u.text; *p1; p1++ )
				Bputrune(&fout, *p1);
			Bputc(&fout, '\n');
		} else {
			for(s = buf, p1= (*aptr)->u.text; *p1; p1++)
					s += runetochar(s, p1);
			*s = '\0';
			if((fi = Bopen(buf, OREAD)) == 0)
				continue;
			while((c = Bgetc(fi)) >= 0)
				Bputc(&fout, c);
			Bterm(fi);
		}
	}
	aptr = abuf;
	*aptr = 0;
}

void
errexit(void)
{
	exits("error");
}

void
quit (char *msg, char *arg)
{
	fprint(2, "sed: ");
	fprint(2, msg, arg);
	fprint(2, "\n");
	errexit();
}

Rune *
gline(Rune *addr)
{
	long	c;
	Rune *p;

	static long peekc = 0;

	if (f == 0 && opendata() < 0)
		return 0;
	sflag = 0;
	lnum++;
/*	Bflush(&fout);********* dumped 4/30/92 - bobf****/
	do {
		p = addr;
		for (c = (peekc ? peekc : Bgetrune(f)); c >= 0; c = Bgetrune(f)) {
			if (c == '\n') {
				if ((peekc = Bgetrune(f)) < 0) {
					if (fhead == 0)
						dolflag = 1;
				}
				*p = '\0';
				return p;
			}
			if (c && p < lbend)
				*p++ = c;
		}
		/* return partial final line, adding implicit newline */
		if(p != addr) {
			*p = '\0';
			peekc = -1;
			if (fhead == 0)
				dolflag = 1;
			return p;
		}
		peekc = 0;
		Bterm(f);
	} while (opendata() > 0);	/* Switch to next stream */
	f = 0;
	return 0;
}

	/* Data file input section - the intent is to transparently
	 *	catenate all data input streams.
	 */
void
enroll(char *filename)		/* Add a file to the input file cache */
{
	FileCache *fp;

	if ((fp = (FileCache *) malloc(sizeof (FileCache))) == 0)
		quit("Out of memory", 0);
	if (ftail == 0)
		fhead = fp;
	else
		ftail->next = fp;
	ftail = fp;
	fp->next = 0;
	fp->name = filename;	/* 0 => stdin */
}

int
opendata(void)
{
	if (fhead == 0)
		return -1;
	if (fhead->name) {
		if ((f = Bopen(fhead->name, OREAD)) == 0)
			quit("Can't open %s", fhead->name);
	} else {
		Binit(&bstdin, 0, OREAD);
		f = &bstdin;
	}
	fhead = fhead->next;
	return 1;
}
