home *** CD-ROM | disk | FTP | other *** search
- /*
- * Usage - fragment input_file offset > stdout
- *
- * FRAGMENT Display a five line fragment of a file in printable form
- * with two lines of context on either side of the selected
- * offset. Useful to get a quick view of contents at a
- * selected location in a file. Use CPB and/or DUMP for an
- * alternate method, less convenient, but with more detail.
- *
- * input: Most useful for printable ASCII files.
- *
- * output: Five double spaced lines in which non-printing characters
- * are shown as blank with a ^ in the blank line below. The
- * character at the exact offset is marked by a | in the blank
- * line below.
- *
- * writeup: MIR TUTORIAL ONE, topic 5
- *
- * Written: Douglas Lowry Feb 17 92
- * Modified: Douglas Lowry Feb 18 92
- * Copyright (C) 1992 Marpex Inc.
- *
- * The MIR (Mass Indexing and Retrieval) Tutorials explain detailed
- * usage and co-ordination of the MIR family of programs to analyze,
- * prepare and index databases (small through gigabyte size), and
- * how to build integrated retrieval software around the MIR search
- * engine. The fifth of the five MIR tutorial series explains how
- * to extend indexing capability into leading edge search-related
- * technologies. For more information, GO IBMPRO on CompuServe;
- * MIR files are in the DBMS library. The same files are on the
- * Canada Remote Systems BBS. A diskette copy of the Introduction
- * is available by mail ($10 US... check, Visa or Mastercard);
- * diskettes with Introduction, Tutorial ONE software and the
- * shareware Tutorial ONE text cost $29. Shareware registration
- * for a tutorial is also $29.
- *
- * E-mail...
- * Compuserve 71431,1337
- * Internet doug.lowry%canrem.com
- * UUCP canrem!doug.lowry
- * Others: doug.lowry@canrem.uucp
- *
- * FAX... 416 963-5677
- *
- * "Snail mail"... Douglas Lowry, Ph.D.
- * Marpex Inc.
- * 5334 Yonge Street, #1102
- * North York, Ontario
- * Canada M2N 6M2
- *
- * Related database consultation and preparation services are
- * available through:
- * Innotech Inc., 2001 Sheppard Avenue E., Suite #118,
- * North York, Ontario Canada M2J 4Z7
- * Tel. 416 492-3838 FAX 416 492-3843
- *
- * This program is free software; you may redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * (file 05LICENS) along with this program; if not, write to the
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
-
- #define repeat for(;;)
-
- /*
- * declarations
- */
-
- typedef enum _bool
- { FALSE = 0, TRUE = 1 } Bool;
-
- void Usage_(), process();
- char *Cmdname_() { return( "fragment" ); }
-
- /*
- * MAIN
- */
-
- main( argc, argv )
- int argc;
- char **argv;
- {
- FILE *fp ;
- long int offset ;
-
- /* Usage - fragment input_file offset > stdout */
-
- if( argc != 3 || argv[1][0] == '-' || argv[1][0] == '?' )
- Usage_() ;
-
- if(( fp = fopen( argv[1], "rb" )) == NULL )
- {
- fprintf( stderr, "\nUnable to open file %s.\n", argv[1] );
- Usage_();
- }
-
- offset = atol( argv[2] );
-
- process( fp, offset ) ;
-
- fclose( fp );
-
- exit( 0 );
- }
- /*
- * Usage
- */
- void
- Usage_()
- {
- fprintf( stderr,"\nUsage: %s input_file offset > stdout\n\n\
- Display a five line fragment of a file in printable form\n\
- with two lines of context on either side of the selected\n\
- offset. Useful to get a quick view of contents at a\n",
- Cmdname_() );
- fprintf( stderr,
- " selected location in a file. Use CPB and/or DUMP for an\n\
- alternate method, less convenient, but with more detail.\n\n\
- input: Most useful for printable ASCII files.\n\n" ) ;
- fprintf( stderr,
- "output: Five double spaced lines in which non-printing characters\n\
- are shown as blank with a ^ in the blank line below. The\n\
- character at the exact offset is marked by a | in the blank\n\
- line below.\n\n\
- writeup: MIR TUTORIAL ONE, topic 5\n\n" ) ;
- exit( 1 ) ;
- }
- /*
- * PROCESS
- */
- void
- process( fp, offset )
- FILE *fp ;
- long int offset ;
- {
- unsigned char buf[ 512 ],
- under_buf[ 80 ], /* holds ^ and | markers */
- c ;
- Bool over_80 ; /* a line contains over 80 bytes */
- int buf_pt, len,
- newlines, /* count of newlines before/after offset */
- marker, /* position in buf equivalent to offset */
- ok_bgn, /* latest series of printables start */
- byt_in_ln, /* bytes in current line */
- i, j ;
- long int start_at ; /* offset that allows straddle of offset */
-
- start_at = offset - 256 ;
- marker = 256 ;
- if( start_at < 0 )
- {
- start_at = 0 ;
- marker = ( int ) offset ;
- }
- over_80 = FALSE ;
- under_buf[0] = '\0' ;
-
- if( start_at )
- {
- if( fseek( fp, start_at, SEEK_SET ))
- {
- fprintf( stderr, "Unable to position file to %ld\n",
- start_at );
- Usage_() ;
- }
- }
-
- if( !( len = fread( buf, sizeof( char ), 512, fp )))
- {
- fprintf( stderr, "FATAL... unable to read file.\n" ) ;
- Usage_() ;
- }
-
- newlines = buf_pt = 0 ;
- for( i = marker - 1 ; i ; i-- )
- {
- /* Find beginning of second line before current */
-
- if( buf[i] == '\n' )
- {
- if( newlines++ > 1 )
- {
- buf_pt = i + 1 ;
- break ;
- }
- }
- }
-
- putchar( '\n' ) ;
-
- newlines = ok_bgn = byt_in_ln = 0 ;
- for( i = buf_pt ; i < len ; i++ )
- {
- c = buf[ i ] ;
- if( i == marker && byt_in_ln < 78 )
- {
- for( j = ok_bgn ; j < byt_in_ln ; j++ )
- under_buf[ j ] = ' ' ;
- under_buf[ byt_in_ln ] = '|' ;
- ok_bgn = byt_in_ln + 1 ;
- }
-
- if( byt_in_ln++ > 77 )
- {
- over_80 = TRUE ;
- if( byt_in_ln > 100 )
- c = '\n' ; /* impose a line end */
- if( c != '\n' )
- continue ; /* cut off the line */
- }
- if( c == '\n' )
- {
- putchar( '\n' ) ;
- if( !ok_bgn )
- putchar( '\n' ) ; /* intervening is blank */
- else
- {
- under_buf[ ok_bgn ] = '\0' ;
- puts( under_buf ) ;
- ok_bgn = 0 ;
- }
- byt_in_ln = 0 ;
- if( ++newlines > 4 )
- break ;
- continue ;
- }
- if( c == '\015' ) /* ignore carriage returns */
- continue ;
-
- /* Change next line if making a non-PC version! */
-
- if( c < 0x20 || c == 0x7f || c == 0xff )
- {
- /* Non-printing characters. Note tabs must be */
- /* included since they distort the marker line. */
-
- for( j = ok_bgn ; j < byt_in_ln - 1 ; j++ )
- under_buf[ j ] = ' ' ;
- if( i != marker )
- under_buf[ byt_in_ln - 1 ] = '^' ;
- ok_bgn = byt_in_ln ;
- c = ' ' ;
- }
- putchar( c ) ;
- }
-
- if( over_80 )
- printf( "\n\n\tWARNING: Contains lines over 80 bytes long.\n" );
-
- return ;
- }