diff --git a/src/parser.c b/src/parser.c index 1110582..5a46b25 100644 --- a/src/parser.c +++ b/src/parser.c @@ -79,9 +79,11 @@ static enum parse_fragment_result parse_fragment(apfl_parser_ptr, struct fragmen static bool grow_fragment_cap(struct fragment_list *list, size_t inc) { - return apfl_resizable_grow_cap( + return apfl_resizable_ensure_cap_for_more_elements( sizeof(struct fragment), - APFL_RESIZABLE_ARGS(*list, children), + (void **)&list->children, + list->len, + &list->cap, inc ); } @@ -1536,9 +1538,11 @@ break_inner: goto error; } - if (!apfl_resizable_grow_cap( + if (!apfl_resizable_ensure_cap_for_more_elements( sizeof(struct partial_assignment), - APFL_RESIZABLE_ARGS(partial_assignments, items), + (void **)&partial_assignments.items, + partial_assignments.len, + &partial_assignments.cap, 1 )) { p->error = apfl_error_simple(APFL_ERR_MALLOC_FAILED); diff --git a/src/resizable.c b/src/resizable.c index 895f80a..9e00733 100644 --- a/src/resizable.c +++ b/src/resizable.c @@ -25,7 +25,7 @@ apfl_resizable_resize(size_t elem_size, void **mem, size_t *len, size_t *cap, si assert(newlen >= *cap); - if (!apfl_resizable_grow_cap(elem_size, mem, len, cap, newlen - *cap)) { + if (!apfl_resizable_ensure_cap(elem_size, mem, cap, newlen)) { return false; } @@ -34,37 +34,36 @@ apfl_resizable_resize(size_t elem_size, void **mem, size_t *len, size_t *cap, si } bool -apfl_resizable_grow_cap(size_t elem_size, void **mem, size_t *len, size_t *cap, size_t inc_cap) +apfl_resizable_ensure_cap(size_t elem_size, void **mem, size_t *cap, size_t want_cap) { - (void)len;// \mystuff\TODO:better not even have the arg - - if (inc_cap == 0) { + if (want_cap <= *cap) { return true; } - size_t newcap = *cap + inc_cap; - // TODO: We currently simply grow the memory to have space for exactly - // inc_cap more elements. It would probably be smarter to grow the - // memory a bit larger to reduce calls to realloc. - void *newmem = realloc(*mem, newcap * elem_size); + // want_cap elements. It would probably be smarter to grow the memory + // a bit larger to reduce calls to realloc. + void *newmem = realloc(*mem, want_cap * elem_size); if (newmem == NULL) { return false; } *mem = newmem; - *cap = newcap; + *cap = want_cap; return true; } +bool +apfl_resizable_ensure_cap_for_more_elements(size_t elem_size, void **mem, size_t len, size_t *cap, size_t more_elements) +{ + return apfl_resizable_ensure_cap(elem_size, mem, cap, len + more_elements); // TODO: What if len + more_elements overflows? +} + bool apfl_resizable_append(size_t elem_size, void **mem, size_t *len, size_t *cap, const void *other_mem, size_t other_len) { - size_t newlen = *len + other_len; - if (newlen > *cap) { - if (!apfl_resizable_grow_cap(elem_size, mem, len, cap, newlen - *cap)) { - return false; - } + if (!apfl_resizable_ensure_cap_for_more_elements(elem_size, mem, *len, cap, other_len)) { + return false; } memcpy(*((char**)mem) + (elem_size * *len), other_mem, other_len * elem_size); diff --git a/src/resizable.h b/src/resizable.h index 806862e..fe7d12c 100644 --- a/src/resizable.h +++ b/src/resizable.h @@ -15,7 +15,9 @@ void apfl_resizable_init(void **mem, size_t *len, size_t *cap); bool apfl_resizable_resize(size_t elem_size, void **mem, size_t *len, size_t *cap, size_t newlen); -bool apfl_resizable_grow_cap(size_t elem_size, void **mem, size_t *len, size_t *cap, size_t inc_cap); +bool apfl_resizable_ensure_cap(size_t elem_size, void **mem, size_t *cap, size_t want_cap); +bool apfl_resizable_ensure_cap_for_more_elements(size_t elem_size, void **mem, size_t len, size_t *cap, size_t more_elements); + bool apfl_resizable_append(size_t elem_size, void **mem, size_t *len, size_t *cap, const void *other_mem, size_t other_len);