IRPLIB error handling
[Error handling]

Data Structures

struct  irplib_error

Defines

#define MAX_STRING_LENGTH   200
#define MAX_ERRORS   20
#define irplib_error_assure(CONDITION, ERROR_CODE, MSG, ACTION)
 Generic error handling macro.
#define irplib_error_push(ec, msg)
 Set or propagate an error.
#define irplib_error_dump(severity, trace_severity)
 Print the error queue.

Functions

static void irplib_error_validate_state (const char *func, const char *file, unsigned int line)
 Synchronize IRPLIB error state with CPL's error state.
cpl_error_code xsh_irplib_error_push_macro (const char *func, cpl_error_code ec, const char *file, unsigned int line)
 Set or propagate an error.
void xsh_irplib_error_set_msg (const char *format,...)
 Temporarily store an error message.
void xsh_irplib_error_reset (void)
 Reset the error state.
void xsh_irplib_error_dump_macro (const char *func, const char *file, unsigned int line, cpl_msg_severity severity, cpl_msg_severity trace_severity)
 Print the error queue.

Variables

struct {
   irplib_error   errors [MAX_ERRORS]
   cpl_boolean   is_empty
   unsigned int   first
   unsigned int   last
queue
static char error_msg [MAX_STRING_LENGTH]
static cpl_boolean is_initialized = CPL_FALSE

Define Documentation

#define irplib_error_assure ( CONDITION,
ERROR_CODE,
MSG,
ACTION   ) 
Value:
do {\
      if (cpl_error_get_code() != CPL_ERROR_NONE){                             \
          irplib_error_push(cpl_error_get_code(),                              \
                           ("An error occurred that was not caught: %s",       \
                           cpl_error_get_where()) );                           \
          ACTION;                                                              \
      }                                                                        \
      else if (!(CONDITION))                                                   \
      {\
          irplib_error_push(ERROR_CODE, MSG);                                  \
          ACTION;                                                              \
      }                                                                        \
  } while (0)

Generic error handling macro.

Parameters:
CONDITION The condition to check
ERROR_CODE The CPL error code to set if CONDTION evaluates to false
MSG A parentheses-enclosed, printf-style error message. If this is an empty string or a string consisting only of spaces, the default error message associated with the provided error code is used.
ACTION A statement that is executed iff the CONDITION evaluates to false.

This macro should not be used directly. It is defined only to allow the user to build his/her custom error handling macros.

Useful definitions might include

   #define assure(BOOL, CODE)                                               \
     irplib_error_assure(BOOL, CODE, (" "), goto cleanup)

   #define  check(CMD)                                                      \
     irplib_error_assure((CMD, cpl_error_get_code() == CPL_ERROR_NONE),     \
                          cpl_error_get_code(), (" "), goto cleanup)

   #define assert(BOOL)                                                     \
     irplib_error_assure(BOOL, CPL_ERROR_UNSPECIFIED,                       \
                         ("Internal error, please report to "               \
                          PACKAGE_BUGREPORT), goto cleanup)

or (same as above, but including printf-style error messages)

   #define assure(BOOL, CODE, ...)                                          \
     irplib_error_assure(BOOL, CODE, (__VA_ARGS__), goto cleanup)

   #define  check(CMD, ...)                                                 \
     irplib_error_assure((CMD, cpl_error_get_code() == CPL_ERROR_NONE),     \
                          cpl_error_get_code(), (__VA_ARGS__), goto cleanup)

   #define assert(BOOL, ...)                                                \
     irplib_error_assure(BOOL, CPL_ERROR_UNSPECIFIED,                       \
                         ("Internal error, please report to "               \
                          PACKAGE_BUGREPORT " " __VA_ARGS__), goto cleanup)
                         / *  Assumes that PACKAGE_BUGREPORT
                              contains no formatting special characters  * /

or

   #define assure(BOOL, CODE, RETURN)                                         \
     irplib_error_assure(BOOL, CODE, (" "), return RETURN)

   #define assure_code(BOOL, CODE)                                            \
     irplib_error_assure(BOOL, CODE, (" "), return cpl_error_get_code())

   #define skip_if(BOOL)                                                      \
     irplib_error_assure(BOOL,                                                \
                         cpl_error_get_code() != CPL_ERROR_NONE ?             \
                         cpl_error_get_code() : CPL_ERROR_UNSPECIFIED,        \
                         (" "), goto cleanup)

The check macros in the examples above can be used to check a command which set the cpl_error_code in case of failure (or, by use of a comma expression, a longer sequence of such commands):

   check(
       (x = cpl_table_get_int(table, "x", 0, NULL),
        y = cpl_table_get_int(table, "y", 0, NULL),
        z = cpl_table_get_int(table, "z", 0, NULL)),
       ("Error reading wavelength catalogue"));

The provided ERROR_CODE, MSG and ACTION are evaluated/executed only if the CONDITION evaluates to false.

Note:
Some of the examples above use a goto statement to jump to a cleanup label, assumed to be located immediately before the function's unified cleanup-code and exit point. This error-handling scheme is reminiscent of using exceptions in languages that support exceptions (C++, Java, ...). While the use of goto's "if the error-handling code is non-trivial, and if errors can occur in several places" is "sanctioned" by Kernigan&Richie: "The C Programming Language", goto's should be avoided in all other cases.

Definition at line 155 of file irplib_error.h.

#define irplib_error_dump ( severity,
trace_severity   ) 
Value:
xsh_irplib_error_dump_macro(__func__, __FILE__, __LINE__,              \
                severity, trace_severity)

