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