/* err.c - error handling routines */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2002,2005,2007,2008  Free Software Foundation, Inc.
 *
 *  GRUB is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/err.h>
#include <grub/misc.h>
#include <stdarg.h>
#include <grub/i18n.h>

#define GRUB_ERROR_STACK_SIZE	10

grub_err_t grub_errno;
char grub_errmsg[GRUB_MAX_ERRMSG];
int grub_err_printed_errors;

static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE];

static int grub_error_stack_pos;
static int grub_error_stack_assert;

grub_err_t
grub_error (grub_err_t n, const char *fmt, ...)
{
  va_list ap;

  grub_errno = n;

  va_start (ap, fmt);
  grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
  va_end (ap);

  return n;
}

void
grub_error_push (void)
{
  /* Only add items to stack, if there is enough room.  */
  if (grub_error_stack_pos < GRUB_ERROR_STACK_SIZE)
    {
      /* Copy active error message to stack.  */
      grub_error_stack_items[grub_error_stack_pos].grub_errno = grub_errno;
      grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
                   grub_errmsg,
                   sizeof (grub_errmsg));

      /* Advance to next error stack position.  */
      grub_error_stack_pos++;
    }
  else
    {
      /* There is no room for new error message. Discard new error message
         and mark error stack assertion flag.  */
      grub_error_stack_assert = 1;
    }

  /* Allow further operation of other components by resetting
     active errno to GRUB_ERR_NONE.  */
  grub_errno = GRUB_ERR_NONE;
}

int
grub_error_pop (void)
{
  if (grub_error_stack_pos > 0)
    {
      /* Pop error message from error stack to current active error.  */
      grub_error_stack_pos--;

      grub_errno = grub_error_stack_items[grub_error_stack_pos].grub_errno;
      grub_memcpy (grub_errmsg,
                   grub_error_stack_items[grub_error_stack_pos].errmsg,
                   sizeof (grub_errmsg));

      return 1;
    }
  else
    {
      /* There is no more items on error stack, reset to no error state.  */
      grub_errno = GRUB_ERR_NONE;

      return 0;
    }
}

void
grub_print_error (void)
{
  /* Print error messages in reverse order. First print active error message
     and then empty error stack.  */
  do
    {
      if (grub_errno != GRUB_ERR_NONE)
	{
	  grub_err_printf (_("error: %s.\n"), grub_errmsg);
	  grub_err_printed_errors++;
	}
    }
  while (grub_error_pop ());

  /* If there was an assert while using error stack, report about it.  */
  if (grub_error_stack_assert)
    {
      grub_err_printf ("assert: error stack overflow detected!\n");
      grub_error_stack_assert = 0;
    }
}
