140 lines
2.8 KiB
C
140 lines
2.8 KiB
C
/*
|
|
* tr - transliterate data stream
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
int dflag = 0;
|
|
int sflag = 0;
|
|
int cflag = 0;
|
|
int save = 0;
|
|
char code[256];
|
|
char squeez[256];
|
|
char vect[256];
|
|
struct string { int last, max; char *p; } string1, string2;
|
|
|
|
main(argc,argv)
|
|
char **argv;
|
|
{
|
|
register i;
|
|
int j;
|
|
register c, d;
|
|
char *compl;
|
|
int lastd;
|
|
|
|
string1.last = string2.last = 0;
|
|
string1.max = string2.max = 0;
|
|
string1.p = string2.p = "";
|
|
|
|
if(--argc>0) {
|
|
argv++;
|
|
if(*argv[0]=='-'&&argv[0][1]!=0) {
|
|
while(*++argv[0])
|
|
switch(*argv[0]) {
|
|
case 'c':
|
|
cflag++;
|
|
continue;
|
|
case 'd':
|
|
dflag++;
|
|
continue;
|
|
case 's':
|
|
sflag++;
|
|
continue;
|
|
}
|
|
argc--;
|
|
argv++;
|
|
}
|
|
}
|
|
if(argc>0) string1.p = argv[0];
|
|
if(argc>1) string2.p = argv[1];
|
|
for(i=0; i<256; i++)
|
|
code[i] = vect[i] = 0;
|
|
if(cflag) {
|
|
while(c = next(&string1))
|
|
vect[c&0377] = 1;
|
|
j = 0;
|
|
for(i=1; i<256; i++)
|
|
if(vect[i]==0) vect[j++] = i;
|
|
vect[j] = 0;
|
|
compl = vect;
|
|
}
|
|
for(i=0; i<256; i++)
|
|
squeez[i] = 0;
|
|
lastd = 0;
|
|
for(;;){
|
|
if(cflag) c = *compl++;
|
|
else c = next(&string1);
|
|
if(c==0) break;
|
|
d = next(&string2);
|
|
if(d==0) d = lastd;
|
|
else lastd = d;
|
|
squeez[d&0377] = 1;
|
|
code[c&0377] = dflag?1:d;
|
|
}
|
|
while(d = next(&string2))
|
|
squeez[d&0377] = 1;
|
|
squeez[0] = 1;
|
|
for(i=0;i<256;i++) {
|
|
if(code[i]==0) code[i] = i;
|
|
else if(dflag) code[i] = 0;
|
|
}
|
|
|
|
clearerr(stdout);
|
|
while((c=getc(stdin)) != EOF ) {
|
|
if(c == 0) continue;
|
|
if(c = code[c&0377]&0377)
|
|
if(!sflag || c!=save || !squeez[c&0377]) {
|
|
putchar(save = c);
|
|
if(ferror(stdout))
|
|
exit(1);
|
|
}
|
|
}
|
|
exit(0);
|
|
}
|
|
|
|
next(s)
|
|
struct string *s;
|
|
{
|
|
|
|
again:
|
|
if(s->max) {
|
|
if(s->last++ < s->max)
|
|
return(s->last);
|
|
s->max = s->last = 0;
|
|
}
|
|
if(s->last && *s->p=='-') {
|
|
nextc(s);
|
|
s->max = nextc(s);
|
|
if(s->max==0) {
|
|
s->p--;
|
|
return('-');
|
|
}
|
|
if(s->max < s->last) {
|
|
s->last = s->max-1;
|
|
return('-');
|
|
}
|
|
goto again;
|
|
}
|
|
return(s->last = nextc(s));
|
|
}
|
|
|
|
nextc(s)
|
|
struct string *s;
|
|
{
|
|
register c, i, n;
|
|
|
|
c = *s->p++;
|
|
if(c=='\\') {
|
|
i = n = 0;
|
|
while(i<3 && (c = *s->p)>='0' && c<='7') {
|
|
n = n*8 + c - '0';
|
|
i++;
|
|
s->p++;
|
|
}
|
|
if(i>0) c = n;
|
|
else c = *s->p++;
|
|
}
|
|
if(c==0) *--s->p = 0;
|
|
return(c&0377);
|
|
}
|