4
* This file is part of clar, distributed under the ISC license.
5
* For full terms see the included COPYING file.
6
*/
7
-#include <assert.h>
7
+
8
+#define _BSD_SOURCE
9
+#define _DARWIN_C_SOURCE
10
+#define _DEFAULT_SOURCE
11
+
12
+#include <errno.h>
13
#include <setjmp.h>
14
#include <stdlib.h>
15
#include <stdio.h>
18
#include <stdarg.h>
19
#include <wchar.h>
20
#include <time.h>
21
+#include <inttypes.h>
22
23
/* required for sandboxing */
24
#include <sys/types.h>
25
#include <sys/stat.h>
26
27
+#if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_WCHAR__)
28
+ /*
29
+ * uClibc can optionally be built without wchar support, in which case
30
+ * the installed <wchar.h> is a stub that only defines the `whar_t`
31
+ * type but none of the functions typically declared by it.
32
+ */
33
+#else
34
+# define CLAR_HAVE_WCHAR
35
+#endif
36
+
37
#ifdef _WIN32
38
# define WIN32_LEAN_AND_MEAN
39
# include <windows.h>
44
45
# ifndef stat
46
# define stat(path, st) _stat(path, st)
47
+ typedef struct _stat STAT_T;
48
+# else
49
+ typedef struct stat STAT_T;
50
# endif
51
# ifndef mkdir
52
# define mkdir(path, mode) _mkdir(path)
79
# else
80
# define p_snprintf snprintf
81
# endif
63
-
64
-# ifndef PRIuZ
65
-# define PRIuZ "Iu"
66
-# endif
67
-# ifndef PRIxZ
68
-# define PRIxZ "Ix"
69
-# endif
70
-
71
-# if defined(_MSC_VER) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
72
- typedef struct stat STAT_T;
73
-# else
74
- typedef struct _stat STAT_T;
75
-# endif
82
#else
83
# include <sys/wait.h> /* waitpid(2) */
84
# include <unistd.h>
85
# define _MAIN_CC
86
# define p_snprintf snprintf
81
-# ifndef PRIuZ
82
-# define PRIuZ "zu"
83
-# endif
84
-# ifndef PRIxZ
85
-# define PRIxZ "zx"
86
-# endif
87
typedef struct stat STAT_T;
88
#endif
89
102
struct clar_error {
103
const char *file;
104
const char *function;
105
- size_t line_number;
105
+ uintmax_t line_number;
106
const char *error_msg;
107
char *description;
108
195
static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error);
196
static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed);
197
static void clar_print_onsuite(const char *suite_name, int suite_index);
198
+static void clar_print_onabortv(const char *msg, va_list argp);
199
static void clar_print_onabort(const char *msg, ...);
200
201
/* From clar_sandbox.c */
202
static void clar_unsandbox(void);
202
-static int clar_sandbox(void);
203
+static void clar_sandbox(void);
204
205
/* From summary.h */
206
static struct clar_summary *clar_summary_init(const char *filename);
219
_clar.trace_payload); \
220
} while (0)
221
222
+static void clar_abort(const char *msg, ...)
223
+{
224
+ va_list argp;
225
+ va_start(argp, msg);
226
+ clar_print_onabortv(msg, argp);
227
+ va_end(argp);
228
+ exit(-1);
229
+}
230
+
231
void cl_trace_register(cl_trace_cb *cb, void *payload)
232
{
233
_clar.pfn_trace_cb = cb;
281
282
static void clar_time_now(clar_time *out)
283
{
274
- struct timezone tz;
275
-
276
- gettimeofday(out, &tz);
284
+ gettimeofday(out, NULL);
285
}
286
287
static double clar_time_diff(clar_time *start, clar_time *end)
394
395
_clar.active_test = test[i].name;
396
389
- report = calloc(1, sizeof(struct clar_report));
397
+ if ((report = calloc(1, sizeof(*report))) == NULL)
398
+ clar_abort("Failed to allocate report.\n");
399
report->suite = _clar.active_suite;
400
report->test = _clar.active_test;
401
report->test_number = _clar.tests_ran;
488
489
switch (action) {
490
case 's': {
482
- struct clar_explicit *explicit =
483
- calloc(1, sizeof(struct clar_explicit));
484
- assert(explicit);
491
+ struct clar_explicit *explicit;
492
+
493
+ if ((explicit = calloc(1, sizeof(*explicit))) == NULL)
494
+ clar_abort("Failed to allocate explicit test.\n");
495
496
explicit->suite_idx = j;
497
explicit->filter = argument;
515
}
516
}
517
508
- if (!found) {
509
- clar_print_onabort("No suite matching '%s' found.\n", argument);
510
- exit(-1);
511
- }
518
+ if (!found)
519
+ clar_abort("No suite matching '%s' found.\n", argument);
520
break;
521
}
522
548
case 'r':
549
_clar.write_summary = 1;
550
free(_clar.summary_filename);
543
- _clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL;
551
+ if (*(argument + 2)) {
552
+ if ((_clar.summary_filename = strdup(argument + 2)) == NULL)
553
+ clar_abort("Failed to allocate summary filename.\n");
554
+ } else {
555
+ _clar.summary_filename = NULL;
556
+ }
557
break;
558
559
default:
547
- assert(!"Unexpected commandline argument!");
560
+ clar_abort("Unexpected commandline argument '%s'.\n",
561
+ argument[1]);
562
}
563
}
564
}
580
if (!_clar.summary_filename &&
581
(summary_env = getenv("CLAR_SUMMARY")) != NULL) {
582
_clar.write_summary = 1;
569
- _clar.summary_filename = strdup(summary_env);
583
+ if ((_clar.summary_filename = strdup(summary_env)) == NULL)
584
+ clar_abort("Failed to allocate summary filename.\n");
585
}
586
587
if (_clar.write_summary && !_clar.summary_filename)
573
- _clar.summary_filename = strdup("summary.xml");
588
+ if ((_clar.summary_filename = strdup("summary.xml")) == NULL)
589
+ clar_abort("Failed to allocate summary filename.\n");
590
575
- if (_clar.write_summary &&
576
- !(_clar.summary = clar_summary_init(_clar.summary_filename))) {
577
- clar_print_onabort("Failed to open the summary file\n");
578
- exit(-1);
579
- }
591
+ if (_clar.write_summary)
592
+ _clar.summary = clar_summary_init(_clar.summary_filename);
593
581
- if (clar_sandbox() < 0) {
582
- clar_print_onabort("Failed to sandbox the test runner.\n");
583
- exit(-1);
584
- }
594
+ clar_sandbox();
595
}
596
597
int
625
626
clar_unsandbox();
627
618
- if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) {
619
- clar_print_onabort("Failed to write the summary file\n");
620
- exit(-1);
621
- }
628
+ if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0)
629
+ clar_abort("Failed to write the summary file '%s: %s.\n",
630
+ _clar.summary_filename, strerror(errno));
631
632
for (explicit = _clar.explicit; explicit; explicit = explicit_next) {
633
explicit_next = explicit->next;
658
{
659
if (!_clar.trampoline_enabled) {
660
clar_print_onabort(
652
- "Fatal error: a cleanup method raised an exception.");
661
+ "Fatal error: a cleanup method raised an exception.\n");
662
clar_report_errors(_clar.last_report);
663
exit(-1);
664
}
682
const char *description,
683
int should_abort)
684
{
676
- struct clar_error *error = calloc(1, sizeof(struct clar_error));
685
+ struct clar_error *error;
686
+
687
+ if ((error = calloc(1, sizeof(*error))) == NULL)
688
+ clar_abort("Failed to allocate error.\n");
689
690
if (_clar.last_report->errors == NULL)
691
_clar.last_report->errors = error;
700
error->line_number = line;
701
error->error_msg = error_msg;
702
691
- if (description != NULL)
692
- error->description = strdup(description);
703
+ if (description != NULL &&
704
+ (error->description = strdup(description)) == NULL)
705
+ clar_abort("Failed to allocate description.\n");
706
707
_clar.total_errors++;
708
_clar.last_report->status = CL_TEST_FAILURE;
776
}
777
}
778
}
779
+#ifdef CLAR_HAVE_WCHAR
780
else if (!strcmp("%ls", fmt)) {
781
const wchar_t *wcs1 = va_arg(args, const wchar_t *);
782
const wchar_t *wcs2 = va_arg(args, const wchar_t *);
812
}
813
}
814
}
801
- else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) {
802
- size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t);
815
+#endif /* CLAR_HAVE_WCHAR */
816
+ else if (!strcmp("%"PRIuMAX, fmt) || !strcmp("%"PRIxMAX, fmt)) {
817
+ uintmax_t sz1 = va_arg(args, uintmax_t), sz2 = va_arg(args, uintmax_t);
818
is_equal = (sz1 == sz2);
819
if (!is_equal) {
820
int offset = p_snprintf(buf, sizeof(buf), fmt, sz1);