/* error.c: communication of informational, warning, error and 
 * fatal error messages for the pools library. */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include "pools.h"
#include "error.h"

/* default callback for showing informational messages */


/* default callback for showing warning messages */
static void pools_warning(char *message)
{
  fprintf(stderr, "warning: %s\n", message);
}

/* default callback for showing error messages */
static void pools_error(char *message)
{
  fprintf(stderr, "error: %s\n", message);
}

/* default callback for showing fatal error messages */
static void pools_fatal(char *message)
{
  fprintf(stderr, "fatal error: %s\n", message);
  abort();
  exit(-1);
}

POOLS_MSG_CALLBACK_FUNC pools_info_callback_func = NULL,
                        pools_warning_callback_func = pools_warning,
                        pools_error_callback_func = pools_error,
                        pools_fatal_callback_func = pools_fatal;

/* The SetCallback functions return the previously set callback function */
POOLS_MSG_CALLBACK_FUNC PoolsSetInfoCallback(POOLS_MSG_CALLBACK_FUNC func)
{
  POOLS_MSG_CALLBACK_FUNC old_func = pools_info_callback_func;
  pools_info_callback_func = func;
  return old_func;
}

POOLS_MSG_CALLBACK_FUNC PoolsSetWarningCallback(POOLS_MSG_CALLBACK_FUNC func)
{
  POOLS_MSG_CALLBACK_FUNC old_func = pools_warning_callback_func;
  pools_warning_callback_func = func;
  return old_func;
}

POOLS_MSG_CALLBACK_FUNC PoolsSetErrorCallback(POOLS_MSG_CALLBACK_FUNC func)
{
  POOLS_MSG_CALLBACK_FUNC old_func = pools_error_callback_func;
  pools_error_callback_func = func;
  return old_func;
}

POOLS_MSG_CALLBACK_FUNC PoolsSetFatalCallback(POOLS_MSG_CALLBACK_FUNC func)
{
  POOLS_MSG_CALLBACK_FUNC old_func = pools_fatal_callback_func;
  pools_fatal_callback_func = func;
  return old_func;
}

/* prints an informational message */
void PoolsInfo(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[POOLS_MAX_MESSAGE_LENGTH], *p;
	
	va_start(pvar, text);
	vsprintf(buf, text, pvar);
	va_end(pvar);

	if (routine) {
	  /* go to the end of the string */
	  for (p=buf; *p; p++) {}
	  sprintf(p, " (in subroutine %s)", routine);
	}
	
	pools_info_callback_func(buf);
}

/* prints a warning message */
void PoolsWarning(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[POOLS_MAX_MESSAGE_LENGTH], *p;

	va_start(pvar, text);
	vsprintf(buf, text, pvar);
	va_end(pvar);

	if (routine) {
	  /* go to the end of the string */
	  for (p=buf; *p; p++) {}
	  sprintf(p, " (in subroutine %s)", routine);
	}
	
	pools_warning_callback_func(buf);
}

/* prints an error message */
void PoolsError(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[POOLS_MAX_MESSAGE_LENGTH], *p;
	
	va_start(pvar, text);
	vsprintf(buf, text, pvar);
	va_end(pvar);

	if (routine) {
	  /* go to the end of the string */
	  for (p=buf; *p; p++) {}
	  sprintf(p, " (in subroutine %s)", routine);
	}
	
	pools_error_callback_func(buf);
}

/* prints a fatal error message */
void PoolsFatal(char *routine, char *text, ...)
{
	va_list pvar;
	char buf[POOLS_MAX_MESSAGE_LENGTH], *p;
	
	va_start(pvar, text);
	vsprintf(buf, text, pvar);
	va_end(pvar);

	if (routine) {
	  /* go to the end of the string */
	  for (p=buf; *p; p++) {}
	  sprintf(p, " (in subroutine %s)", routine);
	}
	
	pools_fatal_callback_func(buf);
}

