home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-2 / UNIQ.C < prev    next >
Text File  |  2000-06-30  |  4KB  |  201 lines

  1. #define VERSION "uniq.c -- BDS Version 1.0 -- 6/20/82"
  2. /*
  3.  *    uniq - report repeated lines in a file
  4.  *
  5.  *    Adapted for BDS C by Jeff Martin, from a program by the same
  6.  *    name written to run under the Unix (tm) operating system.
  7.  *
  8.  *    From the manual page for the Unix command:
  9.  *
  10.  *      "Uniq reads the input file comparing adjacent lines.  In the
  11.  *      normal case, the second and succeeding copies    of repeated
  12.  *      lines    are removed; the remainder is written on the output
  13.  *      file.     Input and output should always    be different.  Note
  14.  *      that repeated    lines must be adjacent in order    to be found.
  15.  *      If the -u flag is used, just the lines that
  16.  *      are not repeated in the original file    are output.  The -d
  17.  *      option specifies that    one copy of just the repeated lines is
  18.  *      to be    written.  The normal mode output is the    union of the
  19.  *      -u and -d mode outputs.
  20.  *
  21.  *      "The -c option supersedes -u and -d and generates an output
  22.  *      report in default style but with each    line preceded by a
  23.  *      count    of the number of times it occurred.
  24.  *
  25.  *      "The n arguments specify skipping an initial portion of each
  26.  *      line in the comparison:
  27.  *
  28.  *      -n      The first n fields together with any blanks before
  29.  *          each are ignored.  A field is    defined    as a string of
  30.  *          non-space, non-tab characters    separated by tabs and
  31.  *          spaces from its neighbors.
  32.  *
  33.  *      ^n      The first n characters are ignored.  Fields are
  34.  *          skipped before characters."
  35.  *
  36.  *    To compile: CC1 uniq.c
  37.  *
  38.  *    To link: L2 uniq dio
  39.  *      or --  CLINK uniq -f dio
  40.  */
  41.  
  42. #define STDERR 4
  43. #include <a:bdscio.h>
  44. #include <a:dio.h>
  45.  
  46.     int    fields;
  47.     int    letters;
  48.     int    linec;
  49.     char    mode;
  50.     int    uniq;
  51.     char    *skip();
  52.     char    b1[1000], b2[1000];
  53.     struct _buf    infile;
  54.  
  55. main(argc, argv)
  56. int argc;
  57. char *argv[];
  58. {
  59.     dioinit(&argc, argv);
  60.  
  61.     fields = letters = linec = uniq = 0;
  62.     mode = '\0';
  63.     while(argc > 1) {
  64.         if(*argv[1] == '-') {
  65.             if (isdigit(argv[1][1]))
  66.                 fields = atoi(&argv[1][1]);
  67.             else mode = tolower(argv[1][1]);
  68.             argc--;
  69.             argv++;
  70.             continue;
  71.         }
  72.         if(*argv[1] == '^') {
  73.             letters = atoi(&argv[1][1]);
  74.             argc--;
  75.             argv++;
  76.             continue;
  77.         }
  78.         if ((argc == 2) && (fopen(argv[1], infile) == ERROR)) {
  79.             fprintf(STDERR,"Cannot open %s\n", argv[1]);
  80.             exit(1);
  81.         }
  82.         break;
  83.     }
  84.  
  85.     if (argc != 2) {
  86.         usage();
  87.         exit(1);
  88.     }
  89.  
  90.     if(gline(b1)) {
  91.         dioflush();
  92.         exit(0);
  93.     }
  94.     for(;;) {
  95.         linec++;
  96.         if(gline(b2)) {
  97.             pline(b1);
  98.             dioflush();
  99.             exit(0);
  100.         }
  101.         if(!equal(b1, b2)) {
  102.             pline(b1);
  103.             linec = 0;
  104.             do {
  105.                 linec++;
  106.                 if(gline(b1)) {
  107.                     pline(b2);
  108.                     dioflush();
  109.                     exit(0);
  110.                 }
  111.             } while(equal(b1, b2));
  112.             pline(b2);
  113.             linec = 0;
  114.         }
  115.     }
  116. }
  117.  
  118. usage()
  119. {
  120.     fprintf(STDERR,"\n%s\n",VERSION);
  121.     fputs("\nUsage: UNIQ [-u][-d][-c] [-n] [^n] input [>output]\n",STDERR);
  122.     fputs("\t-u ==> just output unrepeated lines\n",STDERR);
  123.     fputs("\t-d ==> output one copy of just repeated lines\n",STDERR);
  124.     fputs("\t(default) ==> union of -u and -d options\n\n",STDERR);
  125.     fputs("\t-c ==> prefix each output line with count of occurrences\n\n",STDERR);
  126.     fputs("\t-n ==> skip first n fields in comparison\n",STDERR);
  127.     fputs("\t^n ==> ignore first n characters (fields are skipped first)\n",STDERR);
  128.     exit(1);
  129. }
  130.  
  131. gline(buf)
  132. char buf[];
  133. {
  134.  
  135.     if (fgets(buf,infile) == NULL) {
  136.         *buf = 0;
  137.         return(1);
  138.     }
  139.     buf[strlen(buf)-1] = '\0';
  140.     return(0);
  141. }
  142.  
  143. pline(buf)
  144. char buf[];
  145. {
  146.     switch(mode) {
  147.  
  148.     case 'u':
  149.         if(uniq) {
  150.             uniq = 0;
  151.             return;
  152.         }
  153.         break;
  154.  
  155.     case 'd':
  156.         if(uniq)
  157.             break;
  158.         return;
  159.  
  160.     case 'c':
  161.         printf("%4d ", linec);
  162.     }
  163.     uniq = 0;
  164.     puts(buf);
  165.     putchar('\n');
  166. }
  167.  
  168. equal(s1, s2)
  169. char s1[], s2[];
  170. {
  171.     char c;
  172.  
  173.     s1 = skip(s1);
  174.     s2 = skip(s2);
  175.     while((c = *s1++) != 0)
  176.         if(c != *s2++) return(0);
  177.     if(*s2 != 0)
  178.         return(0);
  179.     uniq++;
  180.     return(1);
  181. }
  182.  
  183. char *
  184. skip(s)
  185. char *s;
  186. {
  187.     int nf, nl;
  188.  
  189.     nf = nl = 0;
  190.     while(nf++ < fields) {
  191.         while(*s == ' ' || *s == '\t')
  192.             s++;
  193.         while( !(*s == ' ' || *s == '\t' || *s == 0) ) 
  194.             s++;
  195.     }
  196.     while(nl++ < letters && *s != 0) 
  197.             s++;
  198.     return(s);
  199. }
  200.  
  201.