Skip to content

Commit b67a93f

Browse files
committed
clar: remove globals; error-check fprintf/fclose
Remove the global summary filename and file pointer; pass them in to the summary functions as needed. Error check the results of buffered I/O calls.
1 parent a2d73f5 commit b67a93f

File tree

2 files changed

+87
-44
lines changed

2 files changed

+87
-44
lines changed

tests/clar.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ struct clar_report {
123123
struct clar_report *next;
124124
};
125125

126+
struct clar_summary {
127+
const char *filename;
128+
FILE *fp;
129+
};
130+
126131
static struct {
127132
enum cl_test_status test_status;
128133

@@ -138,8 +143,10 @@ static struct {
138143
int report_errors_only;
139144
int exit_on_error;
140145
int report_suite_names;
146+
141147
int write_summary;
142-
const char *summary_file;
148+
const char *summary_filename;
149+
struct clar_summary *summary;
143150

144151
struct clar_explicit *explicit;
145152
struct clar_explicit *last_explicit;
@@ -185,8 +192,8 @@ static void clar_unsandbox(void);
185192
static int clar_sandbox(void);
186193

187194
/* From summary.h */
188-
static int clar_summary_init(const char *filename);
189-
static void clar_summary_shutdown(void);
195+
static struct clar_summary *clar_summary_init(const char *filename);
196+
static int clar_summary_shutdown(struct clar_summary *fp);
190197

191198
/* Load the declarations for the test suite */
192199
#include "clar.suite"
@@ -352,14 +359,14 @@ clar_usage(const char *arg)
352359
{
353360
printf("Usage: %s [options]\n\n", arg);
354361
printf("Options:\n");
355-
printf(" -sname\tRun only the suite with `name` (can go to individual test name)\n");
356-
printf(" -iname\tInclude the suite with `name`\n");
357-
printf(" -xname\tExclude the suite with `name`\n");
358-
printf(" -v \tIncrease verbosity (show suite names)\n");
359-
printf(" -q \tOnly report tests that had an error\n");
360-
printf(" -Q \tQuit as soon as a test fails\n");
361-
printf(" -l \tPrint suite names\n");
362-
printf(" -r \tWrite summary file\n");
362+
printf(" -sname Run only the suite with `name` (can go to individual test name)\n");
363+
printf(" -iname Include the suite with `name`\n");
364+
printf(" -xname Exclude the suite with `name`\n");
365+
printf(" -v Increase verbosity (show suite names)\n");
366+
printf(" -q Only report tests that had an error\n");
367+
printf(" -Q Quit as soon as a test fails\n");
368+
printf(" -l Print suite names\n");
369+
printf(" -r[filename] Write summary file (to the optional filename)\n");
363370
exit(-1);
364371
}
365372

@@ -471,7 +478,7 @@ clar_parse_args(int argc, char **argv)
471478

472479
case 'r':
473480
_clar.write_summary = 1;
474-
_clar.summary_file = *(argument + 2) ? (argument + 2) :
481+
_clar.summary_filename = *(argument + 2) ? (argument + 2) :
475482
"summary.xml";
476483
break;
477484

@@ -493,8 +500,9 @@ clar_test_init(int argc, char **argv)
493500
if (argc > 1)
494501
clar_parse_args(argc, argv);
495502

496-
if (_clar.write_summary && !clar_summary_init(_clar.summary_file)) {
497-
clar_print_onabort("Failed to open the summary file: %s\n");
503+
if (_clar.write_summary &&
504+
!(_clar.summary = clar_summary_init(_clar.summary_filename))) {
505+
clar_print_onabort("Failed to open the summary file\n");
498506
exit(-1);
499507
}
500508

@@ -535,8 +543,10 @@ clar_test_shutdown(void)
535543

536544
clar_unsandbox();
537545

538-
if (_clar.write_summary)
539-
clar_summary_shutdown();
546+
if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) {
547+
clar_print_onabort("Failed to write the summary file\n");
548+
exit(-1);
549+
}
540550

541551
for (explicit = _clar.explicit; explicit; explicit = explicit_next) {
542552
explicit_next = explicit->next;

tests/clar/summary.h

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@
22
#include <stdio.h>
33
#include <time.h>
44

5-
static const char *filename;
6-
static FILE *summary;
7-
8-
int clar_summary_close_tag(const char *tag, int indent)
5+
int clar_summary_close_tag(
6+
struct clar_summary *summary, const char *tag, int indent)
97
{
108
const char *indt;
119

1210
if (indent == 0) indt = "";
1311
else if (indent == 1) indt = "\t";
1412
else indt = "\t\t";
1513

16-
return fprintf(summary, "%s</%s>\n", indt, tag);
14+
return fprintf(summary->fp, "%s</%s>\n", indt, tag);
1715
}
1816

19-
int clar_summary_testsuites(void)
17+
int clar_summary_testsuites(struct clar_summary *summary)
2018
{
21-
return fprintf(summary, "<testsuites>\n");
19+
return fprintf(summary->fp, "<testsuites>\n");
2220
}
2321

24-
int clar_summary_testsuite(int idn, const char *name, const char *pkg, time_t timestamp, double elapsed, int test_count, int fail_count, int error_count)
22+
int clar_summary_testsuite(struct clar_summary *summary,
23+
int idn, const char *name, const char *pkg, time_t timestamp,
24+
double elapsed, int test_count, int fail_count, int error_count)
2525
{
2626
struct tm *tm = localtime(&timestamp);
2727
char iso_dt[20];
2828

2929
if (strftime(iso_dt, sizeof(iso_dt), "%FT%T", tm) == 0)
3030
return -1;
3131

32-
return fprintf(summary, "\t<testsuite "
32+
return fprintf(summary->fp, "\t<testsuite "
3333
" id=\"%d\""
3434
" name=\"%s\""
3535
" package=\"%s\""
@@ -42,60 +42,93 @@ int clar_summary_testsuite(int idn, const char *name, const char *pkg, time_t ti
4242
idn, name, pkg, iso_dt, elapsed, test_count, fail_count, error_count);
4343
}
4444

45-
int clar_summary_testcase(const char *name, const char *classname, double elapsed)
45+
int clar_summary_testcase(struct clar_summary *summary,
46+
const char *name, const char *classname, double elapsed)
4647
{
47-
return fprintf(summary, "\t\t<testcase name=\"%s\" classname=\"%s\" time=\"%.2f\">\n", name, classname, elapsed);
48+
return fprintf(summary->fp,
49+
"\t\t<testcase name=\"%s\" classname=\"%s\" time=\"%.2f\">\n",
50+
name, classname, elapsed);
4851
}
4952

50-
int clar_summary_failure(const char *type, const char *message, const char *desc)
53+
int clar_summary_failure(struct clar_summary *summary,
54+
const char *type, const char *message, const char *desc)
5155
{
52-
return fprintf(summary, "\t\t\t<failure type=\"%s\"><![CDATA[%s\n%s]]></failure>\n", type, message, desc);
56+
return fprintf(summary->fp,
57+
"\t\t\t<failure type=\"%s\"><![CDATA[%s\n%s]]></failure>\n",
58+
type, message, desc);
5359
}
5460

55-
int clar_summary_init(const char *fn)
61+
struct clar_summary *clar_summary_init(const char *filename)
5662
{
57-
filename = fn;
63+
struct clar_summary *summary;
64+
FILE *fp;
65+
66+
if ((fp = fopen(filename, "w")) == NULL)
67+
return NULL;
68+
69+
if ((summary = malloc(sizeof(struct clar_summary))) == NULL) {
70+
fclose(fp);
71+
return NULL;
72+
}
5873

59-
summary = fopen(filename, "w");
74+
summary->filename = filename;
75+
summary->fp = fp;
6076

61-
return !!summary;
77+
return summary;
6278
}
6379

64-
void clar_summary_shutdown(void)
80+
int clar_summary_shutdown(struct clar_summary *summary)
6581
{
6682
struct clar_report *report;
6783
const char *last_suite = NULL;
6884

69-
clar_summary_testsuites();
85+
if (clar_summary_testsuites(summary) < 0)
86+
goto on_error;
7087

7188
report = _clar.reports;
7289
while (report != NULL) {
7390
struct clar_error *error = report->errors;
7491

7592
if (last_suite == NULL || strcmp(last_suite, report->suite) != 0) {
76-
clar_summary_testsuite(0, report->suite, "", time(NULL), 0, _clar.tests_ran, _clar.total_errors, 0);
93+
if (clar_summary_testsuite(summary, 0, report->suite, "",
94+
time(NULL), 0, _clar.tests_ran, _clar.total_errors, 0) < 0)
95+
goto on_error;
7796
}
7897

7998
last_suite = report->suite;
8099

81-
clar_summary_testcase(report->test, "what", 0);
100+
clar_summary_testcase(summary, report->test, "what", 0);
82101

83102
while (error != NULL) {
84-
clar_summary_failure("assert", error->error_msg, error->description);
103+
if (clar_summary_failure(summary, "assert",
104+
error->error_msg, error->description) < 0)
105+
goto on_error;
106+
85107
error = error->next;
86108
}
87109

88-
clar_summary_close_tag("testcase", 2);
110+
if (clar_summary_close_tag(summary, "testcase", 2) < 0)
111+
goto on_error;
89112

90113
report = report->next;
91114

92-
if (!report || strcmp(last_suite, report->suite) != 0)
93-
clar_summary_close_tag("testsuite", 1);
115+
if (!report || strcmp(last_suite, report->suite) != 0) {
116+
if (clar_summary_close_tag(summary, "testsuite", 1) < 0)
117+
goto on_error;
118+
}
94119
}
95120

96-
clar_summary_close_tag("testsuites", 0);
121+
if (clar_summary_close_tag(summary, "testsuites", 0) < 0 ||
122+
fclose(summary->fp) != 0)
123+
goto on_error;
124+
125+
printf("written summary file to %s\n", summary->filename);
97126

98-
fclose(summary);
127+
free(summary);
128+
return 0;
99129

100-
printf("written summary file to %s\n", filename);
130+
on_error:
131+
fclose(summary->fp);
132+
free(summary);
133+
return -1;
101134
}

0 commit comments

Comments
 (0)