|
|
1.1 root 1: /* sed0.c 4.2 85/06/19 */
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: if(op)
445: rep->re1 = op;
446: else {
447: fprintf(stderr,
448: "First RE may not be null\n");
449: exit(2);
450: }
451: } else {
452: op = rep->re1;
453: }
454:
455: if((rep->rhs = p) > reend) {
456: fprintf(stderr, TMMES, linebuf);
457: exit(2);
458: }
459:
460: if((p = compsub(rep->rhs)) == badp) {
461: fprintf(stderr, CGMES, linebuf);
462: exit(2);
463: }
464: if(*cp == 'g') {
465: cp++;
466: rep->gfl++;
467: } else if(gflag)
468: rep->gfl++;
469:
470: if(*cp == 'p') {
471: cp++;
472: rep->pfl = 1;
473: }
474:
475: if(*cp == 'P') {
476: cp++;
477: rep->pfl = 2;
478: }
479:
480: if(*cp == 'w') {
481: cp++;
482: if(*cp++ != ' ') {
483: fprintf(stderr, CGMES, linebuf);
484: exit(2);
485: }
486: if(nfiles >= 10) {
487: fprintf(stderr, "Too many files in w commands\n");
488: exit(2);
489: }
490:
491: text(fname[nfiles]);
492: for(i = nfiles - 1; i >= 0; i--)
493: if(cmp(fname[nfiles],fname[i]) == 0) {
494: rep->fcode = fcode[i];
495: goto done;
496: }
497: if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
498: fprintf(stderr, "cannot open %s\n", fname[nfiles]);
499: exit(2);
500: }
501: fcode[nfiles++] = rep->fcode;
502: }
503: break;
504:
505: case 'w':
506: rep->command = WCOM;
507: if(*cp++ != ' ') {
508: fprintf(stderr, CGMES, linebuf);
509: exit(2);
510: }
511: if(nfiles >= 10){
512: fprintf(stderr, "Too many files in w commands\n");
513: exit(2);
514: }
515:
516: text(fname[nfiles]);
517: for(i = nfiles - 1; i >= 0; i--)
518: if(cmp(fname[nfiles], fname[i]) == 0) {
519: rep->fcode = fcode[i];
520: goto done;
521: }
522:
523: if((rep->fcode = fopen(fname[nfiles], "w")) == NULL) {
524: fprintf(stderr, "Cannot create %s\n", fname[nfiles]);
525: exit(2);
526: }
527: fcode[nfiles++] = rep->fcode;
528: break;
529:
530: case 'x':
531: rep->command = XCOM;
532: break;
533:
534: case 'y':
535: rep->command = YCOM;
536: seof = *cp++;
537: rep->re1 = p;
538: p = ycomp(rep->re1);
539: if(p == badp) {
540: fprintf(stderr, CGMES, linebuf);
541: exit(2);
542: }
543: if(p > reend) {
544: fprintf(stderr, TMMES, linebuf);
545: exit(2);
546: }
547: break;
548:
549: }
550: done:
551: if(++rep >= ptrend) {
552: fprintf(stderr, "Too many commands, last: %s\n", linebuf);
553: exit(2);
554: }
555:
556: rep->ad1 = p;
557:
558: if(*cp++ != '\0') {
559: if(cp[-1] == ';')
560: goto comploop;
561: fprintf(stderr, CGMES, linebuf);
562: exit(2);
563: }
564:
565: }
566: rep->command = 0;
567: lastre = op;
568: }
569: char *compsub(rhsbuf)
570: char *rhsbuf;
571: {
572: register char *p, *q;
573:
574: p = rhsbuf;
575: q = cp;
576: for(;;) {
577: if((*p = *q++) == '\\') {
578: *p = *q++;
579: if(*p > numbra + '0' && *p <= '9')
580: return(badp);
581: *p++ |= 0200;
582: continue;
583: }
584: if(*p == seof) {
585: *p++ = '\0';
586: cp = q;
587: return(p);
588: }
589: if(*p++ == '\0') {
590: return(badp);
591: }
592:
593: }
594: }
595:
596: char *compile(expbuf)
597: char *expbuf;
598: {
599: register c;
600: register char *ep, *sp;
601: char neg;
602: char *lastep, *cstart;
603: int cclcnt;
604: int closed;
605: char bracket[NBRA], *bracketp;
606:
607: if(*cp == seof) {
608: cp++;
609: return(expbuf);
610: }
611:
612: ep = expbuf;
613: lastep = 0;
614: bracketp = bracket;
615: closed = numbra = 0;
616: sp = cp;
617: if (*sp == '^') {
618: *ep++ = 1;
619: sp++;
620: } else {
621: *ep++ = 0;
622: }
623: for (;;) {
624: if (ep >= &expbuf[ESIZE]) {
625: cp = sp;
626: return(badp);
627: }
628: if((c = *sp++) == seof) {
629: if(bracketp != bracket) {
630: cp = sp;
631: return(badp);
632: }
633: cp = sp;
634: *ep++ = CEOF;
635: return(ep);
636: }
637: if(c != '*')
638: lastep = ep;
639: switch (c) {
640:
641: case '\\':
642: if((c = *sp++) == '(') {
643: if(numbra >= NBRA) {
644: cp = sp;
645: return(badp);
646: }
647: *bracketp++ = numbra;
648: *ep++ = CBRA;
649: *ep++ = numbra++;
650: continue;
651: }
652: if(c == ')') {
653: if(bracketp <= bracket) {
654: cp = sp;
655: return(badp);
656: }
657: *ep++ = CKET;
658: *ep++ = *--bracketp;
659: closed++;
660: continue;
661: }
662:
663: if(c >= '1' && c <= '9') {
664: if((c -= '1') >= closed)
665: return(badp);
666:
667: *ep++ = CBACK;
668: *ep++ = c;
669: continue;
670: }
671: if(c == '\n') {
672: cp = sp;
673: return(badp);
674: }
675: if(c == 'n') {
676: c = '\n';
677: }
678: goto defchar;
679:
680: case '\0':
681: continue;
682: case '\n':
683: cp = sp;
684: return(badp);
685:
686: case '.':
687: *ep++ = CDOT;
688: continue;
689:
690: case '*':
691: if (lastep == 0)
692: goto defchar;
693: if(*lastep == CKET) {
694: cp = sp;
695: return(badp);
696: }
697: *lastep |= STAR;
698: continue;
699:
700: case '$':
701: if (*sp != seof)
702: goto defchar;
703: *ep++ = CDOL;
704: continue;
705:
706: case '[':
707: if(&ep[17] >= &expbuf[ESIZE]) {
708: fprintf(stderr, "RE too long: %s\n", linebuf);
709: exit(2);
710: }
711:
712: *ep++ = CCL;
713:
714: neg = 0;
715: if((c = *sp++) == '^') {
716: neg = 1;
717: c = *sp++;
718: }
719:
720: cstart = sp;
721: do {
722: if(c == '\0') {
723: fprintf(stderr, CGMES, linebuf);
724: exit(2);
725: }
726: if (c=='-' && sp>cstart && *sp!=']') {
727: for (c = sp[-2]; c<*sp; c++)
728: ep[c>>3] |= bittab[c&07];
729: }
730: if(c == '\\') {
731: switch(c = *sp++) {
732: case 'n':
733: c = '\n';
734: break;
735: }
736: }
737:
738: ep[c >> 3] |= bittab[c & 07];
739: } while((c = *sp++) != ']');
740:
741: if(neg)
742: for(cclcnt = 0; cclcnt < 16; cclcnt++)
743: ep[cclcnt] ^= -1;
744: ep[0] &= 0376;
745:
746: ep += 16;
747:
748: continue;
749:
750: defchar:
751: default:
752: *ep++ = CCHR;
753: *ep++ = c;
754: }
755: }
756: }
757: rline(lbuf)
758: char *lbuf;
759: {
760: register char *p, *q;
761: register t;
762: static char *saveq;
763:
764: p = lbuf - 1;
765:
766: if(eflag) {
767: if(eflag > 0) {
768: eflag = -1;
769: if(eargc-- <= 0)
770: exit(2);
771: q = *++eargv;
772: while(*++p = *q++) {
773: if(*p == '\\') {
774: if((*++p = *q++) == '\0') {
775: saveq = 0;
776: return(-1);
777: } else
778: continue;
779: }
780: if(*p == '\n') {
781: *p = '\0';
782: saveq = q;
783: return(1);
784: }
785: }
786: saveq = 0;
787: return(1);
788: }
789: if((q = saveq) == 0) return(-1);
790:
791: while(*++p = *q++) {
792: if(*p == '\\') {
793: if((*++p = *q++) == '0') {
794: saveq = 0;
795: return(-1);
796: } else
797: continue;
798: }
799: if(*p == '\n') {
800: *p = '\0';
801: saveq = q;
802: return(1);
803: }
804: }
805: saveq = 0;
806: return(1);
807: }
808:
809: while((t = getc(fin)) != EOF) {
810: *++p = t;
811: if(*p == '\\') {
812: t = getc(fin);
813: *++p = t;
814: }
815: else if(*p == '\n') {
816: *p = '\0';
817: return(1);
818: }
819: }
820: *++p = '\0';
821: return(-1);
822: }
823:
824: char *address(expbuf)
825: char *expbuf;
826: {
827: register char *rcp;
828: long lno;
829:
830: if(*cp == '$') {
831: cp++;
832: *expbuf++ = CEND;
833: *expbuf++ = CEOF;
834: return(expbuf);
835: }
836:
837: if(*cp == '/') {
838: seof = '/';
839: cp++;
840: return(compile(expbuf));
841: }
842:
843: rcp = cp;
844: lno = 0;
845:
846: while(*rcp >= '0' && *rcp <= '9')
847: lno = lno*10 + *rcp++ - '0';
848:
849: if(rcp > cp) {
850: *expbuf++ = CLNUM;
851: *expbuf++ = nlno;
852: tlno[nlno++] = lno;
853: if(nlno >= NLINES) {
854: fprintf(stderr, "Too many line numbers\n");
855: exit(2);
856: }
857: *expbuf++ = CEOF;
858: cp = rcp;
859: return(expbuf);
860: }
861: return(0);
862: }
863: cmp(a, b)
864: char *a,*b;
865: {
866: register char *ra, *rb;
867:
868: ra = a - 1;
869: rb = b - 1;
870:
871: while(*++ra == *++rb)
872: if(*ra == '\0') return(0);
873: return(1);
874: }
875:
876: char *text(textbuf)
877: char *textbuf;
878: {
879: register char *p, *q;
880:
881: p = textbuf;
882: q = cp;
883: while(*q == '\t' || *q == ' ') q++;
884: for(;;) {
885:
886: if((*p = *q++) == '\\')
887: *p = *q++;
888: if(*p == '\0') {
889: cp = --q;
890: return(++p);
891: }
892: if(*p == '\n') {
893: while(*q == '\t' || *q == ' ') q++;
894: }
895: p++;
896: }
897: }
898:
899:
900: struct label *search(ptr)
901: struct label *ptr;
902: {
903: struct label *rp;
904:
905: rp = labtab;
906: while(rp < ptr) {
907: if(cmp(rp->asc, ptr->asc) == 0)
908: return(rp);
909: rp++;
910: }
911:
912: return(0);
913: }
914:
915:
916: dechain()
917: {
918: struct label *lptr;
919: union reptr *rptr, *trptr;
920:
921: for(lptr = labtab; lptr < lab; lptr++) {
922:
923: if(lptr->address == 0) {
924: fprintf(stderr, "Undefined label: %s\n", lptr->asc);
925: exit(2);
926: }
927:
928: if(lptr->chain) {
929: rptr = lptr->chain;
930: while(trptr = rptr->lb1) {
931: rptr->lb1 = lptr->address;
932: rptr = trptr;
933: }
934: rptr->lb1 = lptr->address;
935: }
936: }
937: }
938:
939: char *ycomp(expbuf)
940: char *expbuf;
941: {
942: register char c, *ep, *tsp;
943: char *sp;
944:
945: ep = expbuf;
946: sp = cp;
947: for(tsp = cp; *tsp != seof; tsp++) {
948: if(*tsp == '\\')
949: tsp++;
950: if(*tsp == '\n')
951: return(badp);
952: }
953: tsp++;
954:
955: while((c = *sp++ & 0177) != seof) {
956: if(c == '\\' && *sp == 'n') {
957: sp++;
958: c = '\n';
959: }
960: if((ep[c] = *tsp++) == '\\' && *tsp == 'n') {
961: ep[c] = '\n';
962: tsp++;
963: }
964: if(ep[c] == seof || ep[c] == '\0')
965: return(badp);
966: }
967: if(*tsp != seof)
968: return(badp);
969: cp = ++tsp;
970:
971: for(c = 0; !(c & 0200); c++)
972: if(ep[c] == 0)
973: ep[c] = c;
974:
975: return(ep + 0200);
976: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.