/*
** mg_err.c for  in 
** 
** Made by vianney rancurel
** Login   <vianney@epita.fr>
** 
** Started on  Wed Aug 25 12:15:39 1999 vianney rancurel
** Last update Thu Oct 28 20:16:09 1999 
*/
#include "mg.h"

char		*err_a_list[] = 
{
  "Error 0",					/* 0 */
  "Buffer has a zero length",			/* 1 */
  "Truncated",					/* 2 */
  "Buffer overflow",				/* 3 */
  "Syntax error",				/* 4 */
  "Invalid argument",				/* 5 */
  "Bad ASCII vector",				/* 6 */
  "Already exists",				/* 7 */
  "Break",					/* 8 */
  "Not found",					/* 9 */
  "Objects are identical",		        /* 10 */
  "No such key",				/* 11 */
  "No entry",					/* 12 */
  "No such base",				/* 13 */
  "Unrecognized base",				/* 14 */
  "Need more arguments",			/* 15 */
  "Too many arguments",				/* 16 */
  "Bad match",					/* 17 */
  "Bad format",					/* 18 */
  "Division by zero",				/* 19 */
  "Read error",					/* 20 */
  "Memory problem",				/* 21 */
  "Bad boolean syntax",				/* 22 */
  "Printf prematured end",			/* 23 */
  "Printf bad format",				/* 24 */
  "Printf null string",				/* 25 */
  "Undefined error",				/* 26 */
};	

t_id		*err_id = NULL;		

t_status	err_init(VOID_DECL)
{
  t_status	status;
  int		i;

  if ((err_id = id_new(HASH_SMALL_BASE,
		       VEC_ONE_BASE,
		       alloc_algorithm_factor2,
		       alloc_malloc,
		       realloc_realloc,
		       free_free,
		       "err",
		       &status)) == NULL)
    return (status);
  i = 0;
  while (i < ARRAY_COUNT(err_a_list))
    {
      if ((status = id_add(err_id,
			   (VOID_PTR)(ERR_MG_START + i),
			   err_a_list[i])) != 0)
	return (status);
      i++;
    }
  return (0);
}	

/* gets the error message associated with errcode. 
   Note: errcode must be positive.
   Returns string or NULL */
char		*err_msg(errcode)
t_status	errcode;
{
  t_hash_elt	*he;

  assert(err_id);
  if (errcode < 0)
    {
      fprintf(stderr,"errcode=%d\n",errcode);
      assert(errcode >= 0);
    }
  if (errcode >= ERR_MAGIC_SYS)
    errcode -= ERR_MAGIC_SYS;
  if ((he = id_get(err_id,
		   (VOID_PTR)errcode)) == NULL)
    return (NULL);
  return (he->value);
}

/* prints an error message on stderr.
   The output string will look like:
   user-error-msg: a-error-msg[: sys-error-msg]
   Note that user-error-msg is issued from a vsnprintf(3), a-error-msg is
   issued from a err_msg(3), sys-error-msg by strerror(3) */
#ifdef HAVE_STDARG_H
VOID_FUNC	err_print(int errcode,char *fmt,...)
#else
VOID_FUNC	err_print(errcode,fmt,va_alist)
t_status	errcode;
char		*fmt;
va_dcl
#endif
{
  va_list	ap;
  char		buf[BUFSIZ];
  char		*err;

  assert(fmt);
#ifdef HAVE_STDARG_H
  va_start(ap,fmt);
#else
  va_start(ap);
  va_arg(ap,int);
  va_arg(ap,char *);
#endif
  vsnprintf(buf,sizeof (buf),fmt,ap);
  if (err = err_msg(errcode))
    fprintf(stderr,"%s: %s (%d)",buf,err,errcode);
  else
    fprintf(stderr,"%s: (%d)",buf,errcode);
  if (ERR_LOOKUP_ERRNO(errcode))
    fprintf(stderr,": %s\n",strerror(errno));
  else
    fprintf(stderr,"\n");
  va_end(ap);
}

