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