00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023
00024
00025
00026
00027
00028 #include <irplib_test.h>
00029
00030
00031 #include <irplib_utils.h>
00032
00033 #include <cpl.h>
00034
00035
00036 #include <math.h>
00037
00038 #include <string.h>
00039
00043
00044
00045
00046
00047
00048
00052 static unsigned long irplib_test_nfail = 0;
00053
00054
00063
00064 static void
00065 test(int expression, const char *message,
00066 const char *function, const char *file, unsigned line)
00067 {
00068 const char *error_state = (cpl_error_get_code() != CPL_ERROR_NONE) ?
00069 irplib_sprintf(" (CPL-error state: '%s' at %s)",
00070 cpl_error_get_message(), cpl_error_get_where()) :
00071 NULL;
00072
00073 if (expression) {
00074 cpl_msg_debug(function,
00075 "OK at %s:%u%s: %s",
00076 file, line, error_state != NULL ? error_state : "",
00077 message);
00078 } else {
00079 if (irplib_test_nfail + 1 > irplib_test_nfail) {
00080 irplib_test_nfail++;
00081 }
00082 else {
00083 cpl_msg_error(function, "Number of errors (%lu) overflow!",
00084 irplib_test_nfail);
00085 }
00086
00087 cpl_msg_error(function,
00088 "Failure at %s:%u%s: %s",
00089 file, line, error_state != NULL ? error_state : "",
00090 message);
00091 }
00092
00093 if (error_state != NULL)
00094 {
00095 cpl_free((char *)error_state);
00096 }
00097
00098 return;
00099 }
00100
00101
00102
00112
00113 void
00114 irplib_test_macro(int expression, const char *expr_string,
00115 const char *function, const char *file, unsigned line)
00116 {
00117 const char *message = irplib_sprintf("(%s) = %d", expr_string, expression);
00118
00119 test(expression, message,
00120 function, file, line);
00121
00122 cpl_free((char *)message);
00123
00124 return;
00125 }
00126
00127
00139
00140 void
00141 irplib_test_eq_macro(int first, const char *first_string,
00142 int second, const char *second_string,
00143 const char *function, const char *file, unsigned line)
00144 {
00145 const char *message =
00146 irplib_sprintf("(%s) = %d; (%s) = %d",
00147 first_string, first,
00148 second_string, second);
00149
00150 test(first == second, message,
00151 function, file, line);
00152
00153 cpl_free((char *)message);
00154
00155 return;
00156 }
00157
00158
00170
00171 void
00172 irplib_test_eq_string_macro(const char *first, const char *first_string,
00173 const char *second, const char *second_string,
00174 const char *function,
00175 const char *file, unsigned line)
00176 {
00177 const char *message;
00178
00179 message = irplib_sprintf("%s = '%s'; %s = '%s'",
00180 first_string, first != NULL ? first : "NULL",
00181 second_string, second != NULL ? second : "NULL");
00182
00183 test(first != NULL && second != NULL && strcmp(first, second) == 0,
00184 message,
00185 function, file, line);
00186
00187 cpl_free((char *)message);
00188
00189 return;
00190 }
00191
00192
00208
00209 void
00210 irplib_test_abs_macro(double first, const char *first_string,
00211 double second, const char *second_string,
00212 double tolerance, const char *tolerance_string,
00213 const char *function, const char *file, unsigned line)
00214 {
00215 const char *message =
00216 irplib_sprintf("|%s - (%s)| = |%g - (%g)| <= %g = %s",
00217 first_string, second_string, first, second,
00218 tolerance, tolerance_string);
00219
00220 test(fabs(first - second) <= tolerance, message,
00221 function, file, line);
00222
00223
00224 cpl_free((char *)message);
00225
00226 return;
00227 }
00228
00229
00245
00246 void
00247 irplib_test_rel_macro(double first, const char *first_string,
00248 double second, const char *second_string,
00249 double tolerance, const char *tolerance_string,
00250 const char *function, const char *file, unsigned line)
00251 {
00252 const char *message;
00253
00254 if (first == 0 || second == 0) {
00255
00256 message = irplib_sprintf("%s = %g; %s = %g (division by zero)",
00257 first_string, first,
00258 second_string, second);
00259 test(0, message,
00260 function, file, line);
00261 }
00262 else {
00263 message =
00264 irplib_sprintf("|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s and "
00265 "|%s - (%s)|/|%s| = |%g - (%g)|/|%g| <= %g = %s",
00266 first_string, second_string, first_string,
00267 first, second, first, tolerance, tolerance_string,
00268 first_string, second_string, second_string,
00269 first, second, second, tolerance, tolerance_string);
00270
00271 test(fabs((first - second)/first ) <= tolerance &&
00272 fabs((first - second)/second) <= tolerance, message,
00273 function, file, line);
00274
00275 }
00276
00277 cpl_free((char *)message);
00278
00279 return;
00280 }
00281
00282
00283
00290
00291 void
00292 irplib_test_init_macro(const char *file)
00293 {
00294
00295
00296
00297 unsigned len = strlen(file);
00298 int able_to_parse_filename;
00299
00300 cpl_init();
00301 irplib_reset();
00302
00303 if (len < strlen("s.c") || strcmp(file + len - strlen(".c"), ".c") != 0)
00304 {
00305 able_to_parse_filename = 0;
00306
00307
00308 }
00309 else
00310 {
00311
00312
00313
00314 const char dir_delimiter = '/';
00315 unsigned path_length = 0;
00316
00317 int i;
00318
00319 for (i = len - strlen(".c") - 1; i >= 0; i--)
00320 {
00321 if (file[i] == dir_delimiter && path_length == 0)
00322 {
00323 path_length = i + 1;
00324 }
00325 }
00326
00327 able_to_parse_filename = (len - path_length - strlen(".c") >= 1);
00328 if (able_to_parse_filename)
00329 {
00330 const char *logfile;
00331 char *domain;
00332
00333 domain = cpl_strdup(file + path_length);
00334 domain[len - path_length - strlen(".c")] = '\0';
00335
00336 cpl_msg_set_domain(domain);
00337
00338 logfile = irplib_sprintf("%s.log", domain);
00339 cpl_msg_set_log_name(logfile);
00340
00341 cpl_free((char *)logfile);
00342 cpl_free(domain);
00343 }
00344
00345 }
00346
00347
00348
00349
00350 cpl_msg_set_level(CPL_MSG_WARNING);
00351 cpl_msg_set_log_level(CPL_MSG_DEBUG);
00352
00353 if (!able_to_parse_filename)
00354 {
00355 cpl_msg_warning(cpl_func,
00356 "Source file name '%s' does not match [base].c. ",
00357 file);
00358 }
00359
00360 if (cpl_error_get_code() != CPL_ERROR_NONE)
00361 {
00362 cpl_msg_error(cpl_func,
00363 "Failure during initialization: %s at %s",
00364 cpl_error_get_message(), cpl_error_get_where());
00365 }
00366
00367 return;
00368 }
00369
00370
00380
00381 unsigned
00382 irplib_test_end_macro(const char *function, const char *file, unsigned line)
00383 {
00384 const int memory_is_empty = cpl_memory_is_empty();
00385
00386 irplib_test_eq_macro(cpl_error_get_code(), "cpl_error_get_code()",
00387 CPL_ERROR_NONE, "CPL_ERROR_NONE",
00388 function, file, line);
00389
00390 irplib_test_macro(memory_is_empty,
00391 "memory_is_empty",
00392 function, file, line);
00393
00394 if (!memory_is_empty) {
00395 cpl_msg_error(function, "Memory leak detected:");
00396 cpl_memory_dump();
00397 }
00398
00399 cpl_end();
00400
00401 return irplib_test_nfail;
00402 }
00403