Lines Matching +full:enum +full:- +full:cnt +full:- +full:name
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
39 enum stat_id {
57 NUM_STATS_CNT = FILE_NAME - VERDICT,
61 * - A side value;
62 * - B side value;
63 * - absolute diff value;
64 * - relative (percentage) diff value.
69 * - `_a` for A side value;
70 * - `_b` for B side value;
71 * - `_diff` for absolute diff value;
72 * - `_pct` for relative (percentage) diff value.
79 * --------- --------- --------------
80 * 21547 20920 -627 (-2.91%)
83 * - 21547 is A side value (insns_a);
84 * - 20920 is B side value (insns_b);
85 * - -627 is absolute diff value (insns_diff);
86 * - -2.91% is relative diff value (insns_pct).
89 * For file and program name, _a and _b variants are equivalent and there are
92 enum stat_variant {
117 enum stat_id ids[ALL_STATS_CNT];
118 enum stat_variant variants[ALL_STATS_CNT];
124 enum resfmt {
126 RESFMT_TABLE_CALCLEN, /* fake format to pre-calculate table's column widths */
130 enum filter_kind {
135 enum operator_kind {
145 enum filter_kind kind;
151 enum operator_kind op;
153 enum stat_variant stat_var;
159 char *name; member
160 enum { INTEGRAL, ENUMERATOR } type;
176 enum resfmt out_fmt;
213 static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) in libbpf_print_fn()
231 "USAGE: veristat <obj-file> [<obj-file>...]\n"
232 " OR: veristat -C <baseline.csv> <comparison.csv>\n"
233 " OR: veristat -R <results.csv>\n"
234 " OR: veristat -vl2 <to_analyze.bpf.o>\n";
236 enum {
246 …{ "log-level", 'l', "LEVEL", 0, "Verifier log level (default 0 for normal mode, 1 for verbose mode…
247 { "log-fixed", OPT_LOG_FIXED, NULL, 0, "Disable verifier log rotation" },
248 { "log-size", OPT_LOG_SIZE, "BYTES", 0, "Customize verifier log size (default to 16MB)" },
249 { "top-n", 'n', "N", 0, "Emit only up to first N results." },
253 { "output-format", 'o', "FMT", 0, "Result output format (table, csv), default is table." },
257 { "test-states", 't', NULL, 0,
259 { "test-reg-invariants", 'r', NULL, 0,
261 { "top-src-lines", 'S', "N", 0, "Emit N most frequent source code lines" },
262 …{ "set-global-vars", 'G', "GLOBAL", 0, "Set global variables provided in the expression, for examp…
267 static int append_filter(struct filter **filters, int *cnt, const char *str);
269 static int append_var_preset(struct var_preset **presets, int *cnt, const char *expr);
312 return -EINVAL; in parse_arg()
431 int fd, err = -EINVAL; in is_bpf_obj_file()
450 if (!ehdr || ehdr->e_type != ET_REL || (ehdr->e_machine && ehdr->e_machine != EM_BPF)) in is_bpf_obj_file()
468 if (f->kind != FILTER_NAME) in should_process_file_prog()
471 if (f->any_glob && glob_matches(filename, f->any_glob)) in should_process_file_prog()
473 if (f->any_glob && prog_name && glob_matches(prog_name, f->any_glob)) in should_process_file_prog()
475 if (f->file_glob && glob_matches(filename, f->file_glob)) in should_process_file_prog()
477 if (f->prog_glob && prog_name && glob_matches(prog_name, f->prog_glob)) in should_process_file_prog()
483 if (f->kind != FILTER_NAME) in should_process_file_prog()
487 if (f->any_glob) { in should_process_file_prog()
488 if (glob_matches(filename, f->any_glob)) in should_process_file_prog()
490 /* If we don't know program name yet, any_glob filter in should_process_file_prog()
493 * BPF object file, at which point program name will in should_process_file_prog()
496 if (!prog_name || glob_matches(prog_name, f->any_glob)) in should_process_file_prog()
499 if (f->file_glob && !glob_matches(filename, f->file_glob)) in should_process_file_prog()
501 if (f->prog_glob && prog_name && !glob_matches(prog_name, f->prog_glob)) in should_process_file_prog()
507 /* if there are no file/prog name allow filters, allow all progs, in should_process_file_prog()
514 enum operator_kind op_kind;
531 static bool parse_stat_id_var(const char *name, size_t len, int *id,
532 enum stat_variant *var, bool *is_abs);
534 static int append_filter(struct filter **filters, int *cnt, const char *str) in append_filter() argument
541 tmp = realloc(*filters, (*cnt + 1) * sizeof(**filters)); in append_filter()
543 return -ENOMEM; in append_filter()
546 f = &(*filters)[*cnt]; in append_filter()
551 * - <stat> is one of supported numerical stats (verdict is also in append_filter()
553 * - <op> is comparison operator (see `operators` definitions); in append_filter()
554 * - <value> is an integer (or failure/success, or false/true as in append_filter()
560 enum stat_variant var; in append_filter()
572 if (!parse_stat_id_var(str, p - str, &id, &var, &is_abs)) { in append_filter()
573 fprintf(stderr, "Unrecognized stat name in '%s'!\n", str); in append_filter()
574 return -EINVAL; in append_filter()
577 fprintf(stderr, "Non-integer stat is specified in '%s'!\n", str); in append_filter()
578 return -EINVAL; in append_filter()
603 return -EINVAL; in append_filter()
607 f->kind = FILTER_STAT; in append_filter()
608 f->stat_id = id; in append_filter()
609 f->stat_var = var; in append_filter()
610 f->op = operators[i].op_kind; in append_filter()
611 f->abs = true; in append_filter()
612 f->value = val; in append_filter()
614 *cnt += 1; in append_filter()
619 * '<file-glob>/<prog-glob>'. In the former case <glob> is applied to in append_filter()
621 * practice. If user needs full control, they can use '/<prog-glob>' in append_filter()
622 * form to glob just program name, or '<file-glob>/' to glob only file in append_filter()
623 * name. But usually common <glob> seems to be the most useful and in append_filter()
626 f->kind = FILTER_NAME; in append_filter()
629 f->any_glob = strdup(str); in append_filter()
630 if (!f->any_glob) in append_filter()
631 return -ENOMEM; in append_filter()
634 /* non-empty file glob */ in append_filter()
635 f->file_glob = strndup(str, p - str); in append_filter()
636 if (!f->file_glob) in append_filter()
637 return -ENOMEM; in append_filter()
640 /* non-empty prog glob */ in append_filter()
641 f->prog_glob = strdup(p + 1); in append_filter()
642 if (!f->prog_glob) { in append_filter()
643 free(f->file_glob); in append_filter()
644 f->file_glob = NULL; in append_filter()
645 return -ENOMEM; in append_filter()
650 *cnt += 1; in append_filter()
662 err = -errno; in append_filter_file()
663 fprintf(stderr, "Failed to open filters in '%s': %s\n", path, strerror(-err)); in append_filter_file()
699 return -ENOMEM; in append_file()
703 return -ENOMEM; in append_file()
716 err = -errno; in append_file_from_file()
786 static bool parse_stat_id_var(const char *name, size_t len, int *id, in parse_stat_id_var() argument
787 enum stat_variant *var, bool *is_abs) in parse_stat_id_var()
799 if (len > 2 && name[0] == '|' && name[len - 1] == '|') { in parse_stat_id_var()
801 name += 1; in parse_stat_id_var()
802 len -= 2; in parse_stat_id_var()
811 alias = def->names[j]; in parse_stat_id_var()
816 if (strncmp(name, alias, alias_len) != 0) in parse_stat_id_var()
823 * non-comparison mode. in parse_stat_id_var()
835 if (strncmp(name + alias_len, var_sfxs[k], sfx_len) == 0) { in parse_stat_id_var()
836 *var = (enum stat_variant)k; in parse_stat_id_var()
862 enum stat_variant var; in parse_stat()
864 if (specs->spec_cnt >= ARRAY_SIZE(specs->ids)) { in parse_stat()
865 fprintf(stderr, "Can't specify more than %zd stats\n", ARRAY_SIZE(specs->ids)); in parse_stat()
866 return -E2BIG; in parse_stat()
869 if (len > 1 && (is_asc_sym(stat_name[len - 1]) || is_desc_sym(stat_name[len - 1]))) { in parse_stat()
871 is_asc = is_asc_sym(stat_name[len - 1]); in parse_stat()
872 len -= 1; in parse_stat()
876 fprintf(stderr, "Unrecognized stat name '%s'\n", stat_name); in parse_stat()
877 return -ESRCH; in parse_stat()
880 specs->ids[specs->spec_cnt] = id; in parse_stat()
881 specs->variants[specs->spec_cnt] = var; in parse_stat()
882 specs->asc[specs->spec_cnt] = has_order ? is_asc : stat_defs[id].asc_by_default; in parse_stat()
883 specs->abs[specs->spec_cnt] = is_abs; in parse_stat()
884 specs->spec_cnt++; in parse_stat()
892 int err, cnt = 0; in parse_stats() local
896 return -ENOMEM; in parse_stats()
898 while ((next = strtok_r(cnt++ ? NULL : input, ",", &state))) { in parse_stats()
931 int pos, lines, sub_stack, cnt = 0; in parse_verif_log() local
934 buf[buf_sz - 1] = '\0'; in parse_verif_log()
936 for (pos = strlen(buf) - 1, lines = 0; pos >= 0 && lines < MAX_PARSED_LOG_LINES; lines++) { in parse_verif_log()
938 for (cur = &buf[pos]; cur > buf && cur[0] != '\n'; cur--, pos--) { in parse_verif_log()
941 pos--; in parse_verif_log()
948 if (1 == sscanf(cur, "verification time %ld usec\n", &s->stats[DURATION])) in parse_verif_log()
951 &s->stats[TOTAL_INSNS], in parse_verif_log()
952 &s->stats[MAX_STATES_PER_INSN], in parse_verif_log()
953 &s->stats[TOTAL_STATES], in parse_verif_log()
954 &s->stats[PEAK_STATES], in parse_verif_log()
955 &s->stats[MARK_READ_MAX_LEN])) in parse_verif_log()
961 while ((token = strtok_r(cnt++ ? NULL : stack, "+", &state))) { in parse_verif_log()
964 s->stats[STACK] += sub_stack; in parse_verif_log()
971 int cnt; member
987 if (a_cnt->cnt != b_cnt->cnt) in line_cnt_cmp()
988 return a_cnt->cnt > b_cnt->cnt ? -1 : 1; in line_cnt_cmp()
989 return strcmp(a_cnt->line, b_cnt->line); in line_cnt_cmp()
1016 err = -ENOMEM; in print_top_src_lines()
1032 err = -ENOMEM; in print_top_src_lines()
1037 cur->line = lines[0]; in print_top_src_lines()
1038 cur->cnt = 1; in print_top_src_lines()
1040 if (strcmp(lines[i], cur->line) != 0) { in print_top_src_lines()
1042 cur->line = lines[i]; in print_top_src_lines()
1043 cur->cnt = 0; in print_top_src_lines()
1045 cur->cnt++; in print_top_src_lines()
1047 unique_lines = cur - freq + 1; in print_top_src_lines()
1064 split--; in print_top_src_lines()
1069 printf("%5d: (%s)\t%s\n", freq[i].cnt, src_line, src_code); in print_top_src_lines()
1071 printf("%5d: %s\n", freq[i].cnt, src_code); in print_top_src_lines()
1082 enum bpf_prog_type *prog_type, in guess_prog_type_by_ctx_name()
1083 enum bpf_attach_type *attach_type) in guess_prog_type_by_ctx_name()
1090 * Just in case, we support both UAPI-side type names and in guess_prog_type_by_ctx_name()
1091 * kernel-internal names. in guess_prog_type_by_ctx_name()
1096 enum bpf_prog_type prog_type; in guess_prog_type_by_ctx_name()
1097 enum bpf_attach_type attach_type; in guess_prog_type_by_ctx_name()
1115 * to match on that, probably; so NULL for kern-side type in guess_prog_type_by_ctx_name()
1122 return -EINVAL; in guess_prog_type_by_ctx_name()
1133 return -ESRCH; in guess_prog_type_by_ctx_name()
1159 mt = btf__type_by_id(btf, m->type); in mask_unrelated_struct_ops_progs()
1162 moff = m->offset / 8; in mask_unrelated_struct_ops_progs()
1203 enum bpf_prog_type prog_type; in fixup_obj()
1204 enum bpf_attach_type attach_type; in fixup_obj()
1214 t = btf__type_by_id(btf, t->type); in fixup_obj()
1221 t = btf__type_by_id(btf, t->type); in fixup_obj()
1224 t = btf__type_by_id(btf, t->type); in fixup_obj()
1226 t = btf__type_by_id(btf, t->type); in fixup_obj()
1230 ctx_name = btf__name_by_offset(btf, t->name_off); in fixup_obj()
1243 …fprintf(stderr, "Failed to guess program type for freplace program with context type name '%s' for… in fixup_obj()
1262 .log_buf = (void *)-1, in max_verifier_log_size()
1273 if (ret == -EFAULT) in max_verifier_log_size()
1275 else /* ret == -EINVAL, big log size is not supported by the verifier */ in max_verifier_log_size()
1301 return -ENOMEM; in process_prog()
1310 return -ENOMEM; in process_prog()
1313 /* --top-src-lines needs verifier log */ in process_prog()
1338 stats->file_name = strdup(base_filename); in process_prog()
1339 stats->prog_name = strdup(bpf_program__name(prog)); in process_prog()
1340 stats->stats[VERDICT] = err == 0; /* 1 - success, 0 - failure */ in process_prog()
1341 stats->stats[SIZE] = bpf_program__insn_cnt(prog); in process_prog()
1342 stats->stats[PROG_TYPE] = bpf_program__type(prog); in process_prog()
1343 stats->stats[ATTACH_TYPE] = bpf_program__expected_attach_type(prog); in process_prog()
1348 stats->stats[JITED_SIZE] = info.jited_prog_len; in process_prog()
1354 filename, prog_name, stats->stats[DURATION], in process_prog()
1358 print_top_src_lines(buf, buf_sz, stats->prog_name); in process_prog()
1366 static int append_var_preset(struct var_preset **presets, int *cnt, const char *expr) in append_var_preset() argument
1374 tmp = realloc(*presets, (*cnt + 1) * sizeof(**presets)); in append_var_preset()
1376 return -ENOMEM; in append_var_preset()
1378 cur = &(*presets)[*cnt]; in append_var_preset()
1380 (*cnt)++; in append_var_preset()
1384 return -EINVAL; in append_var_preset()
1387 if (val[0] == '-' || isdigit(val[0])) { in append_var_preset()
1397 return -EINVAL; in append_var_preset()
1399 cur->ivalue = value; in append_var_preset()
1400 cur->type = INTEGRAL; in append_var_preset()
1402 /* if not a number, consider it enum value */ in append_var_preset()
1403 cur->svalue = strdup(val); in append_var_preset()
1404 if (!cur->svalue) in append_var_preset()
1405 return -ENOMEM; in append_var_preset()
1406 cur->type = ENUMERATOR; in append_var_preset()
1409 cur->name = strdup(var); in append_var_preset()
1410 if (!cur->name) in append_var_preset()
1411 return -ENOMEM; in append_var_preset()
1424 err = -errno; in append_var_preset_file()
1425 fprintf(stderr, "Failed to open presets in '%s': %s\n", filename, strerror(-err)); in append_var_preset_file()
1426 return -EINVAL; in append_var_preset_file()
1460 const char *cur_name = btf__name_by_offset(btf, e->name_off); in enum_value_from_name()
1463 *retval = e->val; in enum_value_from_name()
1472 const char *cur_name = btf__name_by_offset(btf, e->name_off); in enum_value_from_name()
1481 return -EINVAL; in enum_value_from_name()
1495 long long value = preset->ivalue; in set_global_var()
1498 base_type = btf__type_by_id(btf, btf__resolve_type(btf, t->type)); in set_global_var()
1500 fprintf(stderr, "Failed to resolve type %d\n", t->type); in set_global_var()
1501 return -EINVAL; in set_global_var()
1505 btf__name_by_offset(btf, base_type->name_off)); in set_global_var()
1506 return -EINVAL; in set_global_var()
1509 if (preset->type == ENUMERATOR) { in set_global_var()
1511 if (enum_value_from_name(btf, base_type, preset->svalue, &value)) { in set_global_var()
1513 "Failed to find integer value for enum element %s\n", in set_global_var()
1514 preset->svalue); in set_global_var()
1515 return -EINVAL; in set_global_var()
1519 preset->svalue, btf__name_by_offset(btf, base_type->name_off)); in set_global_var()
1520 return -EINVAL; in set_global_var()
1525 if (sinfo->size < sizeof(value)) { in set_global_var()
1527 __u32 unsigned_bits = sinfo->size * 8 - (is_signed ? 1 : 0); in set_global_var()
1530 if (value >= max_val || value < -max_val) { in set_global_var()
1533 btf__name_by_offset(btf, t->name_off), value, in set_global_var()
1534 is_signed ? -max_val : 0, max_val - 1); in set_global_var()
1535 return -EINVAL; in set_global_var()
1540 if (!ptr || sinfo->offset + sinfo->size > size) in set_global_var()
1541 return -EINVAL; in set_global_var()
1544 memcpy(ptr + sinfo->offset, &value, sinfo->size); in set_global_var()
1546 __u8 src_offset = sizeof(value) - sinfo->size; in set_global_var()
1548 memcpy(ptr + sinfo->offset, (void *)&value + src_offset, sinfo->size); in set_global_var()
1560 int i, j, k, n, cnt, err = 0; in set_global_vars() local
1567 return -EINVAL; in set_global_vars()
1569 cnt = btf__type_cnt(btf); in set_global_vars()
1570 for (i = 1; i != cnt; ++i) { in set_global_vars()
1577 sec_name = btf__name_by_offset(btf, t->name_off); in set_global_vars()
1584 const struct btf_type *var_type = btf__type_by_id(btf, sinfo->type); in set_global_vars()
1590 var_name = btf__name_by_offset(btf, var_type->name_off); in set_global_vars()
1593 if (strcmp(var_name, presets[k].name) != 0) in set_global_vars()
1599 return -EINVAL; in set_global_vars()
1614 presets[i].name); in set_global_vars()
1655 fprintf(stderr, "Failed to open '%s': %d\n", filename, -errno); in process_obj()
1684 err = -errno; in process_obj()
1718 enum stat_id id, bool asc, bool abs) in cmp_stat()
1724 cmp = strcmp(s1->file_name, s2->file_name); in cmp_stat()
1727 cmp = strcmp(s1->prog_name, s2->prog_name); in cmp_stat()
1741 long v1 = s1->stats[id]; in cmp_stat()
1742 long v2 = s2->stats[id]; in cmp_stat()
1745 v1 = v1 < 0 ? -v1 : v1; in cmp_stat()
1746 v2 = v2 < 0 ? -v2 : v2; in cmp_stat()
1750 cmp = v1 < v2 ? -1 : 1; in cmp_stat()
1758 return asc ? cmp : -cmp; in cmp_stat()
1774 cmp = strcmp(s1->file_name, s2->file_name); in cmp_prog_stats()
1777 return strcmp(s1->prog_name, s2->prog_name); in cmp_prog_stats()
1781 enum stat_id id, enum stat_variant var, in fetch_join_stat_value()
1788 *str_val = s->file_name; in fetch_join_stat_value()
1792 *str_val = s->prog_name; in fetch_join_stat_value()
1796 v1 = s->stats_a ? s->stats_a->stats[id] : 0; in fetch_join_stat_value()
1797 v2 = s->stats_b ? s->stats_b->stats[id] : 0; in fetch_join_stat_value()
1801 if (!s->stats_a) in fetch_join_stat_value()
1802 *num_val = -DBL_MAX; in fetch_join_stat_value()
1804 *num_val = s->stats_a->stats[id]; in fetch_join_stat_value()
1807 if (!s->stats_b) in fetch_join_stat_value()
1808 *num_val = -DBL_MAX; in fetch_join_stat_value()
1810 *num_val = s->stats_b->stats[id]; in fetch_join_stat_value()
1813 if (!s->stats_a || !s->stats_b) in fetch_join_stat_value()
1814 *num_val = -DBL_MAX; in fetch_join_stat_value()
1818 *num_val = (double)(v2 - v1); in fetch_join_stat_value()
1821 if (!s->stats_a || !s->stats_b) { in fetch_join_stat_value()
1822 *num_val = -DBL_MAX; in fetch_join_stat_value()
1827 *num_val = v2 < v1 ? -100.0 : 100.0; in fetch_join_stat_value()
1829 *num_val = (v2 - v1) * 100.0 / v1; in fetch_join_stat_value()
1837 enum stat_id id, enum stat_variant var, in cmp_join_stat()
1855 cmp = v1 < v2 ? -1 : 1; in cmp_join_stat()
1857 return asc ? cmp : -cmp; in cmp_join_stat()
1876 cmp = strcmp(s1->file_name, s2->file_name); in cmp_join_stats()
1879 return strcmp(s1->prog_name, s2->prog_name); in cmp_join_stats()
1882 #define HEADER_CHAR '-'
1899 static void output_headers(enum resfmt fmt) in output_headers()
1915 fmt_str = stat_defs[id].left_aligned ? "%s%-*s" : "%s%*s"; in output_headers()
1917 if (i == env.output_spec.spec_cnt - 1) in output_headers()
1922 if (i == env.output_spec.spec_cnt - 1) in output_headers()
1932 static void prepare_value(const struct verif_stats *s, enum stat_id id, in prepare_value()
1937 *str = s ? s->file_name : "N/A"; in prepare_value()
1940 *str = s ? s->prog_name : "N/A"; in prepare_value()
1946 *str = s->stats[VERDICT] ? "success" : "failure"; in prepare_value()
1952 *str = libbpf_bpf_attach_type_str(s->stats[ATTACH_TYPE]) ?: "N/A"; in prepare_value()
1958 *str = libbpf_bpf_prog_type_str(s->stats[PROG_TYPE]) ?: "N/A"; in prepare_value()
1969 *val = s ? s->stats[id] : 0; in prepare_value()
1977 static void output_stats(const struct verif_stats *s, enum resfmt fmt, bool last) in output_stats()
2000 printf("%s%-*s", i == 0 ? "" : COLUMN_SEP, *max_len, str); in output_stats()
2003 if (i == env.output_spec.spec_cnt - 1) in output_stats()
2011 if (i == env.output_spec.spec_cnt - 1) in output_stats()
2024 static int parse_stat_value(const char *str, enum stat_id id, struct verif_stats *st) in parse_stat_value()
2028 st->file_name = strdup(str); in parse_stat_value()
2029 if (!st->file_name) in parse_stat_value()
2030 return -ENOMEM; in parse_stat_value()
2033 st->prog_name = strdup(str); in parse_stat_value()
2034 if (!st->prog_name) in parse_stat_value()
2035 return -ENOMEM; in parse_stat_value()
2039 st->stats[VERDICT] = true; in parse_stat_value()
2041 st->stats[VERDICT] = false; in parse_stat_value()
2044 return -EINVAL; in parse_stat_value()
2060 err = -errno; in parse_stat_value()
2065 st->stats[id] = val; in parse_stat_value()
2069 enum bpf_prog_type prog_type = 0; in parse_stat_value()
2074 st->stats[id] = prog_type; in parse_stat_value()
2082 return -EINVAL; in parse_stat_value()
2087 enum bpf_attach_type attach_type = 0; in parse_stat_value()
2092 st->stats[id] = attach_type; in parse_stat_value()
2100 return -EINVAL; in parse_stat_value()
2106 return -EINVAL; in parse_stat_value()
2121 err = -errno; in parse_stats_csv()
2131 int col = 0, cnt = 0; in parse_stats_csv() local
2138 err = -ENOMEM; in parse_stats_csv()
2149 while ((next = strtok_r(cnt++ ? NULL : input, ",\n", &state))) { in parse_stats_csv()
2159 if (col >= specs->spec_cnt) { in parse_stats_csv()
2162 err = -EINVAL; in parse_stats_csv()
2165 err = parse_stat_value(next, specs->ids[col], st); in parse_stats_csv()
2176 if (col < specs->spec_cnt) { in parse_stats_csv()
2179 err = -EINVAL; in parse_stats_csv()
2183 if (!st->file_name || !st->prog_name) { in parse_stats_csv()
2184 fprintf(stderr, "Row #%d in '%s' is missing file and/or program name\n", in parse_stats_csv()
2186 err = -EINVAL; in parse_stats_csv()
2194 if (!should_process_file_prog(st->file_name, st->prog_name)) { in parse_stats_csv()
2195 free(st->file_name); in parse_stats_csv()
2196 free(st->prog_name); in parse_stats_csv()
2197 *stat_cntp -= 1; in parse_stats_csv()
2202 err = -errno; in parse_stats_csv()
2214 static bool is_key_stat(enum stat_id id) in is_key_stat()
2239 static void output_comp_headers(enum resfmt fmt) in output_comp_headers()
2252 bool last = (i == env.output_spec.spec_cnt - 1) && (j == max_j - 1); in output_comp_headers()
2264 printf("%s%-*s%s", i + j == 0 ? "" : COLUMN_SEP, in output_comp_headers()
2265 *max_len - (int)strlen(sfx), stat_defs[id].header, sfx); in output_comp_headers()
2284 enum resfmt fmt, bool last) in output_comp_stats()
2286 const struct verif_stats *base = join_stats->stats_a; in output_comp_stats()
2287 const struct verif_stats *comp = join_stats->stats_b; in output_comp_stats()
2304 /* key stats (file and program name) are always strings */ in output_comp_stats()
2330 diff_val = comp_val - base_val; in output_comp_stats()
2338 p = comp_val < base_val ? -100.0 : 100.0; in output_comp_stats()
2361 /* string outputs are left-aligned, number outputs are right-aligned */ in output_comp_stats()
2362 const char *fmt = base_str ? "%s%-*s" : "%s%*s"; in output_comp_stats()
2369 if (i == env.output_spec.spec_cnt - 1) in output_comp_stats()
2379 if (i == env.output_spec.spec_cnt - 1) in output_comp_stats()
2393 r = strcmp(base->file_name, comp->file_name); in cmp_stats_key()
2396 return strcmp(base->prog_name, comp->prog_name); in cmp_stats_key()
2401 static const double eps = 1e-9; in is_join_stat_filter_matched()
2405 fetch_join_stat_value(stats, f->stat_id, f->stat_var, &str, &value); in is_join_stat_filter_matched()
2407 if (f->abs) in is_join_stat_filter_matched()
2410 switch (f->op) { in is_join_stat_filter_matched()
2411 case OP_EQ: return value > f->value - eps && value < f->value + eps; in is_join_stat_filter_matched()
2412 case OP_NEQ: return value < f->value - eps || value > f->value + eps; in is_join_stat_filter_matched()
2413 case OP_LT: return value < f->value - eps; in is_join_stat_filter_matched()
2414 case OP_LE: return value <= f->value + eps; in is_join_stat_filter_matched()
2415 case OP_GT: return value > f->value + eps; in is_join_stat_filter_matched()
2416 case OP_GE: return value >= f->value - eps; in is_join_stat_filter_matched()
2419 fprintf(stderr, "BUG: unknown filter op %d!\n", f->op); in is_join_stat_filter_matched()
2430 if (f->kind != FILTER_STAT) in should_output_join_stats()
2439 if (f->kind != FILTER_STAT) in should_output_join_stats()
2455 enum resfmt cur_fmt; in handle_comparison_mode()
2456 int err, i, j, last_idx, cnt; in handle_comparison_mode() local
2461 return -EINVAL; in handle_comparison_mode()
2479 * pre-processing later. in handle_comparison_mode()
2485 return -EINVAL; in handle_comparison_mode()
2493 return -EINVAL; in handle_comparison_mode()
2497 /* Replace user-specified sorting spec with file+prog sorting rule to in handle_comparison_mode()
2522 if (!base->file_name || !base->prog_name) { in handle_comparison_mode()
2523 fprintf(stderr, "Entry #%d in '%s' doesn't have file and/or program name specified!\n", in handle_comparison_mode()
2525 return -EINVAL; in handle_comparison_mode()
2527 if (!comp->file_name || !comp->prog_name) { in handle_comparison_mode()
2528 fprintf(stderr, "Entry #%d in '%s' doesn't have file and/or program name specified!\n", in handle_comparison_mode()
2530 return -EINVAL; in handle_comparison_mode()
2535 return -ENOMEM; in handle_comparison_mode()
2543 join->file_name = base->file_name; in handle_comparison_mode()
2544 join->prog_name = base->prog_name; in handle_comparison_mode()
2545 join->stats_a = base; in handle_comparison_mode()
2546 join->stats_b = comp; in handle_comparison_mode()
2550 join->file_name = base->file_name; in handle_comparison_mode()
2551 join->prog_name = base->prog_name; in handle_comparison_mode()
2552 join->stats_a = base; in handle_comparison_mode()
2553 join->stats_b = NULL; in handle_comparison_mode()
2556 join->file_name = comp->file_name; in handle_comparison_mode()
2557 join->prog_name = comp->prog_name; in handle_comparison_mode()
2558 join->stats_a = NULL; in handle_comparison_mode()
2559 join->stats_b = comp; in handle_comparison_mode()
2564 return -EINVAL; in handle_comparison_mode()
2572 /* for human-readable table output we need to do extra pass to in handle_comparison_mode()
2585 last_idx = -1; in handle_comparison_mode()
2586 cnt = 0; in handle_comparison_mode()
2593 if (env.top_n && cnt >= env.top_n) in handle_comparison_mode()
2601 cnt++; in handle_comparison_mode()
2614 long value = stats->stats[f->stat_id]; in is_stat_filter_matched()
2616 if (f->abs) in is_stat_filter_matched()
2617 value = value < 0 ? -value : value; in is_stat_filter_matched()
2619 switch (f->op) { in is_stat_filter_matched()
2620 case OP_EQ: return value == f->value; in is_stat_filter_matched()
2621 case OP_NEQ: return value != f->value; in is_stat_filter_matched()
2622 case OP_LT: return value < f->value; in is_stat_filter_matched()
2623 case OP_LE: return value <= f->value; in is_stat_filter_matched()
2624 case OP_GT: return value > f->value; in is_stat_filter_matched()
2625 case OP_GE: return value >= f->value; in is_stat_filter_matched()
2628 fprintf(stderr, "BUG: unknown filter op %d!\n", f->op); in is_stat_filter_matched()
2639 if (f->kind != FILTER_STAT) in should_output_stats()
2648 if (f->kind != FILTER_STAT) in should_output_stats()
2663 int i, last_stat_idx = 0, cnt = 0; in output_prog_stats() local
2683 if (env.top_n && cnt >= env.top_n) in output_prog_stats()
2686 cnt++; in output_prog_stats()
2697 return -EINVAL; in handle_verif_mode()
2723 return -EINVAL; in handle_replay_mode()
2801 free(env.presets[i].name); in main()
2806 return -err; in main()