1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #include <stdio.h> 41 42 /* tr - transliterate data stream */ 43 int dflag = 0; 44 int sflag = 0; 45 int cflag = 0; 46 int save = 0; 47 char code[256]; 48 char squeez[256]; 49 char vect[256]; 50 struct string { int last, max; char *p; } string1, string2; 51 52 int 53 main(int argc, char **argv) 54 { 55 int i; 56 int j; 57 int c, d; 58 char *compl; 59 int lastd; 60 61 string1.last = string2.last = 0; 62 string1.max = string2.max = 0; 63 string1.p = string2.p = ""; 64 65 if(--argc>0) { 66 argv++; 67 if(*argv[0]=='-'&&argv[0][1]!=0) { 68 while(*++argv[0]) 69 switch(*argv[0]) { 70 case 'c': 71 cflag++; 72 continue; 73 case 'd': 74 dflag++; 75 continue; 76 case 's': 77 sflag++; 78 continue; 79 } 80 argc--; 81 argv++; 82 } 83 } 84 if(argc>0) string1.p = argv[0]; 85 if(argc>1) string2.p = argv[1]; 86 for(i=0; i<256; i++) 87 code[i] = vect[i] = 0; 88 if(cflag) { 89 while(c = next(&string1)) 90 vect[c&0377] = 1; 91 j = 0; 92 for(i=1; i<256; i++) 93 if(vect[i]==0) vect[j++] = i; 94 vect[j] = 0; 95 compl = vect; 96 } 97 for(i=0; i<256; i++) 98 squeez[i] = 0; 99 lastd = 0; 100 for(;;){ 101 if(cflag) c = *compl++; 102 else c = next(&string1); 103 if(c==0) break; 104 d = next(&string2); 105 if(d==0) d = lastd; 106 else lastd = d; 107 squeez[d&0377] = 1; 108 code[c&0377] = dflag?1:d; 109 } 110 while(d = next(&string2)) 111 squeez[d&0377] = 1; 112 squeez[0] = 1; 113 for(i=0;i<256;i++) { 114 if(code[i]==0) code[i] = i; 115 else if(dflag) code[i] = 0; 116 } 117 118 clearerr(stdout); 119 while((c=getc(stdin)) != EOF ) { 120 if(c == 0) continue; 121 if(c = code[c&0377]&0377) 122 if(!sflag || c!=save || !squeez[c&0377]) { 123 (void)putchar(save = c); 124 if(ferror(stdout)) 125 exit(1); 126 } 127 } 128 return (0); 129 } 130 131 int 132 next(struct string *s) 133 { 134 135 again: 136 if(s->max) { 137 if(s->last++ < s->max) 138 return(s->last); 139 s->max = s->last = 0; 140 } 141 if(s->last && *s->p=='-') { 142 (void)nextc(s); 143 s->max = nextc(s); 144 if(s->max==0) { 145 s->p--; 146 return('-'); 147 } 148 if(s->max < s->last) { 149 s->last = s->max-1; 150 return('-'); 151 } 152 goto again; 153 } 154 return(s->last = nextc(s)); 155 } 156 157 int 158 nextc(struct string *s) 159 { 160 int c, i, n; 161 162 c = *s->p++; 163 if(c=='\\') { 164 i = n = 0; 165 while(i<3 && (c = *s->p)>='0' && c<='7') { 166 n = n*8 + c - '0'; 167 i++; 168 s->p++; 169 } 170 if(i>0) c = n; 171 else c = *s->p++; 172 } 173 if(c==0) *--s->p = 0; 174 return(c&0377); 175 } 176