Index: ChangeLog =================================================================== RCS file: /sources/grub/grub2/ChangeLog,v retrieving revision 1.210 diff -u -r1.210 ChangeLog --- ChangeLog 10 Dec 2005 05:24:58 -0000 1.210 +++ ChangeLog 17 Dec 2005 17:32:13 -0000 @@ -1,3 +1,18 @@ +2005-12-17 Vesa Jaaskelainen + + * kern/err.c (grub_error_push): Added new function to support error + stacks. + (grub_error_pop): Likewise. + (grub_error_stack_items): New local variable to support error stacks. + (grub_error_stack_pos): Likewise. + (grub_error_stack_assert): Likewise. + (GRUB_ERROR_STACK_SIZE): Added new define to configure maximum error + stack depth. + (grub_print_error): Added support to print errors from error stack. + + * include/grub/err.h (grub_error_push): Added function prototype. + (grub_error_pop): Likewise. + 2005-12-09 Hollis Blanchard * configure.ac: Accept `powerpc64' as host_cpu. Index: include/grub/err.h =================================================================== RCS file: /sources/grub/grub2/include/grub/err.h,v retrieving revision 1.10 diff -u -r1.10 err.h --- include/grub/err.h 6 Nov 2005 22:19:59 -0000 1.10 +++ include/grub/err.h 17 Dec 2005 17:32:14 -0000 @@ -1,7 +1,7 @@ /* err.h - error numbers and prototypes */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003,2004 Free Software Foundation, Inc. + * Copyright (C) 2002-2005 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 @@ -60,6 +60,8 @@ grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...); void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn)); +void EXPORT_FUNC(grub_error_push) (void); +int EXPORT_FUNC(grub_error_pop) (void); void EXPORT_FUNC(grub_print_error) (void); #endif /* ! GRUB_ERR_HEADER */ Index: kern/err.c =================================================================== RCS file: /sources/grub/grub2/kern/err.c,v retrieving revision 1.3 diff -u -r1.3 err.c --- kern/err.c 4 Apr 2004 13:46:01 -0000 1.3 +++ kern/err.c 17 Dec 2005 17:32:14 -0000 @@ -1,7 +1,7 @@ /* err.c - error handling routines */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002,2005 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 @@ -22,11 +22,21 @@ #include #include -#define GRUB_MAX_ERRMSG 256 +#define GRUB_MAX_ERRMSG 256 +#define GRUB_ERROR_STACK_SIZE 10 grub_err_t grub_errno; char grub_errmsg[GRUB_MAX_ERRMSG]; +static struct +{ + grub_err_t errno; + char errmsg[GRUB_MAX_ERRMSG]; +} 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, ...) { @@ -54,8 +64,72 @@ } 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].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].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) { - if (grub_errno != GRUB_ERR_NONE) - grub_printf ("error: %s\n", grub_errmsg); + /* Print error messages in reverse order. First print active error message + and then empty error stack. */ + do + { + if (grub_errno != GRUB_ERR_NONE) + grub_printf ("error: %s\n", grub_errmsg); + } + while (grub_error_pop ()); + + /* If there was an assert while using error stack, report about it. */ + if (grub_error_stack_assert) + { + grub_printf ("assert: error stack overflow detected!\n"); + grub_error_stack_assert = 0; + } }