65#if !defined (PATH_MAX) || PATH_MAX < 128 || 4096 < PATH_MAX
97merge_argv (
const char* target,
char*
const argv [])
101 unsigned i, arg_count = 0, spl_count = 0, wld_count = 0;
106 tlen = strlen (target);
113 if (isspace (target [tlen])) {
121 for (; argv [arg_count]; ++arg_count);
127 for (
i=0;
i < arg_count; ++
i)
137 for (spl_count = 1;
split [spl_count]; ++spl_count) {
138 if (
'%' ==
split [spl_count][0] &&
'x' ==
split [spl_count][1]
139 &&
'\0' ==
split [spl_count][2])
150 for (; argv [arg_count]; ++arg_count);
152 if (0 == arg_count) {
155 for (
i = 1;
i <= spl_count; ++
i) {
163 else if (1 == arg_count) {
166 for (
i = 1;
i < spl_count; ++
i) {
175 const unsigned new_len = spl_count + (arg_count - 1) * wld_count;
182 for (; wld_count; --spl_count) {
183 if (
split [spl_count] &&
'%' ==
split [spl_count][0]
184 &&
'x' ==
split [spl_count][1]
185 &&
'\0' ==
split [spl_count][2]) {
187 for (
i = arg_count;
i; --
i) {
188 split [spl_count + (arg_count - 1) * wld_count +
i - 1] =
193 split [spl_count + (arg_count - 1) * wld_count] =
205#define READ_BUF_LEN 64
219void count_warnings (
const char*
const target,
unsigned* counter,
220 const char*
const match)
232 path_len = strlen (target);
233 tmp_name = (
char*)
RW_MALLOC (path_len + 5);
234 memcpy (tmp_name, target, path_len + 1);
235 strcat (tmp_name,
".log");
237 data = fopen (tmp_name,
"r");
239 size_t pos = 0, limit = strlen (match);
240 while (!feof (
data)) {
247 warn (
"Error reading %s: %s\n", tmp_name, strerror (errno));
252 for (
size_t i = 0;
i < nread; ++
i) {
255 else if (++
pos == limit) {
265 warn (
"Error opening %s: %s\n", tmp_name, strerror (errno));
287check_target_ok (
const char* target,
struct target_status* status)
289 struct stat file_info;
297 path_len = strlen (target);
301 tmp_name = (
char*)
RW_MALLOC (path_len + 3);
302 memcpy (tmp_name, target, path_len + 1);
303 strcat (tmp_name,
".o");
307 const char*
const target_name =
get_target ();
308 size_t target_len = strlen (target_name);
309 size_t tmp_len = path_len + target_len - 2;
313 memcpy (tmp_name, target, path_len - 4);
315 memcpy (tmp_name + path_len - 3, target_name, target_len);
316 tmp_name [tmp_len - 4] =
'o';
317 tmp_name [tmp_len - 3] =
'b';
318 tmp_name [tmp_len - 2] =
'j';
319 tmp_name [tmp_len - 1] =
'\0';
323 count_warnings (target, &status->
l_warn,
"warning:");
324 count_warnings (tmp_name, &status->
c_warn,
"warning:");
326 if (0 > stat (target, &file_info)) {
328 warn (
"Error stating %s: %s\n", target, strerror (errno));
333 file_info.st_mode = 0;
344 if (
'.' == target [path_len-1] &&
'o' == target [path_len]) {
359 if (0 > stat (tmp_name, &file_info)) {
361 warn (
"Error stating %s: %s\n", tmp_name, strerror (errno));
393rw_basename (
const char*
path)
395 const char *
pos, *mark;
409static const char* target_name;
438 assert (0 != target_template);
441 memcpy (&options, target_template,
sizeof options);
442 memset (&results, 0,
sizeof results);
445 options.argv = merge_argv (target, options.argv);
447 assert (0 != options.argv);
448 assert (0 != options.argv [0]);
450 target_name = rw_basename (options.argv [0]);
453 options.infname =
input_name (options.data_dir, target_name);
458 if (check_target_ok (options.argv [0], &results)) {
460 if (0 == results.exit && 0 == results.signaled)
468 if (0 == results.signaled && results.exit)
472 if (results.usr_time != (clock_t)-1)
473 summary->
usr_time += results.usr_time;
475 if (results.sys_time != (clock_t)-1)
476 summary->
sys_time += results.sys_time;
478 if (results.wall_time != (clock_t)-1)
481 summary->
signaled += results.signaled;
482 summary->
c_warn += results.c_warn;
483 summary->
l_warn += results.l_warn;
484 summary->
t_warn += results.t_warn;
486 if ((
unsigned)-1 != results.assert) {
488 summary->
assert += results.assert;
489 summary->
failed += results.failed;
494 free (options.argv [0]);
496 free ((
char*)options.infname);
497 free ((
char*)options.outfname);
516 const char* exe_opts =
"";
517 const char*
const*
const saved_argv = (
const char*
const*)
argv;
521 if (1 < argc &&
'-' ==
argv [1][0]) {
533 memset (&target_template, 0,
sizeof target_template);
557 memset (&summary, 0,
sizeof summary);
562 for (
i = 0;
i < argc; ++
i) {
563 const char* target = argv [
i];
565 if (
'@' == target [0]) {
567 const char* lst_name = target + 1;
568 FILE* lst = fopen (lst_name,
"r");
570 warn (
"Error opening %s: %s\n", lst_name, strerror (errno));
574 while (!feof (lst)) {
576 target = fgets (
buf,
int (
sizeof buf), lst);
579 warn (
"Error reading %s: %s\n", lst_name, strerror (errno));
586 if (
char*
pos = strchr (
buf,
'\n'))
590 run_target (&summary, target, &target_template);
599 run_target (&summary, target, &target_template);
605 if (target_template.
argv [0])
606 free (target_template.
argv [0]);
607 free (target_template.
argv);
610 free (target_template.
core);
611 free (target_template.
cpu);
612 free (target_template.
data);
613 free (target_template.
fsize);
614 free (target_template.
nofile);
615 free (target_template.
stack);
616 free (target_template.
as);
void split(const std::string &text, const std::string &separators, std::list< std::string, std::allocator< std::string > > &words)
void(* print_status)(const struct target_status *)
void(* print_header)(const char *const[])
void(* print_footer)(int, const struct target_status *)
void set_output_format(enum OutputFmt format)
void(* print_target)(const struct target_opts *)
void exec_file(const struct target_opts *options, struct target_status *result)
void parse_output(const struct target_opts *options, struct target_status *status)
const char * get_target()
enum ProcessStatus status
char ** split_opt_string(const char *opts)
const char default_path_sep
int eval_options(int argc, char **argv, struct target_opts *defaults, const char **exe_opts)
char * input_name(const char *data_dir, const char *target)
char * output_name(const char *target)
void warn(const char *const format,...)
#define RW_REALLOC(source, size)