argpar.c: remove stdarg.h include
[argpar.git] / argpar / argpar.c
index 55995124fb6332e5a4a3cf8296b55d55adfde3b2..4402d2537295472bfe1daf11bf5289f3270a462e 100644 (file)
@@ -5,8 +5,6 @@
  * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
  */
 
-#include <assert.h>
-#include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #define ARGPAR_ZALLOC(_type) ARGPAR_CALLOC(_type, 1)
 
-#define ARGPAR_ASSERT(_cond) assert(_cond)
+#ifdef NDEBUG
+/*
+ * Force usage of the assertion condition to prevent unused variable
+ * warnings when `assert()` are disabled by the `NDEBUG` definition.
+ */
+# define ARGPAR_ASSERT(_cond) ((void) sizeof((void) (_cond), 0))
+#else
+# include <assert.h>
+# define ARGPAR_ASSERT(_cond) assert(_cond)
+#endif
 
 /*
  * An argpar iterator.
@@ -38,7 +45,7 @@ struct argpar_iter {
        struct {
                unsigned int argc;
                const char * const *argv;
-               const struct argpar_opt_descr *descrs;
+               const argpar_opt_descr_t *descrs;
        } user;
 
        /*
@@ -67,23 +74,23 @@ struct argpar_iter {
 
 /* Base parsing item */
 struct argpar_item {
-       enum argpar_item_type type;
+       argpar_item_type_t type;
 };
 
 /* Option parsing item */
-struct argpar_item_opt {
-       struct argpar_item base;
+typedef struct argpar_item_opt {
+       argpar_item_t base;
 
        /* Corresponding descriptor */
-       const struct argpar_opt_descr *descr;
+       const argpar_opt_descr_t *descr;
 
        /* Argument, or `NULL` if none; owned by this */
        char *arg;
-};
+} argpar_item_opt_t;
 
 /* Non-option parsing item */
-struct argpar_item_non_opt {
-       struct argpar_item base;
+typedef struct argpar_item_non_opt {
+       argpar_item_t base;
 
        /*
         * Complete argument, pointing to one of the entries of the
@@ -99,10 +106,13 @@ struct argpar_item_non_opt {
 
        /* Index of this argument amongst other non-option arguments */
        unsigned int non_opt_index;
-};
+} argpar_item_non_opt_t;
 
 /* Parsing error */
 struct argpar_error {
+       /* Error type */
+       argpar_error_type_t type;
+
        /* Original argument index */
        unsigned int orig_index;
 
@@ -110,72 +120,71 @@ struct argpar_error {
        char *unknown_opt_name;
 
        /* Option descriptor */
-       const struct argpar_opt_descr *opt_descr;
+       const argpar_opt_descr_t *opt_descr;
 
        /* `true` if a short option caused the error */
        bool is_short;
 };
 
 ARGPAR_HIDDEN
-enum argpar_item_type argpar_item_type(const struct argpar_item * const item)
+argpar_item_type_t argpar_item_type(const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        return item->type;
 }
 
 ARGPAR_HIDDEN
-const struct argpar_opt_descr *argpar_item_opt_descr(
-               const struct argpar_item * const item)
+const argpar_opt_descr_t *argpar_item_opt_descr(
+               const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
-       return ((const struct argpar_item_opt *) item)->descr;
+       return ((const argpar_item_opt_t *) item)->descr;
 }
 
 ARGPAR_HIDDEN
-const char *argpar_item_opt_arg(const struct argpar_item * const item)
+const char *argpar_item_opt_arg(const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_OPT);
-       return ((const struct argpar_item_opt *) item)->arg;
+       return ((const argpar_item_opt_t *) item)->arg;
 }
 
 ARGPAR_HIDDEN
