home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / doc / mir / fragment.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-02  |  8.3 KB  |  266 lines

  1. /*
  2.  * Usage -  fragment  input_file  offset  > stdout
  3.  *
  4.  * FRAGMENT Display a five line fragment of a file in printable form
  5.  *          with two lines of context on either side of the selected
  6.  *          offset.  Useful to get a quick view of contents at a
  7.  *          selected location in a file.  Use CPB and/or DUMP for an
  8.  *          alternate method, less convenient, but with more detail.
  9.  *
  10.  *  input:  Most useful for printable ASCII files.
  11.  *
  12.  *  output: Five double spaced lines in which  non-printing characters
  13.  *          are shown as blank with a ^ in the blank line below.  The
  14.  *          character at the exact offset is marked by a | in the blank
  15.  *          line below.
  16.  *
  17.  *  writeup: MIR TUTORIAL ONE, topic 5
  18.  *
  19.  *  Written:    Douglas Lowry   Feb 17 92
  20.  *  Modified:   Douglas Lowry   Feb 18 92
  21.  *              Copyright (C) 1992 Marpex 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. #include <ctype.h>
  76.  
  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( "fragment" );  }
  88.  
  89. /*
  90.  * MAIN
  91.  */
  92.  
  93. main( argc, argv )
  94.     int  argc;
  95.     char **argv;
  96. {
  97.     FILE        *fp ;
  98.     long int    offset ;
  99.  
  100.     /* Usage -  fragment  input_file  offset  > stdout  */
  101.  
  102.     if( argc != 3 || argv[1][0] == '-' || argv[1][0] == '?' )
  103.         Usage_() ;
  104.  
  105.     if(( fp = fopen( argv[1], "rb" )) == NULL )
  106.     {
  107.         fprintf( stderr, "\nUnable to open file %s.\n", argv[1] );
  108.         Usage_();
  109.     }
  110.  
  111.     offset = atol( argv[2] );
  112.  
  113.     process( fp, offset ) ;
  114.  
  115.     fclose( fp );
  116.  
  117.     exit( 0 );
  118. }
  119. /*
  120.  *  Usage
  121.  */
  122.     void
  123. Usage_()
  124. {
  125.     fprintf( stderr,"\nUsage:  %s  input_file  offset > stdout\n\n\
  126.         Display a five line fragment of a file in printable form\n\
  127.         with two lines of context on either side of the selected\n\
  128.         offset.  Useful to get a quick view of contents at a\n",
  129.             Cmdname_() );
  130.     fprintf( stderr,
  131. "        selected location in a file.  Use CPB and/or DUMP for an\n\
  132.         alternate method, less convenient, but with more detail.\n\n\
  133. input:  Most useful for printable ASCII files.\n\n" ) ;
  134.     fprintf( stderr,
  135. "output: Five double spaced lines in which  non-printing characters\n\
  136.         are shown as blank with a ^ in the blank line below.  The\n\
  137.         character at the exact offset is marked by a | in the blank\n\
  138.         line below.\n\n\
  139. writeup: MIR TUTORIAL ONE, topic 5\n\n" ) ;
  140.     exit( 1 ) ;
  141. }
  142. /*
  143.  *  PROCESS
  144.  */
  145.     void
  146. process( fp, offset )
  147.     FILE        *fp ;
  148.     long int    offset ;
  149. {
  150.     unsigned char  buf[ 512 ],
  151.                 under_buf[ 80 ],  /*  holds ^ and | markers           */
  152.                 c ;
  153.     Bool        over_80 ;   /*  a line contains over 80 bytes         */
  154.     int         buf_pt, len,
  155.                 newlines,   /*  count of newlines before/after offset */
  156.                 marker,     /*  position in buf equivalent to offset  */
  157.                 ok_bgn,     /*  latest series of printables start     */
  158.                 byt_in_ln,  /*  bytes in current line            */
  159.                 i, j ;
  160.     long int    start_at ;  /*  offset that allows straddle of offset */
  161.  
  162.     start_at = offset - 256 ;
  163.     marker = 256 ;
  164.     if( start_at < 0 )
  165.     {
  166.         start_at = 0 ;
  167.         marker = ( int ) offset ;
  168.     }
  169.     over_80 = FALSE ;
  170.     under_buf[0] = '\0' ;
  171.  
  172.     if( start_at )
  173.     {
  174.         if( fseek( fp, start_at, SEEK_SET ))
  175.         {
  176.             fprintf( stderr, "Unable to position file to %ld\n",
  177.                 start_at );
  178.             Usage_() ;
  179.         }
  180.     }
  181.  
  182.     if( !( len = fread( buf, sizeof( char ), 512, fp )))
  183.     {
  184.         fprintf( stderr, "FATAL... unable to read file.\n" ) ;
  185.         Usage_() ;
  186.     }
  187.  
  188.     newlines = buf_pt = 0 ;
  189.     for( i = marker - 1 ; i  ; i-- )
  190.     {
  191.         /*  Find beginning of second line before current    */
  192.  
  193.         if( buf[i] == '\n' )
  194.         {
  195.             if( newlines++ > 1 )
  196.             {
  197.                 buf_pt = i + 1 ;
  198.                 break ;
  199.             }
  200.         }
  201.     }
  202.  
  203.     putchar( '\n' ) ;
  204.  
  205.     newlines = ok_bgn = byt_in_ln = 0 ;
  206.     for( i = buf_pt ; i < len ; i++ )
  207.     {
  208.         c = buf[ i ] ;
  209.         if( i == marker && byt_in_ln < 78 )
  210.         {
  211.             for( j = ok_bgn ; j < byt_in_ln ; j++ )
  212.                 under_buf[ j ]  = ' ' ;
  213.             under_buf[ byt_in_ln ] = '|' ;
  214.             ok_bgn = byt_in_ln + 1 ;
  215.         }
  216.  
  217.         if( byt_in_ln++ > 77 )
  218.         {
  219.             over_80 = TRUE ;
  220.             if( byt_in_ln > 100 )
  221.                 c = '\n' ;          /*  impose a line end   */
  222.             if( c != '\n' )
  223.                 continue ;          /*  cut off the line    */
  224.         }
  225.         if( c == '\n' )
  226.         {
  227.             putchar( '\n' ) ;
  228.             if( !ok_bgn )
  229.                 putchar( '\n' ) ;   /*  intervening is blank */
  230.             else
  231.             {
  232.                 under_buf[ ok_bgn ] = '\0' ;
  233.                 puts( under_buf ) ;
  234.                 ok_bgn = 0 ;
  235.             }
  236.             byt_in_ln = 0 ;
  237.             if( ++newlines > 4 )
  238.                 break ;
  239.              continue ;
  240.         }
  241.         if( c == '\015' )       /*  ignore carriage returns */
  242.             continue ;
  243.  
  244.         /*  Change next line if making a non-PC version!     */
  245.  
  246.         if( c < 0x20 || c == 0x7f || c == 0xff )
  247.         {
  248.             /*  Non-printing characters.  Note tabs must be  */
  249.             /*  included since they distort the marker line. */
  250.  
  251.             for( j = ok_bgn ; j < byt_in_ln - 1 ; j++ )
  252.                 under_buf[ j ]  = ' ' ;
  253.             if( i != marker )
  254.                 under_buf[ byt_in_ln - 1 ] = '^' ;
  255.             ok_bgn = byt_in_ln ;
  256.             c = ' ' ;
  257.         }
  258.         putchar( c ) ;
  259.     }
  260.  
  261.     if( over_80 )
  262.         printf( "\n\n\tWARNING: Contains lines over 80 bytes long.\n" );
  263.  
  264.     return ;
  265. }
  266.