xref: /csrg-svn/old/sed/sed0.c (revision 48309)
1*48309Sbostic /*-
2*48309Sbostic  * %sccs.include.proprietary.c%
3*48309Sbostic  */
418583Sralph 
5*48309Sbostic #ifndef lint
6*48309Sbostic static char sccsid[] = "@(#)sed0.c	4.7 (Berkeley) 04/18/91";
7*48309Sbostic #endif /* not lint */
8*48309Sbostic 
932202Sbostic #include <sys/param.h>
1018583Sralph #include <stdio.h>
1118583Sralph #include "sed.h"
1218583Sralph 
1318583Sralph struct label	*labtab = ltab;
1418583Sralph char	CGMES[]	= "command garbled: %s\n";
1518583Sralph char	TMMES[]	= "Too much text: %s\n";
1618583Sralph char	LTL[]	= "Label too long: %s\n";
1718583Sralph char	AD0MES[]	= "No addresses allowed: %s\n";
1818583Sralph char	AD1MES[]	= "Only one address allowed: %s\n";
1918583Sralph char	bittab[]  = {
2018583Sralph 		1,
2118583Sralph 		2,
2218583Sralph 		4,
2318583Sralph 		8,
2418583Sralph 		16,
2518583Sralph 		32,
2618583Sralph 		64,
2718583Sralph 		128
2818583Sralph 	};
2918583Sralph 
3018583Sralph main(argc, argv)
3118583Sralph char	*argv[];
3218583Sralph {
3318583Sralph 
3418583Sralph 	eargc = argc;
3518583Sralph 	eargv = argv;
3618583Sralph 
3718583Sralph 	badp = &bad;
3818583Sralph 	aptr = abuf;
3918583Sralph 	lab = labtab + 1;	/* 0 reserved for end-pointer */
4018583Sralph 	rep = ptrspace;
4118583Sralph 	rep->ad1 = respace;
4218583Sralph 	lbend = &linebuf[LBSIZE];
4318583Sralph 	hend = &holdsp[LBSIZE];
4418583Sralph 	lcomend = &genbuf[71];
4518583Sralph 	ptrend = &ptrspace[PTRSIZE];
4618583Sralph 	reend = &respace[RESIZE];
4718583Sralph 	labend = &labtab[LABSIZE];
4818583Sralph 	lnum = 0;
4918583Sralph 	pending = 0;
5018583Sralph 	depth = 0;
5118583Sralph 	spend = linebuf;
5218583Sralph 	hspend = holdsp;
5318583Sralph 	fcode[0] = stdout;
5418583Sralph 	nfiles = 1;
5518583Sralph 
5618583Sralph 	if(eargc == 1)
5718583Sralph 		exit(0);
5818583Sralph 
5918583Sralph 
6018583Sralph 	while (--eargc > 0 && (++eargv)[0][0] == '-')
6118583Sralph 		switch (eargv[0][1]) {
6218583Sralph 
6318583Sralph 		case 'n':
6418583Sralph 			nflag++;
6518583Sralph 			continue;
6618583Sralph 
6718583Sralph 		case 'f':
6818583Sralph 			if(eargc-- <= 0)	exit(2);
6918583Sralph 
7018583Sralph 			if((fin = fopen(*++eargv, "r")) == NULL) {
7118583Sralph 				fprintf(stderr, "Cannot open pattern-file: %s\n", *eargv);
7218583Sralph 				exit(2);
7318583Sralph 			}
7418583Sralph 
7518583Sralph 			fcomp();
7618583Sralph 			fclose(fin);
7718583Sralph 			continue;
7818583Sralph 
7918583Sralph 		case 'e':
8018583Sralph 			eflag++;
8118583Sralph 			fcomp();
8218583Sralph 			eflag = 0;
8318583Sralph 			continue;
8418583Sralph 
8518583Sralph 		case 'g':
8618583Sralph 			gflag++;
8718583Sralph 			continue;
8818583Sralph 
8918583Sralph 		default:
9018583Sralph 			fprintf(stdout, "Unknown flag: %c\n", eargv[0][1]);
9118583Sralph 			continue;
9218583Sralph 		}
9318583Sralph 
9418583Sralph 
9518583Sralph 	if(compfl == 0) {
9618583Sralph 		eargv--;
9718583Sralph 		eargc++;
9818583Sralph 		eflag++;
9918583Sralph 		fcomp();
10018583Sralph 		eargv++;
10118583Sralph 		eargc--;
10218583Sralph 		eflag = 0;
10318583Sralph 	}
10418583Sralph 
10518583Sralph 	if(depth) {
10618583Sralph 		fprintf(stderr, "Too many {'s");
10718583Sralph 		exit(2);
10818583Sralph 	}
10918583Sralph 
11018583Sralph 	labtab->address = rep;
11118583Sralph 
11218583Sralph 	dechain();
11318583Sralph 
11418583Sralph /*	abort();	/*DEBUG*/
11518583Sralph 
11618583Sralph 	if(eargc <= 0)
11718583Sralph 		execute((char *)NULL);
11818583Sralph 	else while(--eargc >= 0) {
11918583Sralph 		execute(*eargv++);
12018583Sralph 	}
12118583Sralph 	fclose(stdout);
12218583Sralph 	exit(0);
12318583Sralph }
12418583Sralph fcomp()
12518583Sralph {
12618583Sralph 
12718583Sralph 	register char	*p, *op, *tp;
12818583Sralph 	char	*address();
12933076Sbostic 	struct reptr	*pt, *pt1;
13018583Sralph 	int	i;
13118583Sralph 	struct label	*lpt;
13232202Sbostic 	char fbuf[MAXPATHLEN + 1], *newstr();
13318583Sralph 
13418583Sralph 	compfl = 1;
13518583Sralph 	op = lastre;
13618583Sralph 
13718583Sralph 	if(rline(linebuf) < 0)	return;
13818583Sralph 	if(*linebuf == '#') {
13918583Sralph 		if(linebuf[1] == 'n')
14018583Sralph 			nflag = 1;
14118583Sralph 	}
14218583Sralph 	else {
14318583Sralph 		cp = linebuf;
14418583Sralph 		goto comploop;
14518583Sralph 	}
14618583Sralph 
14718583Sralph 	for(;;) {
14818583Sralph 		if(rline(linebuf) < 0)	break;
14918583Sralph 
15018583Sralph 		cp = linebuf;
15118583Sralph 
15218583Sralph comploop:
15318583Sralph /*	fprintf(stdout, "cp: %s\n", cp);	/*DEBUG*/
15418583Sralph 		while(*cp == ' ' || *cp == '\t')	cp++;
15518583Sralph 		if(*cp == '\0' || *cp == '#')		continue;
15618583Sralph 		if(*cp == ';') {
15718583Sralph 			cp++;
15818583Sralph 			goto comploop;
15918583Sralph 		}
16018583Sralph 
16118583Sralph 		p = address(rep->ad1);
16218583Sralph 		if(p == badp) {
16318583Sralph 			fprintf(stderr, CGMES, linebuf);
16418583Sralph 			exit(2);
16518583Sralph 		}
16618583Sralph 
16718583Sralph 		if(p == rep->ad1) {
16818583Sralph 			if(op)
16918583Sralph 				rep->ad1 = op;
17018583Sralph 			else {
17118583Sralph 				fprintf(stderr, "First RE may not be null\n");
17218583Sralph 				exit(2);
17318583Sralph 			}
17418583Sralph 		} else if(p == 0) {
17518583Sralph 			p = rep->ad1;
17618583Sralph 			rep->ad1 = 0;
17718583Sralph 		} else {
17818583Sralph 			op = rep->ad1;
17918583Sralph 			if(*cp == ',' || *cp == ';') {
18018583Sralph 				cp++;
18118583Sralph 				if((rep->ad2 = p) > reend) {
18218583Sralph 					fprintf(stderr, TMMES, linebuf);
18318583Sralph 					exit(2);
18418583Sralph 				}
18518583Sralph 				p = address(rep->ad2);
18618583Sralph 				if(p == badp || p == 0) {
18718583Sralph 					fprintf(stderr, CGMES, linebuf);
18818583Sralph 					exit(2);
18918583Sralph 				}
19018583Sralph 				if(p == rep->ad2)
19118583Sralph 					rep->ad2 = op;
19218583Sralph 				else
19318583Sralph 					op = rep->ad2;
19418583Sralph 
19518583Sralph 			} else
19618583Sralph 				rep->ad2 = 0;
19718583Sralph 		}
19818583Sralph 
19918583Sralph 		if(p > reend) {
20018583Sralph 			fprintf(stderr, "Too much text: %s\n", linebuf);
20118583Sralph 			exit(2);
20218583Sralph 		}
20318583Sralph 
20418583Sralph 		while(*cp == ' ' || *cp == '\t')	cp++;
20518583Sralph 
20618583Sralph swit:
20718583Sralph 		switch(*cp++) {
20818583Sralph 
20918583Sralph 			default:
21018583Sralph 				fprintf(stderr, "Unrecognized command: %s\n", linebuf);
21118583Sralph 				exit(2);
21218583Sralph 
21318583Sralph 			case '!':
21418583Sralph 				rep->negfl = 1;
21518583Sralph 				goto swit;
21618583Sralph 
21718583Sralph 			case '{':
21818583Sralph 				rep->command = BCOM;
21918583Sralph 				rep->negfl = !(rep->negfl);
22018583Sralph 				cmpend[depth++] = &rep->lb1;
22118583Sralph 				if(++rep >= ptrend) {
22218583Sralph 					fprintf(stderr, "Too many commands: %s\n", linebuf);
22318583Sralph 					exit(2);
22418583Sralph 				}
22518583Sralph 				rep->ad1 = p;
22618583Sralph 				if(*cp == '\0')	continue;
22718583Sralph 
22818583Sralph 				goto comploop;
22918583Sralph 
23018583Sralph 			case '}':
23118583Sralph 				if(rep->ad1) {
23218583Sralph 					fprintf(stderr, AD0MES, linebuf);
23318583Sralph 					exit(2);
23418583Sralph 				}
23518583Sralph 
23618583Sralph 				if(--depth < 0) {
23718583Sralph 					fprintf(stderr, "Too many }'s\n");
23818583Sralph 					exit(2);
23918583Sralph 				}
24018583Sralph 				*cmpend[depth] = rep;
24118583Sralph 
24218583Sralph 				rep->ad1 = p;
24318583Sralph 				continue;
24418583Sralph 
24518583Sralph 			case '=':
24618583Sralph 				rep->command = EQCOM;
24718583Sralph 				if(rep->ad2) {
24818583Sralph 					fprintf(stderr, AD1MES, linebuf);
24918583Sralph 					exit(2);
25018583Sralph 				}
25118583Sralph 				break;
25218583Sralph 
25318583Sralph 			case ':':
25418583Sralph 				if(rep->ad1) {
25518583Sralph 					fprintf(stderr, AD0MES, linebuf);
25618583Sralph 					exit(2);
25718583Sralph 				}
25818583Sralph 
25918583Sralph 				while(*cp++ == ' ');
26018583Sralph 				cp--;
26118583Sralph 
26218583Sralph 
26318583Sralph 				tp = lab->asc;
26418583Sralph 				while((*tp++ = *cp++))
26518583Sralph 					if(tp >= &(lab->asc[8])) {
26618583Sralph 						fprintf(stderr, LTL, linebuf);
26718583Sralph 						exit(2);
26818583Sralph 					}
26918583Sralph 				*--tp = '\0';
27018583Sralph 
27118583Sralph 				if(lpt = search(lab)) {
27218583Sralph 					if(lpt->address) {
27318583Sralph 						fprintf(stderr, "Duplicate labels: %s\n", linebuf);
27418583Sralph 						exit(2);
27518583Sralph 					}
27618583Sralph 				} else {
27718583Sralph 					lab->chain = 0;
27818583Sralph 					lpt = lab;
27918583Sralph 					if(++lab >= labend) {
28018583Sralph 						fprintf(stderr, "Too many labels: %s\n", linebuf);
28118583Sralph 						exit(2);
28218583Sralph 					}
28318583Sralph 				}
28418583Sralph 				lpt->address = rep;
28518583Sralph 				rep->ad1 = p;
28618583Sralph 
28718583Sralph 				continue;
28818583Sralph 
28918583Sralph 			case 'a':
29018583Sralph 				rep->command = ACOM;
29118583Sralph 				if(rep->ad2) {
29218583Sralph 					fprintf(stderr, AD1MES, linebuf);
29318583Sralph 					exit(2);
29418583Sralph 				}
29518583Sralph 				if(*cp == '\\')	cp++;
29618583Sralph 				if(*cp++ != '\n') {
29718583Sralph 					fprintf(stderr, CGMES, linebuf);
29818583Sralph 					exit(2);
29918583Sralph 				}
30018583Sralph 				rep->re1 = p;
30118583Sralph 				p = text(rep->re1);
30218583Sralph 				break;
30318583Sralph 			case 'c':
30418583Sralph 				rep->command = CCOM;
30518583Sralph 				if(*cp == '\\')	cp++;
30618583Sralph 				if(*cp++ != ('\n')) {
30718583Sralph 					fprintf(stderr, CGMES, linebuf);
30818583Sralph 					exit(2);
30918583Sralph 				}
31018583Sralph 				rep->re1 = p;
31118583Sralph 				p = text(rep->re1);
31218583Sralph 				break;
31318583Sralph 			case 'i':
31418583Sralph 				rep->command = ICOM;
31518583Sralph 				if(rep->ad2) {
31618583Sralph 					fprintf(stderr, AD1MES, linebuf);
31718583Sralph 					exit(2);
31818583Sralph 				}
31918583Sralph 				if(*cp == '\\')	cp++;
32018583Sralph 				if(*cp++ != ('\n')) {
32118583Sralph 					fprintf(stderr, CGMES, linebuf);
32218583Sralph 					exit(2);
32318583Sralph 				}
32418583Sralph 				rep->re1 = p;
32518583Sralph 				p = text(rep->re1);
32618583Sralph 				break;
32718583Sralph 
32818583Sralph 			case 'g':
32918583Sralph 				rep->command = GCOM;
33018583Sralph 				break;
33118583Sralph 
33218583Sralph 			case 'G':
33318583Sralph 				rep->command = CGCOM;
33418583Sralph 				break;
33518583Sralph 
33618583Sralph 			case 'h':
33718583Sralph 				rep->command = HCOM;
33818583Sralph 				break;
33918583Sralph 
34018583Sralph 			case 'H':
34118583Sralph 				rep->command = CHCOM;
34218583Sralph 				break;
34318583Sralph 
34418583Sralph 			case 't':
34518583Sralph 				rep->command = TCOM;
34618583Sralph 				goto jtcommon;
34718583Sralph 
34818583Sralph 			case 'b':
34918583Sralph 				rep->command = BCOM;
35018583Sralph jtcommon:
35118583Sralph 				while(*cp++ == ' ');
35218583Sralph 				cp--;
35318583Sralph 
35418583Sralph 				if(*cp == '\0') {
35518583Sralph 					if(pt = labtab->chain) {
35618583Sralph 						while(pt1 = pt->lb1)
35718583Sralph 							pt = pt1;
35818583Sralph 						pt->lb1 = rep;
35918583Sralph 					} else
36018583Sralph 						labtab->chain = rep;
36118583Sralph 					break;
36218583Sralph 				}
36318583Sralph 				tp = lab->asc;
36418583Sralph 				while((*tp++ = *cp++))
36518583Sralph 					if(tp >= &(lab->asc[8])) {
36618583Sralph 						fprintf(stderr, LTL, linebuf);
36718583Sralph 						exit(2);
36818583Sralph 					}
36918583Sralph 				cp--;
37018583Sralph 				*--tp = '\0';
37118583Sralph 
37218583Sralph 				if(lpt = search(lab)) {
37318583Sralph 					if(lpt->address) {
37418583Sralph 						rep->lb1 = lpt->address;
37518583Sralph 					} else {
37618583Sralph 						pt = lpt->chain;
37718583Sralph 						while(pt1 = pt->lb1)
37818583Sralph 							pt = pt1;
37918583Sralph 						pt->lb1 = rep;
38018583Sralph 					}
38118583Sralph 				} else {
38218583Sralph 					lab->chain = rep;
38318583Sralph 					lab->address = 0;
38418583Sralph 					if(++lab >= labend) {
38518583Sralph 						fprintf(stderr, "Too many labels: %s\n", linebuf);
38618583Sralph 						exit(2);
38718583Sralph 					}
38818583Sralph 				}
38918583Sralph 				break;
39018583Sralph 
39118583Sralph 			case 'n':
39218583Sralph 				rep->command = NCOM;
39318583Sralph 				break;
39418583Sralph 
39518583Sralph 			case 'N':
39618583Sralph 				rep->command = CNCOM;
39718583Sralph 				break;
39818583Sralph 
39918583Sralph 			case 'p':
40018583Sralph 				rep->command = PCOM;
40118583Sralph 				break;
40218583Sralph 
40318583Sralph 			case 'P':
40418583Sralph 				rep->command = CPCOM;
40518583Sralph 				break;
40618583Sralph 
40718583Sralph 			case 'r':
40818583Sralph 				rep->command = RCOM;
40918583Sralph 				if(rep->ad2) {
41018583Sralph 					fprintf(stderr, AD1MES, linebuf);
41118583Sralph 					exit(2);
41218583Sralph 				}
41318583Sralph 				if(*cp++ != ' ') {
41418583Sralph 					fprintf(stderr, CGMES, linebuf);
41518583Sralph 					exit(2);
41618583Sralph 				}
41718583Sralph 				rep->re1 = p;
41818583Sralph 				p = text(rep->re1);
41918583Sralph 				break;
42018583Sralph 
42118583Sralph 			case 'd':
42218583Sralph 				rep->command = DCOM;
42318583Sralph 				break;
42418583Sralph 
42518583Sralph 			case 'D':
42618583Sralph 				rep->command = CDCOM;
42718583Sralph 				rep->lb1 = ptrspace;
42818583Sralph 				break;
42918583Sralph 
43018583Sralph 			case 'q':
43118583Sralph 				rep->command = QCOM;
43218583Sralph 				if(rep->ad2) {
43318583Sralph 					fprintf(stderr, AD1MES, linebuf);
43418583Sralph 					exit(2);
43518583Sralph 				}
43618583Sralph 				break;
43718583Sralph 
43818583Sralph 			case 'l':
43918583Sralph 				rep->command = LCOM;
44018583Sralph 				break;
44118583Sralph 
44218583Sralph 			case 's':
44318583Sralph 				rep->command = SCOM;
44418583Sralph 				seof = *cp++;
44518583Sralph 				rep->re1 = p;
44618583Sralph 				p = compile(rep->re1);
44718583Sralph 				if(p == badp) {
44818583Sralph 					fprintf(stderr, CGMES, linebuf);
44918583Sralph 					exit(2);
45018583Sralph 				}
45118583Sralph 				if(p == rep->re1) {
45223554Sbloom 					if(op)
45323554Sbloom 					    rep->re1 = op;
45423554Sbloom 					else {
45523554Sbloom 					    fprintf(stderr,
45623554Sbloom 						"First RE may not be null\n");
45723554Sbloom 					    exit(2);
45823554Sbloom 					}
45918583Sralph 				} else {
46018583Sralph 					op = rep->re1;
46118583Sralph 				}
46218583Sralph 
46318583Sralph 				if((rep->rhs = p) > reend) {
46418583Sralph 					fprintf(stderr, TMMES, linebuf);
46518583Sralph 					exit(2);
46618583Sralph 				}
46718583Sralph 
46818583Sralph 				if((p = compsub(rep->rhs)) == badp) {
46918583Sralph 					fprintf(stderr, CGMES, linebuf);
47018583Sralph 					exit(2);
47118583Sralph 				}
47218583Sralph 				if(*cp == 'g') {
47318583Sralph 					cp++;
47418583Sralph 					rep->gfl++;
47518583Sralph 				} else if(gflag)
47618583Sralph 					rep->gfl++;
47718583Sralph 
47818583Sralph 				if(*cp == 'p') {
47918583Sralph 					cp++;
48018583Sralph 					rep->pfl = 1;
48118583Sralph 				}
48218583Sralph 
48318583Sralph 				if(*cp == 'P') {
48418583Sralph 					cp++;
48518583Sralph 					rep->pfl = 2;
48618583Sralph 				}
48718583Sralph 
48818583Sralph 				if(*cp == 'w') {
48918583Sralph 					cp++;
49018583Sralph 					if(*cp++ !=  ' ') {
49118583Sralph 						fprintf(stderr, CGMES, linebuf);
49218583Sralph 						exit(2);
49318583Sralph 					}
49432197Sbostic 					if(nfiles > 10) {
49518583Sralph 						fprintf(stderr, "Too many files in w commands\n");
49618583Sralph 						exit(2);
49718583Sralph 					}
49818583Sralph 
49932202Sbostic 					text(fbuf);
50032202Sbostic 					fname[nfiles] = newstr(fbuf);
50118583Sralph 					for(i = nfiles - 1; i >= 0; i--)
50218583Sralph 						if(cmp(fname[nfiles],fname[i]) == 0) {
50318583Sralph 							rep->fcode = fcode[i];
50418583Sralph 							goto done;
50518583Sralph 						}
50618583Sralph 					if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
50718583Sralph 						fprintf(stderr, "cannot open %s\n", fname[nfiles]);
50818583Sralph 						exit(2);
50918583Sralph 					}
51018583Sralph 					fcode[nfiles++] = rep->fcode;
51118583Sralph 				}
51218583Sralph 				break;
51318583Sralph 
51418583Sralph 			case 'w':
51518583Sralph 				rep->command = WCOM;
51618583Sralph 				if(*cp++ != ' ') {
51718583Sralph 					fprintf(stderr, CGMES, linebuf);
51818583Sralph 					exit(2);
51918583Sralph 				}
52032197Sbostic 				if(nfiles > 10){
52118583Sralph 					fprintf(stderr, "Too many files in w commands\n");
52218583Sralph 					exit(2);
52318583Sralph 				}
52418583Sralph 
52532202Sbostic 				text(fbuf);
52632202Sbostic 				fname[nfiles] = newstr(fbuf);
52718583Sralph 				for(i = nfiles - 1; i >= 0; i--)
52818583Sralph 					if(cmp(fname[nfiles], fname[i]) == 0) {
52918583Sralph 						rep->fcode = fcode[i];
53018583Sralph 						goto done;
53118583Sralph 					}
53218583Sralph 
53318583Sralph 				if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
53418583Sralph 					fprintf(stderr, "Cannot create %s\n", fname[nfiles]);
53518583Sralph 					exit(2);
53618583Sralph 				}
53718583Sralph 				fcode[nfiles++] = rep->fcode;
53818583Sralph 				break;
53918583Sralph 
54018583Sralph 			case 'x':
54118583Sralph 				rep->command = XCOM;
54218583Sralph 				break;
54318583Sralph 
54418583Sralph 			case 'y':
54518583Sralph 				rep->command = YCOM;
54618583Sralph 				seof = *cp++;
54718583Sralph 				rep->re1 = p;
54818583Sralph 				p = ycomp(rep->re1);
54918583Sralph 				if(p == badp) {
55018583Sralph 					fprintf(stderr, CGMES, linebuf);
55118583Sralph 					exit(2);
55218583Sralph 				}
55318583Sralph 				if(p > reend) {
55418583Sralph 					fprintf(stderr, TMMES, linebuf);
55518583Sralph 					exit(2);
55618583Sralph 				}
55718583Sralph 				break;
55818583Sralph 
55918583Sralph 		}
56018583Sralph done:
56118583Sralph 		if(++rep >= ptrend) {
56218583Sralph 			fprintf(stderr, "Too many commands, last: %s\n", linebuf);
56318583Sralph 			exit(2);
56418583Sralph 		}
56518583Sralph 
56618583Sralph 		rep->ad1 = p;
56718583Sralph 
56818583Sralph 		if(*cp++ != '\0') {
56918583Sralph 			if(cp[-1] == ';')
57018583Sralph 				goto comploop;
57118583Sralph 			fprintf(stderr, CGMES, linebuf);
57218583Sralph 			exit(2);
57318583Sralph 		}
57418583Sralph 
57518583Sralph 	}
57618583Sralph 	rep->command = 0;
57718583Sralph 	lastre = op;
57818583Sralph }
57918583Sralph char	*compsub(rhsbuf)
58018583Sralph char	*rhsbuf;
58118583Sralph {
58218583Sralph 	register char	*p, *q;
58318583Sralph 
58418583Sralph 	p = rhsbuf;
58518583Sralph 	q = cp;
58618583Sralph 	for(;;) {
58718583Sralph 		if((*p = *q++) == '\\') {
58818583Sralph 			*p = *q++;
58918583Sralph 			if(*p > numbra + '0' && *p <= '9')
59018583Sralph 				return(badp);
59118583Sralph 			*p++ |= 0200;
59218583Sralph 			continue;
59318583Sralph 		}
59418583Sralph 		if(*p == seof) {
59518583Sralph 			*p++ = '\0';
59618583Sralph 			cp = q;
59718583Sralph 			return(p);
59818583Sralph 		}
59918583Sralph 		if(*p++ == '\0') {
60018583Sralph 			return(badp);
60118583Sralph 		}
60218583Sralph 
60318583Sralph 	}
60418583Sralph }
60518583Sralph 
60618583Sralph char *compile(expbuf)
60718583Sralph char	*expbuf;
60818583Sralph {
60918583Sralph 	register c;
61018583Sralph 	register char *ep, *sp;
61118583Sralph 	char	neg;
61218583Sralph 	char *lastep, *cstart;
61318583Sralph 	int cclcnt;
61418583Sralph 	int	closed;
61518583Sralph 	char	bracket[NBRA], *bracketp;
61618583Sralph 
61718583Sralph 	if(*cp == seof) {
61818583Sralph 		cp++;
61918583Sralph 		return(expbuf);
62018583Sralph 	}
62118583Sralph 
62218583Sralph 	ep = expbuf;
62318583Sralph 	lastep = 0;
62418583Sralph 	bracketp = bracket;
62518583Sralph 	closed = numbra = 0;
62618583Sralph 	sp = cp;
62718583Sralph 	if (*sp == '^') {
62818583Sralph 		*ep++ = 1;
62918583Sralph 		sp++;
63018583Sralph 	} else {
63118583Sralph 		*ep++ = 0;
63218583Sralph 	}
63318583Sralph 	for (;;) {
63418583Sralph 		if (ep >= &expbuf[ESIZE]) {
63518583Sralph 			cp = sp;
63618583Sralph 			return(badp);
63718583Sralph 		}
63818583Sralph 		if((c = *sp++) == seof) {
63918583Sralph 			if(bracketp != bracket) {
64018583Sralph 				cp = sp;
64118583Sralph 				return(badp);
64218583Sralph 			}
64318583Sralph 			cp = sp;
64418583Sralph 			*ep++ = CEOF;
64518583Sralph 			return(ep);
64618583Sralph 		}
64718583Sralph 		if(c != '*')
64818583Sralph 			lastep = ep;
64918583Sralph 		switch (c) {
65018583Sralph 
65118583Sralph 		case '\\':
65218583Sralph 			if((c = *sp++) == '(') {
65318583Sralph 				if(numbra >= NBRA) {
65418583Sralph 					cp = sp;
65518583Sralph 					return(badp);
65618583Sralph 				}
65718583Sralph 				*bracketp++ = numbra;
65818583Sralph 				*ep++ = CBRA;
65918583Sralph 				*ep++ = numbra++;
66018583Sralph 				continue;
66118583Sralph 			}
66218583Sralph 			if(c == ')') {
66318583Sralph 				if(bracketp <= bracket) {
66418583Sralph 					cp = sp;
66518583Sralph 					return(badp);
66618583Sralph 				}
66718583Sralph 				*ep++ = CKET;
66818583Sralph 				*ep++ = *--bracketp;
66918583Sralph 				closed++;
67018583Sralph 				continue;
67118583Sralph 			}
67218583Sralph 
67318583Sralph 			if(c >= '1' && c <= '9') {
67418583Sralph 				if((c -= '1') >= closed)
67518583Sralph 					return(badp);
67618583Sralph 
67718583Sralph 				*ep++ = CBACK;
67818583Sralph 				*ep++ = c;
67918583Sralph 				continue;
68018583Sralph 			}
68118583Sralph 			if(c == '\n') {
68218583Sralph 				cp = sp;
68318583Sralph 				return(badp);
68418583Sralph 			}
68518583Sralph 			if(c == 'n') {
68618583Sralph 				c = '\n';
68718583Sralph 			}
68818583Sralph 			goto defchar;
68918583Sralph 
69018583Sralph 		case '\0':
69118583Sralph 			continue;
69218583Sralph 		case '\n':
69318583Sralph 			cp = sp;
69418583Sralph 			return(badp);
69518583Sralph 
69618583Sralph 		case '.':
69718583Sralph 			*ep++ = CDOT;
69818583Sralph 			continue;
69918583Sralph 
70018583Sralph 		case '*':
70118583Sralph 			if (lastep == 0)
70218583Sralph 				goto defchar;
70318583Sralph 			if(*lastep == CKET) {
70418583Sralph 				cp = sp;
70518583Sralph 				return(badp);
70618583Sralph 			}
70718583Sralph 			*lastep |= STAR;
70818583Sralph 			continue;
70918583Sralph 
71018583Sralph 		case '$':
71118583Sralph 			if (*sp != seof)
71218583Sralph 				goto defchar;
71318583Sralph 			*ep++ = CDOL;
71418583Sralph 			continue;
71518583Sralph 
71618583Sralph 		case '[':
71718583Sralph 			if(&ep[17] >= &expbuf[ESIZE]) {
71818583Sralph 				fprintf(stderr, "RE too long: %s\n", linebuf);
71918583Sralph 				exit(2);
72018583Sralph 			}
72118583Sralph 
72218583Sralph 			*ep++ = CCL;
72318583Sralph 
72418583Sralph 			neg = 0;
72518583Sralph 			if((c = *sp++) == '^') {
72618583Sralph 				neg = 1;
72718583Sralph 				c = *sp++;
72818583Sralph 			}
72918583Sralph 
73018583Sralph 			cstart = sp;
73118583Sralph 			do {
73218583Sralph 				if(c == '\0') {
73318583Sralph 					fprintf(stderr, CGMES, linebuf);
73418583Sralph 					exit(2);
73518583Sralph 				}
73618583Sralph 				if (c=='-' && sp>cstart && *sp!=']') {
73718583Sralph 					for (c = sp[-2]; c<*sp; c++)
73818583Sralph 						ep[c>>3] |= bittab[c&07];
73918583Sralph 				}
74018583Sralph 				if(c == '\\') {
74118583Sralph 					switch(c = *sp++) {
74218583Sralph 						case 'n':
74318583Sralph 							c = '\n';
74418583Sralph 							break;
74518583Sralph 					}
74618583Sralph 				}
74718583Sralph 
74818583Sralph 				ep[c >> 3] |= bittab[c & 07];
74918583Sralph 			} while((c = *sp++) != ']');
75018583Sralph 
75118583Sralph 			if(neg)
75218583Sralph 				for(cclcnt = 0; cclcnt < 16; cclcnt++)
75318583Sralph 					ep[cclcnt] ^= -1;
75418583Sralph 			ep[0] &= 0376;
75518583Sralph 
75618583Sralph 			ep += 16;
75718583Sralph 
75818583Sralph 			continue;
75918583Sralph 
76018583Sralph 		defchar:
76118583Sralph 		default:
76218583Sralph 			*ep++ = CCHR;
76318583Sralph 			*ep++ = c;
76418583Sralph 		}
76518583Sralph 	}
76618583Sralph }
76718583Sralph rline(lbuf)
76818583Sralph char	*lbuf;
76918583Sralph {
77018583Sralph 	register char	*p, *q;
77118583Sralph 	register	t;
77218583Sralph 	static char	*saveq;
77318583Sralph 
77418583Sralph 	p = lbuf - 1;
77518583Sralph 
77618583Sralph 	if(eflag) {
77718583Sralph 		if(eflag > 0) {
77818583Sralph 			eflag = -1;
77918583Sralph 			if(eargc-- <= 0)
78018583Sralph 				exit(2);
78118583Sralph 			q = *++eargv;
78218583Sralph 			while(*++p = *q++) {
78318583Sralph 				if(*p == '\\') {
78418583Sralph 					if((*++p = *q++) == '\0') {
78518583Sralph 						saveq = 0;
78618583Sralph 						return(-1);
78718583Sralph 					} else
78818583Sralph 						continue;
78918583Sralph 				}
79018583Sralph 				if(*p == '\n') {
79118583Sralph 					*p = '\0';
79218583Sralph 					saveq = q;
79318583Sralph 					return(1);
79418583Sralph 				}
79518583Sralph 			}
79618583Sralph 			saveq = 0;
79718583Sralph 			return(1);
79818583Sralph 		}
79918583Sralph 		if((q = saveq) == 0)	return(-1);
80018583Sralph 
80118583Sralph 		while(*++p = *q++) {
80218583Sralph 			if(*p == '\\') {
80318583Sralph 				if((*++p = *q++) == '0') {
80418583Sralph 					saveq = 0;
80518583Sralph 					return(-1);
80618583Sralph 				} else
80718583Sralph 					continue;
80818583Sralph 			}
80918583Sralph 			if(*p == '\n') {
81018583Sralph 				*p = '\0';
81118583Sralph 				saveq = q;
81218583Sralph 				return(1);
81318583Sralph 			}
81418583Sralph 		}
81518583Sralph 		saveq = 0;
81618583Sralph 		return(1);
81718583Sralph 	}
81818583Sralph 
81918583Sralph 	while((t = getc(fin)) != EOF) {
82018583Sralph 		*++p = t;
82118583Sralph 		if(*p == '\\') {
82218583Sralph 			t = getc(fin);
82318583Sralph 			*++p = t;
82418583Sralph 		}
82518583Sralph 		else if(*p == '\n') {
82618583Sralph 			*p = '\0';
82718583Sralph 			return(1);
82818583Sralph 		}
82918583Sralph 	}
83018583Sralph 	*++p = '\0';
83118583Sralph 	return(-1);
83218583Sralph }
83318583Sralph 
83418583Sralph char	*address(expbuf)
83518583Sralph char	*expbuf;
83618583Sralph {
83718583Sralph 	register char	*rcp;
83818583Sralph 	long	lno;
83918583Sralph 
84018583Sralph 	if(*cp == '$') {
84118583Sralph 		cp++;
84218583Sralph 		*expbuf++ = CEND;
84318583Sralph 		*expbuf++ = CEOF;
84418583Sralph 		return(expbuf);
84518583Sralph 	}
84618583Sralph 
84718583Sralph 	if(*cp == '/') {
84818583Sralph 		seof = '/';
84918583Sralph 		cp++;
85018583Sralph 		return(compile(expbuf));
85118583Sralph 	}
85218583Sralph 
85318583Sralph 	rcp = cp;
85418583Sralph 	lno = 0;
85518583Sralph 
85618583Sralph 	while(*rcp >= '0' && *rcp <= '9')
85718583Sralph 		lno = lno*10 + *rcp++ - '0';
85818583Sralph 
85918583Sralph 	if(rcp > cp) {
86018583Sralph 		*expbuf++ = CLNUM;
86118583Sralph 		*expbuf++ = nlno;
86218583Sralph 		tlno[nlno++] = lno;
86318583Sralph 		if(nlno >= NLINES) {
86418583Sralph 			fprintf(stderr, "Too many line numbers\n");
86518583Sralph 			exit(2);
86618583Sralph 		}
86718583Sralph 		*expbuf++ = CEOF;
86818583Sralph 		cp = rcp;
86918583Sralph 		return(expbuf);
87018583Sralph 	}
87118583Sralph 	return(0);
87218583Sralph }
87318583Sralph cmp(a, b)
87418583Sralph char	*a,*b;
87518583Sralph {
87618583Sralph 	register char	*ra, *rb;
87718583Sralph 
87818583Sralph 	ra = a - 1;
87918583Sralph 	rb = b - 1;
88018583Sralph 
88118583Sralph 	while(*++ra == *++rb)
88218583Sralph 		if(*ra == '\0')	return(0);
88318583Sralph 	return(1);
88418583Sralph }
88518583Sralph 
88618583Sralph char	*text(textbuf)
88718583Sralph char	*textbuf;
88818583Sralph {
88918583Sralph 	register char	*p, *q;
89018583Sralph 
89118583Sralph 	p = textbuf;
89218583Sralph 	q = cp;
89318583Sralph 	while(*q == '\t' || *q == ' ')	q++;
89418583Sralph 	for(;;) {
89518583Sralph 
89618583Sralph 		if((*p = *q++) == '\\')
89718583Sralph 			*p = *q++;
89818583Sralph 		if(*p == '\0') {
89918583Sralph 			cp = --q;
90018583Sralph 			return(++p);
90118583Sralph 		}
90218583Sralph 		if(*p == '\n') {
90318583Sralph 			while(*q == '\t' || *q == ' ')	q++;
90418583Sralph 		}
90518583Sralph 		p++;
90618583Sralph 	}
90718583Sralph }
90818583Sralph 
90918583Sralph 
91018583Sralph struct label	*search(ptr)
91118583Sralph struct label	*ptr;
91218583Sralph {
91318583Sralph 	struct label	*rp;
91418583Sralph 
91518583Sralph 	rp = labtab;
91618583Sralph 	while(rp < ptr) {
91718583Sralph 		if(cmp(rp->asc, ptr->asc) == 0)
91818583Sralph 			return(rp);
91918583Sralph 		rp++;
92018583Sralph 	}
92118583Sralph 
92218583Sralph 	return(0);
92318583Sralph }
92418583Sralph 
92518583Sralph 
92618583Sralph dechain()
92718583Sralph {
92818583Sralph 	struct label	*lptr;
92933076Sbostic 	struct reptr	*rptr, *trptr;
93018583Sralph 
93118583Sralph 	for(lptr = labtab; lptr < lab; lptr++) {
93218583Sralph 
93318583Sralph 		if(lptr->address == 0) {
93418583Sralph 			fprintf(stderr, "Undefined label: %s\n", lptr->asc);
93518583Sralph 			exit(2);
93618583Sralph 		}
93718583Sralph 
93818583Sralph 		if(lptr->chain) {
93918583Sralph 			rptr = lptr->chain;
94018583Sralph 			while(trptr = rptr->lb1) {
94118583Sralph 				rptr->lb1 = lptr->address;
94218583Sralph 				rptr = trptr;
94318583Sralph 			}
94418583Sralph 			rptr->lb1 = lptr->address;
94518583Sralph 		}
94618583Sralph 	}
94718583Sralph }
94818583Sralph 
94918583Sralph char *ycomp(expbuf)
95018583Sralph char	*expbuf;
95118583Sralph {
95218583Sralph 	register char	c, *ep, *tsp;
95318583Sralph 	char	*sp;
95418583Sralph 
95518583Sralph 	ep = expbuf;
95618583Sralph 	sp = cp;
95718583Sralph 	for(tsp = cp; *tsp != seof; tsp++) {
95818583Sralph 		if(*tsp == '\\')
95918583Sralph 			tsp++;
96018583Sralph 		if(*tsp == '\n')
96118583Sralph 			return(badp);
96218583Sralph 	}
96318583Sralph 	tsp++;
96418583Sralph 
96518583Sralph 	while((c = *sp++ & 0177) != seof) {
96618583Sralph 		if(c == '\\' && *sp == 'n') {
96718583Sralph 			sp++;
96818583Sralph 			c = '\n';
96918583Sralph 		}
97018583Sralph 		if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
97118583Sralph 			ep[c] = '\n';
97218583Sralph 			tsp++;
97318583Sralph 		}
97418583Sralph 		if(ep[c] == seof || ep[c] == '\0')
97518583Sralph 			return(badp);
97618583Sralph 	}
97718583Sralph 	if(*tsp != seof)
97818583Sralph 		return(badp);
97918583Sralph 	cp = ++tsp;
98018583Sralph 
98118583Sralph 	for(c = 0; !(c & 0200); c++)
98218583Sralph 		if(ep[c] == 0)
98318583Sralph 			ep[c] = c;
98418583Sralph 
98518583Sralph 	return(ep + 0200);
98618583Sralph }
98732202Sbostic 
98846854Sbostic char *
98932202Sbostic newstr(buf)
99032202Sbostic 	char	*buf;
99132202Sbostic {
99232202Sbostic 	char	*new, *malloc(), *strcpy();
99332202Sbostic 
99432202Sbostic 	if (!(new = malloc((u_int)(strlen(buf) + 1)))) {
99532202Sbostic 		fputs("sed: out of memory.\n", stderr);
99632202Sbostic 		exit(2);
99732202Sbostic 	}
99832202Sbostic 	return(strcpy(new, buf));
99932202Sbostic }
1000