Annotation of researchv10no/cmd/ansi/tr.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.