X-shooter Pipeline Reference Manual 3.8.15
Data Structures | Macros | Functions | Variables
IRPLIB error handling

Data Structures

struct  irplib_error
 

Macros

#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
 

Detailed Description

Macro Definition Documentation

◆ irplib_error_assure

#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
CONDITIONThe condition to check
ERROR_CODEThe CPL error code to set if CONDTION evaluates to false
MSGA 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.
ACTIONA 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):

(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"));
#define check(COMMAND)
Definition: xsh_error.h:71
int * y
int * x

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.

◆ irplib_error_dump

#define irplib_error_dump (   severity,
  trace_severity 
)
Value:
xsh_irplib_error_dump_macro(__func__, __FILE__, __LINE__, \
severity, trace_severity)
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.
Definition: irplib_error.c:375

Print the error queue.

Parameters
severityThe severity of the error message (usually CPL_MSG_ERROR or CPL_MSG_WARNING)
trace_severityThe 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 ]
#define ERROR

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.

◆ irplib_error_push

#define irplib_error_push (   ec,
  msg 
)
Value:
do { \
xsh_irplib_error_push_macro(__func__, ec, __FILE__, __LINE__); \
} while (0)
void xsh_irplib_error_set_msg(const char *format,...)
Temporarily store an error message.
Definition: irplib_error.c:325

Set or propagate an error.

Parameters
ecThe CPL error code
msgA 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.

◆ MAX_ERRORS

#define MAX_ERRORS   20

Definition at line 59 of file irplib_error.c.

◆ MAX_STRING_LENGTH

#define MAX_STRING_LENGTH   200

Definition at line 58 of file irplib_error.c.

Function Documentation

◆ irplib_error_validate_state()

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
funcError handler was called from this function
fileError handler was called from this file
lineError 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().

Referenced by xsh_irplib_error_dump_macro(), and xsh_irplib_error_push_macro().

◆ xsh_irplib_error_dump_macro()

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
funcCaller function
fileCaller filename
lineCaller linenumber
severityThe error message is printed using this message level (usually CPL_MSG_ERROR or CPL_MSG_WARNING)
trace_severityThe 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()

Definition at line 375 of file irplib_error.c.

References irplib_error_validate_state(), MAX_ERRORS, and queue.

◆ xsh_irplib_error_push_macro()

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
ecThe error code
fileFilename
funcFunction name
lineLine 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() .

Definition at line 259 of file irplib_error.c.

References error_msg, irplib_error_validate_state(), MAX_ERRORS, MAX_STRING_LENGTH, and queue.

Referenced by irplib_error_validate_state().

◆ xsh_irplib_error_reset()

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.

Definition at line 347 of file irplib_error.c.

References error_msg, is_initialized, and queue.

Referenced by irplib_error_validate_state().

◆ xsh_irplib_error_set_msg()

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

Temporarily store an error message.

Parameters
formatprintf-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() .

Definition at line 325 of file irplib_error.c.

References error_msg, and MAX_STRING_LENGTH.

Referenced by irplib_error_validate_state().

Variable Documentation

◆ error_msg

char error_msg[MAX_STRING_LENGTH]
static

◆ 

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

Definition at line 86 of file irplib_error.c.

◆ 

unsigned int { ... } ::first

Definition at line 88 of file irplib_error.c.

◆ 

cpl_boolean { ... } ::is_empty

Definition at line 87 of file irplib_error.c.

◆ is_initialized

cpl_boolean is_initialized = CPL_FALSE
static

Definition at line 115 of file irplib_error.c.

Referenced by irplib_error_validate_state(), and xsh_irplib_error_reset().

◆ 

unsigned int { ... } ::last

Definition at line 89 of file irplib_error.c.

◆ 

struct { ... } queue