From 868d7c4b26d8b4be6d41b18dacdbc80644488ee8 Mon Sep 17 00:00:00 2001 From: Vaclav Petras Date: Fri, 4 Apr 2025 17:06:11 -0400 Subject: [PATCH] lib/parser: Use a function to get num of items in a tuple This uses a function to get the required number of items in a tuple if the parameter value is defined as a tuple using key_desc. This is a first step to providing this information in the API and tool metadata which is important because it has implications for type (tool option parameter of type int with key_desc with comma has to have the comma, so it is actually not an int in e.g. Python). There is little more what can be done here and that's not doing the check when there is no tuple, but this would be better done with some tests in place for this parser feature. The function is actually already in #5490 so this is a draft also for this reason, but the logic should be reviewable. --- lib/gis/parser.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/gis/parser.c b/lib/gis/parser.c index b954bc9faa5..13e9530b497 100644 --- a/lib/gis/parser.c +++ b/lib/gis/parser.c @@ -1637,11 +1637,32 @@ void split_opts(void) } } +static int G__option_num_tuple_items(const struct Option *opt); + +int G__option_num_tuple_items(const struct Option *opt) +{ + // If empty, it cannot be considered a tuple. + if (!opt->key_desc) + return 0; + + int n_items = 1; + const char *ptr; + + for (ptr = opt->key_desc; *ptr != '\0'; ptr++) + if (*ptr == ',') + n_items++; + + // Only one item is not considered a tuple. + if (n_items == 1) + return 0; + // Only two and more items are a tuple. + return n_items; +} + void check_multiple_opts(void) { struct Option *opt; const char *ptr; - int n_commas; int n; char *err; @@ -1653,20 +1674,20 @@ void check_multiple_opts(void) while (opt) { /* "-" is reserved from standard input/output */ if (opt->answer && strcmp(opt->answer, "-") && opt->key_desc) { - /* count commas */ - n_commas = 1; - for (ptr = opt->key_desc; *ptr != '\0'; ptr++) - if (*ptr == ',') - n_commas++; - /* count items */ + int expected_items = G__option_num_tuple_items(opt); + // For the computation, we actually use number of items in general + // regardless of whether it is a tuple or not. (This can be removed + // with some tests in place. No need to test for 1.) + expected_items = expected_items ? expected_items : 1; + // actual number of items for (n = 0; opt->answers[n] != NULL; n++) ; /* if not correct multiple of items */ - if (n % n_commas) { + if (n % expected_items) { G_asprintf(&err, _("Option <%s> must be provided in multiples of %d\n" "\tYou provided %d item(s): %s"), - opt->key, n_commas, n, opt->answer); + opt->key, expected_items, n, opt->answer); append_error(err); } }