Home | History | Annotate | Line # | Download | only in tr
tr.c revision 1.1.1.2
      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.2  jtc static char sccsid[] = "@(#)tr.c	8.1 (Berkeley) 6/6/93";
     42      1.1  cgd #endif /* not lint */
     43      1.1  cgd 
     44      1.1  cgd #include <sys/types.h>
     45      1.1  cgd #include <stdio.h>
     46  1.1.1.2  jtc #include <stdlib.h>
     47  1.1.1.2  jtc #include <string.h>
     48  1.1.1.2  jtc #include "extern.h"
     49  1.1.1.2  jtc 
     50  1.1.1.2  jtc static int string1[NCHARS] = {
     51  1.1.1.2  jtc 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,		/* ASCII */
     52  1.1.1.2  jtc 	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     53  1.1.1.2  jtc 	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
     54  1.1.1.2  jtc 	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
     55  1.1.1.2  jtc 	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
     56  1.1.1.2  jtc 	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
     57  1.1.1.2  jtc 	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
     58  1.1.1.2  jtc 	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
     59  1.1.1.2  jtc 	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
     60  1.1.1.2  jtc 	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
     61  1.1.1.2  jtc 	0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
     62  1.1.1.2  jtc 	0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
     63  1.1.1.2  jtc 	0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
     64  1.1.1.2  jtc 	0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
     65  1.1.1.2  jtc 	0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
     66  1.1.1.2  jtc 	0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
     67  1.1.1.2  jtc 	0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
     68  1.1.1.2  jtc 	0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
     69  1.1.1.2  jtc 	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
     70  1.1.1.2  jtc 	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
     71  1.1.1.2  jtc 	0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
     72  1.1.1.2  jtc 	0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
     73  1.1.1.2  jtc 	0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
     74  1.1.1.2  jtc 	0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
     75  1.1.1.2  jtc 	0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
     76  1.1.1.2  jtc 	0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
     77  1.1.1.2  jtc 	0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
     78  1.1.1.2  jtc 	0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
     79  1.1.1.2  jtc 	0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
     80  1.1.1.2  jtc 	0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
     81  1.1.1.2  jtc 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
     82  1.1.1.2  jtc 	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
     83  1.1.1.2  jtc }, string2[NCHARS];
     84      1.1  cgd 
     85  1.1.1.2  jtc STR s1 = { STRING1, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
     86  1.1.1.2  jtc STR s2 = { STRING2, NORMAL, 0, OOBCH, { 0, OOBCH }, NULL, NULL };
     87      1.1  cgd 
     88  1.1.1.2  jtc static void setup __P((int *, char *, STR *, int));
     89  1.1.1.2  jtc static void usage __P((void));
     90      1.1  cgd 
     91  1.1.1.2  jtc int
     92      1.1  cgd main(argc, argv)
     93      1.1  cgd 	int argc;
     94      1.1  cgd 	char **argv;
     95      1.1  cgd {
     96  1.1.1.2  jtc 	register int ch, cnt, lastch, *p;
     97  1.1.1.2  jtc 	int cflag, dflag, sflag, isstring2;
     98      1.1  cgd 
     99      1.1  cgd 	cflag = dflag = sflag = 0;
    100      1.1  cgd 	while ((ch = getopt(argc, argv, "cds")) != EOF)
    101      1.1  cgd 		switch((char)ch) {
    102      1.1  cgd 		case 'c':
    103      1.1  cgd 			cflag = 1;
    104      1.1  cgd 			break;
    105      1.1  cgd 		case 'd':
    106      1.1  cgd 			dflag = 1;
    107      1.1  cgd 			break;
    108      1.1  cgd 		case 's':
    109      1.1  cgd 			sflag = 1;
    110      1.1  cgd 			break;
    111      1.1  cgd 		case '?':
    112      1.1  cgd 		default:
    113  1.1.1.2  jtc 			usage();
    114      1.1  cgd 		}
    115      1.1  cgd 	argc -= optind;
    116      1.1  cgd 	argv += optind;
    117      1.1  cgd 
    118  1.1.1.2  jtc 	switch(argc) {
    119  1.1.1.2  jtc 	case 0:
    120  1.1.1.2  jtc 	default:
    121  1.1.1.2  jtc 		usage();
    122  1.1.1.2  jtc 		/* NOTREACHED */
    123  1.1.1.2  jtc 	case 1:
    124  1.1.1.2  jtc 		isstring2 = 0;
    125  1.1.1.2  jtc 		break;
    126  1.1.1.2  jtc 	case 2:
    127  1.1.1.2  jtc 		isstring2 = 1;
    128  1.1.1.2  jtc 		break;
    129  1.1.1.2  jtc 	}
    130  1.1.1.2  jtc 
    131      1.1  cgd 	/*
    132  1.1.1.2  jtc 	 * tr -ds [-c] string1 string2
    133  1.1.1.2  jtc 	 * Delete all characters (or complemented characters) in string1.
    134  1.1.1.2  jtc 	 * Squeeze all characters in string2.
    135      1.1  cgd 	 */
    136  1.1.1.2  jtc 	if (dflag && sflag) {
    137  1.1.1.2  jtc 		if (!isstring2)
    138  1.1.1.2  jtc 			usage();
    139  1.1.1.2  jtc 
    140  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    141  1.1.1.2  jtc 		setup(string2, argv[1], &s2, 0);
    142  1.1.1.2  jtc 
    143  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;)
    144  1.1.1.2  jtc 			if (!string1[ch] && (!string2[ch] || lastch != ch)) {
    145  1.1.1.2  jtc 				lastch = ch;
    146  1.1.1.2  jtc 				(void)putchar(ch);
    147  1.1.1.2  jtc 			}
    148      1.1  cgd 		exit(0);
    149      1.1  cgd 	}
    150      1.1  cgd 
    151  1.1.1.2  jtc 	/*
    152  1.1.1.2  jtc 	 * tr -d [-c] string1
    153  1.1.1.2  jtc 	 * Delete all characters (or complemented characters) in string1.
    154  1.1.1.2  jtc 	 */
    155      1.1  cgd 	if (dflag) {
    156  1.1.1.2  jtc 		if (isstring2)
    157  1.1.1.2  jtc 			usage();
    158  1.1.1.2  jtc 
    159  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    160  1.1.1.2  jtc 
    161  1.1.1.2  jtc 		while ((ch = getchar()) != EOF)
    162  1.1.1.2  jtc 			if (!string1[ch])
    163  1.1.1.2  jtc 				(void)putchar(ch);
    164  1.1.1.2  jtc 		exit(0);
    165  1.1.1.2  jtc 	}
    166  1.1.1.2  jtc 
    167  1.1.1.2  jtc 	/*
    168  1.1.1.2  jtc 	 * tr -s [-c] string1
    169  1.1.1.2  jtc 	 * Squeeze all characters (or complemented characters) in string1.
    170  1.1.1.2  jtc 	 */
    171  1.1.1.2  jtc 	if (sflag && !isstring2) {
    172  1.1.1.2  jtc 		setup(string1, argv[0], &s1, cflag);
    173  1.1.1.2  jtc 
    174  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;)
    175  1.1.1.2  jtc 			if (!string1[ch] || lastch != ch) {
    176      1.1  cgd 				lastch = ch;
    177  1.1.1.2  jtc 				(void)putchar(ch);
    178      1.1  cgd 			}
    179  1.1.1.2  jtc 		exit(0);
    180  1.1.1.2  jtc 	}
    181  1.1.1.2  jtc 
    182  1.1.1.2  jtc 	/*
    183  1.1.1.2  jtc 	 * tr [-cs] string1 string2
    184  1.1.1.2  jtc 	 * Replace all characters (or complemented characters) in string1 with
    185  1.1.1.2  jtc 	 * the character in the same position in string2.  If the -s option is
    186  1.1.1.2  jtc 	 * specified, squeeze all the characters in string2.
    187  1.1.1.2  jtc 	 */
    188  1.1.1.2  jtc 	if (!isstring2)
    189  1.1.1.2  jtc 		usage();
    190  1.1.1.2  jtc 
    191  1.1.1.2  jtc 	s1.str = argv[0];
    192  1.1.1.2  jtc 	s2.str = argv[1];
    193  1.1.1.2  jtc 
    194  1.1.1.2  jtc 	if (cflag)
    195  1.1.1.2  jtc 		for (cnt = NCHARS, p = string1; cnt--;)
    196  1.1.1.2  jtc 			*p++ = OOBCH;
    197  1.1.1.2  jtc 
    198  1.1.1.2  jtc 	if (!next(&s2))
    199  1.1.1.2  jtc 		err("empty string2");
    200  1.1.1.2  jtc 
    201  1.1.1.2  jtc 	/* If string2 runs out of characters, use the last one specified. */
    202  1.1.1.2  jtc 	if (sflag)
    203  1.1.1.2  jtc 		while (next(&s1)) {
    204  1.1.1.2  jtc 			string1[s1.lastch] = ch = s2.lastch;
    205  1.1.1.2  jtc 			string2[ch] = 1;
    206  1.1.1.2  jtc 			(void)next(&s2);
    207      1.1  cgd 		}
    208  1.1.1.2  jtc 	else
    209  1.1.1.2  jtc 		while (next(&s1)) {
    210  1.1.1.2  jtc 			string1[s1.lastch] = ch = s2.lastch;
    211  1.1.1.2  jtc 			(void)next(&s2);
    212  1.1.1.2  jtc 		}
    213  1.1.1.2  jtc 
    214  1.1.1.2  jtc 	if (cflag)
    215  1.1.1.2  jtc 		for (cnt = 0, p = string1; cnt < NCHARS; ++p, ++cnt)
    216  1.1.1.2  jtc 			*p = *p == OOBCH ? ch : cnt;
    217  1.1.1.2  jtc 
    218  1.1.1.2  jtc 	if (sflag)
    219  1.1.1.2  jtc 		for (lastch = OOBCH; (ch = getchar()) != EOF;) {
    220  1.1.1.2  jtc 			ch = string1[ch];
    221  1.1.1.2  jtc 			if (!string2[ch] || lastch != ch) {
    222      1.1  cgd 				lastch = ch;
    223  1.1.1.2  jtc 				(void)putchar(ch);
    224      1.1  cgd 			}
    225  1.1.1.2  jtc 		}
    226  1.1.1.2  jtc 	else
    227  1.1.1.2  jtc 		while ((ch = getchar()) != EOF)
    228  1.1.1.2  jtc 			(void)putchar(string1[ch]);
    229  1.1.1.2  jtc 	exit (0);
    230      1.1  cgd }
    231      1.1  cgd 
    232  1.1.1.2  jtc static void
    233  1.1.1.2  jtc setup(string, arg, str, cflag)
    234  1.1.1.2  jtc 	int *string;
    235  1.1.1.2  jtc 	char *arg;
    236  1.1.1.2  jtc 	STR *str;
    237  1.1.1.2  jtc 	int cflag;
    238      1.1  cgd {
    239  1.1.1.2  jtc 	register int cnt, *p;
    240      1.1  cgd 
    241  1.1.1.2  jtc 	str->str = arg;
    242  1.1.1.2  jtc 	bzero(string, NCHARS * sizeof(int));
    243  1.1.1.2  jtc 	while (next(str))
    244  1.1.1.2  jtc 		string[str->lastch] = 1;
    245  1.1.1.2  jtc 	if (cflag)
    246  1.1.1.2  jtc 		for (p = string, cnt = NCHARS; cnt--; ++p)
    247  1.1.1.2  jtc 			*p = !*p;
    248      1.1  cgd }
    249      1.1  cgd 
    250  1.1.1.2  jtc static void
    251  1.1.1.2  jtc usage()
    252      1.1  cgd {
    253  1.1.1.2  jtc 	(void)fprintf(stderr, "usage: tr [-cs] string1 string2\n");
    254  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -d string1\n");
    255  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -s string1\n");
    256  1.1.1.2  jtc 	(void)fprintf(stderr, "       tr [-c] -ds string1 string2\n");
    257  1.1.1.2  jtc 	exit(1);
    258  1.1.1.2  jtc }
    259      1.1  cgd 
    260  1.1.1.2  jtc #if __STDC__
    261  1.1.1.2  jtc #include <stdarg.h>
    262  1.1.1.2  jtc #else
    263  1.1.1.2  jtc #include <varargs.h>
    264  1.1.1.2  jtc #endif
    265  1.1.1.2  jtc 
    266  1.1.1.2  jtc void
    267  1.1.1.2  jtc #if __STDC__
    268  1.1.1.2  jtc err(const char *fmt, ...)
    269  1.1.1.2  jtc #else
    270  1.1.1.2  jtc err(fmt, va_alist)
    271  1.1.1.2  jtc 	char *fmt;
    272  1.1.1.2  jtc         va_dcl
    273  1.1.1.2  jtc #endif
    274  1.1.1.2  jtc {
    275  1.1.1.2  jtc 	va_list ap;
    276  1.1.1.2  jtc #if __STDC__
    277  1.1.1.2  jtc 	va_start(ap, fmt);
    278  1.1.1.2  jtc #else
    279  1.1.1.2  jtc 	va_start(ap);
    280  1.1.1.2  jtc #endif
    281  1.1.1.2  jtc 	(void)fprintf(stderr, "tr: ");
    282  1.1.1.2  jtc 	(void)vfprintf(stderr, fmt, ap);
    283  1.1.1.2  jtc 	va_end(ap);
    284  1.1.1.2  jtc 	(void)fprintf(stderr, "\n");
    285  1.1.1.2  jtc 	exit(1);
    286  1.1.1.2  jtc 	/* NOTREACHED */
    287      1.1  cgd }
    288