home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / doc / mir / a_occur.c < prev    next >
Text File  |  1992-07-02  |  8KB  |  240 lines

  1. /*
  2.  *  usage - a_occur [ min_freq ] [ /n ]  < ascii_text > report
  3.  *              /n = non-sequenced data is okay
  4.  *
  5.  *  A_OCCUR Count the frequency of occurrence of identical lines
  6.  *          If a minimum frequency is specified, lines occurring
  7.  *          fewer times are dropped entirely from the result.
  8.  *
  9.  * Input:   ASCII text, which must be in sorted order UNLESS the
  10.  *          flag "/n" is included.
  11.  *
  12.  * Output:  A reduced copy of the file with each line shown only
  13.  *          once.  Each line begins with a frequency count, padded
  14.  *          out to six characters with blanks.
  15.  *
  16.  * Writeup: MIR TUTORIAL ONE, topic five.
  17.  *          See also the related programs A_OCCUR2 and A_OCCUR3.
  18.  *
  19.  *  Written:    Douglas Lowry   Mar 04 87
  20.  *  Modified:   Douglas Lowry   Apr 30 92  Reworked entirely
  21.  *              Copyright (C) 1992 Innotech Inc.
  22.  *
  23.  *    The MIR (Mass Indexing and Retrieval) Tutorials explain detailed
  24.  *    usage and co-ordination of the MIR family of programs to analyze,
  25.  *    prepare and index databases (small through gigabyte size), and
  26.  *    how to build integrated retrieval software around the MIR search
  27.  *    engine.  The fifth of the five MIR tutorial series explains how
  28.  *    to extend indexing capability into leading edge search-related
  29.  *    technologies.  For more information, GO IBMPRO on CompuServe;
  30.  *    MIR files are in the DBMS library.  The same files are on the
  31.  *    Canada Remote Systems BBS.  A diskette copy of the Introduction
  32.  *    is available by mail ($10 US... check, Visa or Mastercard);
  33.  *    diskettes with Introduction, Tutorial ONE software and the
  34.  *    shareware Tutorial ONE text cost $29.  Shareware registration
  35.  *    for a tutorial is also $29.
  36.  *
  37.  *    E-mail...
  38.  *                Compuserve  71431,1337
  39.  *                Internet    doug.lowry%canrem.com
  40.  *                UUCP        canrem!doug.lowry
  41.  *                Others:     doug.lowry@canrem.uucp
  42.  *
  43.  *    FAX...                  416 963-5677
  44.  *
  45.  *    "Snail mail"...         Douglas Lowry, Ph.D.
  46.  *                            Marpex Inc.
  47.  *                            5334 Yonge Street, #1102
  48.  *                            North York, Ontario
  49.  *                            Canada  M2N 6M2
  50.  *
  51.  *    Related database consultation and preparation services are
  52.  *    available through:
  53.  *              Innotech Inc., 2001 Sheppard Avenue E., Suite #118,
  54.  *              North York, Ontario  Canada   M2J 4Z7
  55.  *              Tel.  416 492-3838   FAX  416 492-3843
  56.  *
  57.  *  This program is free software; you may redistribute it and/or
  58.  *  modify it under the terms of the GNU General Public License as
  59.  *  published by the Free Software Foundation; either version 2 of
  60.  *  the License, or (at your option) any later version.
  61.  *
  62.  *  This program is distributed in the hope that it will be useful,
  63.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  64.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  65.  *  GNU General Public License for more details.
  66.  *
  67.  *  You should have received a copy of the GNU General Public License
  68.  *  (file 05LICENS) along with this program; if not, write to the
  69.  *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  70.  *  USA.
  71.  */
  72.  
  73. #include <stdio.h>
  74. #include <stdlib.h>
  75.  
  76. #define     MAX_BYTES   512
  77. #define     repeat      for(;;)
  78.  
  79. /*
  80.  * declarations 
  81.  */
  82.  
  83. typedef     enum        _bool
  84.              { FALSE = 0, TRUE = 1 }  Bool;
  85.  
  86.     void        Usage_(), process();
  87.     char        *Cmdname_() {    return( "a_occur" );  }
  88.  
  89. /*
  90.  * MAIN
  91.  */
  92.  
  93. main( argc, argv )
  94.     int  argc;
  95.     char **argv;
  96. {
  97.     Bool    must_be_seq ;   /*  Must be sequential ASCII order */
  98.     int     min_freq,   /* threshold frequency to show a line  */
  99.             i, val;
  100.  
  101.     min_freq = 1;
  102.     must_be_seq = TRUE;
  103.  
  104.     if( argc > 3 )
  105.         Usage_();
  106.  
  107.     for( i = 1 ; i < argc ; i++ )
  108.     {
  109.         if(( val = atoi( argv[i] )))
  110.             min_freq = val;
  111.         else if(( argv[i][0] == '-' || argv[i][0] == '/' ) &&
  112.                 ( argv[i][1] == 'n' || argv[i][1] == 'N' ))
  113.             must_be_seq = FALSE;
  114.         else
  115.             Usage_();
  116.     }
  117.  
  118.     process( min_freq, must_be_seq ) ;
  119.  
  120.     exit( 0 ) ;
  121. }
  122. /*
  123.  *  Usage_
  124.  */
  125.     void
  126. Usage_()
  127. {
  128.     fprintf( stderr,
  129.         "\nusage:  %s [ min_freq ] [ /n ]  < ascii_text > report\n\
  130.             /n = non-sequenced data is okay\n\n\
  131.         Count the frequency of occurrence of identical lines\n\
  132.         If a minimum frequency is specified, lines occurring\n",
  133.             Cmdname_() );
  134.     fprintf( stderr,
  135. "        fewer times are dropped entirely from the result.\n\n\
  136. Input:  ASCII text, which must be in sorted order UNLESS the\n\
  137.         flag \"/n\" is included.\n\n\
  138. Output: A reduced copy of the file with each line shown only\n\
  139.         once.  Each line begins with a frequency count, padded\n" );
  140.     fprintf( stderr,
  141. "        out to six characters with blanks.\n\n\
  142. Writeup: MIR TUTORIAL ONE, topic five.\n\
  143.         See also the related programs A_OCCUR2 and A_OCCUR3.\n\n" ) ;
  144.     exit( 1 ) ;
  145. }
  146. /*
  147.  *  PROCESS
  148.  */
  149.     void
  150. process( min_freq, must_be_seq )
  151.     int     min_freq ;
  152.     Bool    must_be_seq ; /* must be sequential order (default) */
  153. {
  154.     char    buf[2][MAX_BYTES];  /* alternating line inputs      */
  155.     Bool    done,       /* last line has been read      */
  156.             same;       /* 2 successive lines identical */
  157.     long int
  158.             freq,       /* count of occurrences of line */
  159.             sizer ;
  160.     int     this,       /* current buffer is 0 or 1     */
  161.             that,       /* other buffer is 1 or 0       */
  162.             lines_in,   /* count                        */
  163.             len[2],     /* line length of each buffer   */
  164.             i ;
  165.  
  166.     len[0] = len[1] = freq = lines_in = 0;
  167.     done = FALSE;
  168.     this = 0;
  169.     that = 1;
  170.  
  171.     while( !done )
  172.     {
  173.         if( fgets( buf[this], MAX_BYTES, stdin ) == NULL )
  174.             done = TRUE;
  175.         lines_in++ ;
  176.         len[this] = strlen( buf[this] ) - 1 ;
  177.         while( isspace( buf[this][len[this]-1] ))
  178.             len[this] -= 1 ;
  179.         if( len[this] > MAX_BYTES - 3 )
  180.         {
  181.             fprintf( stderr, "FATAL... Line length exceeds %d bytes.\n\n",
  182.                 MAX_BYTES ) ;
  183.             exit( 1 ) ;
  184.         }
  185.         buf[this][len[this]] = '\0' ;
  186.         if( done || len[this] < 0 )
  187.             len[this] = 0;
  188.  
  189.         same = FALSE;       /* compare 2 consecutive lines  */
  190.         if( len[this] == len[that] )
  191.         {
  192.             same = TRUE;
  193.             for( i = 0; i < len[0]; i++ )
  194.             {
  195.                 if( buf[0][i] != buf[1][i] )
  196.                 {
  197.                     same = FALSE;
  198.                     if( must_be_seq && buf[this][i] < buf[that][i] )
  199.                     {
  200.                         fprintf( stderr,
  201. "Not sorted... lines %d and %d\n%s\n%s\n", lines_in - 1, lines_in,
  202.                             buf[this], buf[that] );
  203.                         Usage_();
  204.                     }
  205.                     break;
  206.                 }
  207.             }
  208.         }
  209.  
  210.         if( same )
  211.             freq++;
  212.         else            /* if not same, print       */
  213.         {
  214.             if( freq >= min_freq )
  215.             {
  216.                 printf( "%d", freq ) ;
  217.                 sizer = freq ;
  218.                 while( sizer < 100000 )
  219.                 {
  220.                     putchar( ' ' ) ;
  221.                     sizer *= 10 ;
  222.                 }
  223.                 if( !printf( "%s\n", buf[that] ))
  224.                 {
  225.                     fprintf( stderr, "FATAL... unable to write.\n\n" ) ;
  226.                     exit( 1 ) ;
  227.                 }
  228.             }
  229.             freq = 1;
  230.             this = that;
  231.             if( this )
  232.                 that = 0;
  233.             else
  234.                 that = 1;
  235.         }
  236.     }
  237.  
  238.     return;
  239. }
  240.