xref: /csrg-svn/old/sed/sed0.c (revision 18583)
1*18583Sralph /*	sed0.c	4.1	85/04/05	*/
2*18583Sralph 
3*18583Sralph #include <stdio.h>
4*18583Sralph #include "sed.h"
5*18583Sralph 
6*18583Sralph struct label	*labtab = ltab;
7*18583Sralph char	CGMES[]	= "command garbled: %s\n";
8*18583Sralph char	TMMES[]	= "Too much text: %s\n";
9*18583Sralph char	LTL[]	= "Label too long: %s\n";
10*18583Sralph char	AD0MES[]	= "No addresses allowed: %s\n";
11*18583Sralph char	AD1MES[]	= "Only one address allowed: %s\n";
12*18583Sralph char	bittab[]  = {
13*18583Sralph 		1,
14*18583Sralph 		2,
15*18583Sralph 		4,
16*18583Sralph 		8,
17*18583Sralph 		16,
18*18583Sralph 		32,
19*18583Sralph 		64,
20*18583Sralph 		128
21*18583Sralph 	};
22*18583Sralph 
23*18583Sralph main(argc, argv)
24*18583Sralph char	*argv[];
25*18583Sralph {
26*18583Sralph 
27*18583Sralph 	eargc = argc;
28*18583Sralph 	eargv = argv;
29*18583Sralph 
30*18583Sralph 	badp = &bad;
31*18583Sralph 	aptr = abuf;
32*18583Sralph 	lab = labtab + 1;	/* 0 reserved for end-pointer */
33*18583Sralph 	rep = ptrspace;
34*18583Sralph 	rep->ad1 = respace;
35*18583Sralph 	lbend = &linebuf[LBSIZE];
36*18583Sralph 	hend = &holdsp[LBSIZE];
37*18583Sralph 	lcomend = &genbuf[71];
38*18583Sralph 	ptrend = &ptrspace[PTRSIZE];
39*18583Sralph 	reend = &respace[RESIZE];
40*18583Sralph 	labend = &labtab[LABSIZE];
41*18583Sralph 	lnum = 0;
42*18583Sralph 	pending = 0;
43*18583Sralph 	depth = 0;
44*18583Sralph 	spend = linebuf;
45*18583Sralph 	hspend = holdsp;
46*18583Sralph 	fcode[0] = stdout;
47*18583Sralph 	nfiles = 1;
48*18583Sralph 
49*18583Sralph 	if(eargc == 1)
50*18583Sralph 		exit(0);
51*18583Sralph 
52*18583Sralph 
53*18583Sralph 	while (--eargc > 0 && (++eargv)[0][0] == '-')
54*18583Sralph 		switch (eargv[0][1]) {
55*18583Sralph 
56*18583Sralph 		case 'n':
57*18583Sralph 			nflag++;
58*18583Sralph 			continue;
59*18583Sralph 
60*18583Sralph 		case 'f':
61*18583Sralph 			if(eargc-- <= 0)	exit(2);
62*18583Sralph 
63*18583Sralph 			if((fin = fopen(*++eargv, "r")) == NULL) {
64*18583Sralph 				fprintf(stderr, "Cannot open pattern-file: %s\n", *eargv);
65*18583Sralph 				exit(2);
66*18583Sralph 			}
67*18583Sralph 
68*18583Sralph 			fcomp();
69*18583Sralph 			fclose(fin);
70*18583Sralph 			continue;
71*18583Sralph 
72*18583Sralph 		case 'e':
73*18583Sralph 			eflag++;
74*18583Sralph 			fcomp();
75*18583Sralph 			eflag = 0;
76*18583Sralph 			continue;
77*18583Sralph 
78*18583Sralph 		case 'g':
79*18583Sralph 			gflag++;
80*18583Sralph 			continue;
81*18583Sralph 
82*18583Sralph 		default:
83*18583Sralph 			fprintf(stdout, "Unknown flag: %c\n", eargv[0][1]);
84*18583Sralph 			continue;
85*18583Sralph 		}
86*18583Sralph 
87*18583Sralph 
88*18583Sralph 	if(compfl == 0) {
89*18583Sralph 		eargv--;
90*18583Sralph 		eargc++;
91*18583Sralph 		eflag++;
92*18583Sralph 		fcomp();
93*18583Sralph 		eargv++;
94*18583Sralph 		eargc--;
95*18583Sralph 		eflag = 0;
96*18583Sralph 	}
97*18583Sralph 
98*18583Sralph 	if(depth) {
99*18583Sralph 		fprintf(stderr, "Too many {'s");
100*18583Sralph 		exit(2);
101*18583Sralph 	}
102*18583Sralph 
103*18583Sralph 	labtab->address = rep;
104*18583Sralph 
105*18583Sralph 	dechain();
106*18583Sralph 
107*18583Sralph /*	abort();	/*DEBUG*/
108*18583Sralph 
109*18583Sralph 	if(eargc <= 0)
110*18583Sralph 		execute((char *)NULL);
111*18583Sralph 	else while(--eargc >= 0) {
112*18583Sralph 		execute(*eargv++);
113*18583Sralph 	}
114*18583Sralph 	fclose(stdout);
115*18583Sralph 	exit(0);
116*18583Sralph }
117*18583Sralph fcomp()
118*18583Sralph {
119*18583Sralph 
120*18583Sralph 	register char	*p, *op, *tp;
121*18583Sralph 	char	*address();
122*18583Sralph 	union reptr	*pt, *pt1;
123*18583Sralph 	int	i;
124*18583Sralph 	struct label	*lpt;
125*18583Sralph 
126*18583Sralph 	compfl = 1;
127*18583Sralph 	op = lastre;
128*18583Sralph 
129*18583Sralph 	if(rline(linebuf) < 0)	return;
130*18583Sralph 	if(*linebuf == '#') {
131*18583Sralph 		if(linebuf[1] == 'n')
132*18583Sralph 			nflag = 1;
133*18583Sralph 	}
134*18583Sralph 	else {
135*18583Sralph 		cp = linebuf;
136*18583Sralph 		goto comploop;
137*18583Sralph 	}
138*18583Sralph 
139*18583Sralph 	for(;;) {
140*18583Sralph 		if(rline(linebuf) < 0)	break;
141*18583Sralph 
142*18583Sralph 		cp = linebuf;
143*18583Sralph 
144*18583Sralph comploop:
145*18583Sralph /*	fprintf(stdout, "cp: %s\n", cp);	/*DEBUG*/
146*18583Sralph 		while(*cp == ' ' || *cp == '\t')	cp++;
147*18583Sralph 		if(*cp == '\0' || *cp == '#')		continue;
148*18583Sralph 		if(*cp == ';') {
149*18583Sralph 			cp++;
150*18583Sralph 			goto comploop;
151*18583Sralph 		}
152*18583Sralph 
153*18583Sralph 		p = address(rep->ad1);
154*18583Sralph 		if(p == badp) {
155*18583Sralph 			fprintf(stderr, CGMES, linebuf);
156*18583Sralph 			exit(2);
157*18583Sralph 		}
158*18583Sralph 
159*18583Sralph 		if(p == rep->ad1) {
160*18583Sralph 			if(op)
161*18583Sralph 				rep->ad1 = op;
162*18583Sralph 			else {
163*18583Sralph 				fprintf(stderr, "First RE may not be null\n");
164*18583Sralph 				exit(2);
165*18583Sralph 			}
166*18583Sralph 		} else if(p == 0) {
167*18583Sralph 			p = rep->ad1;
168*18583Sralph 			rep->ad1 = 0;
169*18583Sralph 		} else {
170*18583Sralph 			op = rep->ad1;
171*18583Sralph 			if(*cp == ',' || *cp == ';') {
172*18583Sralph 				cp++;
173*18583Sralph 				if((rep->ad2 = p) > reend) {
174*18583Sralph 					fprintf(stderr, TMMES, linebuf);
175*18583Sralph 					exit(2);
176*18583Sralph 				}
177*18583Sralph 				p = address(rep->ad2);
178*18583Sralph 				if(p == badp || p == 0) {
179*18583Sralph 					fprintf(stderr, CGMES, linebuf);
180*18583Sralph 					exit(2);
181*18583Sralph 				}
182*18583Sralph 				if(p == rep->ad2)
183*18583Sralph 					rep->ad2 = op;
184*18583Sralph 				else
185*18583Sralph 					op = rep->ad2;
186*18583Sralph 
187*18583Sralph 			} else
188*18583Sralph 				rep->ad2 = 0;
189*18583Sralph 		}
190*18583Sralph 
191*18583Sralph 		if(p > reend) {
192*18583Sralph 			fprintf(stderr, "Too much text: %s\n", linebuf);
193*18583Sralph 			exit(2);
194*18583Sralph 		}
195*18583Sralph 
196*18583Sralph 		while(*cp == ' ' || *cp == '\t')	cp++;
197*18583Sralph 
198*18583Sralph swit:
199*18583Sralph 		switch(*cp++) {
200*18583Sralph 
201*18583Sralph 			default:
202*18583Sralph 				fprintf(stderr, "Unrecognized command: %s\n", linebuf);
203*18583Sralph 				exit(2);
204*18583Sralph 
205*18583Sralph 			case '!':
206*18583Sralph 				rep->negfl = 1;
207*18583Sralph 				goto swit;
208*18583Sralph 
209*18583Sralph 			case '{':
210*18583Sralph 				rep->command = BCOM;
211*18583Sralph 				rep->negfl = !(rep->negfl);
212*18583Sralph 				cmpend[depth++] = &rep->lb1;
213*18583Sralph 				if(++rep >= ptrend) {
214*18583Sralph 					fprintf(stderr, "Too many commands: %s\n", linebuf);
215*18583Sralph 					exit(2);
216*18583Sralph 				}
217*18583Sralph 				rep->ad1 = p;
218*18583Sralph 				if(*cp == '\0')	continue;
219*18583Sralph 
220*18583Sralph 				goto comploop;
221*18583Sralph 
222*18583Sralph 			case '}':
223*18583Sralph 				if(rep->ad1) {
224*18583Sralph 					fprintf(stderr, AD0MES, linebuf);
225*18583Sralph 					exit(2);
226*18583Sralph 				}
227*18583Sralph 
228*18583Sralph 				if(--depth < 0) {
229*18583Sralph 					fprintf(stderr, "Too many }'s\n");
230*18583Sralph 					exit(2);
231*18583Sralph 				}
232*18583Sralph 				*cmpend[depth] = rep;
233*18583Sralph 
234*18583Sralph 				rep->ad1 = p;
235*18583Sralph 				continue;
236*18583Sralph 
237*18583Sralph 			case '=':
238*18583Sralph 				rep->command = EQCOM;
239*18583Sralph 				if(rep->ad2) {
240*18583Sralph 					fprintf(stderr, AD1MES, linebuf);
241*18583Sralph 					exit(2);
242*18583Sralph 				}
243*18583Sralph 				break;
244*18583Sralph 
245*18583Sralph 			case ':':
246*18583Sralph 				if(rep->ad1) {
247*18583Sralph 					fprintf(stderr, AD0MES, linebuf);
248*18583Sralph 					exit(2);
249*18583Sralph 				}
250*18583Sralph 
251*18583Sralph 				while(*cp++ == ' ');
252*18583Sralph 				cp--;
253*18583Sralph 
254*18583Sralph 
255*18583Sralph 				tp = lab->asc;
256*18583Sralph 				while((*tp++ = *cp++))
257*18583Sralph 					if(tp >= &(lab->asc[8])) {
258*18583Sralph 						fprintf(stderr, LTL, linebuf);
259*18583Sralph 						exit(2);
260*18583Sralph 					}
261*18583Sralph 				*--tp = '\0';
262*18583Sralph 
263*18583Sralph 				if(lpt = search(lab)) {
264*18583Sralph 					if(lpt->address) {
265*18583Sralph 						fprintf(stderr, "Duplicate labels: %s\n", linebuf);
266*18583Sralph 						exit(2);
267*18583Sralph 					}
268*18583Sralph 				} else {
269*18583Sralph 					lab->chain = 0;
270*18583Sralph 					lpt = lab;
271*18583Sralph 					if(++lab >= labend) {
272*18583Sralph 						fprintf(stderr, "Too many labels: %s\n", linebuf);
273*18583Sralph 						exit(2);
274*18583Sralph 					}
275*18583Sralph 				}
276*18583Sralph 				lpt->address = rep;
277*18583Sralph 				rep->ad1 = p;
278*18583Sralph 
279*18583Sralph 				continue;
280*18583Sralph 
281*18583Sralph 			case 'a':
282*18583Sralph 				rep->command = ACOM;
283*18583Sralph 				if(rep->ad2) {
284*18583Sralph 					fprintf(stderr, AD1MES, linebuf);
285*18583Sralph 					exit(2);
286*18583Sralph 				}
287*18583Sralph 				if(*cp == '\\')	cp++;
288*18583Sralph 				if(*cp++ != '\n') {
289*18583Sralph 					fprintf(stderr, CGMES, linebuf);
290*18583Sralph 					exit(2);
291*18583Sralph 				}
292*18583Sralph 				rep->re1 = p;
293*18583Sralph 				p = text(rep->re1);
294*18583Sralph 				break;
295*18583Sralph 			case 'c':
296*18583Sralph 				rep->command = CCOM;
297*18583Sralph 				if(*cp == '\\')	cp++;
298*18583Sralph 				if(*cp++ != ('\n')) {
299*18583Sralph 					fprintf(stderr, CGMES, linebuf);
300*18583Sralph 					exit(2);
301*18583Sralph 				}
302*18583Sralph 				rep->re1 = p;
303*18583Sralph 				p = text(rep->re1);
304*18583Sralph 				break;
305*18583Sralph 			case 'i':
306*18583Sralph 				rep->command = ICOM;
307*18583Sralph 				if(rep->ad2) {
308*18583Sralph 					fprintf(stderr, AD1MES, linebuf);
309*18583Sralph 					exit(2);
310*18583Sralph 				}
311*18583Sralph 				if(*cp == '\\')	cp++;
312*18583Sralph 				if(*cp++ != ('\n')) {
313*18583Sralph 					fprintf(stderr, CGMES, linebuf);
314*18583Sralph 					exit(2);
315*18583Sralph 				}
316*18583Sralph 				rep->re1 = p;
317*18583Sralph 				p = text(rep->re1);
318*18583Sralph 				break;
319*18583Sralph 
320*18583Sralph 			case 'g':
321*18583Sralph 				rep->command = GCOM;
322*18583Sralph 				break;
323*18583Sralph 
324*18583Sralph 			case 'G':
325*18583Sralph 				rep->command = CGCOM;
326*18583Sralph 				break;
327*18583Sralph 
328*18583Sralph 			case 'h':
329*18583Sralph 				rep->command = HCOM;
330*18583Sralph 				break;
331*18583Sralph 
332*18583Sralph 			case 'H':
333*18583Sralph 				rep->command = CHCOM;
334*18583Sralph 				break;
335*18583Sralph 
336*18583Sralph 			case 't':
337*18583Sralph 				rep->command = TCOM;
338*18583Sralph 				goto jtcommon;
339*18583Sralph 
340*18583Sralph 			case 'b':
341*18583Sralph 				rep->command = BCOM;
342*18583Sralph jtcommon:
343*18583Sralph 				while(*cp++ == ' ');
344*18583Sralph 				cp--;
345*18583Sralph 
346*18583Sralph 				if(*cp == '\0') {
347*18583Sralph 					if(pt = labtab->chain) {
348*18583Sralph 						while(pt1 = pt->lb1)
349*18583Sralph 							pt = pt1;
350*18583Sralph 						pt->lb1 = rep;
351*18583Sralph 					} else
352*18583Sralph 						labtab->chain = rep;
353*18583Sralph 					break;
354*18583Sralph 				}
355*18583Sralph 				tp = lab->asc;
356*18583Sralph 				while((*tp++ = *cp++))
357*18583Sralph 					if(tp >= &(lab->asc[8])) {
358*18583Sralph 						fprintf(stderr, LTL, linebuf);
359*18583Sralph 						exit(2);
360*18583Sralph 					}
361*18583Sralph 				cp--;
362*18583Sralph 				*--tp = '\0';
363*18583Sralph 
364*18583Sralph 				if(lpt = search(lab)) {
365*18583Sralph 					if(lpt->address) {
366*18583Sralph 						rep->lb1 = lpt->address;
367*18583Sralph 					} else {
368*18583Sralph 						pt = lpt->chain;
369*18583Sralph 						while(pt1 = pt->lb1)
370*18583Sralph 							pt = pt1;
371*18583Sralph 						pt->lb1 = rep;
372*18583Sralph 					}
373*18583Sralph 				} else {
374*18583Sralph 					lab->chain = rep;
375*18583Sralph 					lab->address = 0;
376*18583Sralph 					if(++lab >= labend) {
377*18583Sralph 						fprintf(stderr, "Too many labels: %s\n", linebuf);
378*18583Sralph 						exit(2);
379*18583Sralph 					}
380*18583Sralph 				}
381*18583Sralph 				break;
382*18583Sralph 
383*18583Sralph 			case 'n':
384*18583Sralph 				rep->command = NCOM;
385*18583Sralph 				break;
386*18583Sralph 
387*18583Sralph 			case 'N':
388*18583Sralph 				rep->command = CNCOM;
389*18583Sralph 				break;
390*18583Sralph 
391*18583Sralph 			case 'p':
392*18583Sralph 				rep->command = PCOM;
393*18583Sralph 				break;
394*18583Sralph 
395*18583Sralph 			case 'P':
396*18583Sralph 				rep->command = CPCOM;
397*18583Sralph 				break;
398*18583Sralph 
399*18583Sralph 			case 'r':
400*18583Sralph 				rep->command = RCOM;
401*18583Sralph 				if(rep->ad2) {
402*18583Sralph 					fprintf(stderr, AD1MES, linebuf);
403*18583Sralph 					exit(2);
404*18583Sralph 				}
405*18583Sralph 				if(*cp++ != ' ') {
406*18583Sralph 					fprintf(stderr, CGMES, linebuf);
407*18583Sralph 					exit(2);
408*18583Sralph 				}
409*18583Sralph 				rep->re1 = p;
410*18583Sralph 				p = text(rep->re1);
411*18583Sralph 				break;
412*18583Sralph 
413*18583Sralph 			case 'd':
414*18583Sralph 				rep->command = DCOM;
415*18583Sralph 				break;
416*18583Sralph 
417*18583Sralph 			case 'D':
418*18583Sralph 				rep->command = CDCOM;
419*18583Sralph 				rep->lb1 = ptrspace;
420*18583Sralph 				break;
421*18583Sralph 
422*18583Sralph 			case 'q':
423*18583Sralph 				rep->command = QCOM;
424*18583Sralph 				if(rep->ad2) {
425*18583Sralph 					fprintf(stderr, AD1MES, linebuf);
426*18583Sralph 					exit(2);
427*18583Sralph 				}
428*18583Sralph 				break;
429*18583Sralph 
430*18583Sralph 			case 'l':
431*18583Sralph 				rep->command = LCOM;
432*18583Sralph 				break;
433*18583Sralph 
434*18583Sralph 			case 's':
435*18583Sralph 				rep->command = SCOM;
436*18583Sralph 				seof = *cp++;
437*18583Sralph 				rep->re1 = p;
438*18583Sralph 				p = compile(rep->re1);
439*18583Sralph 				if(p == badp) {
440*18583Sralph 					fprintf(stderr, CGMES, linebuf);
441*18583Sralph 					exit(2);
442*18583Sralph 				}
443*18583Sralph 				if(p == rep->re1) {
444*18583Sralph 					rep->re1 = op;
445*18583Sralph 				} else {
446*18583Sralph 					op = rep->re1;
447*18583Sralph 				}
448*18583Sralph 
449*18583Sralph 				if((rep->rhs = p) > reend) {
450*18583Sralph 					fprintf(stderr, TMMES, linebuf);
451*18583Sralph 					exit(2);
452*18583Sralph 				}
453*18583Sralph 
454*18583Sralph 				if((p = compsub(rep->rhs)) == badp) {
455*18583Sralph 					fprintf(stderr, CGMES, linebuf);
456*18583Sralph 					exit(2);
457*18583Sralph 				}
458*18583Sralph 				if(*cp == 'g') {
459*18583Sralph 					cp++;
460*18583Sralph 					rep->gfl++;
461*18583Sralph 				} else if(gflag)
462*18583Sralph 					rep->gfl++;
463*18583Sralph 
464*18583Sralph 				if(*cp == 'p') {
465*18583Sralph 					cp++;
466*18583Sralph 					rep->pfl = 1;
467*18583Sralph 				}
468*18583Sralph 
469*18583Sralph 				if(*cp == 'P') {
470*18583Sralph 					cp++;
471*18583Sralph 					rep->pfl = 2;
472*18583Sralph 				}
473*18583Sralph 
474*18583Sralph 				if(*cp == 'w') {
475*18583Sralph 					cp++;
476*18583Sralph 					if(*cp++ !=  ' ') {
477*18583Sralph 						fprintf(stderr, CGMES, linebuf);
478*18583Sralph 						exit(2);
479*18583Sralph 					}
480*18583Sralph 					if(nfiles >= 10) {
481*18583Sralph 						fprintf(stderr, "Too many files in w commands\n");
482*18583Sralph 						exit(2);
483*18583Sralph 					}
484*18583Sralph 
485*18583Sralph 					text(fname[nfiles]);
486*18583Sralph 					for(i = nfiles - 1; i >= 0; i--)
487*18583Sralph 						if(cmp(fname[nfiles],fname[i]) == 0) {
488*18583Sralph 							rep->fcode = fcode[i];
489*18583Sralph 							goto done;
490*18583Sralph 						}
491*18583Sralph 					if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
492*18583Sralph 						fprintf(stderr, "cannot open %s\n", fname[nfiles]);
493*18583Sralph 						exit(2);
494*18583Sralph 					}
495*18583Sralph 					fcode[nfiles++] = rep->fcode;
496*18583Sralph 				}
497*18583Sralph 				break;
498*18583Sralph 
499*18583Sralph 			case 'w':
500*18583Sralph 				rep->command = WCOM;
501*18583Sralph 				if(*cp++ != ' ') {
502*18583Sralph 					fprintf(stderr, CGMES, linebuf);
503*18583Sralph 					exit(2);
504*18583Sralph 				}
505*18583Sralph 				if(nfiles >= 10){
506*18583Sralph 					fprintf(stderr, "Too many files in w commands\n");
507*18583Sralph 					exit(2);
508*18583Sralph 				}
509*18583Sralph 
510*18583Sralph 				text(fname[nfiles]);
511*18583Sralph 				for(i = nfiles - 1; i >= 0; i--)
512*18583Sralph 					if(cmp(fname[nfiles], fname[i]) == 0) {
513*18583Sralph 						rep->fcode = fcode[i];
514*18583Sralph 						goto done;
515*18583Sralph 					}
516*18583Sralph 
517*18583Sralph 				if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
518*18583Sralph 					fprintf(stderr, "Cannot create %s\n", fname[nfiles]);
519*18583Sralph 					exit(2);
520*18583Sralph 				}
521*18583Sralph 				fcode[nfiles++] = rep->fcode;
522*18583Sralph 				break;
523*18583Sralph 
524*18583Sralph 			case 'x':
525*18583Sralph 				rep->command = XCOM;
526*18583Sralph 				break;
527*18583Sralph 
528*18583Sralph 			case 'y':
529*18583Sralph 				rep->command = YCOM;
530*18583Sralph 				seof = *cp++;
531*18583Sralph 				rep->re1 = p;
532*18583Sralph 				p = ycomp(rep->re1);
533*18583Sralph 				if(p == badp) {
534*18583Sralph 					fprintf(stderr, CGMES, linebuf);
535*18583Sralph 					exit(2);
536*18583Sralph 				}
537*18583Sralph 				if(p > reend) {
538*18583Sralph 					fprintf(stderr, TMMES, linebuf);
539*18583Sralph 					exit(2);
540*18583Sralph 				}
541*18583Sralph 				break;
542*18583Sralph 
543*18583Sralph 		}
544*18583Sralph done:
545*18583Sralph 		if(++rep >= ptrend) {
546*18583Sralph 			fprintf(stderr, "Too many commands, last: %s\n", linebuf);
547*18583Sralph 			exit(2);
548*18583Sralph 		}
549*18583Sralph 
550*18583Sralph 		rep->ad1 = p;
551*18583Sralph 
552*18583Sralph 		if(*cp++ != '\0') {
553*18583Sralph 			if(cp[-1] == ';')
554*18583Sralph 				goto comploop;
555*18583Sralph 			fprintf(stderr, CGMES, linebuf);
556*18583Sralph 			exit(2);
557*18583Sralph 		}
558*18583Sralph 
559*18583Sralph 	}
560*18583Sralph 	rep->command = 0;
561*18583Sralph 	lastre = op;
562*18583Sralph }
563*18583Sralph char	*compsub(rhsbuf)
564*18583Sralph char	*rhsbuf;
565*18583Sralph {
566*18583Sralph 	register char	*p, *q;
567*18583Sralph 
568*18583Sralph 	p = rhsbuf;
569*18583Sralph 	q = cp;
570*18583Sralph 	for(;;) {
571*18583Sralph 		if((*p = *q++) == '\\') {
572*18583Sralph 			*p = *q++;
573*18583Sralph 			if(*p > numbra + '0' && *p <= '9')
574*18583Sralph 				return(badp);
575*18583Sralph 			*p++ |= 0200;
576*18583Sralph 			continue;
577*18583Sralph 		}
578*18583Sralph 		if(*p == seof) {
579*18583Sralph 			*p++ = '\0';
580*18583Sralph 			cp = q;
581*18583Sralph 			return(p);
582*18583Sralph 		}
583*18583Sralph 		if(*p++ == '\0') {
584*18583Sralph 			return(badp);
585*18583Sralph 		}
586*18583Sralph 
587*18583Sralph 	}
588*18583Sralph }
589*18583Sralph 
590*18583Sralph char *compile(expbuf)
591*18583Sralph char	*expbuf;
592*18583Sralph {
593*18583Sralph 	register c;
594*18583Sralph 	register char *ep, *sp;
595*18583Sralph 	char	neg;
596*18583Sralph 	char *lastep, *cstart;
597*18583Sralph 	int cclcnt;
598*18583Sralph 	int	closed;
599*18583Sralph 	char	bracket[NBRA], *bracketp;
600*18583Sralph 
601*18583Sralph 	if(*cp == seof) {
602*18583Sralph 		cp++;
603*18583Sralph 		return(expbuf);
604*18583Sralph 	}
605*18583Sralph 
606*18583Sralph 	ep = expbuf;
607*18583Sralph 	lastep = 0;
608*18583Sralph 	bracketp = bracket;
609*18583Sralph 	closed = numbra = 0;
610*18583Sralph 	sp = cp;
611*18583Sralph 	if (*sp == '^') {
612*18583Sralph 		*ep++ = 1;
613*18583Sralph 		sp++;
614*18583Sralph 	} else {
615*18583Sralph 		*ep++ = 0;
616*18583Sralph 	}
617*18583Sralph 	for (;;) {
618*18583Sralph 		if (ep >= &expbuf[ESIZE]) {
619*18583Sralph 			cp = sp;
620*18583Sralph 			return(badp);
621*18583Sralph 		}
622*18583Sralph 		if((c = *sp++) == seof) {
623*18583Sralph 			if(bracketp != bracket) {
624*18583Sralph 				cp = sp;
625*18583Sralph 				return(badp);
626*18583Sralph 			}
627*18583Sralph 			cp = sp;
628*18583Sralph 			*ep++ = CEOF;
629*18583Sralph 			return(ep);
630*18583Sralph 		}
631*18583Sralph 		if(c != '*')
632*18583Sralph 			lastep = ep;
633*18583Sralph 		switch (c) {
634*18583Sralph 
635*18583Sralph 		case '\\':
636*18583Sralph 			if((c = *sp++) == '(') {
637*18583Sralph 				if(numbra >= NBRA) {
638*18583Sralph 					cp = sp;
639*18583Sralph 					return(badp);
640*18583Sralph 				}
641*18583Sralph 				*bracketp++ = numbra;
642*18583Sralph 				*ep++ = CBRA;
643*18583Sralph 				*ep++ = numbra++;
644*18583Sralph 				continue;
645*18583Sralph 			}
646*18583Sralph 			if(c == ')') {
647*18583Sralph 				if(bracketp <= bracket) {
648*18583Sralph 					cp = sp;
649*18583Sralph 					return(badp);
650*18583Sralph 				}
651*18583Sralph 				*ep++ = CKET;
652*18583Sralph 				*ep++ = *--bracketp;
653*18583Sralph 				closed++;
654*18583Sralph 				continue;
655*18583Sralph 			}
656*18583Sralph 
657*18583Sralph 			if(c >= '1' && c <= '9') {
658*18583Sralph 				if((c -= '1') >= closed)
659*18583Sralph 					return(badp);
660*18583Sralph 
661*18583Sralph 				*ep++ = CBACK;
662*18583Sralph 				*ep++ = c;
663*18583Sralph 				continue;
664*18583Sralph 			}
665*18583Sralph 			if(c == '\n') {
666*18583Sralph 				cp = sp;
667*18583Sralph 				return(badp);
668*18583Sralph 			}
669*18583Sralph 			if(c == 'n') {
670*18583Sralph 				c = '\n';
671*18583Sralph 			}
672*18583Sralph 			goto defchar;
673*18583Sralph 
674*18583Sralph 		case '\0':
675*18583Sralph 			continue;
676*18583Sralph 		case '\n':
677*18583Sralph 			cp = sp;
678*18583Sralph 			return(badp);
679*18583Sralph 
680*18583Sralph 		case '.':
681*18583Sralph 			*ep++ = CDOT;
682*18583Sralph 			continue;
683*18583Sralph 
684*18583Sralph 		case '*':
685*18583Sralph 			if (lastep == 0)
686*18583Sralph 				goto defchar;
687*18583Sralph 			if(*lastep == CKET) {
688*18583Sralph 				cp = sp;
689*18583Sralph 				return(badp);
690*18583Sralph 			}
691*18583Sralph 			*lastep |= STAR;
692*18583Sralph 			continue;
693*18583Sralph 
694*18583Sralph 		case '$':
695*18583Sralph 			if (*sp != seof)
696*18583Sralph 				goto defchar;
697*18583Sralph 			*ep++ = CDOL;
698*18583Sralph 			continue;
699*18583Sralph 
700*18583Sralph 		case '[':
701*18583Sralph 			if(&ep[17] >= &expbuf[ESIZE]) {
702*18583Sralph 				fprintf(stderr, "RE too long: %s\n", linebuf);
703*18583Sralph 				exit(2);
704*18583Sralph 			}
705*18583Sralph 
706*18583Sralph 			*ep++ = CCL;
707*18583Sralph 
708*18583Sralph 			neg = 0;
709*18583Sralph 			if((c = *sp++) == '^') {
710*18583Sralph 				neg = 1;
711*18583Sralph 				c = *sp++;
712*18583Sralph 			}
713*18583Sralph 
714*18583Sralph 			cstart = sp;
715*18583Sralph 			do {
716*18583Sralph 				if(c == '\0') {
717*18583Sralph 					fprintf(stderr, CGMES, linebuf);
718*18583Sralph 					exit(2);
719*18583Sralph 				}
720*18583Sralph 				if (c=='-' && sp>cstart && *sp!=']') {
721*18583Sralph 					for (c = sp[-2]; c<*sp; c++)
722*18583Sralph 						ep[c>>3] |= bittab[c&07];
723*18583Sralph 				}
724*18583Sralph 				if(c == '\\') {
725*18583Sralph 					switch(c = *sp++) {
726*18583Sralph 						case 'n':
727*18583Sralph 							c = '\n';
728*18583Sralph 							break;
729*18583Sralph 					}
730*18583Sralph 				}
731*18583Sralph 
732*18583Sralph 				ep[c >> 3] |= bittab[c & 07];
733*18583Sralph 			} while((c = *sp++) != ']');
734*18583Sralph 
735*18583Sralph 			if(neg)
736*18583Sralph 				for(cclcnt = 0; cclcnt < 16; cclcnt++)
737*18583Sralph 					ep[cclcnt] ^= -1;
738*18583Sralph 			ep[0] &= 0376;
739*18583Sralph 
740*18583Sralph 			ep += 16;
741*18583Sralph 
742*18583Sralph 			continue;
743*18583Sralph 
744*18583Sralph 		defchar:
745*18583Sralph 		default:
746*18583Sralph 			*ep++ = CCHR;
747*18583Sralph 			*ep++ = c;
748*18583Sralph 		}
749*18583Sralph 	}
750*18583Sralph }
751*18583Sralph rline(lbuf)
752*18583Sralph char	*lbuf;
753*18583Sralph {
754*18583Sralph 	register char	*p, *q;
755*18583Sralph 	register	t;
756*18583Sralph 	static char	*saveq;
757*18583Sralph 
758*18583Sralph 	p = lbuf - 1;
759*18583Sralph 
760*18583Sralph 	if(eflag) {
761*18583Sralph 		if(eflag > 0) {
762*18583Sralph 			eflag = -1;
763*18583Sralph 			if(eargc-- <= 0)
764*18583Sralph 				exit(2);
765*18583Sralph 			q = *++eargv;
766*18583Sralph 			while(*++p = *q++) {
767*18583Sralph 				if(*p == '\\') {
768*18583Sralph 					if((*++p = *q++) == '\0') {
769*18583Sralph 						saveq = 0;
770*18583Sralph 						return(-1);
771*18583Sralph 					} else
772*18583Sralph 						continue;
773*18583Sralph 				}
774*18583Sralph 				if(*p == '\n') {
775*18583Sralph 					*p = '\0';
776*18583Sralph 					saveq = q;
777*18583Sralph 					return(1);
778*18583Sralph 				}
779*18583Sralph 			}
780*18583Sralph 			saveq = 0;
781*18583Sralph 			return(1);
782*18583Sralph 		}
783*18583Sralph 		if((q = saveq) == 0)	return(-1);
784*18583Sralph 
785*18583Sralph 		while(*++p = *q++) {
786*18583Sralph 			if(*p == '\\') {
787*18583Sralph 				if((*++p = *q++) == '0') {
788*18583Sralph 					saveq = 0;
789*18583Sralph 					return(-1);
790*18583Sralph 				} else
791*18583Sralph 					continue;
792*18583Sralph 			}
793*18583Sralph 			if(*p == '\n') {
794*18583Sralph 				*p = '\0';
795*18583Sralph 				saveq = q;
796*18583Sralph 				return(1);
797*18583Sralph 			}
798*18583Sralph 		}
799*18583Sralph 		saveq = 0;
800*18583Sralph 		return(1);
801*18583Sralph 	}
802*18583Sralph 
803*18583Sralph 	while((t = getc(fin)) != EOF) {
804*18583Sralph 		*++p = t;
805*18583Sralph 		if(*p == '\\') {
806*18583Sralph 			t = getc(fin);
807*18583Sralph 			*++p = t;
808*18583Sralph 		}
809*18583Sralph 		else if(*p == '\n') {
810*18583Sralph 			*p = '\0';
811*18583Sralph 			return(1);
812*18583Sralph 		}
813*18583Sralph 	}
814*18583Sralph 	*++p = '\0';
815*18583Sralph 	return(-1);
816*18583Sralph }
817*18583Sralph 
818*18583Sralph char	*address(expbuf)
819*18583Sralph char	*expbuf;
820*18583Sralph {
821*18583Sralph 	register char	*rcp;
822*18583Sralph 	long	lno;
823*18583Sralph 
824*18583Sralph 	if(*cp == '$') {
825*18583Sralph 		cp++;
826*18583Sralph 		*expbuf++ = CEND;
827*18583Sralph 		*expbuf++ = CEOF;
828*18583Sralph 		return(expbuf);
829*18583Sralph 	}
830*18583Sralph 
831*18583Sralph 	if(*cp == '/') {
832*18583Sralph 		seof = '/';
833*18583Sralph 		cp++;
834*18583Sralph 		return(compile(expbuf));
835*18583Sralph 	}
836*18583Sralph 
837*18583Sralph 	rcp = cp;
838*18583Sralph 	lno = 0;
839*18583Sralph 
840*18583Sralph 	while(*rcp >= '0' && *rcp <= '9')
841*18583Sralph 		lno = lno*10 + *rcp++ - '0';
842*18583Sralph 
843*18583Sralph 	if(rcp > cp) {
844*18583Sralph 		*expbuf++ = CLNUM;
845*18583Sralph 		*expbuf++ = nlno;
846*18583Sralph 		tlno[nlno++] = lno;
847*18583Sralph 		if(nlno >= NLINES) {
848*18583Sralph 			fprintf(stderr, "Too many line numbers\n");
849*18583Sralph 			exit(2);
850*18583Sralph 		}
851*18583Sralph 		*expbuf++ = CEOF;
852*18583Sralph 		cp = rcp;
853*18583Sralph 		return(expbuf);
854*18583Sralph 	}
855*18583Sralph 	return(0);
856*18583Sralph }
857*18583Sralph cmp(a, b)
858*18583Sralph char	*a,*b;
859*18583Sralph {
860*18583Sralph 	register char	*ra, *rb;
861*18583Sralph 
862*18583Sralph 	ra = a - 1;
863*18583Sralph 	rb = b - 1;
864*18583Sralph 
865*18583Sralph 	while(*++ra == *++rb)
866*18583Sralph 		if(*ra == '\0')	return(0);
867*18583Sralph 	return(1);
868*18583Sralph }
869*18583Sralph 
870*18583Sralph char	*text(textbuf)
871*18583Sralph char	*textbuf;
872*18583Sralph {
873*18583Sralph 	register char	*p, *q;
874*18583Sralph 
875*18583Sralph 	p = textbuf;
876*18583Sralph 	q = cp;
877*18583Sralph 	while(*q == '\t' || *q == ' ')	q++;
878*18583Sralph 	for(;;) {
879*18583Sralph 
880*18583Sralph 		if((*p = *q++) == '\\')
881*18583Sralph 			*p = *q++;
882*18583Sralph 		if(*p == '\0') {
883*18583Sralph 			cp = --q;
884*18583Sralph 			return(++p);
885*18583Sralph 		}
886*18583Sralph 		if(*p == '\n') {
887*18583Sralph 			while(*q == '\t' || *q == ' ')	q++;
888*18583Sralph 		}
889*18583Sralph 		p++;
890*18583Sralph 	}
891*18583Sralph }
892*18583Sralph 
893*18583Sralph 
894*18583Sralph struct label	*search(ptr)
895*18583Sralph struct label	*ptr;
896*18583Sralph {
897*18583Sralph 	struct label	*rp;
898*18583Sralph 
899*18583Sralph 	rp = labtab;
900*18583Sralph 	while(rp < ptr) {
901*18583Sralph 		if(cmp(rp->asc, ptr->asc) == 0)
902*18583Sralph 			return(rp);
903*18583Sralph 		rp++;
904*18583Sralph 	}
905*18583Sralph 
906*18583Sralph 	return(0);
907*18583Sralph }
908*18583Sralph 
909*18583Sralph 
910*18583Sralph dechain()
911*18583Sralph {
912*18583Sralph 	struct label	*lptr;
913*18583Sralph 	union reptr	*rptr, *trptr;
914*18583Sralph 
915*18583Sralph 	for(lptr = labtab; lptr < lab; lptr++) {
916*18583Sralph 
917*18583Sralph 		if(lptr->address == 0) {
918*18583Sralph 			fprintf(stderr, "Undefined label: %s\n", lptr->asc);
919*18583Sralph 			exit(2);
920*18583Sralph 		}
921*18583Sralph 
922*18583Sralph 		if(lptr->chain) {
923*18583Sralph 			rptr = lptr->chain;
924*18583Sralph 			while(trptr = rptr->lb1) {
925*18583Sralph 				rptr->lb1 = lptr->address;
926*18583Sralph 				rptr = trptr;
927*18583Sralph 			}
928*18583Sralph 			rptr->lb1 = lptr->address;
929*18583Sralph 		}
930*18583Sralph 	}
931*18583Sralph }
932*18583Sralph 
933*18583Sralph char *ycomp(expbuf)
934*18583Sralph char	*expbuf;
935*18583Sralph {
936*18583Sralph 	register char	c, *ep, *tsp;
937*18583Sralph 	char	*sp;
938*18583Sralph 
939*18583Sralph 	ep = expbuf;
940*18583Sralph 	sp = cp;
941*18583Sralph 	for(tsp = cp; *tsp != seof; tsp++) {
942*18583Sralph 		if(*tsp == '\\')
943*18583Sralph 			tsp++;
944*18583Sralph 		if(*tsp == '\n')
945*18583Sralph 			return(badp);
946*18583Sralph 	}
947*18583Sralph 	tsp++;
948*18583Sralph 
949*18583Sralph 	while((c = *sp++ & 0177) != seof) {
950*18583Sralph 		if(c == '\\' && *sp == 'n') {
951*18583Sralph 			sp++;
952*18583Sralph 			c = '\n';
953*18583Sralph 		}
954*18583Sralph 		if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
955*18583Sralph 			ep[c] = '\n';
956*18583Sralph 			tsp++;
957*18583Sralph 		}
958*18583Sralph 		if(ep[c] == seof || ep[c] == '\0')
959*18583Sralph 			return(badp);
960*18583Sralph 	}
961*18583Sralph 	if(*tsp != seof)
962*18583Sralph 		return(badp);
963*18583Sralph 	cp = ++tsp;
964*18583Sralph 
965*18583Sralph 	for(c = 0; !(c & 0200); c++)
966*18583Sralph 		if(ep[c] == 0)
967*18583Sralph 			ep[c] = c;
968*18583Sralph 
969*18583Sralph 	return(ep + 0200);
970*18583Sralph }
971