Print the error queue.

Parameters:
severity The severity of the error message (usually CPL_MSG_ERROR or CPL_MSG_WARNING)
trace_severity The severity of the error tracing information (e.g. CPL_MSG_ERROR, CPL_MSG_DEBUG or CPL_MSG_OFF)

This macro prints the error queue in a format best described by example (for severity = CPL_MSG_ERROR and trace_severity = CPL_MSG_DEBUG)

   [ ERROR ]   Identification loop did not converge. After 13 iterations
   [ ERROR ]   the RMS was 20.3 pixels. (The iterative process did not converge)
   [ DEBUG ]     in [3]uves_wavecal_identify() at uves_wavecal_identify.c :101
   [ DEBUG ]    
   [ ERROR ]   Could not calibrate orders
   [ DEBUG ]     in [2]uves_wavecal_process_chip() at uves_wavecal.c  :426
   [ DEBUG ]     
   [ ERROR ]   Wavelength calibration failed
   [ DEBUG ]     in [1]uves_wavecal() at uves_wavecal.c  :679
   [ DEBUG ]

Note that

  • the error that occured first (deepest in the call tree) is printed first,
  • the error queue is not reset, this is left to the caller

Definition at line 223 of file irplib_error.h.

#define irplib_error_push ( ec,
msg   ) 
Value:
do {                                                                     \
        xsh_irplib_error_set_msg msg;                                          \
        xsh_irplib_error_push_macro(__func__, ec, __FILE__, __LINE__);         \
      } while (0)

Set or propagate an error.

Parameters:
ec The CPL error code
msg A parentheses-enclosed, printf-style error message. If this is an empty string or a string consisting only of spaces, the default error message associated with the provided error code is used.
See also:
irplib_error_push_macro().

Definition at line 181 of file irplib_error.h.

#define MAX_ERRORS   20

Definition at line 59 of file irplib_error.c.

#define MAX_STRING_LENGTH   200

Definition at line 58 of file irplib_error.c.

Referenced by irplib_error_validate_state().


Function Documentation

static void irplib_error_validate_state ( const char *  func,
const char *  file,
unsigned int  line 
) [static]

Synchronize IRPLIB error state with CPL's error state.

Parameters:
func Error handler was called from this function
file Error handler was called from this file
line Error handler was called from this linenumber

This function

  • checks that the error module has been properly initialized and prints an error message if not,
  • makes sure that the latest error in the queue matches CPL's error state. (If the cpl_error_code is set, it must match the latest error in the queue; otherwise it's inserted into the queue. If the cpl_error_code is not set, the queue must be empty; otherwise it is cleared. )

Definition at line 139 of file irplib_error.c.

References cplmessage, error_msg, errorcode, filename, function, is_initialized, linenumber, MAX_STRING_LENGTH, queue, xsh_irplib_error_push_macro(), xsh_irplib_error_reset(), and xsh_irplib_error_set_msg().

void xsh_irplib_error_dump_macro ( const char *  func,
const char *  file,
unsigned int  line,
cpl_msg_severity  severity,
cpl_msg_severity  trace_severity 
)

Print the error queue.

Parameters:
func Caller function
file Caller filename
line Caller linenumber
severity The error message is printed using this message level (usually CPL_MSG_ERROR or CPL_MSG_WARNING)
trace_severity The error tracing information is printed using this message level (e.g. CPL_MSG_ERROR, CPL_MSG_DEBUG or CPL_MSG_OFF)

This function should not be called directly. Use irplib_error_dump()

cpl_error_code xsh_irplib_error_push_macro ( const char *  func,
cpl_error_code  ec,
const char *  file,
unsigned int  line 
)

Set or propagate an error.

Parameters:
ec The error code
file Filename
func Function name
line Line number
Returns:
The provided error code

This function should not be called directly, use irplib_error_push() .

The function inserts an error into the (empty or non-empty) error queue, and sets the CPL error state to ec.

If the error code ec is equal to CPL_ERROR_NONE (which is not considered to be a valid error code), an error message is displayed (because it is considered a bug in the caller), and a CPL_ERROR_UNSPECIFIED is set instead.

It uses the error message previously set by irplib_error_set_msg() .

Referenced by irplib_error_validate_state().

void xsh_irplib_error_reset ( void   ) 

Reset the error state.

This function empties the error queue and resets the current cpl_error_code to CPL_ERROR_NONE.

Referenced by irplib_error_validate_state().

void xsh_irplib_error_set_msg ( const char *  format,
  ... 
)

Temporarily store an error message.

Parameters:
format printf-style format string

This function stores an error message to be used later by irplib_error_push_macro() .

Neither of these functions should be called directly. Use irplib_error_push() .

Referenced by irplib_error_validate_state().


Variable Documentation

char error_msg[MAX_STRING_LENGTH] [static]

Definition at line 108 of file irplib_error.c.

Referenced by irplib_error_validate_state().

irplib_error { ... } errors[MAX_ERRORS] [inherited]

Definition at line 86 of file irplib_error.c.

unsigned { ... } first [inherited]

Definition at line 88 of file irplib_error.c.

cpl_boolean { ... } is_empty [inherited]

Definition at line 87 of file irplib_error.c.

cpl_boolean is_initialized = CPL_FALSE [static]

Definition at line 115 of file irplib_error.c.

Referenced by irplib_error_validate_state().

unsigned { ... } last [inherited]

Definition at line 89 of file irplib_error.c.

struct { ... } queue [static]

Generated on 13 Mar 2013 for X-shooter Pipeline Reference Manual by  doxygen 1.6.1