COSC_4P82_Assignment_1/lib/lilgp/kernel/output.c

407 lines
9.8 KiB
C

/* lil-gp Genetic Programming System, version 1.0, 11 July 1995
* Copyright (C) 1995 Michigan State University
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* 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
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Douglas Zongker (zongker@isl.cps.msu.edu)
* Dr. Bill Punch (punch@isl.cps.msu.edu)
*
* Computer Science Department
* A-714 Wells Hall
* Michigan State University
* East Lansing, Michigan 48824
* USA
*
*/
#include <lilgp.h>
char buffer[MAXMESSAGELENGTH];
typedef struct
{
int id;
char *ext;
int reset;
char *mode;
int autoflush;
FILE *f;
int valid;
char *buffer;
} output;
output streams[MAXOUTPUTSTREAMS] =
{ { OUT_SYS, ".sys", 0, "w", 1, NULL, 0 },
{ OUT_GEN, ".gen", 0, "w", 0, NULL, 0 },
{ OUT_PRG, ".prg", 0, "w", 0, NULL, 0 },
{ OUT_STT, ".stt", 0, "w", 0, NULL, 0 },
{ OUT_BST, ".bst", 1, "w", 0, NULL, 0 },
{ OUT_HIS, ".his", 0, "w", 0, NULL, 0 } };
int output_stream_count = SYSOUTPUTSTREAMS;
int toolate = 0;
char *global_basename = NULL;
int detail_level = DEFDETAILLEVEL;
char error_type[3][20] = { "WARNING: ", "ERROR: ", "FATAL ERROR: " };
extern int quietmode;
/* create_output_stream()
*
* make a new entry in the outputstream table.
*/
int create_output_stream ( int id, char *ext, int reset, char *mode,
int autoflush )
{
int i;
/* can't create a new stream if they've already been opened. */
if ( toolate )
return OUTPUT_TOOLATE;
/* is the stream table full? */
if ( output_stream_count >= MAXOUTPUTSTREAMS )
return OUTPUT_TOOMANY;
/* is the id or extension the same as an existing stream? */
for ( i = 0; i < output_stream_count; ++i )
{
if ( id == streams[i].id )
return OUTPUT_DUP_ID;
if ( strcmp ( ext, streams[i].ext ) == 0 )
return OUTPUT_DUP_EXT;
}
/** save stuff in the table. **/
streams[output_stream_count].id = id;
streams[output_stream_count].ext = (char *)malloc ( strlen(ext)+1 );
strcpy ( streams[output_stream_count].ext, ext );
streams[output_stream_count].reset = reset;
streams[output_stream_count].mode = (char *)malloc ( strlen(mode)+1 );
strcpy ( streams[output_stream_count].mode, mode );
streams[output_stream_count].autoflush = autoflush;
streams[output_stream_count].f = NULL;
streams[output_stream_count].valid = 0;
++output_stream_count;
return OUTPUT_OK;
}
/* initialize_output_streams()
*
* initialize the output streams. until they are opened, anything printed
* to one (via oputs() or oprintf()) is saved in memory.
*/
void initialize_output_streams ( void )
{
int i;
toolate = 1;
for ( i = 0; i < output_stream_count; ++i )
streams[i].buffer = NULL;
}
/* open_output_streams()
*
* open files associated with each output stream. dump anything buffered
* in memory to the file.
*/
void open_output_streams ( void )
{
int i;
char *fn = NULL;
char *basename;
basename = get_parameter ( "output.basename" );
fn = (char *)MALLOC ( strlen(basename)+50 );
for ( i = 0; i < output_stream_count; ++i )
{
strcpy ( fn, basename );
strcat ( fn, streams[i].ext );
streams[i].f = fopen ( fn, streams[i].mode );
if ( streams[i].f == NULL )
{
error ( E_ERROR, "can't open output file \"%s\".", fn );
}
else
{
streams[i].valid = 1;
if ( streams[i].buffer )
fputs ( streams[i].buffer, streams[i].f );
FREE ( streams[i].buffer );
streams[i].buffer = NULL;
}
}
global_basename = (char *)malloc ( strlen(basename)+1 );
strcpy ( global_basename, basename );
set_detail_level ( atoi ( get_parameter ( "output.detail" ) ) );
if (fn)
FREE(fn);
}
/* oputs()
*
* prints a string to an output stream.
*/
void oputs ( int streamid, int detail, const char *string )
{
int i, j;
if ( streamid == OUT_SYS && !quietmode )
{
printf ( string );
fflush ( stdout );
}
if ( detail_level < detail )
return;
for ( i = 0; i < output_stream_count; ++i )
{
if ( streamid == streams[i].id )
{
if ( streams[i].valid )
{
fputs ( string, streams[i].f );
if ( streams[i].autoflush )
fflush ( streams[i].f );
break;
}
else
{
if ( streams[i].buffer )
{
j = strlen ( streams[i].buffer ) +
strlen ( string ) + 1;
streams[i].buffer = (char *)REALLOC ( streams[i].buffer, j );
strcat ( streams[i].buffer, string );
}
else
{
streams[i].buffer = (char *)MALLOC ( strlen ( string ) + 1 );
strcpy ( streams[i].buffer, string );
}
}
}
}
}
/* oprintf()
*
* prints a formatted string to an output stream.
*/
void oprintf ( int streamid, int detail, const char *format, ... )
{
va_list ap;
if ( detail_level < detail )
return;
va_start ( ap, format );
vsprintf ( buffer, format, ap );
va_end ( ap );
oputs ( streamid, detail, buffer );
}
/* output_filehandle()
*
* returns the filehandle associated with a given stream.
*/
FILE *output_filehandle ( int streamid )
{
int i;
for ( i = 0; i < output_stream_count; ++i )
if ( streamid == streams[i].id )
if ( streams[i].valid )
return ( streams[i].f );
return NULL;
}
/* output_stream_close()
*
* closes an output stream, if it has been marked as resettable.
*/
void output_stream_close ( int streamid )
{
int i;
for ( i = 0; i < output_stream_count; ++i )
if ( streamid == streams[i].id )
if ( streams[i].reset )
if ( streams[i].valid )
{
fclose ( streams[i].f );
streams[i].valid = 0;
break;
}
}
/* output_stream_open()
*
* reopens a resettable output stream.
*/
void output_stream_open ( int streamid )
{
char *fn = NULL;
int i;
for ( i = 0; i < output_stream_count; ++i )
if ( streamid == streams[i].id )
if ( streams[i].reset )
if ( !streams[i].valid )
{
fn = (char *)MALLOC ( strlen(global_basename)+50 );
strcpy ( fn, global_basename );
strcat ( fn, streams[i].ext );
streams[i].f = fopen ( fn, streams[i].mode );
if ( streams[i].f == NULL )
{
/* an error. */
}
else
streams[i].valid = 1;
}
if (fn)
FREE(fn);
}
/* output_stream_flush()
*
* flushes all the resettable output streams.
*/
void output_stream_flush ( int streamid )
{
int i;
for ( i = 0; i < output_stream_count; ++i )
if ( streamid == streams[i].id )
if ( streams[i].reset )
if ( streams[i].valid )
fflush ( streams[i].f );
}
/* close_output_streams()
*
* closes all the output streams.
*/
void close_output_streams ( void )
{
int i;
for ( i = 0; i < output_stream_count; ++i )
{
if ( streams[i].valid )
{
fclose ( streams[i].f );
streams[i].valid = 0;
}
}
for ( i = SYSOUTPUTSTREAMS; i < MAXOUTPUTSTREAMS; ++i )
{
free ( streams[i].ext );
free ( streams[i].mode );
}
free ( global_basename );
}
/* flush_output_streams()
*
* flushes all the output streams.
*/
void flush_output_streams ( void )
{
int i;
for ( i = 0; i < output_stream_count; ++i )
if ( streams[i].valid )
fflush ( streams[i].f );
}
/* error()
*
* prints an error message to the system output stream, with a given
* level of severity. If the error is fatal, then the error is also
* printed to stderr and the program exits with status 1.
*/
void error ( int severity, char *format, ... )
{
va_list ap;
va_start ( ap, format );
vsprintf ( buffer, format, ap );
va_end ( ap );
strcat ( buffer, "\n" );
oputs ( OUT_SYS, 0, error_type[severity] );
oputs ( OUT_SYS, 0, buffer );
if ( severity == E_FATAL_ERROR )
{
fprintf ( stderr, "exiting due to fatal error.\n" );
exit(1);
}
}
/* set_detail_level()
*
* sets the detail level to a given value.
*/
void set_detail_level ( int newlevel )
{
if ( newlevel >= MINDETAILLEVEL &&
newlevel <= MAXDETAILLEVEL )
detail_level = newlevel;
}
/* test_detail_level()
*
* returns 1 if the argument is less than or equal to the current
* detail level.
*/
int test_detail_level ( int detail )
{
if ( detail_level < detail )
return 0;
return 1;
}