|
|
1.1 ! root 1: #include <libc.h> ! 2: ! 3: #define N 500 ! 4: typedef unsigned char uchar; ! 5: ! 6: uchar from[N]; ! 7: int nfrom; ! 8: uchar to[N]; ! 9: int nto; ! 10: uchar trans[256]; ! 11: uchar occur[256]; ! 12: uchar buf[4096]; ! 13: ! 14: int cflag; ! 15: int dflag; ! 16: int sflag; ! 17: ! 18: void complement(void); ! 19: void delete(void); ! 20: void squeeze(void); ! 21: void translit(void); ! 22: void error(char*); ! 23: int canon(uchar*, uchar*); ! 24: int getch(uchar**); ! 25: ! 26: main(int argc, uchar **argv) ! 27: { ! 28: int c; ! 29: for( ; argc>1 && argv[1][0]=='-'; argc--, argv++){ ! 30: while(c = *++argv[1]){ ! 31: switch(c){ ! 32: case 's': ! 33: sflag++; ! 34: continue; ! 35: case 'd': ! 36: dflag++; ! 37: continue; ! 38: case 'c': ! 39: cflag++; ! 40: continue; ! 41: default: ! 42: error("bad option"); ! 43: } ! 44: } ! 45: } ! 46: if(argc>1) ! 47: nfrom = canon(argv[1],from); ! 48: if(argc>2) ! 49: nto = canon(argv[2],to); ! 50: if(argc>3) ! 51: error("arg count"); ! 52: if(cflag) ! 53: complement(); ! 54: if(dflag) ! 55: delete(); ! 56: else ! 57: translit(); ! 58: return 0; ! 59: } ! 60: ! 61: void ! 62: delete(void) ! 63: { ! 64: int i, c, n, last; ! 65: uchar *p, *q; ! 66: for(i=0; i<nfrom; i++) ! 67: if(c=from[i]) ! 68: trans[c] = 1; ! 69: if(sflag) ! 70: for(i=0; i<nto; i++) ! 71: occur[to[i]] = 1; ! 72: last = -1; ! 73: while((n=read(0, buf, sizeof buf)) > 0){ ! 74: for(p=q=buf; --n>=0;){ ! 75: c = *p++; ! 76: if(!trans[c] && (c!=last || !occur[c])) ! 77: *q++ = last = c; ! 78: } ! 79: if(write(1, buf, q-buf) != q-buf) ! 80: error("write error"); ! 81: } ! 82: } ! 83: ! 84: void ! 85: translit(void) ! 86: { ! 87: int i, n, c; ! 88: uchar *p; ! 89: if(nfrom>0 && nto==0) ! 90: error("arg count"); ! 91: for(i=0; i<sizeof trans; i++) ! 92: trans[i] = i; ! 93: for(i=0; i<nfrom; i++) { ! 94: n = from[i]; ! 95: c = to[i<nto? i: nto-1]; ! 96: if(occur[n] && trans[n]!=c) ! 97: error("ambiguous translation"); ! 98: trans[n] = c; ! 99: occur[n] = 1; ! 100: } ! 101: memset(occur,0,sizeof occur); ! 102: if(sflag) ! 103: squeeze(); ! 104: else ! 105: while((n=read(0, buf, sizeof buf)) > 0){ ! 106: for(p=buf; --n>=0; p++) ! 107: *p = trans[*p]; ! 108: if(write(1, buf, p-buf) != p-buf) ! 109: error("write error"); ! 110: } ! 111: } ! 112: ! 113: void ! 114: squeeze(void) ! 115: { ! 116: int i, n, c, last; ! 117: uchar *p, *q; ! 118: for(i=0; i<nto; i++) ! 119: occur[to[i]] = 1; ! 120: last = -1; ! 121: while((n=read(0, buf, sizeof buf)) > 0){ ! 122: for(p=q=buf; --n>=0;){ ! 123: c = *p++; ! 124: if((c=trans[c]) != last || !occur[c]) ! 125: *q++ = last = c; ! 126: } ! 127: if(write(1, buf, q-buf) != q-buf) ! 128: error("write error"); ! 129: } ! 130: } ! 131: ! 132: void ! 133: complement(void) ! 134: { ! 135: int i; ! 136: for(i=0; i<nfrom; i++) ! 137: occur[from[i]] = 1; ! 138: for(i=nfrom=0; i<sizeof occur; i++) ! 139: if(!occur[i]) ! 140: from[nfrom++] = i; ! 141: memset(occur,0,sizeof occur); ! 142: } ! 143: ! 144: int ! 145: getch(uchar **ps) ! 146: { ! 147: uchar *s = *ps; ! 148: int c = *s++; ! 149: int n, i; ! 150: if(c=='\\' && *s){ ! 151: n = 0; ! 152: for(i=0; i<3; i++) ! 153: if(*s>='0' && *s<='7') ! 154: n = 8*n + *s++ - '0'; ! 155: else ! 156: break; ! 157: if(i == 0) ! 158: c = *s; ! 159: else if(n <= 0377) ! 160: c = n; ! 161: else ! 162: error("char>0377"); ! 163: } ! 164: *ps = s; ! 165: return c; ! 166: } ! 167: ! 168: int ! 169: canon(uchar *s, uchar *t) ! 170: { ! 171: int n = 0; ! 172: int i, c; ! 173: while(*s && n<N){ ! 174: if(*s=='-' && n>0 && s[1]){ ! 175: s++; ! 176: c = getch(&s); ! 177: for(i=t[n-1]; ++i<=c && n<N ; ) ! 178: t[n++] = i; ! 179: } else ! 180: t[n++] = getch(&s); ! 181: } ! 182: if(n >= N) ! 183: error("arg string too long"); ! 184: return n; ! 185: } ! 186: ! 187: void ! 188: error(char *s) ! 189: { ! 190: fprint(2, "tr: %s\n", s); ! 191: exit(1); ! 192: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.