Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
display.cpp
Go to the documentation of this file.
1
27#include <assert.h>
28#include <stdio.h> /* for fflush(), printf(), puts(), ... */
29#include <string.h> /* for strchr() */
30
31#include "cmdopt.h" /* for target_name -should this be moved? */
32#include "exec.h" /* for get_signame */
33
34#include "display.h"
35#include "target.h" /* for target_status */
36
37#include <time.h> /* for CLK_TCK, CLOCKS_PER_SEC */
38
39#ifndef _WIN32
40# include <unistd.h> /* for _SC_CLK_TCK, sysconf() */
41#endif
42
43#if defined (_SC_CLK_TCK)
44
45/* dynamically determine the number of clock ticks per second */
46static const float TICKS_PER_SEC = float (sysconf (_SC_CLK_TCK));
47
48#elif defined CLOCKS_PER_SEC
49
50/* use the POSIX (and MSVC 6.0) CLOCKS_PER_SEC constant */
51static const float TICKS_PER_SEC = CLOCKS_PER_SEC;
52
53#elif defined CLK_TCK
54
55/* use CLK_TCK if it's defined (e.g., pre-MSVC 6.0) */
56static const float TICKS_PER_SEC = CLK_TCK;
57
58#else
59
60/* if all else fails, assume the standard 1 million ticks per second */
61static const float TICKS_PER_SEC = 1000000UL;
62
63#endif
64
65
69static const char* const
70short_st_name [ST_LAST] = {
71 "OK", /*ST_OK*/
72 "COMP", /*ST_COMPILE*/
73 "LINK", /*ST_LINK*/
74 "EXIST", /*ST_EXIST*/
75 "XPERM", /*ST_EXECUTE_FLAG*/
76 "EXEC", /*ST_EXECUTE*/
77 "NOUT", /*ST_NO_OUTPUT*/
78 "OUTPUT", /*ST_NO_REF*/
79 "BREF", /*ST_BAD_REF*/
80 "DIFF", /*ST_BAD_OUTPUT*/
81 "FORMAT", /*ST_FORMAT*/
82 "OFLOW", /*ST_OVERFLOW*/
83 "ERROR", /*ST_SYSTEM_ERROR*/
84 "KILLED", /*ST_KILLED*/
85 "NKILL" /*ST_NOT_KILLED*/
86};
87
88
92static const char* const
93verbose_st_name [ST_LAST] = {
94 "OK", /*ST_OK*/
95 "Program failed to compile.", /*ST_COMPILE*/
96 "Program failed to link.", /*ST_LINK*/
97 "Program executable not found.", /*ST_EXIST*/
98 "Program not executable.", /*ST_EXECUTE_FLAG*/
99 "Program failed to execute.", /*ST_EXECUTE*/
100 "Program generated no output.", /*ST_NO_OUTPUT*/
101 "Program reference output missing.", /*ST_NO_REF*/
102 "Bad reference.", /*ST_BAD_REF*/
103 "Program produced unexpected output.", /*ST_BAD_OUTPUT*/
104 "Program produced output in unexpected format.", /*ST_FORMAT*/
105 "Arithmetic overflow.", /*ST_OVERFLOW*/
106 "System error occurred.", /*ST_SYSTEM_ERROR*/
107 "Process killed after a timeout.", /*ST_KILLED*/
108 "Failed to kill process after a timeout." /*ST_NOT_KILLED*/
109};
110
111
115static int
116print_argv (const char* const argv[], int newline)
117{
118 assert (0 != argv);
119
120 const char* const* parg = argv;
121
122 int nchars = 0;
123
124 for (parg = argv; *parg; ++parg) {
125
126 const char *fmt = "%s ";
127
128 if (strchr (*parg, ' '))
129 fmt = "\"%s\" ";
130
131 nchars += printf (fmt, *parg);
132 }
133
134 if (newline)
135 puts ("");
136
137 return nchars;
138}
139
140
144static void
145print_header_plain (const char* const argv[])
146{
147 (void)&argv;
148
149 puts ("NAME STATUS WARN ASSERTS "
150 "FAILED PERCNT USER SYS REAL");
151}
152
153
157static void
158print_header_verbose (const char* const argv[])
159{
160 print_argv (argv, 1 /* append newline */);
161}
162
163
164
168static void
169print_target_plain (const struct target_opts *defaults)
170{
171 const char* const target_name = get_target ();
172
173 assert (0 == defaults->verbose);
174
175 printf ("%-40.40s ", target_name);
176
177 /* flush to prevent killing a signal from not displaying the text */
178 fflush (stdout);
179}
180
181
185static void
186print_target_verbose (const struct target_opts *defaults)
187{
188 assert (defaults->verbose);
189
190 printf ("%s ", "Executing \"");
191 print_argv (defaults->argv, 0 /* no newline */);
192
193 /* print stdin, stdout, and stderr redirections */
194 if (defaults->infname && *defaults->infname)
195 printf (" <%s", defaults->infname);
196
197 if (defaults->outfname && *defaults->outfname)
198 printf (" >%s 2>&1", defaults->outfname);
199
200 puts ("\"");
201
202 /* flush to prevent killing a signal from not displaying the text */
203 fflush (stdout);
204}
205
206
211static void print_status_plain (const struct target_status* status)
212{
213 unsigned valid_timing;
214 assert (0 != status);
215 assert (ST_OK <= status->status && ST_LAST > status->status);
216
217 valid_timing = status->usr_time != (clock_t)-1
218 && status->sys_time != (clock_t)-1
219 && ST_NOT_KILLED != status->status;
220
221 if (status->status) /* if status is set, print it */
222 printf ("%6s", short_st_name [status->status]);
223 else if (status->signaled) /* if exit signal is non-zero, print it */
224 printf ("%6s", get_signame (status->exit));
225 else if (status->exit) /* if exit code is non-zero, print it */
226 printf ("%6d", status->exit);
227 else
228 printf (" 0");
229
230 printf (" %4u", status->c_warn + status->l_warn + status->t_warn);
231
232 /* Print assetions, if any registered */
233 if ( (unsigned)-1 != status->assert
234 && 0 == status->status
235 && 0 == status->exit) {
236 if (status->assert) {
237 const int percnt = int ( 100.0
238 * (status->assert - status->failed)
239 / status->assert);
240 printf (" %7u %6u %5d%%", status->assert, status->failed, percnt);
241 }
242 else {
243 printf (" 0 %6u 100%%", status->failed);
244 }
245 }
246 else if (valid_timing || status->wall_time != (clock_t)-1)
247 printf (" ");
248
249 /* Print timings, if available */
250 if (valid_timing)
251 printf (" %7.3f %7.3f", (float)status->usr_time / TICKS_PER_SEC,
252 (float)status->sys_time / TICKS_PER_SEC);
253 else if (status->wall_time != (clock_t)-1)
254 printf (" ");
255
256 if (status->wall_time != (clock_t)-1)
257 printf (" %7.3f\n", (float)status->wall_time / TICKS_PER_SEC);
258 else
259 puts ("");
260}
261
262
266static void
267print_status_verbose (const struct target_status* status)
268{
269 unsigned valid_timing;
270
271 assert (0 != status);
272 assert (ST_OK <= status->status && ST_LAST > status->status);
273
274 valid_timing = status->usr_time != (clock_t)-1
275 && status->sys_time != (clock_t)-1
276 && ST_NOT_KILLED != status->status;
277
278 if (status->status) /* if status is set, print it */
279 printf (" Status: %s\n", verbose_st_name [status->status]);
280 else if (status->signaled) /* if exit signal is non-zero, print it */
281 printf (" Process signalled: %s\n", get_signame (status->exit));
282 else {
283 printf (" Exit status: %6d%s\n"
284 " Compiler warnings: %6u\n"
285 " Linker warnings: %6u\n"
286 " Runtime warnings: %6u\n",
287 status->exit, 0 == status->exit ? " (success)" : "",
288 status->c_warn,
289 status->l_warn,
290 status->t_warn);
291
292 /* Print assetions, if any registered */
293 if ((unsigned)-1 != status->assert && status->assert) {
294 printf (" Failed assertions: %6u\n"
295 " Total assertions: %6u\n",
296 status->failed, status->assert);
297 }
298 }
299
300 /* Print timings, if available */
301 if (valid_timing) {
302 const float wall = (float)status->wall_time / TICKS_PER_SEC;
303 const float user = (float)status->usr_time / TICKS_PER_SEC;
304 const float sys = (float)status->sys_time / TICKS_PER_SEC;
305
306 printf (" Times:\n"
307 " Real %7.3fs\n"
308 " User %7.3fs\n"
309 " Sys %7.3fs\n",
310 wall, user, sys);
311 }
312
313 puts ("");
314}
315
316
321static void
322print_footer_plain (int count, const struct target_status *summary)
323{
324 /* compute cumulative times for all targets */
325 const float wall = (float)summary->wall_time / TICKS_PER_SEC;
326 const float user = (float)summary->usr_time / TICKS_PER_SEC;
327 const float sys = (float)summary->sys_time / TICKS_PER_SEC;
328
329 printf ("PROGRAM SUMMARY:\n"
330 " Programs: %9d\n"
331 " Non-zero exit status: %9d\n"
332 " Signalled: %9d\n"
333 " Compiler warnings: %9u\n"
334 " Linker warnings: %9u\n"
335 " Runtime warnings: %9u\n",
336 count,
337 summary->exit,
338 summary->signaled,
339 summary->c_warn,
340 summary->l_warn,
341 summary->t_warn);
342
343 if ((unsigned)-1 != summary->assert) {
344 /* print assertion counters only when they're valid */
345 printf (" Assertions: %9u\n"
346 " Failed assertions: %9u\n",
347 summary->assert,
348 summary->failed);
349 }
350
351 printf ( " Cumulative times:\n"
352 " Real %7.3fs\n"
353 " User %7.3fs\n"
354 " Sys %7.3fs\n",
355 wall,
356 user,
357 sys);
358}
359
360
361static void
362print_footer_verbose (int count, const struct target_status *summary)
363{
364 print_footer_plain (count, summary);
365}
366
367
371void set_output_format (enum OutputFmt format)
372{
373 if (FMT_VERBOSE == format) {
374 print_header = print_header_verbose;
375 print_target = print_target_verbose;
376 print_status = print_status_verbose;
377 print_footer = print_footer_verbose;
378 }
379 else {
380 /* only two formats implemented */
381 assert (FMT_PLAIN == format);
382
383 print_header = print_header_plain;
384 print_target = print_target_plain;
385 print_status = print_status_plain;
386 print_footer = print_footer_plain;
387 }
388}
389
390
391void (*print_header) (const char* const[]) = print_header_plain;
392void (*print_target) (const struct target_opts*) = print_target_plain;
393void (*print_status) (const struct target_status*) = print_status_plain;
394void (*print_footer) (int, const struct target_status*) = print_footer_plain;
void count(T, T, const U &,...)
#define nchars
Definition 17.names.cpp:502
IMPORT_C SInt32 printf(const Char *,...)
#define assert(expr)
Definition _cassert.h:40
#define stdout
#define CLOCKS_PER_SEC
const char * get_target()
Definition runall.cpp:411
void(* print_status)(const struct target_status *)
Definition display.cpp:393
void(* print_header)(const char *const[])
Definition display.cpp:391
void(* print_footer)(int, const struct target_status *)
Definition display.cpp:394
void set_output_format(enum OutputFmt format)
Definition display.cpp:371
void(* print_target)(const struct target_opts *)
Definition display.cpp:392
OutputFmt
Definition display.h:37
@ FMT_VERBOSE
Definition display.h:40
@ FMT_PLAIN
Definition display.h:38
const char * get_signame(int signo)
Definition exec.cpp:397
char ** argv
Definition target.h:76
int verbose
Definition target.h:84
const char * infname
Definition target.h:81
const char * outfname
Definition target.h:82
clock_t usr_time
Definition target.h:124
unsigned l_warn
Definition target.h:128
enum ProcessStatus status
Definition target.h:123
clock_t sys_time
Definition target.h:125
unsigned c_warn
Definition target.h:127
unsigned t_warn
Definition target.h:129
clock_t wall_time
Definition target.h:126
unsigned assert
Definition target.h:130
unsigned failed
Definition target.h:131
@ ST_LAST
Definition target.h:113
@ ST_NOT_KILLED
Definition target.h:112