/* @(#)diagmesg.c	1.3	2/10/93 */
/*******************************************************************************

This code was written and designed by 
Andrew Gene HALL of I.N. Services Pty. Ltd., Scarborough WA, Australia,
for the 
University of Western Australia, Crawley WA, Australia.

*******************************************************************************/
#include "diagmesg.h"
#include <string.h>
/* #include <malloc.h>     CHANGE 11/3 */
#include <stdlib.h>  /* CHANGE 11/3 */

extern char *strdup( char *) ; /* CHANGE 9/3 */

/* Definition of global variables */
enum Diagnostic_Level	current_level = INFORM;
FILE *			error_fp = stderr;
enum Diagnostic_Level *	level_buffer = NULL;
char **			message_buffer = NULL;
int			last_message = -1;
int			N_blocks_buffer = 0;
int			Sizeof_buffer = 0;

/* Buffer_MSG
 * Add the given message to a buffer so that its output can be flushed 
 * later.
 * The buffer is self initialising.
 */
void
Buffer_MSG(
enum Diagnostic_Level	level,
char *			message)
{
   /* check if we have a buffer */
   if( last_message == -1 ) {
      /* build buffer */
      if( (message_buffer = (char **)malloc( ++N_blocks_buffer *
                                             BUFFER_BLOCK * sizeof( char * ))) )
         Sizeof_buffer += BUFFER_BLOCK;
      else 
         fprintf(stderr, "Buffer_MSG: Out of memory."); 
      if( !( level_buffer = (enum Diagnostic_Level*)malloc( N_blocks_buffer * BUFFER_BLOCK * sizeof( enum Diagnostic_Level ))) ) 
         fprintf(stderr, "Buffer_MSG: Out of memory."); 
   }

   /* check if adding this messge will outgrow the buffer */
   if( ++last_message == Sizeof_buffer ) {
      /* extend the buffer */
      if( (message_buffer = (char **)realloc( message_buffer, 
                          ++N_blocks_buffer * BUFFER_BLOCK * sizeof( char * ))))
         Sizeof_buffer += BUFFER_BLOCK;
      else 
         fprintf(stderr, "Buffer_MSG: Out of memory."); 
      if( !( level_buffer = (enum Diagnostic_Level *)realloc( level_buffer, N_blocks_buffer * BUFFER_BLOCK * sizeof( enum Diagnostic_Level ))) ) 
         fprintf(stderr, "Buffer_MSG: Out of memory."); 
   }

   /* add the message to the buffer */
   message_buffer[ last_message ] = strdup(message);
   /* add the level to the buffer */
   level_buffer[ last_message ] = level;

} /* Buffer_MSG */

/* Flush_MSG
 * Flush the contents of the message buffer and
 * free up its space.
 */
void
Flush_MSG( void )
{
   int i;

   /* there are messages to flush */
   for( i = 0; i <= last_message; i++ ) {
      switch( level_buffer[i] ) {
      case ERROR:
         ERROR_MSG( message_buffer[i] );
         break;

      case INFORM:
         INFORM_MSG( message_buffer[i] );
         break;

      case DEBUG:
         DEBUG_MSG( message_buffer[i] );
         break;

      default:
         fprintf( stderr, "Flush_MSG: Unknown level of error.");
      }
      /* free up the string */
      if( message_buffer[i] ) free(message_buffer[i]);
   }
   
   /* free up the buffers */
   if( message_buffer ) free(message_buffer);
   if( level_buffer ) free(level_buffer);
   /* reset the state variables for the buffers */
   last_message = -1;
   N_blocks_buffer = 0;
   Sizeof_buffer = 0;

} /* Flush_MSG */
