30 #include <fors_utils.h>
50 static cpl_errorstate error_init;
63 _test(
int expression,
const char *message,
64 const char *
function,
const char *file,
unsigned line)
66 const char *error_state = (cpl_error_get_code() != CPL_ERROR_NONE) ?
67 cpl_sprintf(
" (CPL-error state: '%s' at %s)",
68 cpl_error_get_message(), cpl_error_get_where()) :
72 cpl_msg_debug(
function,
74 file, line, error_state != NULL ? error_state :
"",
81 cpl_msg_error(
function,
"Number of errors (%lu) overflow!",
85 cpl_msg_error(
function,
86 "Failure at %s:%u%s: %s",
87 file, line, error_state != NULL ? error_state :
"",
91 if (error_state != NULL)
93 cpl_free((
char *)error_state);
113 const char *
function,
const char *file,
unsigned line)
115 const char *message = cpl_sprintf(
"(%s) = %d", expr_string, expression);
117 _test(expression, message,
118 function, file, line);
120 cpl_free((
char *)message);
140 int second,
const char *second_string,
141 const char *
function,
const char *file,
unsigned line)
143 const char *message =
144 cpl_sprintf(
"(%s) = %d; (%s) = %d",
146 second_string, second);
148 _test(first == second, message,
149 function, file, line);
151 cpl_free((
char *)message);
171 const char *second,
const char *second_string,
172 const char *
function,
173 const char *file,
unsigned line)
177 message = cpl_sprintf(
"%s = '%s'; %s = '%s'",
178 first_string, first != NULL ? first :
"NULL",
179 second_string, second != NULL ? second :
"NULL");
181 _test(first != NULL && second != NULL && strcmp(first, second) == 0,
183 function, file, line);
185 cpl_free((
char *)message);
209 double second,
const char *second_string,
210 double tolerance,
const char *tolerance_string,
211 const char *
function,
const char *file,
unsigned line)
213 const char *message =
214 cpl_sprintf(
"|%s - (%s)| = |%g - (%g)| <= %g = %s",
215 first_string, second_string, first, second,
216 tolerance, tolerance_string);
218 _test(fabs(first - second) <= tolerance, message,
219 function, file, line);
222 cpl_free((
char *)message);
246 double second,
const char *second_string,
247 double tolerance,
const char *tolerance_string,
248 const char *
function,
const char *file,
unsigned line)
252 if (first == 0 || second == 0) {
254 message = cpl_sprintf(
"%s = %g; %s = %g (division by zero)",
256 second_string, second);
258 function, file, line);
262 cpl_sprintf(
"|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s and "
263 "|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s",
264 first_string, second_string, first_string,
265 first, second, first, tolerance, tolerance_string,
266 first_string, second_string, second_string,
267 first, second, second, tolerance, tolerance_string);
269 _test(fabs((first - second)/first ) <= tolerance &&
270 fabs((first - second)/second) <= tolerance, message,
271 function, file, line);
275 cpl_free((
char *)message);
295 unsigned len = strlen(file);
296 int able_to_parse_filename;
298 cpl_init(CPL_INIT_DEFAULT);
299 error_init = cpl_errorstate_get();
302 if (len < strlen(
"s.c") || strcmp(file + len - strlen(
".c"),
".c") != 0)
304 able_to_parse_filename = 0;
313 const char dir_delimiter =
'/';
314 unsigned path_length = 0;
318 for (i = len - strlen(
".c") - 1; i >= 0; i--)
320 if (file[i] == dir_delimiter && path_length == 0)
326 able_to_parse_filename = (len - path_length - strlen(
".c") >= 1);
327 if (able_to_parse_filename)
332 domain = cpl_strdup(file + path_length);
333 domain[len - path_length - strlen(
".c")] =
'\0';
335 cpl_msg_set_domain(domain);
337 logfile = cpl_sprintf(
"%s.log", domain);
338 cpl_msg_set_log_name(logfile);
340 cpl_free((
char *)logfile);
349 cpl_msg_set_level(CPL_MSG_WARNING);
350 cpl_msg_set_log_level(CPL_MSG_DEBUG);
352 if (!able_to_parse_filename)
354 cpl_msg_warning(cpl_func,
355 "Source file name '%s' does not match [base].c. ",
359 if (cpl_error_get_code() != CPL_ERROR_NONE)
361 cpl_msg_error(cpl_func,
362 "Failure during initialization: %s at %s",
363 cpl_error_get_message(), cpl_error_get_where());
383 const int memory_is_empty = cpl_memory_is_empty();
386 CPL_ERROR_NONE,
"CPL_ERROR_NONE",
387 function, file, line);
389 if (cpl_error_get_code() != CPL_ERROR_NONE) {
390 cpl_errorstate_dump(error_init, CPL_FALSE, NULL);
395 function, file, line);
397 if (!memory_is_empty) {
398 cpl_msg_error(
function,
"Memory leak detected:");
414 cpl_propertylist_delete(product_header); \
429 const char *
const product_tags[],
int n_prod,
430 const char *main_product,
431 const char *
const qc[],
int n_qc)
433 cpl_propertylist *product_header = NULL;
436 for (i = 0; i < n_prod; i++) {
437 const cpl_frame *product = cpl_frameset_find_const(frames, product_tags[i]);
438 test( product != NULL );
439 test_eq( cpl_frame_get_group(product), CPL_FRAME_GROUP_PRODUCT );
441 cpl_propertylist_delete(product_header);
442 product_header = cpl_propertylist_load(cpl_frame_get_filename(product), 0);
444 assure( !cpl_error_get_code(),
return,
445 "Failed to load product header" );
448 if (strcmp(product_tags[i], main_product) != 0) {
449 test( !cpl_propertylist_has(product_header,
454 for (j = 0; j < n_qc; j++) {
456 const char *full_qc_name = cpl_sprintf(
"ESO %s", qc[j]);
458 cpl_msg_debug(cpl_func,
459 "Looking for '%s' in '%s'",
460 qc[j], product_tags[i]);
462 if (strcmp(product_tags[i], main_product) == 0) {
463 test( cpl_propertylist_has(product_header,
467 test( !cpl_propertylist_has(product_header,
471 cpl_free((
void *)full_qc_name);
void test_macro(int expression, const char *expr_string, const char *function, const char *file, unsigned line)
Test a given expression.
void test_abs_macro(double first, const char *first_string, double second, const char *second_string, double tolerance, const char *tolerance_string, const char *function, const char *file, unsigned line)
Test if two numerical expressions are within a given (absolute) tolerance.
void test_eq_macro(int first, const char *first_string, int second, const char *second_string, const char *function, const char *file, unsigned line)
Test if two integer expressions are equal.
static unsigned long test_nfail
void test_rel_macro(double first, const char *first_string, double second, const char *second_string, double tolerance, const char *tolerance_string, const char *function, const char *file, unsigned line)
Test if two numerical expressions are within a given relative tolerance.
unsigned test_end_macro(const char *function, const char *file, unsigned line)
Perform the final checks and return the number of errors.
void test_eq_string_macro(const char *first, const char *first_string, const char *second, const char *second_string, const char *function, const char *file, unsigned line)
Test if two strings are equal.
void test_init_macro(const char *file)
Initialize CPL + messaging.
void test_recipe_output(const cpl_frameset *frames, const char *const product_tags[], int n_prod, const char *main_product, const char *const qc[], int n_qc)
Test existence of recipe products.
static void _test(int expression, const char *message, const char *function, const char *file, unsigned line)
Evaluate an expression and update an internal counter if it fails.