-const char *argpar_item_non_opt_arg(const struct argpar_item * const item)
+const char *argpar_item_non_opt_arg(const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->arg;
+       return ((const argpar_item_non_opt_t *) item)->arg;
 }
 
 ARGPAR_HIDDEN
 unsigned int argpar_item_non_opt_orig_index(
-               const struct argpar_item * const item)
+               const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->orig_index;
+       return ((const argpar_item_non_opt_t *) item)->orig_index;
 }
 
 ARGPAR_HIDDEN
 unsigned int argpar_item_non_opt_non_opt_index(
-               const struct argpar_item * const item)
+               const argpar_item_t * const item)
 {
        ARGPAR_ASSERT(item);
        ARGPAR_ASSERT(item->type == ARGPAR_ITEM_TYPE_NON_OPT);
-       return ((const struct argpar_item_non_opt *) item)->non_opt_index;
+       return ((const argpar_item_non_opt_t *) item)->non_opt_index;
 }
 
 ARGPAR_HIDDEN
-void argpar_item_destroy(const struct argpar_item * const item)
+void argpar_item_destroy(const argpar_item_t * const item)
 {
        if (!item) {
                goto end;
        }
 
        if (item->type == ARGPAR_ITEM_TYPE_OPT) {
-               struct argpar_item_opt * const opt_item =
-                       (struct argpar_item_opt *) item;
+               argpar_item_opt_t * const opt_item = (argpar_item_opt_t *) item;
 
                free(opt_item->arg);
        }
@@ -193,12 +202,10 @@ end:
  * Returns `NULL` on memory error.
  */
 static
-struct argpar_item_opt *create_opt_item(
-               const struct argpar_opt_descr * const descr,
+argpar_item_opt_t *create_opt_item(const argpar_opt_descr_t * const descr,
                const char * const arg)
 {
-       struct argpar_item_opt *opt_item =
-               ARGPAR_ZALLOC(struct argpar_item_opt);
+       argpar_item_opt_t *opt_item = ARGPAR_ZALLOC(argpar_item_opt_t);
 
        if (!opt_item) {
                goto end;
@@ -232,12 +239,12 @@ end:
  * Returns `NULL` on memory error.
  */
 static
-struct argpar_item_non_opt *create_non_opt_item(const char * const arg,
+argpar_item_non_opt_t *create_non_opt_item(const char * const arg,
                const unsigned int orig_index,
                const unsigned int non_opt_index)
 {
-       struct argpar_item_non_opt * const non_opt_item =
-               ARGPAR_ZALLOC(struct argpar_item_non_opt);
+       argpar_item_non_opt_t * const non_opt_item =
+               ARGPAR_ZALLOC(argpar_item_non_opt_t);
 
        if (!non_opt_item) {
                goto end;
@@ -264,10 +271,9 @@ end:
  * error.
  */
 static
-int set_error(struct argpar_error ** const error,
+int set_error(argpar_error_t ** const error, argpar_error_type_t type,
                const char * const unknown_opt_name,
-               const struct argpar_opt_descr * const opt_descr,
-               const bool is_short)
+               const argpar_opt_descr_t * const opt_descr, const bool is_short)
 {
        int ret = 0;
 
@@ -275,11 +281,13 @@ int set_error(struct argpar_error ** const error,
                goto end;
        }
 
-       *error = ARGPAR_ZALLOC(struct argpar_error);
+       *error = ARGPAR_ZALLOC(argpar_error_t);
        if (!*error) {
                goto error;
        }
 
+       (*error)->type = type;
+
        if (unknown_opt_name) {
                (*error)->unknown_opt_name = ARGPAR_CALLOC(char,
                        strlen(unknown_opt_name) + 1 + (is_short ? 1 : 2));
@@ -309,7 +317,15 @@ end:
 }
 
 ARGPAR_HIDDEN
-unsigned int argpar_error_orig_index(const struct argpar_error * const error)
+argpar_error_type_t argpar_error_type(
+               const argpar_error_t * const error)
+{
+       ARGPAR_ASSERT(error);
+       return error->type;
+}
+
+ARGPAR_HIDDEN
+unsigned int argpar_error_orig_index(const argpar_error_t * const error)
 {
        ARGPAR_ASSERT(error);
        return error->orig_index;
@@ -317,18 +333,21 @@ unsigned int argpar_error_orig_index(const struct argpar_error * const error)
 
 ARGPAR_HIDDEN
 const char *argpar_error_unknown_opt_name(
-               const struct argpar_error * const error)
+               const argpar_error_t * const error)
 {
        ARGPAR_ASSERT(error);
+       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_UNKNOWN_OPT);
        ARGPAR_ASSERT(error->unknown_opt_name);
        return error->unknown_opt_name;
 }
 
 ARGPAR_HIDDEN
-const struct argpar_opt_descr *argpar_error_opt_descr(
-               const struct argpar_error * const error, bool * const is_short)
+const argpar_opt_descr_t *argpar_error_opt_descr(
+               const argpar_error_t * const error, bool * const is_short)
 {
        ARGPAR_ASSERT(error);
+       ARGPAR_ASSERT(error->type == ARGPAR_ERROR_TYPE_MISSING_OPT_ARG ||
+               error->type == ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG);
        ARGPAR_ASSERT(error->opt_descr);
 
        if (is_short) {
@@ -339,7 +358,7 @@ const struct argpar_opt_descr *argpar_error_opt_descr(
 }
 
 ARGPAR_HIDDEN
-void argpar_error_destroy(const struct argpar_error * const error)
+void argpar_error_destroy(const argpar_error_t * const error)
 {
        if (error) {
                free(error->unknown_opt_name);
@@ -359,11 +378,10 @@ void argpar_error_destroy(const struct argpar_error * const error)
  * Returns `NULL` if no descriptor is found.
  */
 static
-const struct argpar_opt_descr *find_descr(
-               const struct argpar_opt_descr * const descrs,
+const argpar_opt_descr_t *find_descr(const argpar_opt_descr_t * const descrs,
                const char short_name, const char * const long_name)
 {
-       const struct argpar_opt_descr *descr;
+       const argpar_opt_descr_t *descr;
 
        for (descr = descrs; descr->short_name || descr->long_name; descr++) {
                if (short_name && descr->short_name &&
@@ -382,13 +400,11 @@ end:
 }
 
 /* Return type of parse_short_opt_group() and parse_long_opt() */
-enum parse_orig_arg_opt_ret {
+typedef enum parse_orig_arg_opt_ret {
        PARSE_ORIG_ARG_OPT_RET_OK,
-       PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT = -1,
-       PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG = -2,
-       PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG = -4,
-       PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -5,
-};
+       PARSE_ORIG_ARG_OPT_RET_ERROR = -1,
+       PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY = -2,
+} parse_orig_arg_opt_ret_t;
 
 /*
  * Parses the short option group argument `short_opt_group`, starting
@@ -400,19 +416,18 @@ enum parse_orig_arg_opt_ret {
  * `*error`.
  */
 static
-enum parse_orig_arg_opt_ret parse_short_opt_group(
+parse_orig_arg_opt_ret_t parse_short_opt_group(
                const char * const short_opt_group,
                const char * const next_orig_arg,
-               const struct argpar_opt_descr * const descrs,
-               struct argpar_iter * const iter,
-               struct argpar_error ** const error,
-               struct argpar_item ** const item)
+               const argpar_opt_descr_t * const descrs,
+               argpar_iter_t * const iter, argpar_error_t ** const error,
+               argpar_item_t ** const item)
 {
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
+       parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK;
        bool used_next_orig_arg = false;
        const char *opt_arg = NULL;
-       const struct argpar_opt_descr *descr;
-       struct argpar_item_opt *opt_item;
+       const argpar_opt_descr_t *descr;
+       argpar_item_opt_t *opt_item;
 
        ARGPAR_ASSERT(strlen(short_opt_group) != 0);
 
@@ -426,9 +441,10 @@ enum parse_orig_arg_opt_ret parse_short_opt_group(
                const char unknown_opt_name[] =
                        {*iter->short_opt_group_ch, '\0'};
 
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT;
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
 
-               if (set_error(error, unknown_opt_name, NULL, true)) {
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
+                               unknown_opt_name, NULL, true)) {
                        ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
                }
 
@@ -451,9 +467,10 @@ enum parse_orig_arg_opt_ret parse_short_opt_group(
                 */
                if (!opt_arg || (iter->short_opt_group_ch[1] &&
                                strlen(opt_arg) == 0)) {
-                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG;
+                       ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
 
-                       if (set_error(error, NULL, descr, true)) {
+                       if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
+                                       NULL, descr, true)) {
                                ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
                        }
 
@@ -500,16 +517,15 @@ end:
  * `*error`.
  */
 static
-enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg,
+parse_orig_arg_opt_ret_t parse_long_opt(const char * const long_opt_arg,
                const char * const next_orig_arg,
-               const struct argpar_opt_descr * const descrs,
-               struct argpar_iter * const iter,
-               struct argpar_error ** const error,
-               struct argpar_item ** const item)
+               const argpar_opt_descr_t * const descrs,
+               argpar_iter_t * const iter, argpar_error_t ** const error,
+               argpar_item_t ** const item)
 {
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
-       const struct argpar_opt_descr *descr;
-       struct argpar_item_opt *opt_item;
+       parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK;
+       const argpar_opt_descr_t *descr;
+       argpar_item_opt_t *opt_item;
        bool used_next_orig_arg = false;
 
        /* Option's argument, if any */
@@ -547,9 +563,10 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg,
        /* Find corresponding option descriptor */
        descr = find_descr(descrs, '\0', long_opt_name);
        if (!descr) {
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT;
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
 
-               if (set_error(error, long_opt_name, NULL, false)) {
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
+                               long_opt_name, NULL, false)) {
                        ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
                }
 
@@ -564,9 +581,10 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg,
                } else {
                        /* `--long-opt arg` style */
                        if (!next_orig_arg) {
-                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG;
+                               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
 
-                               if (set_error(error, NULL, descr, false)) {
+                               if (set_error(error, ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
+                                               NULL, descr, false)) {
                                        ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
                                }
 
@@ -581,9 +599,10 @@ enum parse_orig_arg_opt_ret parse_long_opt(const char * const long_opt_arg,
                 * Unexpected `--opt=arg` style for a long option which
                 * doesn't accept an argument.
                 */
-               ret = PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG;
+               ret = PARSE_ORIG_ARG_OPT_RET_ERROR;
 
-               if (set_error(error, NULL, descr, false)) {
+               if (set_error(error, ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG,
+                               NULL, descr, false)) {
                        ret = PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY;
                }
 
@@ -621,36 +640,35 @@ end:
  * `*error`.
  */
 static
-enum parse_orig_arg_opt_ret parse_orig_arg_opt(const char * const orig_arg,
+parse_orig_arg_opt_ret_t parse_orig_arg_opt(const char * const orig_arg,
                const char * const next_orig_arg,
-               const struct argpar_opt_descr * const descrs,
-               struct argpar_iter * const iter,
-               struct argpar_error ** const error,
-               struct argpar_item ** const item)
+               const argpar_opt_descr_t * const descrs,
+               argpar_iter_t * const iter, argpar_error_t ** const error,
+               argpar_item_t ** const item)
 {
-       enum parse_orig_arg_opt_ret ret = PARSE_ORIG_ARG_OPT_RET_OK;
+       parse_orig_arg_opt_ret_t ret = PARSE_ORIG_ARG_OPT_RET_OK;
 
        ARGPAR_ASSERT(orig_arg[0] == '-');
 
        if (orig_arg[1] == '-') {
                /* Long option */
-               ret = parse_long_opt(&orig_arg[2],
-                       next_orig_arg, descrs, iter, error, item);
+               ret = parse_long_opt(&orig_arg[2], next_orig_arg, descrs, iter,
+                       error, item);
        } else {
                /* Short option */
-               ret = parse_short_opt_group(&orig_arg[1],
-                       next_orig_arg, descrs, iter, error, item);
+               ret = parse_short_opt_group(&orig_arg[1], next_orig_arg, descrs,
+                       iter, error, item);
        }
 
        return ret;
 }
 
 ARGPAR_HIDDEN
-struct argpar_iter *argpar_iter_create(const unsigned int argc,
+argpar_iter_t *argpar_iter_create(const unsigned int argc,
                const char * const * const argv,
-               const struct argpar_opt_descr * const descrs)
+               const argpar_opt_descr_t * const descrs)
 {
-       struct argpar_iter *iter = ARGPAR_ZALLOC(struct argpar_iter);
+       argpar_iter_t *iter = ARGPAR_ZALLOC(argpar_iter_t);
 
        if (!iter) {
                goto end;
@@ -672,7 +690,7 @@ end:
 }
 
 ARGPAR_HIDDEN
-void argpar_iter_destroy(struct argpar_iter * const iter)
+void argpar_iter_destroy(argpar_iter_t * const iter)
 {
        if (iter) {
                free(iter->tmp_buf.data);
@@ -681,16 +699,15 @@ void argpar_iter_destroy(struct argpar_iter * const iter)
 }
 
 ARGPAR_HIDDEN
-enum argpar_iter_next_status argpar_iter_next(
-               struct argpar_iter * const iter,
-               const struct argpar_item ** const item,
-               const struct argpar_error ** const error)
+argpar_iter_next_status_t argpar_iter_next(argpar_iter_t * const iter,
+               const argpar_item_t ** const item,
+               const argpar_error_t ** const error)
 {
-       enum argpar_iter_next_status status;
-       enum parse_orig_arg_opt_ret parse_orig_arg_opt_ret;
+       argpar_iter_next_status_t status;
+       parse_orig_arg_opt_ret_t parse_orig_arg_opt_ret;
        const char *orig_arg;
        const char *next_orig_arg;
-       struct argpar_error ** const nc_error = (struct argpar_error **) error;
+       argpar_error_t ** const nc_error = (argpar_error_t **) error;
 
        ARGPAR_ASSERT(iter->i <= iter->user.argc);
 
@@ -711,7 +728,7 @@ enum argpar_iter_next_status argpar_iter_next(
        if (strcmp(orig_arg, "-") == 0 || strcmp(orig_arg, "--") == 0 ||
                        orig_arg[0] != '-') {
                /* Non-option argument */
-               const struct argpar_item_non_opt * const non_opt_item =
+               const argpar_item_non_opt_t * const non_opt_item =
                        create_non_opt_item(orig_arg, iter->i,
                                iter->non_opt_index);
 
@@ -730,33 +747,17 @@ enum argpar_iter_next_status argpar_iter_next(
        /* Option argument */
        parse_orig_arg_opt_ret = parse_orig_arg_opt(orig_arg,
                next_orig_arg, iter->user.descrs, iter, nc_error,
-               (struct argpar_item **) item);
+               (argpar_item_t **) item);
        switch (parse_orig_arg_opt_ret) {
        case PARSE_ORIG_ARG_OPT_RET_OK:
                status = ARGPAR_ITER_NEXT_STATUS_OK;
                break;
-       case PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT:
-       case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG:
-       case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG:
+       case PARSE_ORIG_ARG_OPT_RET_ERROR:
                if (error) {
                        ARGPAR_ASSERT(*error);
                        (*nc_error)->orig_index = iter->i;
                }
-
-               switch (parse_orig_arg_opt_ret) {
-               case PARSE_ORIG_ARG_OPT_RET_ERROR_UNKNOWN_OPT:
-                       status = ARGPAR_ITER_NEXT_STATUS_ERROR_UNKNOWN_OPT;
-                       break;
-               case PARSE_ORIG_ARG_OPT_RET_ERROR_MISSING_OPT_ARG:
-                       status = ARGPAR_ITER_NEXT_STATUS_ERROR_MISSING_OPT_ARG;
-                       break;
-               case PARSE_ORIG_ARG_OPT_RET_ERROR_UNEXPECTED_OPT_ARG:
-                       status = ARGPAR_ITER_NEXT_STATUS_ERROR_UNEXPECTED_OPT_ARG;
-                       break;
-               default:
-                       abort();
-               }
-
+               status = ARGPAR_ITER_NEXT_STATUS_ERROR;
                break;
        case PARSE_ORIG_ARG_OPT_RET_ERROR_MEMORY:
                status = ARGPAR_ITER_NEXT_STATUS_ERROR_MEMORY;
@@ -770,8 +771,7 @@ end:
 }
 
 ARGPAR_HIDDEN
-unsigned int argpar_iter_ingested_orig_args(
-               const struct argpar_iter * const iter)
+unsigned int argpar_iter_ingested_orig_args(const argpar_iter_t * const iter)
 {
        return iter->i;
 }
This page took 0.031676 seconds and 4 git commands to generate.