1 static char *sccsid = "@(#)tr.c 4.1 (Berkeley) 10/01/80"; 2 #include <stdio.h> 3 4 /* tr - transliterate data stream */ 5 int dflag = 0; 6 int sflag = 0; 7 int cflag = 0; 8 int save = 0; 9 char code[256]; 10 char squeez[256]; 11 char vect[256]; 12 struct string { int last, max; char *p; } string1, string2; 13 14 main(argc,argv) 15 char **argv; 16 { 17 register i; 18 int j; 19 register c, d; 20 char *compl; 21 int lastd; 22 23 string1.last = string2.last = 0; 24 string1.max = string2.max = 0; 25 string1.p = string2.p = ""; 26 27 if(--argc>0) { 28 argv++; 29 if(*argv[0]=='-'&&argv[0][1]!=0) { 30 while(*++argv[0]) 31 switch(*argv[0]) { 32 case 'c': 33 cflag++; 34 continue; 35 case 'd': 36 dflag++; 37 continue; 38 case 's': 39 sflag++; 40 continue; 41 } 42 argc--; 43 argv++; 44 } 45 } 46 if(argc>0) string1.p = argv[0]; 47 if(argc>1) string2.p = argv[1]; 48 for(i=0; i<256; i++) 49 code[i] = vect[i] = 0; 50 if(cflag) { 51 while(c = next(&string1)) 52 vect[c&0377] = 1; 53 j = 0; 54 for(i=1; i<256; i++) 55 if(vect[i]==0) vect[j++] = i; 56 vect[j] = 0; 57 compl = vect; 58 } 59 for(i=0; i<256; i++) 60 squeez[i] = 0; 61 lastd = 0; 62 for(;;){ 63 if(cflag) c = *compl++; 64 else c = next(&string1); 65 if(c==0) break; 66 d = next(&string2); 67 if(d==0) d = lastd; 68 else lastd = d; 69 squeez[d&0377] = 1; 70 code[c&0377] = dflag?1:d; 71 } 72 while(d = next(&string2)) 73 squeez[d&0377] = 1; 74 squeez[0] = 1; 75 for(i=0;i<256;i++) { 76 if(code[i]==0) code[i] = i; 77 else if(dflag) code[i] = 0; 78 } 79 80 while((c=getc(stdin)) != EOF ) { 81 if(c == 0) continue; 82 if(c = code[c&0377]&0377) 83 if(!sflag || c!=save || !squeez[c&0377]) 84 putchar(save = c); 85 } 86 exit(0); 87 } 88 89 next(s) 90 struct string *s; 91 { 92 93 again: 94 if(s->max) { 95 if(s->last++ < s->max) 96 return(s->last); 97 s->max = s->last = 0; 98 } 99 if(s->last && *s->p=='-') { 100 nextc(s); 101 s->max = nextc(s); 102 if(s->max==0) { 103 s->p--; 104 return('-'); 105 } 106 if(s->max < s->last) { 107 s->last = s->max-1; 108 return('-'); 109 } 110 goto again; 111 } 112 return(s->last = nextc(s)); 113 } 114 115 nextc(s) 116 struct string *s; 117 { 118 register c, i, n; 119 120 c = *s->p++; 121 if(c=='\\') { 122 i = n = 0; 123 while(i<3 && (c = *s->p)>='0' && c<='7') { 124 n = n*8 + c - '0'; 125 i++; 126 s->p++; 127 } 128 if(i>0) c = n; 129 else c = *s->p++; 130 } 131 if(c==0) *--s->p = 0; 132 return(c&0377); 133 } 134