diff options
Diffstat (limited to 'vmemalloc.c')
| -rw-r--r-- | vmemalloc.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/vmemalloc.c b/vmemalloc.c index d725374..72e65d2 100644 --- a/vmemalloc.c +++ b/vmemalloc.c @@ -8,8 +8,8 @@ struct memalloc_state { size_t alignment; size_t elem_size; size_t size_prod; - char zero_init; - char if_zero; + signed char zero_init; + signed char if_zero; char round_up_size; char have_size; char cache_align; @@ -18,14 +18,16 @@ struct memalloc_state { }; static int -vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list ap) +vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va_list ap, size_t *ap_advance_out) { + *ap_advance_out = 0; if (state->have_size++) goto inval; state->elem_size = arg; if (n) { while (--n) { arg = va_arg(ap, size_t); + ++*ap_advance_out; if (!state->elem_size) continue; if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) { @@ -38,6 +40,7 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va goto inval; for (;;) { arg = va_arg(ap, size_t); + ++*ap_advance_out; if (!arg) break; if (LIBSIMPLE_UMUL_OVERFLOW_NONZERO(arg, state->elem_size, &state->elem_size, SIZE_MAX)) { @@ -46,7 +49,6 @@ vmemalloc_parse_size_prod(struct memalloc_state *state, size_t n, size_t arg, va } } } - return 0; inval: errno = EINVAL; @@ -58,8 +60,8 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap) { enum libsimple_memalloc_option opt; long int page_size; - va_list *subapp; - size_t arg; + va_list *subap, ap_copy; + size_t arg, ap_advance; for (;;) { opt = va_arg(ap, enum libsimple_memalloc_option); @@ -129,27 +131,31 @@ vmemalloc_parse_args(struct memalloc_state *state, size_t n, va_list ap) case LIBSIMPLE_MEMALLOC_PRODUCT_SIZE: arg = va_arg(ap, size_t); - if (vmemalloc_parse_size_prod(state, n, arg, ap)) + va_copy(ap_copy, ap); + if (vmemalloc_parse_size_prod(state, n, arg, ap_copy, &ap_advance)) return -1; + va_end(ap_copy); + while (ap_advance--) + (void) va_arg(ap, size_t); break; case LIBSIMPLE_MEMALLOC_VA_PRODUCT_SIZE: - subapp = va_arg(ap, va_list *); - arg = va_arg(*subapp, size_t); - if (vmemalloc_parse_size_prod(state, n, arg, *subapp)) + subap = va_arg(ap, va_list *); + arg = va_arg(*subap, size_t); + if (vmemalloc_parse_size_prod(state, n, arg, *subap, &ap_advance)) return -1; break; case LIBSIMPLE_MEMALLOC_1_VA_PRODUCT_SIZE: arg = va_arg(ap, size_t); - subapp = va_arg(ap, va_list *); - if (vmemalloc_parse_size_prod(state, n, arg, *subapp)) + subap = va_arg(ap, va_list *); + if (vmemalloc_parse_size_prod(state, n, arg, *subap, &ap_advance)) return -1; break; case LIBSIMPLE_MEMALLOC_VA_LIST: - subapp = va_arg(ap, va_list *); - if (vmemalloc_parse_args(state, n, *subapp)) + subap = va_arg(ap, va_list *); + if (vmemalloc_parse_args(state, n, *subap)) return -1; break; |
