Doxygenise qpms_error.h
Former-commit-id: 9ed5d7c4352fb6e0d9ef3922fd491010e1f8c16e
This commit is contained in:
parent
3ebc1af946
commit
20a13cdb2c
12
qpms/error.c
12
qpms/error.c
|
@ -66,18 +66,6 @@ void qpms_warn_at_flf(const char *filename, unsigned int linenum,
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qpms_pr_debug_at_flf(const char *filename, unsigned int linenum,
|
|
||||||
const char *func,
|
|
||||||
const char *fmt, ...) {
|
|
||||||
fprintf(stderr, "%s:%u, %s: ", filename, linenum, func);
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(stderr, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
fputc('\n', stderr);
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void qpms_debug_at_flf(const char *filename, unsigned int linenum,
|
void qpms_debug_at_flf(const char *filename, unsigned int linenum,
|
||||||
const char *func, qpms_dbgmsg_flags type,
|
const char *func, qpms_dbgmsg_flags type,
|
||||||
const char *fmt, ...) {
|
const char *fmt, ...) {
|
||||||
|
|
|
@ -1,16 +1,24 @@
|
||||||
|
/*! \file qpms_error.h
|
||||||
|
*
|
||||||
|
* \brief QPMS miscellanous internal error handling functions and macros.
|
||||||
|
*
|
||||||
|
*/
|
||||||
#ifndef QPMS_ERROR_H
|
#ifndef QPMS_ERROR_H
|
||||||
#define QPMS_ERROR_H
|
#define QPMS_ERROR_H
|
||||||
|
|
||||||
#include "optim.h"
|
#include "optim.h"
|
||||||
|
|
||||||
/// Provisional error message with abort();
|
/// Print error message and abort();
|
||||||
QPMS_NORETURN void qpms_pr_error(const char *fmt, ...);
|
QPMS_NORETURN void qpms_pr_error(const char *fmt, ...);
|
||||||
//void qpms_error(const char *fmt, ...);
|
//void qpms_error(const char *fmt, ...);
|
||||||
|
|
||||||
/// Provisional error message with abort(), indicating source and line number.
|
/// Print an error message, indicating source, function name and line number, and abort().
|
||||||
void qpms_pr_error_at_line(const char *filename, unsigned int linenum,
|
/**
|
||||||
const char *fmt, ...);
|
* Usually not used directly, but rather via some of the macros
|
||||||
|
* that fill the first arguments automatically.
|
||||||
|
*
|
||||||
|
* \see QPMS_PR_ERROR
|
||||||
|
*/
|
||||||
QPMS_NORETURN void qpms_pr_error_at_flf(const char *filename, unsigned int linenum,
|
QPMS_NORETURN void qpms_pr_error_at_flf(const char *filename, unsigned int linenum,
|
||||||
const char *func,
|
const char *func,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
@ -20,71 +28,149 @@ void qpms_warn_at_flf(const char *filename, unsigned int linenum,
|
||||||
const char *func,
|
const char *func,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
|
||||||
void qpms_pr_debug_at_flf(const char *filename, unsigned int linenum,
|
/// Classification of debugging messages.
|
||||||
const char *func,
|
/**
|
||||||
const char *fmt, ...);
|
* \see qpms_dbgmsg_enabled, qpms_dbgmsg_enable(), qpms_dbgmsg_disable()
|
||||||
//void qpms_error_at_line(const char *filename, unsigned int linenum,
|
*/
|
||||||
// const char *fmt, ...);
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QPMS_DBGMSG_MISC = 1,
|
QPMS_DBGMSG_MISC = 1,
|
||||||
QPMS_DBGMSG_THREADS = 2, // Multithreading-related debug messages.
|
QPMS_DBGMSG_THREADS = 2, ///< Multithreading-related debug messages.
|
||||||
QPMS_DBGMSG_INTEGRATION = 4 // Quadrature-related debug messages.
|
QPMS_DBGMSG_INTEGRATION = 4 ///< Quadrature-related debug messages.
|
||||||
} qpms_dbgmsg_flags;
|
} qpms_dbgmsg_flags;
|
||||||
|
|
||||||
|
/// Print a debugging message to stderr and flush the buffer. Don't call this directly, use QPMS_DEBUG().
|
||||||
void qpms_debug_at_flf(const char *filename, unsigned int linenum,
|
void qpms_debug_at_flf(const char *filename, unsigned int linenum,
|
||||||
const char *func,
|
const char *func,
|
||||||
qpms_dbgmsg_flags type,
|
qpms_dbgmsg_flags type,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
|
|
||||||
|
/// Global variable determining which types of debug messages shall be printed with QPMS_DEBUG().
|
||||||
|
/**
|
||||||
|
* Use qpms_dbgmsg_enable() and qpms_dbgmsg_disable() to manipulate
|
||||||
|
* this variable.
|
||||||
|
*
|
||||||
|
* \see QPMS_DEBUG()
|
||||||
|
*/
|
||||||
extern qpms_dbgmsg_flags qpms_dbgmsg_enabled;
|
extern qpms_dbgmsg_flags qpms_dbgmsg_enabled;
|
||||||
|
|
||||||
|
/// Enable debugging messages of given \a types.
|
||||||
|
/** \see qpms_dbgmsg_disable() */
|
||||||
qpms_dbgmsg_flags qpms_dbgmsg_disable(qpms_dbgmsg_flags types);
|
qpms_dbgmsg_flags qpms_dbgmsg_disable(qpms_dbgmsg_flags types);
|
||||||
|
|
||||||
|
/// Disable debugging messages of given \a types.
|
||||||
|
/** \see qpms_dbgmsg_enable() */
|
||||||
qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
|
|
||||||
|
/// Print a warning to stderr and flush the buffer.
|
||||||
|
/**
|
||||||
|
* The arguments are the same as in standard printf().
|
||||||
|
*/
|
||||||
#define QPMS_WARN(msg, ...) qpms_warn_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__)
|
#define QPMS_WARN(msg, ...) qpms_warn_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define QPMS_DEBUG(type, msg, ...) qpms_debug_at_flf(__FILE__,__LINE__,__func__,type,msg, ##__VA_ARGS__)
|
/// Print a debugging message to stderr and flush the buffer.
|
||||||
|
/**
|
||||||
|
* The arguments after \a type are the same as in standard printf().
|
||||||
|
*
|
||||||
|
* The debugging message is printed only if the corresponding \a type flag
|
||||||
|
* is set in qpms_dbgmsg_enabled.
|
||||||
|
*
|
||||||
|
* \see qpms_dbgmsg_enabled
|
||||||
|
*/
|
||||||
|
#define QPMS_DEBUG(type /**< Debugging message type flag, see qpms_dbgmsg_flags */ , msg, ...) qpms_debug_at_flf(__FILE__,__LINE__,__func__,type,msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/// Wrapper macro of standard malloc(), crashing on failure.
|
||||||
|
/**
|
||||||
|
* Normally corresponds to a `pointer = malloc(size)`
|
||||||
|
* statement; however, if NULL is returned, this prints an
|
||||||
|
* error message and abort()s the program.
|
||||||
|
*
|
||||||
|
* The arguments are expanded several times.
|
||||||
|
*
|
||||||
|
* Note that this macro expands to a code block, to be kept in mind when using
|
||||||
|
* together with if/else etc.
|
||||||
|
*
|
||||||
|
* Assigned memory block is to be deallocated with standard free().
|
||||||
|
*
|
||||||
|
* \see QPMS_CRASHING_CALLOC.
|
||||||
|
*/
|
||||||
#define QPMS_CRASHING_MALLOC(pointer, size) {\
|
#define QPMS_CRASHING_MALLOC(pointer, size) {\
|
||||||
(pointer) = malloc(size);\
|
(pointer) = malloc(size);\
|
||||||
if(QPMS_UNLIKELY(!(pointer) && (size)))\
|
if(QPMS_UNLIKELY(!(pointer) && (size)))\
|
||||||
qpms_pr_debug_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
"Allocation of %zd bytes for " #pointer " failed.",\
|
"Allocation of %zd bytes for " #pointer " failed.",\
|
||||||
(size_t) (size));\
|
(size_t) (size));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate and copy.
|
||||||
|
/**
|
||||||
|
* Behaves as QPMS_CRASHING_MALLOC(dest, size), but
|
||||||
|
* additionaly copies a chunk of memory from \a src to \a dest.
|
||||||
|
*
|
||||||
|
* \see QPMS_CRASHING_MALLOC()
|
||||||
|
*/
|
||||||
#define QPMS_CRASHING_MALLOCPY(dest, src, size) {\
|
#define QPMS_CRASHING_MALLOCPY(dest, src, size) {\
|
||||||
(dest) = malloc(size);\
|
(dest) = malloc(size);\
|
||||||
if(QPMS_UNLIKELY(!(dest) && (size)))\
|
if(QPMS_UNLIKELY(!(dest) && (size)))\
|
||||||
qpms_pr_debug_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
"Allocation of %zd bytes for " #dest " failed.",\
|
"Allocation of %zd bytes for " #dest " failed.",\
|
||||||
(size_t) (size));\
|
(size_t) (size));\
|
||||||
memcpy((dest), (src), (size));\
|
memcpy((dest), (src), (size));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper macro of standard calloc(), crashing on failure.
|
||||||
|
/**
|
||||||
|
* Normally corresponds to a `pointer = calloc(nmemb, size)`
|
||||||
|
* statement; however, if NULL is returned, this prints an
|
||||||
|
* error message and abort()s the program.
|
||||||
|
*
|
||||||
|
* The arguments are expanded several times.
|
||||||
|
*
|
||||||
|
* Note that this macro expands to a code block, to be kept in mind when using
|
||||||
|
* together with if/else etc.
|
||||||
|
*
|
||||||
|
* Assigned memory block is to be deallocated with standard free().
|
||||||
|
*
|
||||||
|
* \see QPMS_CRASHING_MALLOC, QPMS_CRASHING_REALLOC.
|
||||||
|
*/
|
||||||
#define QPMS_CRASHING_CALLOC(pointer, nmemb, size) {\
|
#define QPMS_CRASHING_CALLOC(pointer, nmemb, size) {\
|
||||||
(pointer) = calloc((nmemb), (size));\
|
(pointer) = calloc((nmemb), (size));\
|
||||||
if(QPMS_UNLIKELY(!(pointer) && (nmemb) && (size)))\
|
if(QPMS_UNLIKELY(!(pointer) && (nmemb) && (size)))\
|
||||||
qpms_pr_debug_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
"Allocation of %zd bytes for " #pointer " failed.",\
|
"Allocation of %zd bytes for " #pointer " failed.",\
|
||||||
(size_t)((nmemb)*(size)));\
|
(size_t)((nmemb)*(size)));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper macro of standard realloc(), crashing on failure.
|
||||||
|
/**
|
||||||
|
* Normally corresponds to a `pointer = realloc(pointer, size)`
|
||||||
|
* statement; however, if NULL is returned, this prints an
|
||||||
|
* error message and abort()s the program.
|
||||||
|
*
|
||||||
|
* The arguments are expanded several times.
|
||||||
|
*
|
||||||
|
* Note that this macro expands to a code block, to be kept in mind when using
|
||||||
|
* together with if/else etc.
|
||||||
|
*
|
||||||
|
* Assigned memory block is to be deallocated with standard free().
|
||||||
|
*
|
||||||
|
* \see QPMS_CRASHING_MALLOC.
|
||||||
|
*/
|
||||||
#define QPMS_CRASHING_REALLOC(pointer, size) {\
|
#define QPMS_CRASHING_REALLOC(pointer, size) {\
|
||||||
(pointer) = realloc((pointer), size);\
|
(pointer) = realloc((pointer), size);\
|
||||||
if(QPMS_UNLIKELY(!(pointer) && (size)))\
|
if(QPMS_UNLIKELY(!(pointer) && (size)))\
|
||||||
qpms_pr_debug_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
"Rellocation of %zd bytes for " #pointer " failed.",\
|
"Rellocation of %zd bytes for " #pointer " failed.",\
|
||||||
(size_t) (size));\
|
(size_t) (size));\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prints an "unexpected error" message and aborts the program.
|
||||||
|
/** Usually only put to presumably unreachable places in the code and similar. */
|
||||||
#define QPMS_WTF qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error.")
|
#define QPMS_WTF qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error.")
|
||||||
|
|
||||||
|
/// Aborts the program with "invalid enumerator" error message.
|
||||||
#define QPMS_INVALID_ENUM(x) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Invalid enum value (" #x " == %d)", (int) (x))
|
#define QPMS_INVALID_ENUM(x) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Invalid enum value (" #x " == %d)", (int) (x))
|
||||||
|
|
||||||
|
/// Prints an "untested function/feature" warning once when reached in the code.
|
||||||
#define QPMS_UNTESTED {\
|
#define QPMS_UNTESTED {\
|
||||||
static _Bool already_bitched = 0; \
|
static _Bool already_bitched = 0; \
|
||||||
if (QPMS_UNLIKELY(!already_bitched)) {\
|
if (QPMS_UNLIKELY(!already_bitched)) {\
|
||||||
|
@ -93,6 +179,8 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prints a given error message and aborts the program.
|
||||||
|
/** The arguments are as in standard printf(). */
|
||||||
#define QPMS_PR_ERROR(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__)
|
#define QPMS_PR_ERROR(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
/// Raises an error if \a x is not zero.
|
/// Raises an error if \a x is not zero.
|
||||||
|
@ -102,7 +190,7 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error (%d)", errorcode); \
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error (%d)", errorcode); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as previous, but with message.
|
/// Raises an error if \a x is not zero, with custom error message.
|
||||||
#define QPMS_ENSURE_SUCCESS_M(x, msg, ...) { \
|
#define QPMS_ENSURE_SUCCESS_M(x, msg, ...) { \
|
||||||
int errorcode = (x); \
|
int errorcode = (x); \
|
||||||
if(QPMS_UNLIKELY(errorcode)) \
|
if(QPMS_UNLIKELY(errorcode)) \
|
||||||
|
@ -121,8 +209,15 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error (%d)", errorcode); \
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,"Unexpected error (%d)", errorcode); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Raises an error if \a x is not true, with custom error message.
|
||||||
#define QPMS_ENSURE(x, msg, ...) {if(QPMS_UNLIKELY(!(x))) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
#define QPMS_ENSURE(x, msg, ...) {if(QPMS_UNLIKELY(!(x))) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,msg, ##__VA_ARGS__); }
|
||||||
|
|
||||||
|
/// Raises an error if \a x is false.
|
||||||
|
/**
|
||||||
|
* Currently, this is always expanded, ignoring the possible NDEBUG macro.
|
||||||
|
* In places where the evaluation could have significant performance impact,
|
||||||
|
* consider using QPMS_PARANOID_ASSERT() instead.
|
||||||
|
*/
|
||||||
#define QPMS_ASSERT(x) {\
|
#define QPMS_ASSERT(x) {\
|
||||||
if(QPMS_UNLIKELY(!(x)))\
|
if(QPMS_UNLIKELY(!(x)))\
|
||||||
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
|
@ -130,6 +225,10 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QPMS_EVALUATE_PARANOID_ASSERTS
|
#ifdef QPMS_EVALUATE_PARANOID_ASSERTS
|
||||||
|
/** \brief Raises an error if \a x is false.
|
||||||
|
*
|
||||||
|
* Expanded only if QPMS_EVALUATE_PARANOID_ASSERTS macro is defined.
|
||||||
|
*/
|
||||||
#define QPMS_PARANOID_ASSERT(x) {\
|
#define QPMS_PARANOID_ASSERT(x) {\
|
||||||
if(QPMS_UNLIKELY(!(x)))\
|
if(QPMS_UNLIKELY(!(x)))\
|
||||||
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
qpms_pr_error_at_flf(__FILE__,__LINE__,__func__,\
|
||||||
|
@ -139,9 +238,13 @@ qpms_dbgmsg_flags qpms_dbgmsg_enable(qpms_dbgmsg_flags types);
|
||||||
#define QPMS_PARANOID_ASSERT(x) {;}
|
#define QPMS_PARANOID_ASSERT(x) {;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Raises a "not implemented" error with additional custom message.
|
||||||
|
/** Serves also as a label/placeholder of not implemented parts of the code. */
|
||||||
#define QPMS_NOT_IMPLEMENTED(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, \
|
#define QPMS_NOT_IMPLEMENTED(msg, ...) qpms_pr_error_at_flf(__FILE__,__LINE__,__func__, \
|
||||||
"Not implemented:" msg, ##__VA_ARGS__)
|
"Not implemented:" msg, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/// Prints an "incomplete implementation" warning once with a custom message.
|
||||||
|
/** Serves mainly as a label/placeholder of incomplete parts of the code. */
|
||||||
#define QPMS_INCOMPLETE_IMPLEMENTATION(msg, ...) {\
|
#define QPMS_INCOMPLETE_IMPLEMENTATION(msg, ...) {\
|
||||||
static _Bool already_bitched = 0; \
|
static _Bool already_bitched = 0; \
|
||||||
if (QPMS_UNLIKELY(!already_bitched)) {\
|
if (QPMS_UNLIKELY(!already_bitched)) {\
|
||||||
|
|
|
@ -487,10 +487,9 @@ qpms_errno_t qpms_load_scuff_tmatrix(
|
||||||
) {
|
) {
|
||||||
FILE *f = fopen(path, "r");
|
FILE *f = fopen(path, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
if (qpms_load_scuff_tmatrix_crash_on_failure)
|
if (qpms_load_scuff_tmatrix_crash_on_failure) {
|
||||||
qpms_pr_error_at_line(__FILE__, __LINE__, __func__,
|
QPMS_PR_ERROR("Could not open T-matrix file %s", path);
|
||||||
"Could not open T-matrix file %s", path);
|
} else return errno;
|
||||||
else return errno;
|
|
||||||
}
|
}
|
||||||
qpms_errno_t retval =
|
qpms_errno_t retval =
|
||||||
qpms_read_scuff_tmatrix(f, bs, n, freqs, freqs_su, tmatrices_array, tmdata);
|
qpms_read_scuff_tmatrix(f, bs, n, freqs, freqs_su, tmatrices_array, tmdata);
|
||||||
|
@ -502,9 +501,8 @@ qpms_errno_t qpms_load_scuff_tmatrix(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fclose(f)) qpms_pr_error_at_line(__FILE__, __LINE__, __func__,
|
if(fclose(f)) { QPMS_PR_ERROR("Could not close the T-matrix file %s "
|
||||||
"Could not close the T-matrix file %s (well, that's weird, "
|
"(well, that's weird, since it's read only).", path); }
|
||||||
"since it's read only).", path);
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue