#include "check-common.h"
static check_number_t check_base[] = {
{ "char", CTF_K_INTEGER, CTF_INT_SIGNED | CTF_INT_CHAR, 0, 8 },
{ "int", CTF_K_INTEGER, CTF_INT_SIGNED, 0, 32 },
{ "float", CTF_K_FLOAT, CTF_FP_SINGLE, 0, 32 },
{ NULL }
};
static check_symbol_t check_syms[] = {
{ "a", "int" },
{ "aa", "test_int_t" },
{ "b", "const short" },
{ "c", "volatile float" },
{ "d", "int *" },
{ "dd", "int **" },
{ "ddd", "int ***" },
{ "e", "test_int_t *" },
{ "ce", "const test_int_t *" },
{ "ve", "volatile test_int_t *" },
{ "cve", "const volatile test_int_t *" },
{ "f", "int *const *" },
{ "g", "const char *const" },
{ NULL },
};
static check_descent_t check_descent_aa[] = {
{ "test_int_t", CTF_K_TYPEDEF },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_b[] = {
{ "const short", CTF_K_CONST },
{ "short", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_c[] = {
{ "volatile float", CTF_K_VOLATILE },
{ "float", CTF_K_FLOAT },
{ NULL }
};
static check_descent_t check_descent_d[] = {
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_dd[] = {
{ "int **", CTF_K_POINTER },
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_ddd[] = {
{ "int ***", CTF_K_POINTER },
{ "int **", CTF_K_POINTER },
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_e[] = {
{ "test_int_t *", CTF_K_POINTER },
{ "test_int_t", CTF_K_TYPEDEF },
{ "int", CTF_K_INTEGER },
{ NULL },
};
static check_descent_t check_descent_ce[] = {
{ "const test_int_t *", CTF_K_POINTER },
{ "const test_int_t", CTF_K_CONST },
{ "test_int_t", CTF_K_TYPEDEF },
{ "int", CTF_K_INTEGER },
{ NULL },
};
static check_descent_t check_descent_ve[] = {
{ "volatile test_int_t *", CTF_K_POINTER},
{ "volatile test_int_t", CTF_K_VOLATILE },
{ "test_int_t", CTF_K_TYPEDEF },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_cve[] = {
{ "const volatile test_int_t *", CTF_K_POINTER },
{ "const volatile test_int_t", CTF_K_CONST },
{ "volatile test_int_t", CTF_K_VOLATILE },
{ "test_int_t", CTF_K_TYPEDEF },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_f[] = {
{ "int *const *", CTF_K_POINTER },
{ "int *const", CTF_K_CONST },
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_g[] = {
{ "const char *const", CTF_K_CONST },
{ "const char *", CTF_K_POINTER },
{ "const char", CTF_K_CONST },
{ "char", CTF_K_INTEGER },
{ NULL }
};
static check_descent_test_t descents[] = {
{ "aa", check_descent_aa },
{ "b", check_descent_b },
{ "c", check_descent_c },
{ "d", check_descent_d },
{ "dd", check_descent_dd },
{ "ddd", check_descent_ddd },
{ "e", check_descent_e },
{ "ce", check_descent_ce },
{ "ve", check_descent_ve },
{ "cve", check_descent_cve },
{ "f", check_descent_f },
{ "g", check_descent_g },
{ NULL }
};
static check_descent_t check_descent_cvh_gcc4[] = {
{ "const volatile foo_t *", CTF_K_POINTER },
{ "const volatile foo_t", CTF_K_CONST },
{ "volatile foo_t", CTF_K_VOLATILE },
{ "foo_t", CTF_K_TYPEDEF },
{ "int *const *", CTF_K_POINTER },
{ "int *const", CTF_K_CONST },
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_t check_descent_cvh_gcc7[] = {
{ "volatile const foo_t *", CTF_K_POINTER },
{ "volatile const foo_t", CTF_K_VOLATILE },
{ "const foo_t", CTF_K_CONST },
{ "foo_t", CTF_K_TYPEDEF },
{ "int *const *", CTF_K_POINTER },
{ "int *const", CTF_K_CONST },
{ "int *", CTF_K_POINTER },
{ "int", CTF_K_INTEGER },
{ NULL }
};
static check_descent_test_t alt_descents[] = {
{ "cvh", check_descent_cvh_gcc4 },
{ "cvh", check_descent_cvh_gcc7 },
};
int
main(int argc, char *argv[])
{
int i, ret = 0;
if (argc < 2) {
errx(EXIT_FAILURE, "missing test files");
}
for (i = 1; i < argc; i++) {
ctf_file_t *fp;
int alt_ok = 0;
uint_t d;
if ((fp = ctf_open(argv[i], &ret)) == NULL) {
warnx("failed to open %s: %s", argv[i],
ctf_errmsg(ret));
ret = EXIT_FAILURE;
continue;
}
if (!ctftest_check_numbers(fp, check_base))
ret = EXIT_FAILURE;
if (!ctftest_check_symbols(fp, check_syms))
ret = EXIT_FAILURE;
for (d = 0; descents[d].cdt_sym != NULL; d++) {
if (!ctftest_check_descent(descents[d].cdt_sym, fp,
descents[d].cdt_tests, B_FALSE)) {
ret = EXIT_FAILURE;
}
}
for (d = 0; alt_descents[d].cdt_sym != NULL; d++) {
if (ctftest_check_descent(alt_descents[d].cdt_sym, fp,
alt_descents[d].cdt_tests, B_TRUE)) {
alt_ok = 1;
break;
}
}
if (!alt_ok) {
warnx("all descents failed for %s",
alt_descents[0].cdt_sym);
ret = EXIT_FAILURE;
}
ctf_close(fp);
}
return (ret);
}