veristat: @files-list.txt notation for object files list

Allow reading object file list from file.
E.g. the following command:

  ./veristat @list.txt

Is equivalent to the following invocation:

  ./veristat line-1 line-2 ... line-N

Where line-i corresponds to lines from list.txt.
Lines starting with '#' are ignored.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Mykyta Yatsenko <mykyta.yatsenko5@gmail.com>
Link: https://lore.kernel.org/bpf/20250301000147.1583999-2-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Eduard Zingerman 2025-02-28 16:01:45 -08:00 committed by Alexei Starovoitov
parent a752ba4332
commit c0d078da7a

View File

@ -268,10 +268,11 @@ static int append_filter(struct filter **filters, int *cnt, const char *str);
static int append_filter_file(const char *path);
static int append_var_preset(struct var_preset **presets, int *cnt, const char *expr);
static int append_var_preset_file(const char *filename);
static int append_file(const char *path);
static int append_file_from_file(const char *path);
static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
void *tmp;
int err;
switch (key) {
@ -381,14 +382,14 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
break;
}
case ARGP_KEY_ARG:
tmp = realloc(env.filenames, (env.filename_cnt + 1) * sizeof(*env.filenames));
if (!tmp)
return -ENOMEM;
env.filenames = tmp;
env.filenames[env.filename_cnt] = strdup(arg);
if (!env.filenames[env.filename_cnt])
return -ENOMEM;
env.filename_cnt++;
if (arg[0] == '@')
err = append_file_from_file(arg + 1);
else
err = append_file(arg);
if (err) {
fprintf(stderr, "Failed to collect BPF object files: %d\n", err);
return err;
}
break;
default:
return ARGP_ERR_UNKNOWN;
@ -689,6 +690,49 @@ static const struct stat_specs default_output_spec = {
},
};
static int append_file(const char *path)
{
void *tmp;
tmp = realloc(env.filenames, (env.filename_cnt + 1) * sizeof(*env.filenames));
if (!tmp)
return -ENOMEM;
env.filenames = tmp;
env.filenames[env.filename_cnt] = strdup(path);
if (!env.filenames[env.filename_cnt])
return -ENOMEM;
env.filename_cnt++;
return 0;
}
static int append_file_from_file(const char *path)
{
char buf[1024];
int err = 0;
FILE *f;
f = fopen(path, "r");
if (!f) {
err = -errno;
fprintf(stderr, "Failed to open object files list in '%s': %s\n",
path, strerror(errno));
return err;
}
while (fscanf(f, " %1023[^\n]\n", buf) == 1) {
/* lines starting with # are comments, skip them */
if (buf[0] == '\0' || buf[0] == '#')
continue;
err = append_file(buf);
if (err)
goto cleanup;
}
cleanup:
fclose(f);
return err;
}
static const struct stat_specs default_csv_output_spec = {
.spec_cnt = 14,
.ids = {