|
|
1.1 root 1: /* %M% %I% %E% */
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 union 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: union 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: union 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: break;
623: case XCOM:
624: p1 = linebuf;
625: p2 = genbuf;
626: while(*p2++ = *p1++);
627: p1 = holdsp;
628: p2 = linebuf;
629: while(*p2++ = *p1++);
630: spend = p2 - 1;
631: p1 = genbuf;
632: p2 = holdsp;
633: while(*p2++ = *p1++);
634: hspend = p2 - 1;
635: break;
636:
637: case YCOM:
638: p1 = linebuf;
639: p2 = ipc->re1;
640: while(*p1 = p2[*p1]) p1++;
641: break;
642: }
643:
644: }
645:
646: char *
647: gline(addr)
648: char *addr;
649: {
650: register char *p1, *p2;
651: register c;
652: p1 = addr;
653: p2 = cbp;
654: for (;;) {
655: if (p2 >= ebp) {
656: if ((c = read(f, ibuf, BUFSIZ)) <= 0) {
657: return(badp);
658: }
659: p2 = ibuf;
660: ebp = ibuf+c;
661: }
662: if ((c = *p2++) == '\n') {
663: if(p2 >= ebp) {
664: if((c = read(f, ibuf, BUFSIZ)) <= 0) {
665: close(f);
666: if(eargc == 0)
667: dolflag = 1;
668: }
669:
670: p2 = ibuf;
671: ebp = ibuf + c;
672: }
673: break;
674: }
675: if(c)
676: if(p1 < lbend)
677: *p1++ = c;
678: }
679: lnum++;
680: *p1 = 0;
681: cbp = p2;
682:
683: return(p1);
684: }
685: ecmp(a, b, count)
686: char *a, *b;
687: {
688: while(count--)
689: if(*a++ != *b++) return(0);
690: return(1);
691: }
692:
693: arout()
694: {
695: register char *p1;
696: FILE *fi;
697: char c;
698: int t;
699:
700: aptr = abuf - 1;
701: while(*++aptr) {
702: if((*aptr)->command == ACOM) {
703: for(p1 = (*aptr)->re1; *p1; )
704: putc(*p1++, stdout);
705: putc('\n', stdout);
706: } else {
707: if((fi = fopen((*aptr)->re1, "r")) == NULL)
708: continue;
709: while((t = getc(fi)) != EOF) {
710: c = t;
711: putc(c, stdout);
712: }
713: fclose(fi);
714: }
715: }
716: aptr = abuf;
717: *aptr = 0;
718: }
719:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.