home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / OS2MNX1.ZIP / UNIQ.C < prev    next >
C/C++ Source or Header  |  1989-12-27  |  6KB  |  249 lines

  1. /*
  2.  * uniq - compact repeated lines        Author: John
  3.  * Woods 
  4.  */
  5. /* $Header: d:/rcs/D:/RCS/RCS/uniq.c 1.2 89/12/27 01:10:56 RCA Exp $
  6.  * $Log:    uniq.c $
  7.  * Revision 1.2  89/12/27  01:10:56  RCA
  8.  * Fixed header lines.
  9.  * 
  10.  */
  11.  
  12. /*
  13.  * uniq [-udc] [-n] [+n] [infile [outfile]] 
  14.  *
  15.  * Written 02/08/86 by John Woods, placed into public domain. 
  16.  * Enjoy. 
  17.  *
  18.  */
  19. /*
  20.  * If the symbol WRITE_ERROR is defined, uniq will exit(1) if it
  21.  * gets a write error on the output.  This is not (of course) how
  22.  * V7 uniq does it, so undefine the symbol if you want to lose
  23.  * your output to a full disk 
  24.  */
  25.  
  26. #define WRITE_ERROR 1
  27. #define isdigit(c) (c >= '0' && c <= '9')
  28. #include "stdio.h"
  29.  
  30.  
  31. FILE   *fopen();
  32. char    buffer[BUFSIZ];
  33. int     uflag = 1;    /* default is union of -d and -u outputs */
  34. int     dflag = 1;    /* flags are mutually exclusive */
  35. int     cflag = 0;
  36. int     fields = 0;
  37. int     chars = 0;
  38.  
  39. FILE   *
  40. xfopen(fn, mode)
  41.    char   *fn, *mode;
  42. {
  43. FILE   *p;
  44. extern int errno;
  45. extern char *sys_errlist[];
  46.    if ((p = fopen(fn, mode)) == NULL)
  47.    {
  48.       perror("uniq");
  49.       fflush(stdout);
  50.       exit(1);
  51.    }
  52.    return (p);
  53. }
  54. main(argc, argv)
  55.    char   *argv[];
  56. {
  57. char   *p;
  58. int     inf = -1, outf;
  59.    if (argc < 2)
  60.    {
  61.         printf("█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█\n");
  62.         printf("█ UNIQ     (Eliminate Duplicate lines)      $Author: RCA $ █\n");
  63.         printf("█          $Date: 89/12/27 01:10:56 $     $Revision: 1.2 $ █\n");
  64.         printf("█ Usage:   UNIQ infile [>outfile]                          █\n");
  65.         printf("█ Purpose: Compresses text files by eliminating adjacent   █\n");
  66.         printf("█          duplicate lines.                                █\n");
  67.         printf("█ Example: File with contents:                             █\n");
  68.         printf("█            This is a test                                █\n");
  69.         printf("█                                                          █\n");
  70.         printf("█                                                          █\n");
  71.         printf("█            This is a test                                █\n");
  72.         printf("█            This is a test                                █\n");
  73.         printf("█          Becomes:                                        █\n");
  74.         printf("█            This is a test                                █\n");
  75.         printf("█                                                          █\n");
  76.         printf("█            This is a test                                █\n");
  77.         printf("█ OS:      DOS or OS/2                                     █\n");
  78.         printf("█ Credits: Code by John Woods.                             █\n");
  79.         printf("█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\n");
  80.         exit(1);
  81.     }
  82.    setbuf(stdout, buffer);
  83.    for (--argc, ++argv; argc > 0 && (**argv == '-' || **argv == '+');
  84.     --argc, ++argv)
  85.    {
  86.       if (**argv == '+')
  87.      chars = atoi(*argv + 1);
  88.       else
  89.       if (isdigit(argv[0][1]))
  90.      fields = atoi(*argv + 1);
  91.       else
  92.       if (argv[0][1] == '\0')
  93.      inf = 0;        /* - is stdin */
  94.       else
  95.      for (p = *argv + 1; *p; p++)
  96.      {
  97.         switch (*p)
  98.         {
  99.         case 'd':
  100.            dflag = 1;
  101.            uflag = 0;
  102.            break;
  103.         case 'u':
  104.            uflag = 1;
  105.            dflag = 0;
  106.            break;
  107.         case 'c':
  108.            cflag = 1;
  109.            break;
  110.         default:
  111.            usage();
  112.         }
  113.      }
  114.    }
  115. /* input file */
  116.    if (argc == 0)
  117.       inf = 0;
  118.    else
  119.    if (inf == -1)
  120.    {                /* if - was not given */
  121.       fclose(stdin);
  122.       xfopen(*argv++, "r");
  123.       argc--;
  124.    }
  125.    if (argc == 0)
  126.       outf = 1;
  127.    else
  128.    {
  129.       fclose(stdout);
  130.       xfopen(*argv++, "w");
  131.       argc--;
  132.    }
  133.  
  134.    uniq();
  135.    fflush(stdout);
  136.    exit(0);
  137. }
  138.  
  139. char   *
  140. skip(s)
  141.    char   *s;
  142. {
  143. int     n;
  144. /* skip fields */
  145.    for (n = fields; n > 0; --n)
  146.    {
  147.    /* skip blanks */
  148.       while (*s && (*s == ' ' || *s == '\t'))
  149.      s++;
  150.       if (!*s)
  151.      return s;
  152.       while (*s && (*s != ' ' && *s != '\t'))
  153.      s++;
  154.       if (!*s)
  155.      return s;
  156.    }
  157. /* skip characters */
  158.    for (n = chars; n > 0; --n)
  159.    {
  160.       if (!*s)
  161.      return s;
  162.       s++;
  163.    }
  164.    return s;
  165. }
  166.  
  167. int 
  168. equal(s1, s2)
  169.    char   *s1, *s2;
  170. {
  171.    return !strcmp(skip(s1), skip(s2));
  172. }
  173.  
  174.  
  175. show(line, count)
  176.    char   *line;
  177. {
  178.    if (cflag)
  179.       printf("%4d %s", count, line);
  180.    else
  181.    {
  182.       if ((uflag && count == 1) || (dflag && count != 1))
  183.      printf("%s", line);
  184.    }
  185. }
  186. /*
  187.  * The meat of the whole affair 
  188.  */
  189. char   *nowline, *prevline, buf1[1024], buf2[1024];
  190. uniq()
  191. {
  192. char   *p;
  193. int     seen;
  194. /* setup */
  195.    prevline = buf1;
  196.    if (getline(prevline, 1024) < 0)
  197.       return (0);
  198.    seen = 1;
  199.    nowline = buf2;
  200. /*
  201.  * get nowline and compare if not equal, dump prevline and swap
  202.  * pointers else continue, bumping seen count 
  203.  */
  204.    while (getline(nowline, 1024) > 0)
  205.    {
  206.       if (!equal(prevline, nowline))
  207.       {
  208.      show(prevline, seen);
  209.      seen = 1;
  210.      p = nowline;
  211.      nowline = prevline;
  212.      prevline = p;
  213.       } else
  214.      seen += 1;
  215.    }
  216.    show(prevline, seen);
  217.    return 0;
  218. }
  219. usage()
  220. {
  221. /*
  222.  * std_err("Usage: uniq [-udc] [+n] [-n] [input [output]]\n"); 
  223.  */
  224.    printf("Usage: uniq [-udc] [+n] [-n] [input [output]]\n");
  225. }
  226.  
  227.  
  228. int 
  229. getline(buf, count)
  230.    char   *buf;
  231.    int     count;
  232. {
  233. char    c;
  234. int     ct = 0;
  235.    while (ct++ < count)
  236.    {
  237.       c = getc(stdin);
  238.       if (c <= 0)
  239.      return (-1);
  240.       *buf++ = c;
  241.       if (c == '\n')
  242.       {
  243.      *buf++ = 0;
  244.      return (ct);
  245.       }
  246.    }
  247.    return (ct);
  248. }
  249.