Home | History | Annotate | Line # | Download | only in tr
tr.c revision 1.1.1.3
      1      1.1  cgd /*
      2  1.1.1.2  jtc  * Copyright (c) 1988, 1993
      3  1.1.1.2  jtc  *	The Regents of the University of California.  All rights reserved.
      4      1.1  cgd  *
      5      1.1  cgd  * Redistribution and use in source and binary forms, with or without
      6      1.1  cgd  * modification, are permitted provided that the following conditions
      7      1.1  cgd  * are met:
      8      1.1  cgd  * 1. Redistributions of source code must retain the above copyright
      9      1.1  cgd  *    notice, this list of conditions and the following disclaimer.
     10      1.1  cgd  * 2. Redistributions in binary form must reproduce the above copyright
     11      1.1  cgd  *    notice, this list of conditions and the following disclaimer in the
     12      1.1  cgd  *    documentation and/or other materials provided with the distribution.
     13      1.1  cgd  * 3. All advertising materials mentioning features or use of this software
     14      1.1  cgd  *    must display the following acknowledgement:
     15      1.1  cgd  *	This product includes software developed by the University of
     16      1.1  cgd  *	California, Berkeley and its contributors.
     17      1.1  cgd  * 4. Neither the name of the University nor the names of its contributors
     18      1.1  cgd  *    may be used to endorse or promote products derived from this software
     19      1.1  cgd  *    without specific prior written permission.
     20      1.1  cgd  *
     21      1.1  cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22      1.1  cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23      1.1  cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24      1.1  cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25      1.1  cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26      1.1  cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27      1.1  cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28      1.1  cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29      1.1  cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30      1.1  cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31      1.1  cgd  * SUCH DAMAGE.
     32      1.1  cgd  */
     33      1.1  cgd 
     34      1.1  cgd #ifndef lint
     35  1.1.1.2  jtc static char copyright[] =
     36  1.1.1.2  jtc "@(#) Copyright (c) 1988, 1993\n\
     37  1.1.1.2  jtc 	The Regents of the University of California.  All rights reserved.\n";
     38      1.1  cgd #endif /* not lint */
     39      1.1  cgd 
     40      1.1  cgd #ifndef lint
     41  1.1.1.3  jtc static char sccsid[] = "@(#)tr.c	8.2 (Berkeley) 5/4/95";
     42      1.1  cgd #endif /* not lint */
     43      1.1  cgd 
     44      1.1  cgd #include <sys/types.h>
     45  1.1.1.3  jtc 
     46      1.1  cgd #include <stdio.h>
     47  1.1.1.2  jtc #include <stdlib.h>
     48  1.1.1.2  jtc #include <string.h>
     49  1.1.1.3  jtc #include <unistd.h>
     50  1.1.1.3  jtc 
     51  1.1.1.2  jtc #include "extern.h"
     52  1.1.1.2  jtc 
     53  1.1.1.2  jtc static int string1[NCHARS] = {
     54  1.1.1.2  jtc 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,		/* ASCII */
     55  1.1.1.2  jtc 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     56  1.1.1.2  jtc 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     57  1.1.1.2  jtc 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
     58  1.1.1.2  jtc 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
     59  1.1.1.2  jtc 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
     60  1.1.1.2  jtc 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
     61  1.1.1.2  jtc 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
     62  1.1.1.2  jtc 	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
     63  1.1.1.2  jtc 	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
     64  1.1.1.2  jtc 	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
     65  1.1.1.2  jtc 	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
     66  1.1.1.2  jtc 	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
     67  1.1.1.2  jtc 	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
     68  1.1.1.2  jtc 	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
     69  1.1.1.2  jtc 	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
     70  1.1.1.2  jtc 	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
     71  1.1.1.2  jtc 	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
     72  1.1.1.2  jtc 	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
     73  1.1.1.2  jtc 	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
     74  1.1.1.2  jtc 	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
     75  1.1.1.2  jtc 	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
     76  1.1.1.2  jtc 	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     77  1.1.1.2  jtc 	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
     78  1.1.1.2  jtc 	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
     79  1.1.1.2  jtc 	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
     80  1.1.1.2  jtc 	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
     81  1.1.1.2  jtc 	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
     82  1.1.1.2  jtc 	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
     83  1.1.1.2  jtc 	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
     84  1.1.1.2  jtc 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
     85  1.1.1.2  jtc 	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
     86  1.1.1.2  jtc }, string2[NCHARS];
     87      1.1  cgd 
     88  1.1.1.2  jtc STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
     89  1.1.1.2  jtc STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
     90      1.1  cgd 
     91  1.1.1.2  jtc static void setup __P((int *, char *, STR *, int));
     92  1.1.1.2  jtc static void usage __P((void));
     93      1.1  cgd 
     94  1.1.1.2  jtc int
     95      1.1  cgd main(argc, argv)
     96      1.1  cgd 	int argc;
     97      1.1  cgd 	char **argv;
     98      1.1  cgd {
     99  1.1.1.2  jtc 	register int ch, cnt, lastch, *p;
    100  1.1.1.2  jtc 	int cflag, dflag, sflag, isstring2;
    101      1.1  cgd 
    102      1.1  cgd 	cflag = dflag = sflag = 0;
    103      1.1  cgd 	while ((ch = getopt(argc, argv, "cds")) != EOF)
    104      1.1  cgd 		switch((char)ch) {
    105      1.1  cgd 		case 'c':
    106      1.1  cgd 			cflag = 1;
    107      1.1  cgd 			break;
    108      1.1  cgd 		case 'd':
    109      1.1  cgd 			dflag = 1;
    110      1.1  cgd 			break;
    111      1.1  cgd 		case 's':
    112      1.1  cgd 			sflag = 1;
    113      1.1  cgd 			break;
    114      1.1  cgd 		case '?':
    115      1.1  cgd 		default:
    116  1.1.1.2  jtc 			usage();
    117      1.1  cgd 		}
    118      1.1  cgd 	argc -= optind;
    119      1.1  cgd 	argv += optind;
    120      1.1  cgd 
    121  1.1.1.2  jtc 	switch(argc) {
    122  1.1.1.2  jtc 	case 0:
    123  1.1.1.2  jtc 	default:
    124  1.1.1.2  jtc 		usage();
    125  1.1.1.2  jtc 		/* NOTREACHED */
    126  1.1.1.2  jtc 	case 1:
    127  1.1.1.2  jtc 		isstring2 = 0;
    128  1.1.1.2  jtc 		break;
    129  1.1.1.2  jtc 	case 2:
    130  1.1.1.2  jtc 		isstring2 = 1;
    131  1.1.1.2  jtc 		break;
    132  1.1.1.2  jtc 	}
    133  1.1.1.2  jtc 
    134      1.1  cgd 	/*
    135  1.1.1.2  jtc 	 * tr -ds [-c] string1 string2
    136  1.1.1.2  jtc 	 * Delete all characters (or complemented characters) in string1.
    137  1.1.1.2  jtc 	 * Squeeze all characters in string2.
    138      1.1  cgd 	 */
    139  1.1.1.2  jtc 	if (dflag && sflag) {
    140  1.1.1.2  jtc 		if (!isstring2)
    141  1.1.1.2  jtc 			usage();
    142  1.1.1.2  jtc 
    143  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    144  1.1.1.2  jtc 		setup(string2, argv[1], &s2, 0);
    145  1.1.1.2  jtc 
    146  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;)
    147  1.1.1.2  jtc 			if (!string1[ch] && (!string2[ch] || lastch != ch)) {
    148  1.1.1.2  jtc 				lastch = ch;
    149  1.1.1.2  jtc 				(void)putchar(ch);
    150  1.1.1.2  jtc 			}
    151      1.1  cgd 		exit(0);
    152      1.1  cgd 	}
    153      1.1  cgd 
    154  1.1.1.2  jtc 	/*
    155  1.1.1.2  jtc 	 * tr -d [-c] string1
    156  1.1.1.2  jtc 	 * Delete all characters (or complemented characters) in string1.
    157  1.1.1.2  jtc 	 */
    158      1.1  cgd 	if (dflag) {
    159  1.1.1.2  jtc 		if (isstring2)
    160  1.1.1.2  jtc 			usage();
    161  1.1.1.2  jtc 
    162  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    163  1.1.1.2  jtc 
    164  1.1.1.2  jtc 		while ((ch = getchar()) != EOF)
    165  1.1.1.2  jtc 			if (!string1[ch])
    166  1.1.1.2  jtc 				(void)putchar(ch);
    167  1.1.1.2  jtc 		exit(0);
    168  1.1.1.2  jtc 	}
    169  1.1.1.2  jtc 
    170  1.1.1.2  jtc 	/*
    171  1.1.1.2  jtc 	 * tr -s [-c] string1
    172  1.1.1.2  jtc 	 * Squeeze all characters (or complemented characters) in string1.
    173  1.1.1.2  jtc 	 */
    174  1.1.1.2  jtc 	if (sflag && !isstring2) {
    175  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    176  1.1.1.2  jtc 
    177  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;)
    178  1.1.1.2  jtc 			if (!string1[ch] || lastch != ch) {
    179      1.1  cgd 				lastch = ch;
    180  1.1.1.2  jtc 				(void)putchar(ch);
    181      1.1  cgd 			}
    182  1.1.1.2  jtc 		exit(0);
    183  1.1.1.2  jtc 	}
    184  1.1.1.2  jtc 
    185  1.1.1.2  jtc 	/*
    186  1.1.1.2  jtc 	 * tr [-cs] string1 string2
    187  1.1.1.2  jtc 	 * Replace all characters (or complemented characters) in string1 with
    188  1.1.1.2  jtc 	 * the character in the same position in string2.  If the -s option is
    189  1.1.1.2  jtc 	 * specified, squeeze all the characters in string2.
    190  1.1.1.2  jtc 	 */
    191  1.1.1.2  jtc 	if (!isstring2)
    192  1.1.1.2  jtc 		usage();
    193  1.1.1.2  jtc 
    194  1.1.1.2  jtc 	s1.str = argv[0];
    195  1.1.1.2  jtc 	s2.str = argv[1];
    196  1.1.1.2  jtc 
    197  1.1.1.2  jtc 	if (cflag)
    198  1.1.1.2  jtc 		for (cnt = NCHARS, p = string1; cnt--;)
    199  1.1.1.2  jtc 			*p++ = OOBCH;
    200  1.1.1.2  jtc 
    201  1.1.1.2  jtc 	if (!next(&s2))
    202  1.1.1.2  jtc 		err("empty string2");
    203  1.1.1.2  jtc 
    204  1.1.1.2  jtc 	/* If string2 runs out of characters, use the last one specified. */
    205  1.1.1.2  jtc 	if (sflag)
    206  1.1.1.2  jtc 		while (next(&s1)) {
    207  1.1.1.2  jtc 			string1[s1.lastch] = ch = s2.lastch;
    208  1.1.1.2  jtc 			string2[ch] = 1;
    209  1.1.1.2  jtc 			(void)next(&s2);
    210      1.1  cgd 		}
    211  1.1.1.2  jtc 	else
    212  1.1.1.2  jtc 		while (next(&s1)) {
    213  1.1.1.2  jtc 			string1[s1.lastch] = ch = s2.lastch;
    214  1.1.1.2  jtc 			(void)next(&s2);
    215  1.1.1.2  jtc 		}
    216  1.1.1.2  jtc 
    217  1.1.1.2  jtc 	if (cflag)
    218  1.1.1.2  jtc 		for (cnt = 0, p = string1; cnt < NCHARS; ++p, ++cnt)
    219  1.1.1.2  jtc 			*p = *p == OOBCH ? ch : cnt;
    220  1.1.1.2  jtc 
    221  1.1.1.2  jtc 	if (sflag)
    222  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;) {
    223  1.1.1.2  jtc 			ch = string1[ch];
    224  1.1.1.2  jtc 			if (!string2[ch] || lastch != ch) {
    225      1.1  cgd 				lastch = ch;
    226  1.1.1.2  jtc 				(void)putchar(ch);
    227      1.1  cgd 			}
    228  1.1.1.2  jtc 		}
    229  1.1.1.2  jtc 	else
    230  1.1.1.2  jtc 		while ((ch = getchar()) != EOF)
    231  1.1.1.2  jtc 			(void)putchar(string1[ch]);
    232  1.1.1.2  jtc 	exit (0);
    233      1.1  cgd }
    234      1.1  cgd 
    235  1.1.1.2  jtc static void
    236  1.1.1.2  jtc setup(string, arg, str, cflag)
    237  1.1.1.2  jtc 	int *string;
    238  1.1.1.2  jtc 	char *arg;
    239  1.1.1.2  jtc 	STR *str;
    240  1.1.1.2  jtc 	int cflag;
    241      1.1  cgd {
    242  1.1.1.2  jtc 	register int cnt, *p;
    243      1.1  cgd 
    244  1.1.1.2  jtc 	str->str = arg;
    245  1.1.1.2  jtc 	bzero(string, NCHARS * sizeof(int));
    246  1.1.1.2  jtc 	while (next(str))
    247  1.1.1.2  jtc 		string[str->lastch] = 1;
    248  1.1.1.2  jtc 	if (cflag)
    249  1.1.1.2  jtc 		for (p = string, cnt = NCHARS; cnt--; ++p)
    250  1.1.1.2  jtc 			*p = !*p;
    251      1.1  cgd }
    252      1.1  cgd 
    253  1.1.1.2  jtc static void
    254  1.1.1.2  jtc usage()
    255      1.1  cgd {
    256  1.1.1.2  jtc 	(void)fprintf(stderr, "usage: tr [-cs] string1 string2\n");
    257  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -d string1\n");
    258  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -s string1\n");
    259  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -ds string1 string2\n");
    260  1.1.1.2  jtc 	exit(1);
    261  1.1.1.2  jtc }
    262      1.1  cgd 
    263  1.1.1.2  jtc #if __STDC__
    264  1.1.1.2  jtc #include <stdarg.h>
    265  1.1.1.2  jtc #else
    266  1.1.1.2  jtc #include <varargs.h>
    267  1.1.1.2  jtc #endif
    268  1.1.1.2  jtc 
    269  1.1.1.2  jtc void
    270  1.1.1.2  jtc #if __STDC__
    271  1.1.1.2  jtc err(const char *fmt, ...)
    272  1.1.1.2  jtc #else
    273  1.1.1.2  jtc err(fmt, va_alist)
    274  1.1.1.2  jtc 	char *fmt;
    275  1.1.1.2  jtc         va_dcl
    276  1.1.1.2  jtc #endif
    277  1.1.1.2  jtc {
    278  1.1.1.2  jtc 	va_list ap;
    279  1.1.1.2  jtc #if __STDC__
    280  1.1.1.2  jtc 	va_start(ap, fmt);
    281  1.1.1.2  jtc #else
    282  1.1.1.2  jtc 	va_start(ap);
    283  1.1.1.2  jtc #endif
    284  1.1.1.2  jtc 	(void)fprintf(stderr, "tr: ");
    285  1.1.1.2  jtc 	(void)vfprintf(stderr, fmt, ap);
    286  1.1.1.2  jtc 	va_end(ap);
    287  1.1.1.2  jtc 	(void)fprintf(stderr, "\n");
    288  1.1.1.2  jtc 	exit(1);
    289  1.1.1.2  jtc 	/* NOTREACHED */
    290      1.1  cgd }
    291