@@ -106,6 +106,15 @@ struct clar_error {
106106 struct clar_error * next ;
107107};
108108
109+ struct clar_timing {
110+ const char * test ;
111+ const char * suite ;
112+
113+ double elapsed ;
114+
115+ struct clar_timing * next ;
116+ };
117+
109118static struct {
110119 int argc ;
111120 char * * argv ;
@@ -124,9 +133,16 @@ static struct {
124133 int exit_on_error ;
125134 int report_suite_names ;
126135
136+ int run_benchmarks ;
137+ double timing_start ;
138+ double timing_end ;
139+
127140 struct clar_error * errors ;
128141 struct clar_error * last_error ;
129142
143+ struct clar_timing * timings ;
144+ struct clar_timing * last_timing ;
145+
130146 void (* local_cleanup )(void * );
131147 void * local_cleanup_payload ;
132148
@@ -141,6 +157,7 @@ static struct {
141157struct clar_func {
142158 const char * name ;
143159 void (* ptr )(void );
160+ int is_bench ;
144161};
145162
146163struct clar_suite {
@@ -156,6 +173,7 @@ struct clar_suite {
156173static void clar_print_init (int test_count , int suite_count , const char * suite_names );
157174static void clar_print_shutdown (int test_count , int suite_count , int error_count );
158175static void clar_print_error (int num , const struct clar_error * error );
176+ static void clar_print_timing (const struct clar_timing * timing );
159177static void clar_print_ontest (const char * test_name , int test_number , enum cl_test_status failed );
160178static void clar_print_onsuite (const char * suite_name , int suite_index );
161179static void clar_print_onabort (const char * msg , ...);
@@ -164,6 +182,12 @@ static void clar_print_onabort(const char *msg, ...);
164182static void clar_unsandbox (void );
165183static int clar_sandbox (void );
166184
185+ /* From time.h */
186+ /**
187+ * Return the time from a monotonic timer.
188+ */
189+ static double clar_timer (void );
190+
167191/* Load the declarations for the test suite */
168192#include "clar.suite"
169193
@@ -203,6 +227,23 @@ clar_report_errors(void)
203227 _clar .errors = _clar .last_error = NULL ;
204228}
205229
230+ static void
231+ clar_report_timings (void )
232+ {
233+ struct clar_timing * timing , * next ;
234+
235+ timing = _clar .timings ;
236+
237+ while (timing != NULL ) {
238+ next = timing -> next ;
239+ clar_print_timing (timing );
240+ free (timing );
241+ timing = next ;
242+ }
243+
244+ _clar .timings = _clar .last_timing = NULL ;
245+ }
246+
206247static void
207248clar_run_test (
208249 const struct clar_func * test ,
@@ -219,7 +260,9 @@ clar_run_test(
219260 initialize -> ptr ();
220261
221262 CL_TRACE (CL_TRACE__TEST__RUN_BEGIN );
263+ _clar .timing_start = clar_timer ();
222264 test -> ptr ();
265+ _clar .timing_end = clar_timer ();
223266 CL_TRACE (CL_TRACE__TEST__RUN_END );
224267 }
225268
@@ -246,6 +289,8 @@ clar_run_test(
246289 }
247290}
248291
292+ static void clar_store_timing (void );
293+
249294static void
250295clar_run_suite (const struct clar_suite * suite , const char * filter )
251296{
@@ -282,13 +327,23 @@ clar_run_suite(const struct clar_suite *suite, const char *filter)
282327 if (filter && strncmp (test [i ].name , filter , matchlen ))
283328 continue ;
284329
330+ if (test [i ].is_bench != _clar .run_benchmarks )
331+ continue ;
332+
285333 _clar .active_test = test [i ].name ;
286334 clar_run_test (& test [i ], & suite -> initialize , & suite -> cleanup );
287335
288336 if (_clar .exit_on_error && _clar .total_errors )
289337 return ;
338+
339+ if (test [i ].is_bench ) {
340+ clar_store_timing ();
341+ }
290342 }
291343
344+ puts ("" );
345+ clar_report_timings ();
346+
292347 _clar .active_test = NULL ;
293348 CL_TRACE (CL_TRACE__SUITE_END );
294349}
@@ -305,6 +360,7 @@ clar_usage(const char *arg)
305360 printf (" -q \tOnly report tests that had an error\n" );
306361 printf (" -Q \tQuit as soon as a test fails\n" );
307362 printf (" -l \tPrint suite names\n" );
363+ printf (" -b \tRun benchmarks instead of tests\n" );
308364 exit (-1 );
309365}
310366
@@ -363,6 +419,10 @@ clar_parse_args(int argc, char **argv)
363419 break ;
364420 }
365421
422+ case 'b' :
423+ _clar .run_benchmarks = 1 ;
424+ break ;
425+
366426 case 'q' :
367427 _clar .report_errors_only = 1 ;
368428 break ;
@@ -447,6 +507,23 @@ clar_test(int argc, char **argv)
447507 return errors ;
448508}
449509
510+ static void clar_store_timing (void )
511+ {
512+ struct clar_timing * timing = calloc (1 , sizeof (struct clar_timing ));
513+
514+ if (_clar .timings == NULL )
515+ _clar .timings = timing ;
516+
517+ if (_clar .last_timing != NULL )
518+ _clar .last_timing -> next = timing ;
519+
520+ _clar .last_timing = timing ;
521+
522+ timing -> elapsed = _clar .timing_end - _clar .timing_start ;
523+ timing -> test = _clar .active_test ;
524+ timing -> suite = _clar .active_suite ;
525+ }
526+
450527static void abort_test (void )
451528{
452529 if (!_clar .trampoline_enabled ) {
@@ -460,6 +537,11 @@ static void abort_test(void)
460537 longjmp (_clar .trampoline , -1 );
461538}
462539
540+ void clar__reset_timer (void )
541+ {
542+ _clar .timing_start = clar_timer ();
543+ }
544+
463545void clar__skip (void )
464546{
465547 _clar .test_status = CL_TEST_SKIP ;
@@ -640,3 +722,4 @@ void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
640722#include "clar/fixtures.h"
641723#include "clar/fs.h"
642724#include "clar/print.h"
725+ #include "clar/time.h"
0 commit comments