|
|
1.1 root 1: #include <stdio.h>
2: #include "sed.h"
3:
4: struct label *labtab = ltab;
5: char CGMES[] = "command garbled: %s\n";
6: char TMMES[] = "Too much text: %s\n";
7: char LTL[] = "Label too long: %s\n";
8: char AD0MES[] = "No addresses allowed: %s\n";
9: char AD1MES[] = "Only one address allowed: %s\n";
10: char bittab[] = {
11: 1,
12: 2,
13: 4,
14: 8,
15: 16,
16: 32,
17: 64,
18: 128
19: };
20:
21: main(argc, argv)
22: char *argv[];
23: {
24:
25: eargc = argc;
26: eargv = argv;
27:
28: badp = &bad;
29: aptr = abuf;
30: lab = labtab + 1; /* 0 reserved for end-pointer */
31: rep = ptrspace;
32: rep->ad1 = respace;
33: lbend = &linebuf[LBSIZE];
34: hend = &holdsp[LBSIZE];
35: ptrend = &ptrspace[PTRSIZE];
36: reend = &respace[RESIZE];
37: labend = &labtab[LABSIZE];
38: lnum = 0;
39: pending = 0;
40: depth = 0;
41: spend = linebuf;
42: fcode[0] = stdout;
43: nfiles = 1;
44:
45: if(eargc == 1)
46: exit(0);
47:
48:
49: while (--eargc > 0 && (++eargv)[0][0] == '-')
50: switch (eargv[0][1]) {
51:
52: case 'n':
53: nflag++;
54: continue;
55:
56: case 'f':
57: if(eargc-- <= 0) exit(2);
58:
59: if((fin = fopen(*++eargv, "r")) == NULL) {
60: fprintf(stderr, "Cannot open pattern-file: %s\n", *eargv);
61: exit(2);
62: }
63:
64: fcomp();
65: fclose(fin);
66: continue;
67:
68: case 'e':
69: eflag++;
70: fcomp();
71: eflag = 0;
72: continue;
73:
74: case 'g':
75: gflag++;
76: continue;
77:
78: default:
79: fprintf(stdout, "Unknown flag: %c\n", eargv[0][1]);
80: continue;
81: }
82:
83:
84: if(rep == ptrspace) {
85: eargv--;
86: eargc++;
87: eflag++;
88: fcomp();
89: eargv++;
90: eargc--;
91: eflag = 0;
92: }
93:
94: if(depth) {
95: fprintf(stderr, "Too many {'s");
96: exit(2);
97: }
98:
99: labtab->address = rep;
100:
101: dechain();
102:
103: /* abort(); /*DEBUG*/
104:
105: if(eargc <= 0)
106: execute((char *)NULL);
107: else while(--eargc >= 0) {
108: execute(*eargv++);
109: }
110: fclose(stdout);
111: exit(0);
112: }
113: fcomp()
114: {
115:
116: register char *p, *op, *tp;
117: char *address();
118: union reptr *pt, *pt1;
119: int i;
120: struct label *lpt;
121:
122: op = lastre;
123:
124: if(rline(linebuf) < 0) return;
125: if(*linebuf == '#') {
126: if(linebuf[1] == 'n')
127: nflag = 1;
128: }
129: else {
130: cp = linebuf;
131: goto comploop;
132: }
133:
134: for(;;) {
135: if(rline(linebuf) < 0) break;
136:
137: cp = linebuf;
138:
139: comploop:
140: /* fprintf(stdout, "cp: %s\n", cp); /*DEBUG*/
141: while(*cp == ' ' || *cp == '\t') cp++;
142: if(*cp == '\0' || *cp == '#') continue;
143: if(*cp == ';') {
144: cp++;
145: goto comploop;
146: }
147:
148: p = address(rep->ad1);
149: if(p == badp) {
150: fprintf(stderr, CGMES, linebuf);
151: exit(2);
152: }
153:
154: if(p == rep->ad1) {
155: if(op)
156: rep->ad1 = op;
157: else {
158: fprintf(stderr, "First RE may not be null\n");
159: exit(2);
160: }
161: } else if(p == 0) {
162: p = rep->ad1;
163: rep->ad1 = 0;
164: } else {
165: op = rep->ad1;
166: if(*cp == ',' || *cp == ';') {
167: cp++;
168: if((rep->ad2 = p) > reend) {
169: fprintf(stderr, TMMES, linebuf);
170: exit(2);
171: }
172: p = address(rep->ad2);
173: if(p == badp || p == 0) {
174: fprintf(stderr, CGMES, linebuf);
175: exit(2);
176: }
177: if(p == rep->ad2)
178: rep->ad2 = op;
179: else
180: op = rep->ad2;
181:
182: } else
183: rep->ad2 = 0;
184: }
185:
186: if(p > reend) {
187: fprintf(stderr, "Too much text: %s\n", linebuf);
188: exit(2);
189: }
190:
191: while(*cp == ' ' || *cp == '\t') cp++;
192:
193: swit:
194: switch(*cp++) {
195:
196: default:
197: fprintf(stderr, "Unrecognized command: %s\n", linebuf);
198: exit(2);
199:
200: case '!':
201: rep->negfl = 1;
202: goto swit;
203:
204: case '{':
205: rep->command = BCOM;
206: rep->negfl = !(rep->negfl);
207: cmpend[depth++] = &rep->lb1;
208: if(++rep >= ptrend) {
209: fprintf(stderr, "Too many commands: %s\n", linebuf);
210: exit(2);
211: }
212: rep->ad1 = p;
213: if(*cp == '\0') continue;
214:
215: goto comploop;
216:
217: case '}':
218: if(rep->ad1) {
219: fprintf(stderr, AD0MES, linebuf);
220: exit(2);
221: }
222:
223: if(--depth < 0) {
224: fprintf(stderr, "Too many }'s\n");
225: exit(2);
226: }
227: *cmpend[depth] = rep;
228:
229: rep->ad1 = p;
230: continue;
231:
232: case '=':
233: rep->command = EQCOM;
234: if(rep->ad2) {
235: fprintf(stderr, AD1MES, linebuf);
236: exit(2);
237: }
238: break;
239:
240: case ':':
241: if(rep->ad1) {
242: fprintf(stderr, AD0MES, linebuf);
243: exit(2);
244: }
245:
246: while(*cp++ == ' ');
247: cp--;
248:
249:
250: tp = lab->asc;
251: while((*tp++ = *cp++))
252: if(tp >= &(lab->asc[8])) {
253: fprintf(stderr, LTL, linebuf);
254: exit(2);
255: }
256: *--tp = '\0';
257:
258: if(lpt = search(lab)) {
259: if(lpt->address) {
260: fprintf(stderr, "Duplicate labels: %s\n", linebuf);
261: exit(2);
262: }
263: } else {
264: lab->chain = 0;
265: lpt = lab;
266: if(++lab >= labend) {
267: fprintf(stderr, "Too many labels: %s\n", linebuf);
268: exit(2);
269: }
270: }
271: lpt->address = rep;
272: rep->ad1 = p;
273:
274: continue;
275:
276: case 'a':
277: rep->command = ACOM;
278: if(rep->ad2) {
279: fprintf(stderr, AD1MES, linebuf);
280: exit(2);
281: }
282: if(*cp == '\\') cp++;
283: if(*cp++ != '\n') {
284: fprintf(stderr, CGMES, linebuf);
285: exit(2);
286: }
287: rep->re1 = p;
288: p = text(rep->re1);
289: break;
290: case 'c':
291: rep->command = CCOM;
292: if(*cp == '\\') cp++;
293: if(*cp++ != ('\n')) {
294: fprintf(stderr, CGMES, linebuf);
295: exit(2);
296: }
297: rep->re1 = p;
298: p = text(rep->re1);
299: break;
300: case 'i':
301: rep->command = ICOM;
302: if(rep->ad2) {
303: fprintf(stderr, AD1MES, linebuf);
304: exit(2);
305: }
306: if(*cp == '\\') cp++;
307: if(*cp++ != ('\n')) {
308: fprintf(stderr, CGMES, linebuf);
309: exit(2);
310: }
311: rep->re1 = p;
312: p = text(rep->re1);
313: break;
314:
315: case 'g':
316: rep->command = GCOM;
317: break;
318:
319: case 'G':
320: rep->command = CGCOM;
321: break;
322:
323: case 'h':
324: rep->command = HCOM;
325: break;
326:
327: case 'H':
328: rep->command = CHCOM;
329: break;
330:
331: case 't':
332: rep->command = TCOM;
333: goto jtcommon;
334:
335: case 'b':
336: rep->command = BCOM;
337: jtcommon:
338: while(*cp++ == ' ');
339: cp--;
340:
341: if(*cp == '\0') {
342: if(pt = labtab->chain) {
343: while(pt1 = pt->lb1)
344: pt = pt1;
345: pt->lb1 = rep;
346: } else
347: labtab->chain = rep;
348: break;
349: }
350: tp = lab->asc;
351: while((*tp++ = *cp++))
352: if(tp >= &(lab->asc[8])) {
353: fprintf(stderr, LTL, linebuf);
354: exit(2);
355: }
356: cp--;
357: *--tp = '\0';
358:
359: if(lpt = search(lab)) {
360: if(lpt->address) {
361: rep->lb1 = lpt->address;
362: } else {
363: pt = lpt->chain;
364: while(pt1 = pt->lb1)
365: pt = pt1;
366: pt->lb1 = rep;
367: }
368: } else {
369: lab->chain = rep;
370: lab->address = 0;
371: if(++lab >= labend) {
372: fprintf(stderr, "Too many labels: %s\n", linebuf);
373: exit(2);
374: }
375: }
376: break;
377:
378: case 'n':
379: rep->command = NCOM;
380: break;
381:
382: case 'N':
383: rep->command = CNCOM;
384: break;
385:
386: case 'p':
387: rep->command = PCOM;
388: break;
389:
390: case 'P':
391: rep->command = CPCOM;
392: break;
393:
394: case 'r':
395: rep->command = RCOM;
396: if(rep->ad2) {
397: fprintf(stderr, AD1MES, linebuf);
398: exit(2);
399: }
400: if(*cp++ != ' ') {
401: fprintf(stderr, CGMES, linebuf);
402: exit(2);
403: }
404: rep->re1 = p;
405: p = text(rep->re1);
406: break;
407:
408: case 'd':
409: rep->command = DCOM;
410: break;
411:
412: case 'D':
413: rep->command = CDCOM;
414: rep->lb1 = ptrspace;
415: break;
416:
417: case 'q':
418: rep->command = QCOM;
419: if(rep->ad2) {
420: fprintf(stderr, AD1MES, linebuf);
421: exit(2);
422: }
423: break;
424:
425: case 'l':
426: rep->command = LCOM;
427: break;
428:
429: case 's':
430: rep->command = SCOM;
431: seof = *cp++;
432: rep->re1 = p;
433: p = compile(rep->re1);
434: if(p == badp) {
435: fprintf(stderr, CGMES, linebuf);
436: exit(2);
437: }
438: if(p == rep->re1) {
439: rep->re1 = op;
440: } else {
441: op = rep->re1;
442: }
443:
444: if((rep->rhs = p) > reend) {
445: fprintf(stderr, TMMES, linebuf);
446: exit(2);
447: }
448:
449: if((p = compsub(rep->rhs)) == badp) {
450: fprintf(stderr, CGMES, linebuf);
451: exit(2);
452: }
453: if(*cp == 'g') {
454: cp++;
455: rep->gfl++;
456: } else if(gflag)
457: rep->gfl++;
458:
459: if(*cp == 'p') {
460: cp++;
461: rep->pfl = 1;
462: }
463:
464: if(*cp == 'P') {
465: cp++;
466: rep->pfl = 2;
467: }
468:
469: if(*cp == 'w') {
470: cp++;
471: if(*cp++ != ' ') {
472: fprintf(stderr, CGMES, linebuf);
473: exit(2);
474: }
475: if(nfiles >= 10) {
476: fprintf(stderr, "Too many files in w commands\n");
477: exit(2);
478: }
479:
480: text(fname[nfiles]);
481: for(i = nfiles - 1; i >= 0; i--)
482: if(cmp(fname[nfiles],fname[i]) == 0) {
483: rep->fcode = fcode[i];
484: goto done;
485: }
486: if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
487: fprintf(stderr, "cannot open %s\n", fname[nfiles]);
488: exit(2);
489: }
490: fcode[nfiles++] = rep->fcode;
491: }
492: break;
493:
494: case 'w':
495: rep->command = WCOM;
496: if(*cp++ != ' ') {
497: fprintf(stderr, CGMES, linebuf);
498: exit(2);
499: }
500: if(nfiles >= 10){
501: fprintf(stderr, "Too many files in w commands\n");
502: exit(2);
503: }
504:
505: text(fname[nfiles]);
506: for(i = nfiles - 1; i >= 0; i--)
507: if(cmp(fname[nfiles], fname[i]) == 0) {
508: rep->fcode = fcode[i];
509: goto done;
510: }
511:
512: if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
513: fprintf(stderr, "Cannot create %s\n", fname[nfiles]);
514: exit(2);
515: }
516: fcode[nfiles++] = rep->fcode;
517: break;
518:
519: case 'x':
520: rep->command = XCOM;
521: break;
522:
523: case 'y':
524: rep->command = YCOM;
525: seof = *cp++;
526: rep->re1 = p;
527: p = ycomp(rep->re1);
528: if(p == badp) {
529: fprintf(stderr, CGMES, linebuf);
530: exit(2);
531: }
532: if(p > reend) {
533: fprintf(stderr, TMMES, linebuf);
534: exit(2);
535: }
536: break;
537:
538: }
539: done:
540: if(++rep >= ptrend) {
541: fprintf(stderr, "Too many commands, last: %s\n", linebuf);
542: exit(2);
543: }
544:
545: rep->ad1 = p;
546:
547: if(*cp++ != '\0') {
548: if(cp[-1] == ';')
549: goto comploop;
550: fprintf(stderr, CGMES, linebuf);
551: exit(2);
552: }
553:
554: }
555: rep->command = 0;
556: lastre = op;
557: }
558: char *compsub(rhsbuf)
559: char *rhsbuf;
560: {
561: register char *p, *q;
562:
563: p = rhsbuf;
564: q = cp;
565: for(;;) {
566: if((*p = *q++) == '\\') {
567: *p = *q++;
568: if(*p > numbra + '0' && *p <= '9')
569: return(badp);
570: *p++ |= 0200;
571: continue;
572: }
573: if(*p == seof) {
574: *p++ = '\0';
575: cp = q;
576: return(p);
577: }
578: if(*p++ == '\0') {
579: return(badp);
580: }
581:
582: }
583: }
584:
585: char *compile(expbuf)
586: char *expbuf;
587: {
588: register c;
589: register char *ep, *sp;
590: char neg;
591: char *lastep, *cstart;
592: int cclcnt;
593: int closed;
594: char bracket[NBRA], *bracketp;
595:
596: if(*cp == seof) {
597: cp++;
598: return(expbuf);
599: }
600:
601: ep = expbuf;
602: lastep = 0;
603: bracketp = bracket;
604: closed = numbra = 0;
605: sp = cp;
606: if (*sp == '^') {
607: *ep++ = 1;
608: sp++;
609: } else {
610: *ep++ = 0;
611: }
612: for (;;) {
613: if (ep >= &expbuf[ESIZE]) {
614: cp = sp;
615: return(badp);
616: }
617: if((c = *sp++) == seof) {
618: if(bracketp != bracket) {
619: cp = sp;
620: return(badp);
621: }
622: cp = sp;
623: *ep++ = CEOF;
624: return(ep);
625: }
626: if(c != '*')
627: lastep = ep;
628: switch (c) {
629:
630: case '\\':
631: if((c = *sp++) == '(') {
632: if(numbra >= NBRA) {
633: cp = sp;
634: return(badp);
635: }
636: *bracketp++ = numbra;
637: *ep++ = CBRA;
638: *ep++ = numbra++;
639: continue;
640: }
641: if(c == ')') {
642: if(bracketp <= bracket) {
643: cp = sp;
644: return(badp);
645: }
646: *ep++ = CKET;
647: *ep++ = *--bracketp;
648: closed++;
649: continue;
650: }
651:
652: if(c >= '1' && c <= '9') {
653: if((c -= '1') >= closed)
654: return(badp);
655:
656: *ep++ = CBACK;
657: *ep++ = c;
658: continue;
659: }
660: if(c == '\n') {
661: cp = sp;
662: return(badp);
663: }
664: if(c == 'n') {
665: c = '\n';
666: }
667: goto defchar;
668:
669: case '\0':
670: continue;
671: case '\n':
672: cp = sp;
673: return(badp);
674:
675: case '.':
676: *ep++ = CDOT;
677: continue;
678:
679: case '*':
680: if (lastep == 0)
681: goto defchar;
682: if(*lastep == CKET) {
683: cp = sp;
684: return(badp);
685: }
686: *lastep |= STAR;
687: continue;
688:
689: case '$':
690: if (*sp != seof)
691: goto defchar;
692: *ep++ = CDOL;
693: continue;
694:
695: case '[':
696: if(&ep[17] >= &expbuf[ESIZE]) {
697: fprintf(stderr, "RE too long: %s\n", linebuf);
698: exit(2);
699: }
700:
701: *ep++ = CCL;
702:
703: neg = 0;
704: if((c = *sp++) == '^') {
705: neg = 1;
706: c = *sp++;
707: }
708:
709: cstart = sp;
710: do {
711: if(c == '\0') {
712: fprintf(stderr, CGMES, linebuf);
713: exit(2);
714: }
715: if (c=='-' && sp>cstart && *sp!=']') {
716: for (c = sp[-2]; c<*sp; c++)
717: ep[c>>3] |= bittab[c&07];
718: }
719: if(c == '\\') {
720: switch(c = *sp++) {
721: case 'n':
722: c = '\n';
723: break;
724: }
725: }
726:
727: ep[c >> 3] |= bittab[c & 07];
728: } while((c = *sp++) != ']');
729:
730: if(neg)
731: for(cclcnt = 0; cclcnt < 16; cclcnt++)
732: ep[cclcnt] ^= -1;
733: ep[0] &= 0376;
734:
735: ep += 16;
736:
737: continue;
738:
739: defchar:
740: default:
741: *ep++ = CCHR;
742: *ep++ = c;
743: }
744: }
745: }
746: rline(lbuf)
747: char *lbuf;
748: {
749: register char *p, *q;
750: register t;
751: static char *saveq;
752:
753: p = lbuf - 1;
754:
755: if(eflag) {
756: if(eflag > 0) {
757: eflag = -1;
758: if(eargc-- <= 0)
759: exit(2);
760: q = *++eargv;
761: while(*++p = *q++) {
762: if(*p == '\\') {
763: if((*++p = *q++) == '\0') {
764: saveq = 0;
765: return(-1);
766: } else
767: continue;
768: }
769: if(*p == '\n') {
770: *p = '\0';
771: saveq = q;
772: return(1);
773: }
774: }
775: saveq = 0;
776: return(1);
777: }
778: if((q = saveq) == 0) return(-1);
779:
780: while(*++p = *q++) {
781: if(*p == '\\') {
782: if((*++p = *q++) == '0') {
783: saveq = 0;
784: return(-1);
785: } else
786: continue;
787: }
788: if(*p == '\n') {
789: *p = '\0';
790: saveq = q;
791: return(1);
792: }
793: }
794: saveq = 0;
795: return(1);
796: }
797:
798: while((t = getc(fin)) != EOF) {
799: *++p = t;
800: if(*p == '\\') {
801: t = getc(fin);
802: *++p = t;
803: }
804: else if(*p == '\n') {
805: *p = '\0';
806: return(1);
807: }
808: }
809: *++p = '\0';
810: return(-1);
811: }
812:
813: char *address(expbuf)
814: char *expbuf;
815: {
816: register char *rcp;
817: long lno;
818:
819: if(*cp == '$') {
820: cp++;
821: *expbuf++ = CEND;
822: *expbuf++ = CEOF;
823: return(expbuf);
824: }
825:
826: if(*cp == '/') {
827: seof = '/';
828: cp++;
829: return(compile(expbuf));
830: }
831:
832: rcp = cp;
833: lno = 0;
834:
835: while(*rcp >= '0' && *rcp <= '9')
836: lno = lno*10 + *rcp++ - '0';
837:
838: if(rcp > cp) {
839: *expbuf++ = CLNUM;
840: *expbuf++ = nlno;
841: tlno[nlno++] = lno;
842: if(nlno >= NLINES) {
843: fprintf(stderr, "Too many line numbers\n");
844: exit(2);
845: }
846: *expbuf++ = CEOF;
847: cp = rcp;
848: return(expbuf);
849: }
850: return(0);
851: }
852: cmp(a, b)
853: char *a,*b;
854: {
855: register char *ra, *rb;
856:
857: ra = a - 1;
858: rb = b - 1;
859:
860: while(*++ra == *++rb)
861: if(*ra == '\0') return(0);
862: return(1);
863: }
864:
865: char *text(textbuf)
866: char *textbuf;
867: {
868: register char *p, *q;
869:
870: p = textbuf;
871: q = cp;
872: while(*q == '\t' || *q == ' ') q++;
873: for(;;) {
874:
875: if((*p = *q++) == '\\')
876: *p = *q++;
877: if(*p == '\0') {
878: cp = --q;
879: return(++p);
880: }
881: if(*p == '\n') {
882: while(*q == '\t' || *q == ' ') q++;
883: }
884: p++;
885: }
886: }
887:
888:
889: struct label *search(ptr)
890: struct label *ptr;
891: {
892: struct label *rp;
893:
894: rp = labtab;
895: while(rp < ptr) {
896: if(cmp(rp->asc, ptr->asc) == 0)
897: return(rp);
898: rp++;
899: }
900:
901: return(0);
902: }
903:
904:
905: dechain()
906: {
907: struct label *lptr;
908: union reptr *rptr, *trptr;
909:
910: for(lptr = labtab; lptr < lab; lptr++) {
911:
912: if(lptr->address == 0) {
913: fprintf(stderr, "Undefined label: %s\n", lptr->asc);
914: exit(2);
915: }
916:
917: if(lptr->chain) {
918: rptr = lptr->chain;
919: while(trptr = rptr->lb1) {
920: rptr->lb1 = lptr->address;
921: rptr = trptr;
922: }
923: rptr->lb1 = lptr->address;
924: }
925: }
926: }
927:
928: char *ycomp(expbuf)
929: char *expbuf;
930: {
931: register char c, *ep, *tsp;
932: char *sp;
933:
934: ep = expbuf;
935: sp = cp;
936: for(tsp = cp; *tsp != seof; tsp++) {
937: if(*tsp == '\\')
938: tsp++;
939: if(*tsp == '\n')
940: return(badp);
941: }
942: tsp++;
943:
944: while((c = *sp++ & 0177) != seof) {
945: if(c == '\\' && *sp == 'n') {
946: sp++;
947: c = '\n';
948: }
949: if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
950: ep[c] = '\n';
951: tsp++;
952: }
953: if(ep[c] == seof || ep[c] == '\0')
954: return(badp);
955: }
956: if(*tsp != seof)
957: return(badp);
958: cp = ++tsp;
959:
960: for(c = 0; !(c & 0200); c++)
961: if(ep[c] == 0)
962: ep[c] = c;
963:
964: return(ep + 0200);
965: }
966:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.