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