xref: /onnv-gate/usr/src/ucbcmd/tr/tr.c (revision 669:3cf64fd04122)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1988 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
280Sstevel@tonic-gate /*	  All Rights Reserved  	*/
290Sstevel@tonic-gate 
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
320Sstevel@tonic-gate  * The Regents of the University of California
330Sstevel@tonic-gate  * All Rights Reserved
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
360Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
370Sstevel@tonic-gate  * contributors.
380Sstevel@tonic-gate  */
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <stdio.h>
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /* tr - transliterate data stream */
450Sstevel@tonic-gate int	dflag	= 0;
460Sstevel@tonic-gate int	sflag	= 0;
470Sstevel@tonic-gate int	cflag = 0;
480Sstevel@tonic-gate int	save	= 0;
490Sstevel@tonic-gate char	code[256];
500Sstevel@tonic-gate char	squeez[256];
510Sstevel@tonic-gate char	vect[256];
520Sstevel@tonic-gate struct string { int last, max; char *p; } string1, string2;
530Sstevel@tonic-gate 
54*669Schin int
main(int argc,char ** argv)55*669Schin main(int argc, char **argv)
560Sstevel@tonic-gate {
57*669Schin 	int i;
580Sstevel@tonic-gate 	int j;
59*669Schin 	int c, d;
600Sstevel@tonic-gate 	char *compl;
610Sstevel@tonic-gate 	int lastd;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate 	string1.last = string2.last = 0;
640Sstevel@tonic-gate 	string1.max = string2.max = 0;
650Sstevel@tonic-gate 	string1.p = string2.p = "";
660Sstevel@tonic-gate 
670Sstevel@tonic-gate 	if(--argc>0) {
680Sstevel@tonic-gate 		argv++;
690Sstevel@tonic-gate 		if(*argv[0]=='-'&&argv[0][1]!=0) {
700Sstevel@tonic-gate 			while(*++argv[0])
710Sstevel@tonic-gate 				switch(*argv[0]) {
720Sstevel@tonic-gate 				case 'c':
730Sstevel@tonic-gate 					cflag++;
740Sstevel@tonic-gate 					continue;
750Sstevel@tonic-gate 				case 'd':
760Sstevel@tonic-gate 					dflag++;
770Sstevel@tonic-gate 					continue;
780Sstevel@tonic-gate 				case 's':
790Sstevel@tonic-gate 					sflag++;
800Sstevel@tonic-gate 					continue;
810Sstevel@tonic-gate 				}
820Sstevel@tonic-gate 			argc--;
830Sstevel@tonic-gate 			argv++;
840Sstevel@tonic-gate 		}
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 	if(argc>0) string1.p = argv[0];
870Sstevel@tonic-gate 	if(argc>1) string2.p = argv[1];
880Sstevel@tonic-gate 	for(i=0; i<256; i++)
890Sstevel@tonic-gate 		code[i] = vect[i] = 0;
900Sstevel@tonic-gate 	if(cflag) {
910Sstevel@tonic-gate 		while(c = next(&string1))
920Sstevel@tonic-gate 			vect[c&0377] = 1;
930Sstevel@tonic-gate 		j = 0;
940Sstevel@tonic-gate 		for(i=1; i<256; i++)
950Sstevel@tonic-gate 			if(vect[i]==0) vect[j++] = i;
960Sstevel@tonic-gate 		vect[j] = 0;
970Sstevel@tonic-gate 		compl = vect;
980Sstevel@tonic-gate 	}
990Sstevel@tonic-gate 	for(i=0; i<256; i++)
1000Sstevel@tonic-gate 		squeez[i] = 0;
1010Sstevel@tonic-gate 	lastd = 0;
1020Sstevel@tonic-gate 	for(;;){
1030Sstevel@tonic-gate 		if(cflag) c = *compl++;
1040Sstevel@tonic-gate 		else c = next(&string1);
1050Sstevel@tonic-gate 		if(c==0) break;
1060Sstevel@tonic-gate 		d = next(&string2);
1070Sstevel@tonic-gate 		if(d==0) d = lastd;
1080Sstevel@tonic-gate 		else lastd = d;
1090Sstevel@tonic-gate 		squeez[d&0377] = 1;
1100Sstevel@tonic-gate 		code[c&0377] = dflag?1:d;
1110Sstevel@tonic-gate 	}
1120Sstevel@tonic-gate 	while(d = next(&string2))
1130Sstevel@tonic-gate 		squeez[d&0377] = 1;
1140Sstevel@tonic-gate 	squeez[0] = 1;
1150Sstevel@tonic-gate 	for(i=0;i<256;i++) {
1160Sstevel@tonic-gate 		if(code[i]==0) code[i] = i;
1170Sstevel@tonic-gate 		else if(dflag) code[i] = 0;
1180Sstevel@tonic-gate 	}
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	clearerr(stdout);
1210Sstevel@tonic-gate 	while((c=getc(stdin)) != EOF ) {
1220Sstevel@tonic-gate 		if(c == 0) continue;
1230Sstevel@tonic-gate 		if(c = code[c&0377]&0377)
1240Sstevel@tonic-gate 			if(!sflag || c!=save || !squeez[c&0377]) {
1250Sstevel@tonic-gate 				(void)putchar(save = c);
1260Sstevel@tonic-gate 				if(ferror(stdout))
1270Sstevel@tonic-gate 					exit(1);
1280Sstevel@tonic-gate 			}
1290Sstevel@tonic-gate 	}
130*669Schin 	return (0);
1310Sstevel@tonic-gate }
1320Sstevel@tonic-gate 
133*669Schin int
next(struct string * s)134*669Schin next(struct string *s)
1350Sstevel@tonic-gate {
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate again:
1380Sstevel@tonic-gate 	if(s->max) {
1390Sstevel@tonic-gate 		if(s->last++ < s->max)
1400Sstevel@tonic-gate 			return(s->last);
1410Sstevel@tonic-gate 		s->max = s->last = 0;
1420Sstevel@tonic-gate 	}
1430Sstevel@tonic-gate 	if(s->last && *s->p=='-') {
1440Sstevel@tonic-gate 		(void)nextc(s);
1450Sstevel@tonic-gate 		s->max = nextc(s);
1460Sstevel@tonic-gate 		if(s->max==0) {
1470Sstevel@tonic-gate 			s->p--;
1480Sstevel@tonic-gate 			return('-');
1490Sstevel@tonic-gate 		}
1500Sstevel@tonic-gate 		if(s->max < s->last)  {
1510Sstevel@tonic-gate 			s->last = s->max-1;
1520Sstevel@tonic-gate 			return('-');
1530Sstevel@tonic-gate 		}
1540Sstevel@tonic-gate 		goto again;
1550Sstevel@tonic-gate 	}
1560Sstevel@tonic-gate 	return(s->last = nextc(s));
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate 
159*669Schin int
nextc(struct string * s)160*669Schin nextc(struct string *s)
1610Sstevel@tonic-gate {
162*669Schin 	int c, i, n;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	c = *s->p++;
1650Sstevel@tonic-gate 	if(c=='\\') {
1660Sstevel@tonic-gate 		i = n = 0;
1670Sstevel@tonic-gate 		while(i<3 && (c = *s->p)>='0' && c<='7') {
1680Sstevel@tonic-gate 			n = n*8 + c - '0';
1690Sstevel@tonic-gate 			i++;
1700Sstevel@tonic-gate 			s->p++;
1710Sstevel@tonic-gate 		}
1720Sstevel@tonic-gate 		if(i>0) c = n;
1730Sstevel@tonic-gate 		else c = *s->p++;
1740Sstevel@tonic-gate 	}
1750Sstevel@tonic-gate 	if(c==0) *--s->p = 0;
1760Sstevel@tonic-gate 	return(c&0377);
1770Sstevel@tonic-gate }
178