Fix issue with creating vec of pointer type ##util

This was due to the weird position of const in (pointer) types, combined
with macro-expansion. Putting const after the type in the macro
generates the correct code.
This commit is contained in:
Luc Tielen 2023-08-11 11:26:30 +02:00 committed by pancake
parent bfd7c14914
commit 8a2732168e
2 changed files with 47 additions and 6 deletions

View File

@ -59,7 +59,7 @@ extern "C" {
* atleast a capacity of "new_capacity". Returns true on success, otherwise false.
* - void R_VEC_FUNC(vec_type, shrink_to_fit)(vec_type *vec): Shrinks the vector to exactly fit the
* current number of elements it contains.
* - void R_VEC_FUNC(vec_type, push_back)(vec_type *vec, const type *value): Appends a single element to
* - void R_VEC_FUNC(vec_type, push_back)(vec_type *vec, type const *value): Appends a single element to
* the end of the vector.
* - type *R_VEC_FUNC(vec_type, emplace_back)(vec_type *vec): Returns a pointer to a new uninitialized
* element at the back of the vector. The pointer must be filled with data afterwards, or it can lead to
@ -167,9 +167,9 @@ extern "C" {
type *_end; \
size_t _capacity; \
} vec_type; \
typedef void (*R_VEC_COPY(vec_type))(type *dst, const type *src); \
typedef int (*R_VEC_CMP(vec_type))(const type *a, const type *b); \
typedef int (*R_VEC_FIND_CMP(vec_type))(const type *a, const void *b); \
typedef void (*R_VEC_COPY(vec_type))(type *dst, type const *src); \
typedef int (*R_VEC_CMP(vec_type))(type const *a, type const *b); \
typedef int (*R_VEC_FIND_CMP(vec_type))(type const *a, const void *b); \
static inline R_MAYBE_UNUSED void R_VEC_FUNC(vec_type, init)(vec_type *vec) { \
r_return_if_fail (vec); \
memset (vec, 0, sizeof (vec_type)); \
@ -315,7 +315,7 @@ extern "C" {
} \
} \
} \
static inline R_MAYBE_UNUSED void R_VEC_FUNC(vec_type, push_back)(vec_type *vec, const type *value) { \
static inline R_MAYBE_UNUSED void R_VEC_FUNC(vec_type, push_back)(vec_type *vec, type const *value) { \
r_return_if_fail (vec && value); \
const ut64 num_elems = R_VEC_FUNC(vec_type, length) (vec); \
const ut64 capacity = R_VEC_CAPACITY (vec); \
@ -372,7 +372,7 @@ extern "C" {
R_VEC_FUNC(vec_type, reserve) (vec, total_count); \
} \
if (copy_fn) { \
const type *src; \
type const *src; \
R_VEC_FOREACH (values, src) { \
type *dst = R_VEC_FUNC(vec_type, emplace_back) (vec); \
copy_fn (dst, src); \

View File

@ -1122,6 +1122,46 @@ static bool test_vec_uniq(void) {
mu_end;
}
static inline void fini_buf(char** buf) {
if (buf) {
free (*buf);
}
}
// This is mainly to test there are no warnings when generating code for a vec containing pointers.
R_VEC_TYPE_WITH_FINI(RVecBuf, char*, fini_buf);
static int find_compare_buf(char *const *const buf, void const *user) {
char *const *const ptr = user;
if (*buf == *ptr) {
return 0;
}
return 1;
}
static bool test_vec_with_pointers(void) {
RVecBuf buf;
RVecBuf_init (&buf);
char *ptr = NULL;
mu_assert_eq (RVecBuf_find (&buf, &ptr, find_compare_buf), NULL, "pointer find1");
ut32 x = 0;
for (x = 0; x < 3; x++) {
ptr = malloc (8);
RVecBuf_push_back (&buf, &ptr);
}
ptr = malloc (8);
RVecBuf_push_back (&buf, &ptr);
char **ptr2 = RVecBuf_at (&buf, 3);
mu_assert_eq (RVecBuf_find (&buf, &ptr, find_compare_buf), ptr2, "pointer find2");
RVecBuf_fini (&buf);
mu_end;
}
static int all_tests(void) {
mu_run_test (test_vec_init);
mu_run_test (test_vec_fini);
@ -1157,6 +1197,7 @@ static int all_tests(void) {
mu_run_test (test_vec_partition);
mu_run_test (test_vec_sort);
mu_run_test (test_vec_uniq);
mu_run_test (test_vec_with_pointers);
return tests_passed != tests_run;
}