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