Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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