capstone/suite/cstest/include/test_compare.h
2024-08-31 21:33:38 +08:00

231 lines
6.9 KiB
C

// Copyright © 2024 Rot127 <unisono@quyllur.org>
// SPDX-License-Identifier: BSD-3
#ifndef TEST_COMPARE_H
#define TEST_COMPARE_H
#include <stdint.h>
#include "test_mapping.h"
#include "../../../utils.h"
/// An integer encoding a boolean value from the test files.
/// libcyaml saves 0 by default, if an optional value was not set.
/// Due to that, boolean values are represented as integer with the
/// interpretation:
///
/// = 0 => unset
/// < 0 => false
/// > 0 => true
typedef int32_t tbool;
/// Compares the @actual bool against the @expected tbool:
/// It returns with @ret_val, if expected is set but the values mismatch.
#define compare_tbool_ret(actual, expected, ret_val) \
if (expected != 0 && \
((actual && expected <= 0) || (!actual && expected >= 0))) { \
fprintf(stderr, \
#actual " is %s but expected is %" PRId32 \
" (=0 unset, >0 true, <0 false)\n", \
actual ? "true" : "false", expected); \
return ret_val; \
}
/// Compares two unsigned int values.
/// It returns with @ret_val if they mismatch.
#define compare_uint_ret(actual, expected, ret_val) \
if (((unsigned int)actual) != ((unsigned int)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint8_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint8_ret(actual, expected, ret_val) \
if (((uint8_t)actual) != ((uint8_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId8 " != %" PRId8 \
"\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint16_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint16_ret(actual, expected, ret_val) \
if (((uint16_t)actual) != ((uint16_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx16 \
" != 0x%" PRIx16 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint32_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint32_ret(actual, expected, ret_val) \
if (((uint32_t)actual) != ((uint32_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two uint64_t values.
/// It returns with @ret_val if they mismatch.
#define compare_uint64_ret(actual, expected, ret_val) \
if (((uint64_t)actual) != ((uint64_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx64 \
" != 0x%" PRIx64 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int values.
/// It returns with @ret_val if they mismatch.
#define compare_int_ret(actual, expected, ret_val) \
if (((int)actual) != ((int)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int8_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int8_ret(actual, expected, ret_val) \
if (((int8_t)actual) != ((int8_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx8 " != 0x%" PRIx8 \
"\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int16_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int16_ret(actual, expected, ret_val) \
if (((int16_t)actual) != ((int16_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx16 \
" != 0x%" PRIx16 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int32_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int32_ret(actual, expected, ret_val) \
if (((int32_t)actual) != ((int32_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx32 \
" != 0x%" PRIx32 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two int64_t values.
/// It returns with @ret_val if they mismatch.
#define compare_int64_ret(actual, expected, ret_val) \
if (((int64_t)actual) != ((int64_t)expected)) { \
fprintf(stderr, \
#actual " != " #expected ": 0x%" PRIx64 \
" != 0x%" PRIx64 "\n", \
actual, expected); \
return ret_val; \
}
/// Compares two floating point values.
/// It returns with @ret_val if they mismatch.
#define compare_fp_ret(actual, expected, ret_val) \
if (actual != expected) { \
fprintf(stderr, #actual " != " #expected ": %f != %f\n", \
actual, expected); \
return ret_val; \
}
/// Compares enum id.
/// Actual is the value, expected is the enum idetifer as string.
/// It returns with @ret_val if they mismatch.
#define compare_enum_ret(actual, expected, ret_val) \
if (expected) { \
bool found = false; \
uint32_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), expected, &found); \
if (expected && (actual != eval || !found)) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId32 \
" != %s%s\n", \
actual, expected, \
found ? "" : " <== id not found"); \
return ret_val; \
} \
}
/// Checks if all bit flags in @expected are set in @actual.
/// Actual is the value with all bits set.
/// @expected is a list the @len enum identifiers as string.
/// It returns with @ret_val if they mismatch.
#define compare_bit_flags_ret(actual, expected, len, ret_val) \
if (expected) { \
for (size_t cmp_i = 0; cmp_i < len; ++cmp_i) { \
bool found = false; \
uint32_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), \
expected[cmp_i], &found); \
if (!(actual & eval) || !found) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId32 \
" != %s%s\n", \
actual, expected[cmp_i], \
found ? " <== Flag not set" : \
" <== id not found"); \
return ret_val; \
} \
} \
}
/// Checks if all bit flags in @expected are set in @actual.
/// Actual is the value with all bits set.
/// @expected is a list the @len enum identifiers as string.
/// It returns with @ret_val if they mismatch.
#define compare_bit_flags_64_ret(actual, expected, len, ret_val) \
if (expected) { \
for (size_t cmp_i = 0; cmp_i < len; ++cmp_i) { \
bool found = false; \
uint64_t eval = enum_map_bin_search( \
cs_enum_map, ARR_SIZE(cs_enum_map), \
expected[cmp_i], &found); \
if (!(actual & eval) || !found) { \
fprintf(stderr, \
#actual " != " #expected ": %" PRId64 \
" != %s%s\n", \
actual, expected[cmp_i], \
found ? " <== Flag not set" : \
" <== id not found"); \
return ret_val; \
} \
} \
}
/// Compares register names.
/// Actual is the register id, expected is name as string.
/// It returns with @ret_val if they mismatch.
#define compare_reg_ret(handle, actual, expected, ret_val) \
if (expected) { \
const char *reg_name = cs_reg_name(handle, actual); \
if (expected && !strings_match(reg_name, expected)) { \
fprintf(stderr, \
#actual " != " #expected ": '%s' != '%s'\n", \
reg_name, expected); \
return ret_val; \
} \
}
#endif // TEST_COMPARE_H