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
execute(file)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 }
match(expbuf,gf)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 }
advance(alp,aep)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
dosub(rhsbuf)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 }
place(asp,al1,al2)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 *
gline(addr)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 }
ecmp(a,b,count)692 ecmp(a, b, count)
693 char *a, *b;
694 {
695 while(count--)
696 if(*a++ != *b++) return(0);
697 return(1);
698 }
699
arout()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