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