return;
}
-static
-bool push_item(struct argpar_item_array * const array,
- const struct argpar_item * const item)
-{
- bool success;
-
- ARGPAR_ASSERT(array);
- ARGPAR_ASSERT(item);
-
- if (array->n_items == array->n_alloc) {
- const unsigned int new_n_alloc = array->n_alloc * 2;
- const struct argpar_item ** const new_items =
- ARGPAR_REALLOC(array->items, const struct argpar_item *,
- new_n_alloc);
- if (!new_items) {
- success = false;
- goto end;
- }
-
- array->n_alloc = new_n_alloc;
- array->items = new_items;
- }
-
- array->items[array->n_items] = item;
- array->n_items++;
- success = true;
-
-end:
- return success;
-}
-
-static
-void destroy_item_array(struct argpar_item_array * const array)
-{
- if (array) {
- unsigned int i;
-
- for (i = 0; i < array->n_items; i++) {
- argpar_item_destroy(array->items[i]);
- }
-
- free(array->items);
- free(array);
- }
-}
-
-static
-struct argpar_item_array *create_item_array(void)
-{
- struct argpar_item_array *ret;
- const int initial_size = 10;
-
- ret = ARGPAR_ZALLOC(struct argpar_item_array);
- if (!ret) {
- goto end;
- }
-
- ret->items = ARGPAR_CALLOC(const struct argpar_item *, initial_size);
- if (!ret->items) {
- goto error;
- }
-
- ret->n_alloc = initial_size;
- goto end;
-
-error:
- destroy_item_array(ret);
- ret = NULL;
-
-end:
- return ret;
-}
-
static
struct argpar_item_opt *create_opt_item(
const struct argpar_opt_descr * const descr,
{
return iter->i;
}
-
-ARGPAR_HIDDEN
-struct argpar_parse_ret argpar_parse(const unsigned int argc,
- const char * const * const argv,
- const struct argpar_opt_descr * const descrs,
- const bool fail_on_unknown_opt)
-{
- struct argpar_parse_ret parse_ret = { 0 };
- const struct argpar_item *item = NULL;
- struct argpar_iter *iter = NULL;
-
- parse_ret.items = create_item_array();
- if (!parse_ret.items) {
- parse_ret.error = strdup("Failed to create items array.");
- ARGPAR_ASSERT(parse_ret.error);
- goto error;
- }
-
- iter = argpar_iter_create(argc, argv, descrs);
- if (!iter) {
- parse_ret.error = strdup("Failed to create argpar iter.");
- ARGPAR_ASSERT(parse_ret.error);
- goto error;
- }
-
- while (true) {
- const enum argpar_iter_next_status status =
- argpar_iter_next(iter, &item, &parse_ret.error);
-
- switch (status) {
- case ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG:
- case ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG:
- case ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY:
- goto error;
- case ARGPAR_ITER_NEXT_STATUS_ERROR_UNKNOWN_OPT:
- if (fail_on_unknown_opt) {
- parse_ret.ingested_orig_args =
- argpar_iter_ingested_orig_args(iter);
- goto error;
- }
-
- free(parse_ret.error);
- parse_ret.error = NULL;
- goto success;
- case ARGPAR_ITER_NEXT_STATUS_END:
- goto success;
- default:
- ARGPAR_ASSERT(status == ARGPAR_ITER_NEXT_STATUS_OK);
- break;
- }
-
- if (!push_item(parse_ret.items, item)) {
- goto error;
- }
-
- item = NULL;
- }
-
-success:
- ARGPAR_ASSERT(!parse_ret.error);
- parse_ret.ingested_orig_args = argpar_iter_ingested_orig_args(iter);
- goto end;
-
-error:
- ARGPAR_ASSERT(parse_ret.error);
-
- /* That's how we indicate that an error occurred */
- destroy_item_array(parse_ret.items);
- parse_ret.items = NULL;
-
-end:
- argpar_iter_destroy(iter);
- argpar_item_destroy(item);
- return parse_ret;
-}
-
-ARGPAR_HIDDEN
-void argpar_parse_ret_fini(struct argpar_parse_ret * const ret)
-{
- ARGPAR_ASSERT(ret);
- destroy_item_array(ret->items);
- ret->items = NULL;
- free(ret->error);
- ret->error = NULL;
-}