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