|
24 | 24 |
|
25 | 25 | # define _MAIN_CC __cdecl |
26 | 26 |
|
27 | | -# define stat(path, st) _stat(path, st) |
28 | | -# define mkdir(path, mode) _mkdir(path) |
29 | | -# define chdir(path) _chdir(path) |
30 | | -# define access(path, mode) _access(path, mode) |
31 | | -# define strdup(str) _strdup(str) |
32 | | -# define strcasecmp(a,b) _stricmp(a,b) |
| 27 | +# ifndef stat |
| 28 | +# define stat(path, st) _stat(path, st) |
| 29 | +# endif |
| 30 | +# ifndef mkdir |
| 31 | +# define mkdir(path, mode) _mkdir(path) |
| 32 | +# endif |
| 33 | +# ifndef chdir |
| 34 | +# define chdir(path) _chdir(path) |
| 35 | +# endif |
| 36 | +# ifndef access |
| 37 | +# define access(path, mode) _access(path, mode) |
| 38 | +# endif |
| 39 | +# ifndef strdup |
| 40 | +# define strdup(str) _strdup(str) |
| 41 | +# endif |
| 42 | +# ifndef strcasecmp |
| 43 | +# define strcasecmp(a,b) _stricmp(a,b) |
| 44 | +# endif |
33 | 45 |
|
34 | 46 | # ifndef __MINGW32__ |
35 | 47 | # pragma comment(lib, "shell32") |
36 | | -# define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE) |
37 | | -# define W_OK 02 |
38 | | -# define S_ISDIR(x) ((x & _S_IFDIR) != 0) |
39 | | -# define snprint_eq(buf,sz,fmt,...) _snprintf_s(buf,sz,_TRUNCATE,fmt,__VA_ARGS__) |
| 48 | +# ifndef strncpy |
| 49 | +# define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE) |
| 50 | +# endif |
| 51 | +# ifndef W_OK |
| 52 | +# define W_OK 02 |
| 53 | +# endif |
| 54 | +# ifndef S_ISDIR |
| 55 | +# define S_ISDIR(x) ((x & _S_IFDIR) != 0) |
| 56 | +# endif |
| 57 | +# define p_snprintf(buf,sz,fmt,...) _snprintf_s(buf,sz,_TRUNCATE,fmt,__VA_ARGS__) |
40 | 58 | # else |
41 | | -# define snprint_eq snprintf |
| 59 | +# define p_snprintf snprintf |
| 60 | +# endif |
| 61 | + |
| 62 | +# ifndef PRIuZ |
| 63 | +# define PRIuZ "Iu" |
| 64 | +# endif |
| 65 | +# ifndef PRIxZ |
| 66 | +# define PRIxZ "Ix" |
42 | 67 | # endif |
43 | 68 | typedef struct _stat STAT_T; |
44 | 69 | #else |
45 | 70 | # include <sys/wait.h> /* waitpid(2) */ |
46 | 71 | # include <unistd.h> |
47 | 72 | # define _MAIN_CC |
48 | | -# define snprint_eq snprintf |
| 73 | +# define p_snprintf snprintf |
| 74 | +# ifndef PRIuZ |
| 75 | +# define PRIuZ "zu" |
| 76 | +# endif |
| 77 | +# ifndef PRIxZ |
| 78 | +# define PRIxZ "zx" |
| 79 | +# endif |
49 | 80 | typedef struct stat STAT_T; |
50 | 81 | #endif |
51 | 82 |
|
@@ -406,45 +437,66 @@ void clar__assert( |
406 | 437 | clar__fail(file, line, error_msg, description, should_abort); |
407 | 438 | } |
408 | 439 |
|
409 | | -void clar__assert_equal_s( |
410 | | - const char *s1, |
411 | | - const char *s2, |
| 440 | +void clar__assert_equal( |
412 | 441 | const char *file, |
413 | 442 | int line, |
414 | 443 | const char *err, |
415 | | - int should_abort) |
| 444 | + int should_abort, |
| 445 | + const char *fmt, |
| 446 | + ...) |
416 | 447 | { |
417 | | - int match = (s1 == NULL || s2 == NULL) ? (s1 == s2) : (strcmp(s1, s2) == 0); |
418 | | - |
419 | | - if (!match) { |
420 | | - char buf[4096]; |
421 | | - |
422 | | - if (s1 && s2) { |
423 | | - int pos; |
424 | | - for (pos = 0; s1[pos] == s2[pos] && s1[pos] && s2[pos]; ++pos) |
425 | | - /* find differing byte offset */; |
426 | | - snprint_eq(buf, sizeof(buf), "'%s' != '%s' (at byte %d)", s1, s2, pos); |
427 | | - } else { |
428 | | - snprint_eq(buf, sizeof(buf), "'%s' != '%s'", s1, s2); |
| 448 | + va_list args; |
| 449 | + char buf[4096]; |
| 450 | + int is_equal = 1; |
| 451 | + |
| 452 | + va_start(args, fmt); |
| 453 | + |
| 454 | + if (!strcmp("%s", fmt)) { |
| 455 | + const char *s1 = va_arg(args, const char *); |
| 456 | + const char *s2 = va_arg(args, const char *); |
| 457 | + is_equal = (!s1 || !s2) ? (s1 == s2) : !strcmp(s1, s2); |
| 458 | + |
| 459 | + if (!is_equal) { |
| 460 | + if (s1 && s2) { |
| 461 | + int pos; |
| 462 | + for (pos = 0; s1[pos] == s2[pos] && s1[pos] && s2[pos]; ++pos) |
| 463 | + /* find differing byte offset */; |
| 464 | + p_snprintf(buf, sizeof(buf), "'%s' != '%s' (at byte %d)", |
| 465 | + s1, s2, pos); |
| 466 | + } else { |
| 467 | + p_snprintf(buf, sizeof(buf), "'%s' != '%s'", s1, s2); |
| 468 | + } |
| 469 | + } |
| 470 | + } |
| 471 | + else if (!strcmp(PRIuZ, fmt) || !strcmp(PRIxZ, fmt)) { |
| 472 | + size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t); |
| 473 | + is_equal = (sz1 == sz2); |
| 474 | + if (!is_equal) { |
| 475 | + int offset = p_snprintf(buf, sizeof(buf), fmt, sz1); |
| 476 | + strncat(buf, " != ", sizeof(buf) - offset); |
| 477 | + p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, sz2); |
| 478 | + } |
| 479 | + } |
| 480 | + else if (!strcmp("%p", fmt)) { |
| 481 | + void *p1 = va_arg(args, void *), *p2 = va_arg(args, void *); |
| 482 | + is_equal = (p1 == p2); |
| 483 | + if (!is_equal) |
| 484 | + p_snprintf(buf, sizeof(buf), "%p != %p", p1, p2); |
| 485 | + } |
| 486 | + else { |
| 487 | + int i1 = va_arg(args, int), i2 = va_arg(args, int); |
| 488 | + is_equal = (i1 == i2); |
| 489 | + if (!is_equal) { |
| 490 | + int offset = p_snprintf(buf, sizeof(buf), fmt, i1); |
| 491 | + strncat(buf, " != ", sizeof(buf) - offset); |
| 492 | + p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, i2); |
429 | 493 | } |
430 | | - |
431 | | - clar__fail(file, line, err, buf, should_abort); |
432 | 494 | } |
433 | | -} |
434 | 495 |
|
435 | | -void clar__assert_equal_i( |
436 | | - int i1, |
437 | | - int i2, |
438 | | - const char *file, |
439 | | - int line, |
440 | | - const char *err, |
441 | | - int should_abort) |
442 | | -{ |
443 | | - if (i1 != i2) { |
444 | | - char buf[128]; |
445 | | - snprint_eq(buf, sizeof(buf), "%d != %d", i1, i2); |
| 496 | + va_end(args); |
| 497 | + |
| 498 | + if (!is_equal) |
446 | 499 | clar__fail(file, line, err, buf, should_abort); |
447 | | - } |
448 | 500 | } |
449 | 501 |
|
450 | 502 | void cl_set_cleanup(void (*cleanup)(void *), void *opaque) |
|
0 commit comments