xref: /original-bsd/old/sed/sed1.c (revision 60c3b96a)
1 /*	sed1.c	4.3	87/12/21	*/
2 
3 #include	<stdio.h>
4 #include "sed.h"
5 
6 char	*trans[040]  = {
7 	"\\01",
8 	"\\02",
9 	"\\03",
10 	"\\04",
11 	"\\05",
12 	"\\06",
13 	"\\07",
14 	"<-",
15 	">-",
16 	"\n",
17 	"\\13",
18 	"\\14",
19 	"\\15",
20 	"\\16",
21 	"\\17",
22 	"\\20",
23 	"\\21",
24 	"\\22",
25 	"\\23",
26 	"\\24",
27 	"\\25",
28 	"\\26",
29 	"\\27",
30 	"\\30",
31 	"\\31",
32 	"\\32",
33 	"\\33",
34 	"\\34",
35 	"\\35",
36 	"\\36",
37 	"\\37"
38 };
39 char	rub[] = {"\177"};
40 
41 execute(file)
42 char *file;
43 {
44 	register char *p1, *p2;
45 	register struct reptr	*ipc;
46 	int	c;
47 	char	*execp;
48 
49 	if (file) {
50 		if ((f = open(file, 0)) < 0) {
51 			fprintf(stderr, "Can't open %s\n", file);
52 		}
53 	} else
54 		f = 0;
55 
56 	ebp = ibuf;
57 	cbp = ibuf;
58 
59 	if(pending) {
60 		ipc = pending;
61 		pending = 0;
62 		goto yes;
63 	}
64 
65 	for(;;) {
66 		if((execp = gline(linebuf)) == badp) {
67 			close(f);
68 			return;
69 		}
70 		spend = execp;
71 
72 		for(ipc = ptrspace; ipc->command; ) {
73 
74 			p1 = ipc->ad1;
75 			p2 = ipc->ad2;
76 
77 			if(p1) {
78 
79 				if(ipc->inar) {
80 					if(*p2 == CEND) {
81 						p1 = 0;
82 					} else if(*p2 == CLNUM) {
83 						c = p2[1];
84 						if(lnum > tlno[c]) {
85 							ipc->inar = 0;
86 							if(ipc->negfl)
87 								goto yes;
88 							ipc++;
89 							continue;
90 						}
91 						if(lnum == tlno[c]) {
92 							ipc->inar = 0;
93 						}
94 					} else if(match(p2, 0)) {
95 						ipc->inar = 0;
96 					}
97 				} else if(*p1 == CEND) {
98 					if(!dolflag) {
99 						if(ipc->negfl)
100 							goto yes;
101 						ipc++;
102 						continue;
103 					}
104 
105 				} else if(*p1 == CLNUM) {
106 					c = p1[1];
107 					if(lnum != tlno[c]) {
108 						if(ipc->negfl)
109 							goto yes;
110 						ipc++;
111 						continue;
112 					}
113 					if(p2)
114 						ipc->inar = 1;
115 				} else if(match(p1, 0)) {
116 					if(p2)
117 						ipc->inar = 1;
118 				} else {
119 					if(ipc->negfl)
120 						goto yes;
121 					ipc++;
122 					continue;
123 				}
124 			}
125 
126 			if(ipc->negfl) {
127 				ipc++;
128 				continue;
129 			}
130 	yes:
131 			command(ipc);
132 
133 			if(delflag)
134 				break;
135 
136 			if(jflag) {
137 				jflag = 0;
138 				if((ipc = ipc->lb1) == 0) {
139 					ipc = ptrspace;
140 					break;
141 				}
142 			} else
143 				ipc++;
144 
145 		}
146 		if(!nflag && !delflag) {
147 			for(p1 = linebuf; p1 < spend; p1++)
148 				putc(*p1, stdout);
149 			putc('\n', stdout);
150 		}
151 
152 		if(aptr > abuf) {
153 			arout();
154 		}
155 
156 		delflag = 0;
157 
158 	}
159 }
160 match(expbuf, gf)
161 char	*expbuf;
162 {
163 	register char	*p1, *p2, c;
164 
165 	if(gf) {
166 		if(*expbuf)	return(0);
167 		p1 = linebuf;
168 		p2 = genbuf;
169 		while(*p1++ = *p2++);
170 		locs = p1 = loc2;
171 	} else {
172 		p1 = linebuf;
173 		locs = 0;
174 	}
175 
176 	p2 = expbuf;
177 	if(*p2++) {
178 		loc1 = p1;
179 		if(*p2 == CCHR && p2[1] != *p1)
180 			return(0);
181 		return(advance(p1, p2));
182 	}
183 
184 	/* fast check for first character */
185 
186 	if(*p2 == CCHR) {
187 		c = p2[1];
188 		do {
189 			if(*p1 != c)
190 				continue;
191 			if(advance(p1, p2)) {
192 				loc1 = p1;
193 				return(1);
194 			}
195 		} while(*p1++);
196 		return(0);
197 	}
198 
199 	do {
200 		if(advance(p1, p2)) {
201 			loc1 = p1;
202 			return(1);
203 		}
204 	} while(*p1++);
205 	return(0);
206 }
207 advance(alp, aep)
208 char	*alp, *aep;
209 {
210 	register char *lp, *ep, *curlp;
211 	char	c;
212 	char *bbeg;
213 	int	ct;
214 
215 /*fprintf(stderr, "*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep);	/*DEBUG*/
216 
217 	lp = alp;
218 	ep = aep;
219 	for (;;) switch (*ep++) {
220 
221 	case CCHR:
222 		if (*ep++ == *lp++)
223 			continue;
224 		return(0);
225 
226 	case CDOT:
227 		if (*lp++)
228 			continue;
229 		return(0);
230 
231 	case CNL:
232 	case CDOL:
233 		if (*lp == 0)
234 			continue;
235 		return(0);
236 
237 	case CEOF:
238 		loc2 = lp;
239 		return(1);
240 
241 	case CCL:
242 		c = *lp++ & 0177;
243 		if(ep[c>>3] & bittab[c & 07]) {
244 			ep += 16;
245 			continue;
246 		}
247 		return(0);
248 
249 	case CBRA:
250 		braslist[*ep++] = lp;
251 		continue;
252 
253 	case CKET:
254 		braelist[*ep++] = lp;
255 		continue;
256 
257 	case CBACK:
258 		bbeg = braslist[*ep];
259 		ct = braelist[*ep++] - bbeg;
260 
261 		if(ecmp(bbeg, lp, ct)) {
262 			lp += ct;
263 			continue;
264 		}
265 		return(0);
266 
267 	case CBACK|STAR:
268 		bbeg = braslist[*ep];
269 		ct = braelist[*ep++] - bbeg;
270 		curlp = lp;
271 		while(ecmp(bbeg, lp, ct))
272 			lp += ct;
273 
274 		while(lp >= curlp) {
275 			if(advance(lp, ep))	return(1);
276 			lp -= ct;
277 		}
278 		return(0);
279 
280 
281 	case CDOT|STAR:
282 		curlp = lp;
283 		while (*lp++);
284 		goto star;
285 
286 	case CCHR|STAR:
287 		curlp = lp;
288 		while (*lp++ == *ep);
289 		ep++;
290 		goto star;
291 
292 	case CCL|STAR:
293 		curlp = lp;
294 		do {
295 			c = *lp++ & 0177;
296 		} while(ep[c>>3] & bittab[c & 07]);
297 		ep += 16;
298 		goto star;
299 
300 	star:
301 		if(--lp == curlp) {
302 			continue;
303 		}
304 
305 		if(*ep == CCHR) {
306 			c = ep[1];
307 			do {
308 				if(*lp != c)
309 					continue;
310 				if(advance(lp, ep))
311 					return(1);
312 			} while(lp-- > curlp);
313 			return(0);
314 		}
315 
316 		if(*ep == CBACK) {
317 			c = *(braslist[ep[1]]);
318 			do {
319 				if(*lp != c)
320 					continue;
321 				if(advance(lp, ep))
322 					return(1);
323 			} while(lp-- > curlp);
324 			return(0);
325 		}
326 
327 		do {
328 			if(lp == locs)	break;
329 			if (advance(lp, ep))
330 				return(1);
331 		} while (lp-- > curlp);
332 		return(0);
333 
334 	default:
335 		fprintf(stderr, "RE botch, %o\n", *--ep);
336 	}
337 }
338 substitute(ipc)
339 struct reptr	*ipc;
340 {
341 	if(match(ipc->re1, 0) == 0)	return(0);
342 
343 	sflag = 1;
344 	dosub(ipc->rhs);
345 
346 	if(ipc->gfl) {
347 		while(*loc2) {
348 			if(match(ipc->re1, 1) == 0) break;
349 			dosub(ipc->rhs);
350 		}
351 	}
352 	return(1);
353 }
354 
355 dosub(rhsbuf)
356 char	*rhsbuf;
357 {
358 	register char *lp, *sp, *rp;
359 	int c;
360 
361 	lp = linebuf;
362 	sp = genbuf;
363 	rp = rhsbuf;
364 	while (lp < loc1)
365 		*sp++ = *lp++;
366 	while(c = *rp++) {
367 		if (c == '&') {
368 			sp = place(sp, loc1, loc2);
369 			continue;
370 		} else if (c&0200 && (c &= 0177) >= '1' && c < NBRA+'1') {
371 			sp = place(sp, braslist[c-'1'], braelist[c-'1']);
372 			continue;
373 		}
374 		*sp++ = c&0177;
375 		if (sp >= &genbuf[LBSIZE])
376 			fprintf(stderr, "output line too long.\n");
377 	}
378 	lp = loc2;
379 	loc2 = sp - genbuf + linebuf;
380 	while (*sp++ = *lp++)
381 		if (sp >= &genbuf[LBSIZE]) {
382 			fprintf(stderr, "Output line too long.\n");
383 		}
384 	lp = linebuf;
385 	sp = genbuf;
386 	while (*lp++ = *sp++);
387 	spend = lp-1;
388 }
389 char	*place(asp, al1, al2)
390 char	*asp, *al1, *al2;
391 {
392 	register char *sp, *l1, *l2;
393 
394 	sp = asp;
395 	l1 = al1;
396 	l2 = al2;
397 	while (l1 < l2) {
398 		*sp++ = *l1++;
399 		if (sp >= &genbuf[LBSIZE])
400 			fprintf(stderr, "Output line too long.\n");
401 	}
402 	return(sp);
403 }
404 
405 command(ipc)
406 struct reptr	*ipc;
407 {
408 	register int	i;
409 	register char	*p1, *p2, *p3;
410 	char	*execp;
411 
412 
413 	switch(ipc->command) {
414 
415 		case ACOM:
416 			*aptr++ = ipc;
417 			if(aptr >= &abuf[ABUFSIZE]) {
418 				fprintf(stderr, "Too many appends after line %ld\n",
419 					lnum);
420 			}
421 			*aptr = 0;
422 			break;
423 
424 		case CCOM:
425 			delflag = 1;
426 			if(!ipc->inar || dolflag) {
427 				for(p1 = ipc->re1; *p1; )
428 					putc(*p1++, stdout);
429 				putc('\n', stdout);
430 			}
431 			break;
432 		case DCOM:
433 			delflag++;
434 			break;
435 		case CDCOM:
436 			p1 = p2 = linebuf;
437 
438 			while(*p1 != '\n') {
439 				if(*p1++ == 0) {
440 					delflag++;
441 					return;
442 				}
443 			}
444 
445 			p1++;
446 			while(*p2++ = *p1++);
447 			spend = p2-1;
448 			jflag++;
449 			break;
450 
451 		case EQCOM:
452 			fprintf(stdout, "%ld\n", lnum);
453 			break;
454 
455 		case GCOM:
456 			p1 = linebuf;
457 			p2 = holdsp;
458 			while(*p1++ = *p2++);
459 			spend = p1-1;
460 			break;
461 
462 		case CGCOM:
463 			*spend++ = '\n';
464 			p1 = spend;
465 			p2 = holdsp;
466 			while(*p1++ = *p2++)
467 				if(p1 >= lbend)
468 					break;
469 			spend = p1-1;
470 			break;
471 
472 		case HCOM:
473 			p1 = holdsp;
474 			p2 = linebuf;
475 			while(*p1++ = *p2++);
476 			hspend = p1-1;
477 			break;
478 
479 		case CHCOM:
480 			*hspend++ = '\n';
481 			p1 = hspend;
482 			p2 = linebuf;
483 			while(*p1++ = *p2++)
484 				if(p1 >= hend)
485 					break;
486 			hspend = p1-1;
487 			break;
488 
489 		case ICOM:
490 			for(p1 = ipc->re1; *p1; )
491 				putc(*p1++, stdout);
492 			putc('\n', stdout);
493 			break;
494 
495 		case BCOM:
496 			jflag = 1;
497 			break;
498 
499 		case LCOM:
500 			p1 = linebuf;
501 			p2 = genbuf;
502 			genbuf[72] = 0;
503 			while(*p1)
504 				if(*p1 >= 040) {
505 					if(*p1 == 0177) {
506 						p3 = rub;
507 						while(*p2++ = *p3++)
508 							if(p2 >= lcomend) {
509 								*p2 = '\\';
510 								fprintf(stdout, "%s\n", genbuf);
511 								p2 = genbuf;
512 							}
513 						p2--;
514 						p1++;
515 						continue;
516 					}
517 					*p2++ = *p1++;
518 					if(p2 >= lcomend) {
519 						*p2 = '\\';
520 						fprintf(stdout, "%s\n", genbuf);
521 						p2 = genbuf;
522 					}
523 				} else {
524 					p3 = trans[*p1-1];
525 					while(*p2++ = *p3++)
526 						if(p2 >= lcomend) {
527 							*p2 = '\\';
528 							fprintf(stdout, "%s\n", genbuf);
529 							p2 = genbuf;
530 						}
531 					p2--;
532 					p1++;
533 				}
534 			*p2 = 0;
535 			fprintf(stdout, "%s\n", genbuf);
536 			break;
537 
538 		case NCOM:
539 			if(!nflag) {
540 				for(p1 = linebuf; p1 < spend; p1++)
541 					putc(*p1, stdout);
542 				putc('\n', stdout);
543 			}
544 
545 			if(aptr > abuf)
546 				arout();
547 			if((execp = gline(linebuf)) == badp) {
548 				pending = ipc;
549 				delflag = 1;
550 				break;
551 			}
552 			spend = execp;
553 
554 			break;
555 		case CNCOM:
556 			if(aptr > abuf)
557 				arout();
558 			*spend++ = '\n';
559 			if((execp = gline(spend)) == badp) {
560 				pending = ipc;
561 				delflag = 1;
562 				break;
563 			}
564 			spend = execp;
565 			break;
566 
567 		case PCOM:
568 			for(p1 = linebuf; p1 < spend; p1++)
569 				putc(*p1, stdout);
570 			putc('\n', stdout);
571 			break;
572 		case CPCOM:
573 	cpcom:
574 			for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; )
575 				putc(*p1++, stdout);
576 			putc('\n', stdout);
577 			break;
578 
579 		case QCOM:
580 			if(!nflag) {
581 				for(p1 = linebuf; p1 < spend; p1++)
582 					putc(*p1, stdout);
583 				putc('\n', stdout);
584 			}
585 			if(aptr > abuf)	arout();
586 			fclose(stdout);
587 			exit(0);
588 		case RCOM:
589 
590 			*aptr++ = ipc;
591 			if(aptr >= &abuf[ABUFSIZE])
592 				fprintf(stderr, "Too many reads after line%ld\n",
593 					lnum);
594 
595 			*aptr = 0;
596 
597 			break;
598 
599 		case SCOM:
600 			i = substitute(ipc);
601 			if(ipc->pfl && i)
602 				if(ipc->pfl == 1) {
603 					for(p1 = linebuf; p1 < spend; p1++)
604 						putc(*p1, stdout);
605 					putc('\n', stdout);
606 				}
607 				else
608 					goto cpcom;
609 			if(i && ipc->fcode)
610 				goto wcom;
611 			break;
612 
613 		case TCOM:
614 			if(sflag == 0)	break;
615 			sflag = 0;
616 			jflag = 1;
617 			break;
618 
619 		wcom:
620 		case WCOM:
621 			fprintf(ipc->fcode, "%s\n", linebuf);
622 			fflush(ipc->fcode);
623 			break;
624 		case XCOM:
625 			p1 = linebuf;
626 			p2 = genbuf;
627 			while(*p2++ = *p1++);
628 			p1 = holdsp;
629 			p2 = linebuf;
630 			while(*p2++ = *p1++);
631 			spend = p2 - 1;
632 			p1 = genbuf;
633 			p2 = holdsp;
634 			while(*p2++ = *p1++);
635 			hspend = p2 - 1;
636 			break;
637 
638 		case YCOM:
639 			p1 = linebuf;
640 			p2 = ipc->re1;
641 			while(*p1 = p2[*p1])	p1++;
642 			break;
643 	}
644 
645 }
646 
647 char	*
648 gline(addr)
649 char	*addr;
650 {
651 	register char	*p1, *p2;
652 	register	c;
653 	p1 = addr;
654 	p2 = cbp;
655 	for (;;) {
656 		if (p2 >= ebp) {
657 			if ((c = read(f, ibuf, BUFSIZ)) <= 0) {
658 				return(badp);
659 			}
660 			p2 = ibuf;
661 			ebp = ibuf+c;
662 		}
663 		if ((c = *p2++) == '\n') {
664 			if(p2 >=  ebp) {
665 				if((c = read(f, ibuf, BUFSIZ)) <= 0) {
666 					close(f);
667 					if(eargc == 0)
668 							dolflag = 1;
669 				}
670 
671 				p2 = ibuf;
672 				ebp = ibuf + c;
673 			}
674 			break;
675 		}
676 		if(c)
677 		if(p1 < lbend)
678 			*p1++ = c;
679 	}
680 	lnum++;
681 	*p1 = 0;
682 	cbp = p2;
683 
684 	return(p1);
685 }
686 ecmp(a, b, count)
687 char	*a, *b;
688 {
689 	while(count--)
690 		if(*a++ != *b++)	return(0);
691 	return(1);
692 }
693 
694 arout()
695 {
696 	register char	*p1;
697 	FILE	*fi;
698 	char	c;
699 	int	t;
700 
701 	aptr = abuf - 1;
702 	while(*++aptr) {
703 		if((*aptr)->command == ACOM) {
704 			for(p1 = (*aptr)->re1; *p1; )
705 				putc(*p1++, stdout);
706 			putc('\n', stdout);
707 		} else {
708 			if((fi = fopen((*aptr)->re1, "r")) == NULL)
709 				continue;
710 			while((t = getc(fi)) != EOF) {
711 				c = t;
712 				putc(c, stdout);
713 			}
714 			fclose(fi);
715 		}
716 	}
717 	aptr = abuf;
718 	*aptr = 0;
719 }
720 
721