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