/* err.c - error handling routines */ /* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2002,2005,2007,2008 Free Software Foundation, Inc. * * VAS_EBOOT 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. * * VAS_EBOOT 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 VAS_EBOOT. If not, see . */ #include #include #include #include #define VAS_EBOOT_ERROR_STACK_SIZE 10 VasEBoot_err_t VasEBoot_errno; char VasEBoot_errmsg[VAS_EBOOT_MAX_ERRMSG]; int VasEBoot_err_printed_errors; static struct VasEBoot_error_saved VasEBoot_error_stack_items[VAS_EBOOT_ERROR_STACK_SIZE]; static int VasEBoot_error_stack_pos; static int VasEBoot_error_stack_assert; #ifdef VasEBoot_error #undef VasEBoot_error #endif VasEBoot_err_t VasEBoot_error (VasEBoot_err_t n, const char *file, const char *function, const int line, const char *fmt, ...) { va_list ap; int m; VasEBoot_errno = n; m = VasEBoot_snprintf (VasEBoot_errmsg, sizeof (VasEBoot_errmsg), "%s:%s:%d:", file, function, line); if (m < 0) m = 0; va_start (ap, fmt); VasEBoot_vsnprintf (VasEBoot_errmsg + m, sizeof (VasEBoot_errmsg) - m, _(fmt), ap); va_end (ap); return n; } void VasEBoot_error_push (void) { /* Only add items to stack, if there is enough room. */ if (VasEBoot_error_stack_pos < VAS_EBOOT_ERROR_STACK_SIZE) { /* Copy active error message to stack. */ VasEBoot_error_stack_items[VasEBoot_error_stack_pos].VasEBoot_errno = VasEBoot_errno; VasEBoot_memcpy (VasEBoot_error_stack_items[VasEBoot_error_stack_pos].errmsg, VasEBoot_errmsg, sizeof (VasEBoot_errmsg)); /* Advance to next error stack position. */ VasEBoot_error_stack_pos++; } else { /* There is no room for new error message. Discard new error message and mark error stack assertion flag. */ VasEBoot_error_stack_assert = 1; } /* Allow further operation of other components by resetting active errno to VAS_EBOOT_ERR_NONE. */ VasEBoot_errno = VAS_EBOOT_ERR_NONE; } int VasEBoot_error_pop (void) { if (VasEBoot_error_stack_pos > 0) { /* Pop error message from error stack to current active error. */ VasEBoot_error_stack_pos--; VasEBoot_errno = VasEBoot_error_stack_items[VasEBoot_error_stack_pos].VasEBoot_errno; VasEBoot_memcpy (VasEBoot_errmsg, VasEBoot_error_stack_items[VasEBoot_error_stack_pos].errmsg, sizeof (VasEBoot_errmsg)); return 1; } else { /* There is no more items on error stack, reset to no error state. */ VasEBoot_errno = VAS_EBOOT_ERR_NONE; return 0; } } void VasEBoot_print_error (void) { /* Print error messages in reverse order. First print active error message and then empty error stack. */ do { if (VasEBoot_errno != VAS_EBOOT_ERR_NONE) { VasEBoot_err_printf (_("error: %s.\n"), VasEBoot_errmsg); VasEBoot_err_printed_errors++; } } while (VasEBoot_error_pop ()); /* If there was an assert while using error stack, report about it. */ if (VasEBoot_error_stack_assert) { VasEBoot_err_printf ("assert: error stack overflow detected!\n"); VasEBoot_error_stack_assert = 0; } }