home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * psfix.c
- *
- */
-
- /*
- * This software is the property of the Smithsonian Astrophysical Observatory
- * and the U.S. government. It may be freely distributed under the following
- * conditions:
- * 1. It is distributed in its current form, without alterations.
- * 2. No monetary profit is made, under any circumstances.
- *
- * Marc A. Murison
- * Smithsonian Astrophysical Observatory
- * 60 Garden Street, MS 63
- * Cambridge, MA 02138
- *
- * (617) 495-7079 murison@cfacx2.harvard.edu
- */
-
-
- #include "psfix.h"
-
-
- int main( int argc, char **argv )
- {
- /* flags */
- Flag msg_flag, file_mode;
- int dirflag=0, EOF_flag;
-
- /* counters */
- long newlines=0, oldlines=0, char_count=0;
- int ncomment, paren_level;
-
- /* misc variables */
- Boolean status;
- int i, min_args;
- int l_bytes, length;
- ulong f_bytes; /* bytes read from input file to file_buffer */
-
- /* file name character arrays and associated pointers */
- static char in_name[MAX_FNAME+1], out_name[MAX_FNAME+1];
- static char in_ext[5], out_ext[5];
- static char default_in_ext[5], default_out_ext[5];
- File_Def infile, outfile, dirfile;
-
-
- /* buffers and buffer pointers */
- static char msg[80];
- static char *line_buffer, *line_buff_start, *line_buff_ptr;
- static char *file_buffer, *file_buff_ptr;
-
- /* other pointers */
- static char *scratch_ptr;
-
-
-
- /* say hi */
- announce( VERSION, __DATE__ );
-
-
- /* parse the command line */
- strcpy( default_in_ext, INEXT );
- strcpy( default_out_ext, OUTEXT );
- min_args = 1;
- file_mode = FBINARY;
- status = cl_dir_in_out( argc, argv, min_args, usage, help, file_mode,
- default_in_ext, default_out_ext, in_name,
- in_ext, out_name, out_ext, &infile, &outfile,
- &dirfile, &dirflag );
-
- if( !status ) return 1;
-
-
- /* create buffers */
- line_buffer = cvector( 0, MAX_LBUFF );
- if( line_buffer == NULL ) {
- errout( 1, stdout, "\nNot enough memory for line buffer!\n" );
- fclose( infile.fp );
- fclose( outfile.fp );
- if( dirflag != 0 ) fclose( dirfile.fp );
- return 1;
- }
-
- file_buffer = (char *) malloc( (uint)MAX_FBUFF*sizeof(char) );
- if( file_buffer == NULL ) {
- errout( 1, stdout, "\nNot enough memory for file buffer!\n" );
- fclose( infile.fp );
- fclose( outfile.fp );
- if( dirflag != 0 ) fclose( dirfile.fp );
- return 1;
- }
-
-
-
- /*
- *
- * process input file(s)
- *
- */
-
- /* initial output and initialize counters */
- banner( infile.name, outfile.name, &char_count, &newlines, &oldlines );
-
- file_buff_ptr = file_buffer;
- line_buff_start = line_buffer;
- line_buff_ptr = line_buffer;
- *file_buffer = NULL;
- *line_buffer = NULL;
- paren_level = 0;
-
-
- /* fill the file buffer */
- printf( "\r% % % % % reading input file % % % % % \r" );
- f_bytes = pfill_file_buff( infile.fp, file_mode, MAX_FBUFF, file_buff_ptr,
- &EOF_flag, &ncomment, &paren_level );
- printf( "\r " );
-
-
- /* count the comment characters skipped */
- char_count += ncomment;
-
-
- if( f_bytes <= 0 ) {
- if( f_bytes == 0 ) {
- sprintf( msg, "\nfill_file_buff: input file %s is empty!\n",
- &infile.name );
- errout( 1, stdout, msg );
- }
- fclose( infile.fp );
- fclose( outfile.fp );
- if( dirflag != 0 )
- fclose( dirfile.fp );
- return 1;
- }
-
-
-
- /* top of processing loop */
- msg_flag = TRUE;
- status = TRUE;
- while( status ) {
-
- /* some screen output */
- if( newlines % OUTP_INTVL == 0 ) {
- #if __MSDOS__
- printf(
- "\r"
- "\xba Input line: %-5li Output line: %-5li"
- " Character: %-7li \xba\r",
- oldlines, newlines, char_count );
- #else
- printf(
- "\r"
- "| Input line: %-5li Output line: %-5li"
- " Character: %-7li |\r",
- oldlines, newlines, char_count );
- #endif
- }
-
-
- /* fill line buffer with MAX_CHARS bytes from file buffer */
- if( (length = strlen(line_buff_start)) < MAX_CHARS ) {
- f_bytes = MAX_FBUFF;
- l_bytes = MAX_CHARS - length;
- scratch_ptr = line_buff_start + length;
- pfill_line_buff( infile.fp, file_mode, file_buffer, &file_buff_ptr,
- f_bytes, l_bytes, scratch_ptr, msg_flag,
- &EOF_flag, &ncomment, &paren_level );
- char_count += ncomment;
- }
-
-
- /* process and output the line buffer contents */
- process_line_buffer( line_buff_start, &line_buff_ptr, &outfile,
- &char_count, &newlines, &oldlines, &EOF_flag );
-
-
- /* are we done with this input file yet? */
- if( EOF_flag && feof(infile.fp) ) {
- /* clean up final output */
- #if __MSDOS__
- printf( "\r"
- "\xba Input line: %-5li Output line: %-5li"
- " Character: %-7li \xba",
- oldlines, newlines, char_count );
- printf( "\n\xc8" );
- for( i=0; i < 59; i++ ) printf( "\xcd" );
- printf( "\xbc\n" );
- #else
- printf(
- "\r"
- "| Input line: %-5li Output line: %-5li Character: %-7li |",
- oldlines, newlines, char_count );
- printf( "\n" );
- for( i=0; i < 61; i++ ) printf( "-" );
- printf( "\n" );
- #endif
-
- fclose( infile.fp );
- fclose( outfile.fp );
- if( dirflag ) {
- status = get_next_file( &dirfile, &infile, &outfile,
- file_mode, default_in_ext, in_name, in_ext,
- out_name, out_ext );
-
- if( status ) {
- /* initial output and reset counters */
- banner( infile.name, outfile.name, &char_count,
- &newlines, &oldlines );
-
- /* reset pointers */
- file_buff_ptr = file_buffer;
- line_buff_ptr = line_buffer;
- *line_buff_ptr = NULL;
- *file_buff_ptr = NULL;
- EOF_flag = 0;
- }
-
- } else {
-
- status = 0;
-
- }
- }
- } /* end of processing loop */
-
-
- /* clean up */
-
- #if __MSDOS__
- if( dirflag || char_count > 100000L )
- errout( 1, stdout, "\n\nDone\n" );
- #else
- if( dirflag || char_count > 100000 )
- errout( 1, stdout, "\n\nDone\n\n" );
- #endif
-
-
- free( file_buffer );
- free_cvector( line_buffer, 0 );
- return 0;
- }
-
-
-
- /*-----------------------------------------------------------------------------
- * Process the contents of the line buffer and output the result to
- * outfile.
- *
- * If either an EOF or a NULL byte are encountered, then EOF_flag is set
- * to 1, via the pointer *EOF_flag; otherwise EOF_flag is set to 0. If
- * a newline character is encountered, the counter oldlines, pointed
- * to by *oldlines, is incremented (to keep track of input lines
- * processed). As each byte is read, char_count (pointed to by
- * *char_count) is incremented to keep count of total input bytes
- * processed. As new lines are written to the output file, counter newlines
- * (via *newlines) is incremented.
- *---------------------------------------------------------------------------*/
- void process_line_buffer( char *line_buff_start, char **line_buff,
- File_Def *outfile, long *char_count, long *newlines,
- long *oldlines, int *EOF_flag )
- {
- int i, length;
- char c;
- static char scratch[MAX_LBUFF], *sp;
- char *lp;
-
-
- *EOF_flag = 0;
-
- /* filter the first MAX_CHARS or less bytes of line buffer */
- lp = line_buff_start;
- sp = scratch;
- for( i=0; i < MAX_CHARS; i++ ) {
-
- c = *lp++;
-
- /* all done with this file */
- if( c == EOF || c == NULL ) {
- (*oldlines)++; /* count the last line */
- *EOF_flag = 1;
- break;
- }
-
- ++(*char_count);
-
- if( c == CR ) {
- if( *lp == LF ) { /* end of input line */
- lp++; /* skip over LF */
- (*char_count)++;
- (*oldlines)++;
- break;
- } else { /* lone cr */
- *(sp++) = BLANK;
- }
- } else if( c == TAB ) { /* replace tabs */
- *(sp++) = BLANK;
- } else { /* normal character */
- *(sp++) = c;
- }
- }
- *sp = NULL;
-
-
- /* now move back to a space */
- length = strlen( scratch );
- if( length == MAX_CHARS ) { /* do only if line is long enough */
- i = length - 1;
- sp = scratch + i; /* point to last character */
- while( i > 0 && *sp != BLANK ) {
- --i;
- --length;
- --sp;
- --(*char_count);
- }
- /* keep going until a non-space, so spaces are at start of next line */
- while( i > 0 && *sp == BLANK ) {
- --i;
- --length;
- --sp;
- --(*char_count);
- }
- /* if no spaces at all, quit */
- if( i == 0 ) {
- printf( "\a\n\nError!"
- "\nUnable to break input line number %li "
- "into pieces less than %i bytes!"
- "\nOffending piece of text is"
- "\n%s"
- "\nCheck last line of output file for context.",
- *oldlines, MAX_CHARS, scratch );
- fprintf( outfile->fp, "%s\n", scratch );
- fflush( outfile->fp );
- fclose( outfile->fp );
- exit(1);
- }
- }
-
-
- /* write a new line to output file */
- sp = scratch;
- for( i = 0; i < length; i++ ) {
- if( putc(*sp, outfile->fp) == EOF ) disk_full( outfile );
- ++sp;
- }
- if( putc(CR, outfile->fp) == EOF || putc(LF, outfile->fp) == EOF )
- disk_full( outfile );
-
- (*newlines)++;
-
-
- /* set up to read next input record to the line buffer */
-
- /* transfer leftovers to beginning of line_buffer, and return */
- *line_buff = lp; /* save new line_buffer position */
- lp = line_buff_start;
- strcpy( lp, sp );
- strcat( lp, *line_buff );
- *line_buff = line_buff_start; /* update line_buff_ptr in main */
- }
-
-
-
- /*-----------------------------------------------------------------------------
- *
- * disk full error out
- *
- *---------------------------------------------------------------------------*/
- void disk_full( File_Def *file )
- {
- int i;
-
- #if __MSDOS__
- printf( "\n\xc8" );
- for( i=0; i < 59; i++ ) printf( "\xcd" );
- printf( "\xbc\n" );
- #else
- printf( "\n" );
- for( i=0; i < 61; i++ ) printf( "-" );
- printf( "\n" );
- #endif
- printf( "\a\nError writing to %s! Disk full?\n", file->name );
- exit(1);
- }
-
-
-
- /*-----------------------------------------------------------------------------
- *
- * announce new filename
- *
- *---------------------------------------------------------------------------*/
- void banner( char infile_name[], char outfile_name[], long *char_count,
- long *newlines, long *oldlines )
- {
- int i;
-
- *newlines = 0;
- *oldlines = 0;
- *char_count = 0;
-
- #if __MSDOS__
-
- /* top line */
- printf( "\n\xc9" );
- for( i=0; i < 31; i++ ) printf( "\xcd" );
- printf( "\xbb" );
-
- /* text */
- printf( "\n\xba Input file: %-15s \xba"
- "\n\xba Output file: %-15s \xba",
- infile_name, outfile_name );
-
- /* separator line */
- printf( "\n\xcc" );
- for( i=0; i < 31; i++ ) printf( "\xcd" );
- printf( "\xca" );
- for( i=0; i < 27; i++ ) printf( "\xcd" );
- printf( "\xbb\n" );
-
- #else
-
- printf( "\n-----------------------"
- "\n| Input file: %-15s |"
- "\n| Output file: %-15s |"
- "\n", infile_name, outfile_name );
- for( i=0; i < 61; i++ ) printf( "-" );
- printf( "\n" );
-
- #endif
- }
-
-
-
- /*-----------------------------------------------------------------------------
- * ulong pfill_file_buff( FILE *infile, int ftype, long Nmax,
- * char *buff, int *EOF_flag, int *ncomment,
- * int *paren_level )
- *
- * modified version of fill_file_buff in strlib.c
- * (this version strips PostScript comments)
- *---------------------------------------------------------------------------*/
- ulong pfill_file_buff( FILE *infile, int ftype, ulong Nmax, char *buff,
- int *EOF_flag, int *ncomment, int *paren_level )
- {
- ulong i;
- int c;
- char *p;
-
-
- if( ftype != FTEXT && ftype != FBINARY ) {
- errout( 1, stdout, "\nfill_file_buff: Invalid ftype!\n\n" );
- *EOF_flag = 1;
- return 0;
- }
-
-
- *EOF_flag = FALSE;
- p = buff;
- i = 0;
- *ncomment = 0;
- while( i < Nmax ) {
- c = getc( infile );
- ++i;
-
- /* check parentheses nesting level (for comment stripping decision) */
- if( c == '(' && *(p-1) != BSLASH ) ++(*paren_level);
- if( c == ')' && *(p-1) != BSLASH ) --(*paren_level);
-
- /* strip P.S. comments */
- if( c == '%' && *paren_level == 0 ) {
- ++i;
- ++(*ncomment);
- while( ( c = getc(infile) ) != CR
- && c != LF && c != EOF ) { ++i; ++(*ncomment); }
- }
-
- /* check end of file */
- if( c == EOF ) {
- *EOF_flag = TRUE;
- break;
- }
-
- /* write character to file buffer */
- *p++ = c;
- }
-
- *p = NULL;
-
- return i;
- }
-
-
-
- /*-----------------------------------------------------------------------------
- * uint pfill_line_buff( FILE *infile, int ftype, char file_buffer,
- * char **file_buff_ptr_ptr, ulong Fbytes, uint Lbytes,
- * char *line_buff_ptr, int msg_flag, int *EOF_flag,
- * int *ncomment, int *paren_level )
- *
- * a modified version of fill_line_buff in strlib.c
- *---------------------------------------------------------------------------*/
- uint pfill_line_buff( FILE *infile, int ftype, char file_buffer[],
- char **file_buff_ptr_ptr, ulong Fbytes, uint Lbytes,
- char *line_buff_ptr, int msg_flag, int *EOF_flag,
- int *ncomment, int *paren_level )
- {
- uint n;
- ulong k;
- char *file_buff_ptr;
-
-
- /* try to move Lbytes bytes */
- file_buff_ptr = *file_buff_ptr_ptr;
- k = append_buff( file_buff_ptr, Lbytes, line_buff_ptr );
- n = (uint) k;
- *file_buff_ptr_ptr += n;
- *ncomment = 0;
-
- /* if not enough bytes were copied, get more from the input file */
- if( n != Lbytes ) {
- *file_buffer = NULL;
- file_buff_ptr = file_buffer;
- *file_buff_ptr_ptr = file_buff_ptr;
- if( !feof(infile) ) {
- if( msg_flag ) {
- printf( "\r % % % % % Reading input file "
- "% % % % % \r" );
- }
- k = pfill_file_buff( infile, ftype, Fbytes, file_buff_ptr,
- EOF_flag, ncomment, paren_level );
- if( msg_flag ) {
- printf( "\r "
- " \r" );
- }
- /* finish filling the line buffer */
- line_buff_ptr += n;
- k = append_buff( file_buff_ptr, Lbytes - n, line_buff_ptr );
- n += (uint) k + *ncomment;
- *file_buff_ptr_ptr += (int) k;
-
- } else { /* already at end of file on entry into this routine */
-
- *EOF_flag = 1;
-
- }
- }
-
- return n;
- }
-
-
-
- /*-----------------------------------------------------------------------------
- *
- * generic error output
- *
- *---------------------------------------------------------------------------*/
- void errout( Boolean bell, FILE *device, char *errstring )
- {
- if( bell ) putc( BELL, device );
- fprintf( device, "%s", errstring );
- return;
- }
-
-
-