return q;
}
+void* greedy_realloc_append(
+ void **p,
+ size_t *n_p,
+ const void *from,
+ size_t n_from,
+ size_t size) {
+
+ uint8_t *q;
+
+ assert(p);
+ assert(n_p);
+ assert(from || n_from == 0);
+
+ if (n_from > SIZE_MAX - *n_p)
+ return NULL;
+
+ q = greedy_realloc(p, *n_p + n_from, size);
+ if (!q)
+ return NULL;
+
+ memcpy_safe(q + *n_p * size, from, n_from * size);
+
+ *n_p += n_from;
+
+ return q;
+}
+
void *expand_to_usable(void *ptr, size_t newsize _unused_) {
return ptr;
}
void* greedy_realloc(void **p, size_t need, size_t size);
void* greedy_realloc0(void **p, size_t need, size_t size);
+void* greedy_realloc_append(void **p, size_t *n_p, const void *from, size_t n_from, size_t size);
#define GREEDY_REALLOC(array, need) \
greedy_realloc((void**) &(array), (need), sizeof((array)[0]))
#define GREEDY_REALLOC0(array, need) \
greedy_realloc0((void**) &(array), (need), sizeof((array)[0]))
+#define GREEDY_REALLOC_APPEND(array, n_array, from, n_from) \
+ greedy_realloc_append((void**) &(array), (size_t*) &(n_array), (from), (n_from), sizeof((array)[0]))
+
#define alloca0(n) \
({ \
char *_new_; \
}
TEST(GREEDY_REALLOC) {
- _cleanup_free_ int *a = NULL, *b = NULL;
- size_t i, j;
+ _cleanup_free_ int *a = NULL, *b = NULL, *c = NULL;
+ size_t i, j, n_c = 0;
/* Give valgrind a chance to verify our realloc() operations */
for (j = 30; j < i / 2; j += 7)
assert_se(b[j] == (int) j);
+
+ size_t n_from = 10;
+ int from[n_from];
+ for (i = 0; i < 2048; i++) {
+ for (j = 0; j < n_from; j++)
+ from[j] = n_from * i + j;
+
+ _cleanup_free_ int *before = NULL;
+ size_t n_before = 0;
+ assert_se(GREEDY_REALLOC_APPEND(before, n_before, c, n_c));
+ assert_se(before);
+ assert_se(n_before == n_c);
+ assert_se(memcmp_safe(c, before, n_c) == 0);
+
+ assert_se(GREEDY_REALLOC_APPEND(c, n_c, from, n_from));
+ assert_se(n_c == n_before + n_from);
+ assert_se(MALLOC_ELEMENTSOF(c) >= n_c);
+ assert_se(MALLOC_SIZEOF_SAFE(c) >= n_c * sizeof(int));
+ assert_se(memcmp_safe(c, before, n_before) == 0);
+ assert_se(memcmp_safe(&c[n_before], from, n_from) == 0);
+
+ before = mfree(before);
+ assert_se(!before);
+ n_before = 0;
+ assert_se(GREEDY_REALLOC_APPEND(before, n_before, c, n_c));
+ assert_se(before);
+ assert_se(n_before == n_c);
+ assert_se(memcmp_safe(c, before, n_c) == 0);
+
+ assert_se(GREEDY_REALLOC_APPEND(c, n_c, NULL, 0));
+ assert_se(c);
+ assert_se(n_c == n_before);
+ assert_se(MALLOC_ELEMENTSOF(c) >= n_c);
+ assert_se(MALLOC_SIZEOF_SAFE(c) >= n_c * sizeof(int));
+ assert_se(memcmp_safe(c, before, n_c) == 0);
+ }
+
+ for (j = 0; j < i * n_from; j++)
+ assert_se(c[j] == (int) j);
}
TEST(memdup_multiply_and_greedy_realloc) {