home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bsd / src / tr / tr-amiga / tr.c < prev   
C/C++ Source or Header  |  1993-09-26  |  7KB  |  274 lines

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