Remove the argpar_parse() API
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 1 Jun 2021 16:21:34 +0000 (12:21 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 4 Jun 2021 17:59:12 +0000 (13:59 -0400)
Since the introduction of the iterator API, argpar_parse() is considered
a subset of what the iterator API can do, only adding a conditional (for
`fail_on_unknown_opt`) and creating an array of parsing items for the
user.

Therefore, as you can trivially implement an argpar_parse() equivalent
outside argpar, I see no interest in keeping it in the project.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I73857fef62de052457c9c7c4b0aab66187e81c27

argpar/argpar.c
argpar/argpar.h
tests/test_argpar.c

index ba577976a789f71d667e4f1b35be322de91bd6e6..45658a5b3e914e538cb47848281a1ffcdc1b178d 100644 (file)
@@ -253,79 +253,6 @@ end:
        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,
@@ -774,88 +701,3 @@ unsigned int argpar_iter_ingested_orig_args(
 {
        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;
-}
index 0a7631524f47f1e2bf763a8eb3f5b3dfc87b73f2..89b96e6d9b73350fd524fff32339a4a8ac51f88e 100644 (file)
  * argpar is a library which provides facilities for command-line
  * argument parsing.
  *
- * Two APIs are available:
+ * Create a parsing iterator with argpar_iter_create(), then
+ * repeatedly call argpar_iter_next() to access the parsing results,
+ * until one of:
  *
- * Iterator API:
- *     Create a parsing iterator with argpar_iter_create(), then
- *     repeatedly call argpar_iter_next() to access the parsing results,
- *     until one of:
+ * * There are no more arguments.
  *
- *     * There are no more arguments.
+ * * The argument parser encounters an error (for example, an unknown
+ *   option).
  *
- *     * The argument parser encounters an error (for example, an
- *       unknown option).
+ * * You need to stop.
  *
- *     * You need to stop.
- *
- *     This API provides more parsing control than the next one.
- *
- * Single call API:
- *     Call argpar_parse(), which parses the arguments until one of:
- *
- *     * There are no more arguments.
- *
- *     * It encounters an argument parsing error.
- *
- *     argpar_parse() returns a single array of parsing results.
- *
- * Both methods parse the arguments `argv` of which the count is `argc`
- * using the sentinel-terminated (use `ARGPAR_OPT_DESCR_SENTINEL`)
- * option descriptor array `descrs`.
+ * The argpar parser parses the original arguments `argv` of which the
+ * count is `argc` using the sentinel-terminated (use
+ * `ARGPAR_OPT_DESCR_SENTINEL`) option descriptor array `descrs`.
  *
  * argpar considers ALL the elements of `argv`, including the first one,
  * so that you would typically pass `argc - 1` and `&argv[1]` from what
  * main() receives.
  *
- * The argpar parsers support:
+ * The argpar parser supports:
  *
  * * Short options without an argument, possibly tied together:
  *
  *
  * * Non-option arguments (anything else).
  *
- * The argpar parsers parse `-` and `--` as non-option arguments. A
+ * The argpar parser parses `-` and `--` as non-option arguments. A
  * non-option argument cannot have the form of an option, for example if
  * you need to pass the exact relative path `--component`. In that case,
  * you would need to pass `./--component`. There's no generic way to
  * escape `-` as of this version.
  *
- * Both argpar_iter_create() and argpar_parse() accept duplicate options
- * (they produce one item for each instance).
+ * argpar_iter_create() accepts duplicate options in `descrs` (it
+ * produces one item for each instance).
  *
  * A returned parsing item has the type `const struct argpar_item *`.
  * Get the type (option or non-option) of an item with
  * argpar_item_type(). Each item type has its set of dedicated methods
  * (`argpar_item_opt_` and `argpar_item_non_opt_` prefixes).
  *
- * Both argpar_iter_create() and argpar_parse() produce the items in
- * the same order that the arguments were parsed, including non-option
- * arguments. This means, for example, that for:
+ * argpar_iter_next() produces the items in the same order that the
+ * original arguments were parsed, including non-option arguments. This
+ * means, for example, that for:
  *
  *     --hello --count=23 /path/to/file -ab --type file magie
  *
- * The produced items are, in this order:
+ * argpar_iter_next() produces the following items, in this order:
  *
  * 1. Option item (`--hello`).
  * 2. Option item (`--count` with argument `23`).
 # define ARGPAR_HIDDEN __attribute__((visibility("hidden")))
 #endif
 
-/* Forward-declaration for the opaque type */
+/* Forward-declaration for the opaque argpar iterator type */
 struct argpar_iter;
 
 /* Option descriptor */
@@ -141,7 +127,7 @@ enum argpar_item_type {
        ARGPAR_ITEM_TYPE_NON_OPT,
 };
 
-/* Parsing item, as created by argpar_parse() and argpar_iter_next() */
+/* Forward-declaration for the opaque argpar parsing item type */
 struct argpar_item;
 
 /*
@@ -191,95 +177,6 @@ unsigned int argpar_item_non_opt_non_opt_index(const struct argpar_item *item);
 ARGPAR_HIDDEN
 void argpar_item_destroy(const struct argpar_item *item);
 
-struct argpar_item_array {
-       const struct argpar_item **items;
-
-       /* Number of used slots in `items` */
-       unsigned int n_items;
-
-       /* Number of allocated slots in `items` */
-       unsigned int n_alloc;
-};
-
-/* What is returned by argpar_parse() */
-struct argpar_parse_ret {
-       /*
-        * Array of parsing items, or `NULL` on error.
-        *
-        * Do NOT destroy those items manually with
-        * argpar_iter_destroy(): call argpar_parse_ret_fini() to
-        * finalize the whole structure.
-        */
-       struct argpar_item_array *items;
-
-       /* Error string, or `NULL` if none */
-       char *error;
-
-       /* Number of original arguments (`argv`) ingested */
-       unsigned int ingested_orig_args;
-};
-
-/*
- * Parses arguments in `argv` until the end is reached or an error is
- * encountered.
- *
- * On success, this function returns an array of items (field `items` of
- * `struct argpar_parse_ret`).
- *
- * In the returned structure, `ingested_orig_args` is the number of
- * ingested arguments within `argv` to produce the resulting array of
- * items.
- *
- * If `fail_on_unknown_opt` is true, then on success
- * `ingested_orig_args` is equal to `argc`. Otherwise,
- * `ingested_orig_args` contains the number of original arguments until
- * an unknown _option_ occurs. For example, with
- *
- *     --great --white contact nuance --shark nuclear
- *
- * if `--shark` is not described within `descrs` and
- * `fail_on_unknown_opt` is false, then `ingested_orig_args` is 4 (two
- * options, two non-options), whereas `argc` is 6.
- *
- * This makes it possible to know where a command name is, for example.
- * With those arguments:
- *
- *     --verbose --stuff=23 do-something --specific-opt -f -b
- *
- * and the descriptors for `--verbose` and `--stuff` only, the function
- * returns the `--verbose` and `--stuff` option items, the
- * `do-something` non-option item, and that three original arguments
- * were ingested. This means you can start the next argument parsing
- * stage, with option descriptors depending on the command name, at
- * `&argv[3]`.
- *
- * Note that `ingested_orig_args` is not always equal to the number of
- * returned items, as
- *
- *     --hello -fdw
- *
- * for example contains two ingested original arguments, but four
- * resulting items.
- *
- * On failure, the `items` member of the returned structure is `NULL`,
- * and the `error` string member contains details about the error.
- *
- * Finalize the returned structure with argpar_parse_ret_fini().
- */
-ARGPAR_HIDDEN
-struct argpar_parse_ret argpar_parse(unsigned int argc,
-               const char * const *argv,
-               const struct argpar_opt_descr *descrs,
-               bool fail_on_unknown_opt);
-
-/*
- * Finalizes what argpar_parse() returns.
- *
- * You may call argpar_parse() multiple times with the same structure.
- */
-ARGPAR_HIDDEN
-void argpar_parse_ret_fini(struct argpar_parse_ret *ret);
-
 /*
  * Creates an argument parsing iterator.
  *
index fee82a9ed06031c32ae5dc70ff159735c3f6da75..a111d423275a87cfb47b1053f2ddcf2fdc17d21b 100644 (file)
@@ -88,7 +88,7 @@ void append_to_res_str(GString * const res_str,
 }
 
 /*
- * Parses `cmdline` with argpar_parse() using the option descriptors
+ * Parses `cmdline` with the argpar API using the option descriptors
  * `descrs`, and ensures that the resulting effective command line is
  * `expected_cmd_line` and that the number of ingested original
  * arguments is `expected_ingested_orig_args`.
@@ -100,73 +100,7 @@ void append_to_res_str(GString * const res_str,
  * by space-separating each formatted item (see append_to_res_str()).
  */
 static
-void test_succeed_argpar_parse(const char * const cmdline,
-               const char * const expected_cmd_line,
-               const struct argpar_opt_descr * const descrs,
-               const unsigned int expected_ingested_orig_args)
-{
-       struct argpar_parse_ret parse_ret;
-       GString * const res_str = g_string_new(NULL);
-       gchar ** const argv = g_strsplit(cmdline, " ", 0);
-       unsigned int i;
-
-       assert(argv);
-       assert(res_str);
-       parse_ret = argpar_parse(g_strv_length(argv),
-               (const char * const *) argv, descrs, false);
-       ok(parse_ret.items,
-               "argpar_parse() succeeds for command line `%s`", cmdline);
-       ok(!parse_ret.error,
-               "argpar_parse() doesn't set an error for command line `%s`",
-               cmdline);
-       ok(parse_ret.ingested_orig_args == expected_ingested_orig_args,
-               "argpar_parse() returns the correct number of ingested "
-               "original arguments for command line `%s`", cmdline);
-
-       if (parse_ret.ingested_orig_args != expected_ingested_orig_args) {
-               diag("Expected: %u    Got: %u", expected_ingested_orig_args,
-                       parse_ret.ingested_orig_args);
-       }
-
-       if (!parse_ret.items) {
-               fail("argpar_parse() returns the expected parsing items "
-                       "for command line `%s`", cmdline);
-               goto end;
-       }
-
-       for (i = 0; i < parse_ret.items->n_items; i++) {
-               append_to_res_str(res_str, parse_ret.items->items[i]);
-       }
-
-       ok(strcmp(expected_cmd_line, res_str->str) == 0,
-               "argpar_parse() returns the expected parsed arguments "
-               "for command line `%s`", cmdline);
-
-       if (strcmp(expected_cmd_line, res_str->str) != 0) {
-               diag("Expected: `%s`", expected_cmd_line);
-               diag("Got:      `%s`", res_str->str);
-       }
-
-end:
-       argpar_parse_ret_fini(&parse_ret);
-       g_string_free(res_str, TRUE);
-       g_strfreev(argv);
-}
-
-/*
- * Parses `cmdline` with the iterator API using the option descriptors
- * `descrs`, and ensures that the resulting effective command line is
- * `expected_cmd_line` and that the number of ingested original
- * arguments is `expected_ingested_orig_args`.
- *
- * This function splits `cmdline` on spaces to create an original
- * argument array.
- *
- * This function builds the resulting command line from parsing items
- * by space-separating each formatted item (see append_to_res_str()).
- */
-static
-void test_succeed_argpar_iter(const char * const cmdline,
+void test_succeed(const char * const cmdline,
                const char * const expected_cmd_line,
                const struct argpar_opt_descr * const descrs,
                const unsigned int expected_ingested_orig_args)
@@ -253,22 +187,6 @@ void test_succeed_argpar_iter(const char * const cmdline,
        free(error);
 }
 
-/*
- * Calls test_succeed_argpar_parse() and test_succeed_argpar_iter()
- * with the provided parameters.
- */
-static
-void test_succeed(const char * const cmdline,
-               const char * const expected_cmd_line,
-               const struct argpar_opt_descr * const descrs,
-               const unsigned int expected_ingested_orig_args)
-{
-       test_succeed_argpar_parse(cmdline, expected_cmd_line, descrs,
-               expected_ingested_orig_args);
-       test_succeed_argpar_iter(cmdline, expected_cmd_line, descrs,
-               expected_ingested_orig_args);
-}
-
 static
 void succeed_tests(void)
 {
@@ -682,50 +600,7 @@ void succeed_tests(void)
 }
 
 /*
- * Parses `cmdline` with argpar_parse() using the option descriptors
- * `descrs`, and ensures that the function fails and that it sets an
- * error which is equal to `expected_error`.
- *
- * This function splits `cmdline` on spaces to create an original
- * argument array.
- */
-static
-void test_fail_argpar_parse(const char * const cmdline,
-               const char * const expected_error,
-               const struct argpar_opt_descr * const descrs)
-{
-       struct argpar_parse_ret parse_ret;
-       gchar ** const argv = g_strsplit(cmdline, " ", 0);
-
-       parse_ret = argpar_parse(g_strv_length(argv),
-               (const char * const *) argv, descrs, true);
-       ok(!parse_ret.items,
-               "argpar_parse() fails for command line `%s`", cmdline);
-       ok(parse_ret.error,
-               "argpar_parse() sets an error string for command line `%s`",
-               cmdline);
-
-       if (parse_ret.items) {
-               fail("argpar_parse() sets the expected error string");
-               goto end;
-       }
-
-       ok(strcmp(expected_error, parse_ret.error) == 0,
-               "argpar_parse() sets the expected error string "
-               "for command line `%s`", cmdline);
-
-       if (strcmp(expected_error, parse_ret.error) != 0) {
-               diag("Expected: `%s`", expected_error);
-               diag("Got:      `%s`", parse_ret.error);
-       }
-
-end:
-       argpar_parse_ret_fini(&parse_ret);
-       g_strfreev(argv);
-}
-
-/*
- * Parses `cmdline` with the iterator API using the option descriptors
+ * Parses `cmdline` with the argpar API using the option descriptors
  * `descrs`, and ensures that argpar_iter_next() fails with status
  * `expected_status` and that it sets an error which is equal to
  * `expected_error`.
@@ -734,8 +609,7 @@ end:
  * argument array.
  */
 static
-void test_fail_argpar_iter(const char * const cmdline,
-               const char * const expected_error,
+void test_fail(const char * const cmdline, const char * const expected_error,
                const enum argpar_iter_next_status expected_status,
                const struct argpar_opt_descr * const descrs)
 {
@@ -803,20 +677,6 @@ void test_fail_argpar_iter(const char * const cmdline,
        g_strfreev(argv);
 }
 
-/*
- * Calls test_fail_argpar_parse() and test_fail_argpar_iter() with the
- * provided parameters.
- */
-static
-void test_fail(const char * const cmdline, const char * const expected_error,
-               const enum argpar_iter_next_status expected_iter_next_status,
-               const struct argpar_opt_descr * const descrs)
-{
-       test_fail_argpar_parse(cmdline, expected_error, descrs);
-       test_fail_argpar_iter(cmdline, expected_error,
-               expected_iter_next_status, descrs);
-}
-
 static
 void fail_tests(void)
 {
@@ -909,7 +769,7 @@ void fail_tests(void)
 
 int main(void)
 {
-       plan_tests(434);
+       plan_tests(296);
        succeed_tests();
        fail_tests();
        return exit_status();
This page took 0.047937 seconds and 4 git commands to generate.