git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] parse-options: add int value pointer to struct option

From
René Scharfe <l.s.r@web.de>
Date
Sep 9, 2023, 21:10 UTC
Message-ID
<2d6f3d74-687a-2d40-5c0c-abc396aef80f@web.de>

Add an int pointer, value_int, to struct option to provide a typed value pointer for the various integer options. It allows type checks at compile time, which is not possible with the void pointer, value. Its use is optional for now.

Signed-off-by: René Scharfe <l.s.r@web.de>
---
 parse-options.c | 34 +++++++++++++++++++---------------
 parse-options.h |  2 ++
 2 files changed, 21 insertions(+), 15 deletions(-)
diff --git a/parse-options.c b/parse-options.c
index e8e076c3a6..2552745804 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -82,10 +82,11 @@ static enum parse_opt_result opt_command_mode_error(
 	 * already, and report that this is not compatible with it.
 	 */
 	for (that = all_opts; that->type != OPTION_END; that++) {
+		int *value_int = opt->value_int ? opt->value_int : opt->value;
 		if (that == opt ||
 		    !(that->flags & PARSE_OPT_CMDMODE) ||
 		    that->value != opt->value ||
-		    that->defval != *(int *)opt->value)
+		    that->defval != *value_int)
 			continue;

 		if (that->long_name)
@@ -109,6 +110,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 	const char *s, *arg;
 	const int unset = flags & OPT_UNSET;
 	int err;
+	int *value_int = opt->value_int ? opt->value_int : opt->value;

 	if (unset && p->opt)
 		return error(_("%s takes no value"), optname(opt, flags));
@@ -122,7 +124,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 	 * is not a grave error, so let it pass.
 	 */
 	if ((opt->flags & PARSE_OPT_CMDMODE) &&
-	    *(int *)opt->value && *(int *)opt->value != opt->defval)
+	    *value_int && *value_int != opt->defval)
 		return opt_command_mode_error(opt, all_opts, flags);

 	switch (opt->type) {
@@ -131,33 +133,33 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,

 	case OPTION_BIT:
 		if (unset)
-			*(int *)opt->value &= ~opt->defval;
+			*value_int &= ~opt->defval;
 		else
-			*(int *)opt->value |= opt->defval;
+			*value_int |= opt->defval;
 		return 0;

 	case OPTION_NEGBIT:
 		if (unset)
-			*(int *)opt->value |= opt->defval;
+			*value_int |= opt->defval;
 		else
-			*(int *)opt->value &= ~opt->defval;
+			*value_int &= ~opt->defval;
 		return 0;

 	case OPTION_BITOP:
 		if (unset)
 			BUG("BITOP can't have unset form");
-		*(int *)opt->value &= ~opt->extra;
-		*(int *)opt->value |= opt->defval;
+		*value_int &= ~opt->extra;
+		*value_int |= opt->defval;
 		return 0;

 	case OPTION_COUNTUP:
-		if (*(int *)opt->value < 0)
-			*(int *)opt->value = 0;
-		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
+		if (*value_int < 0)
+			*value_int = 0;
+		*value_int = unset ? 0 : *value_int + 1;
 		return 0;

 	case OPTION_SET_INT:
-		*(int *)opt->value = unset ? 0 : opt->defval;
+		*value_int = unset ? 0 : opt->defval;
 		return 0;

 	case OPTION_STRING:
@@ -206,11 +208,11 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 	}
 	case OPTION_INTEGER:
 		if (unset) {
-			*(int *)opt->value = 0;
+			*value_int = 0;
 			return 0;
 		}
 		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
-			*(int *)opt->value = opt->defval;
+			*value_int = opt->defval;
 			return 0;
 		}
 		if (get_arg(p, opt, flags, &arg))
@@ -218,7 +220,7 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
 		if (!*arg)
 			return error(_("%s expects a numerical value"),
 				     optname(opt, flags));
-		*(int *)opt->value = strtol(arg, (char **)&s, 10);
+		*value_int = strtol(arg, (char **)&s, 10);
 		if (*s)
 			return error(_("%s expects a numerical value"),
 				     optname(opt, flags));
@@ -483,6 +485,8 @@ static void parse_options_check(const struct option *opts)
 		if (opts->type == OPTION_SET_INT && !opts->defval &&
 		    opts->long_name && !(opts->flags & PARSE_OPT_NONEG))
 			optbug(opts, "OPTION_SET_INT 0 should not be negatable");
+		if (opts->value && opts->value_int)
+			optbug(opts, "only a single value type supported");
 		switch (opts->type) {
 		case OPTION_COUNTUP:
 		case OPTION_BIT:
diff --git a/parse-options.h b/parse-options.h
index 57a7fe9d91..5e7475bd2d 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -158,6 +158,8 @@ struct option {
 	parse_opt_ll_cb *ll_callback;
 	intptr_t extra;
 	parse_opt_subcommand_fn *subcommand_fn;
+
+	int *value_int;
 };

 #define OPT_BIT_F(s, l, v, h, b, f) { \
--
2.42.0
Next: René Scharfe
Message 1 of 36 in “parse-options: add int value pointer to struct option”
  1. 1/2 parse-options: add int value pointer to struct optionRené Scharfe, Sep 9, 2023
  2. 2/2 parse-options: use and require int pointer for OPT_CMDMODERené Scharfe, Sep 9, 2023
  3. Oswald BuddenhagenSep 10, 2023
  4. René ScharfeSep 11, 2023
  5. Jeff KingSep 12, 2023
  6. Junio C HamanoSep 16, 2023
  7. René ScharfeSep 18, 2023
  8. Oswald BuddenhagenSep 18, 2023
  9. René ScharfeSep 19, 2023
  10. am: fix error message in parse_opt_show_current_patch()Oswald Buddenhagen, Sep 21, 2023
  11. Junio C HamanoSep 21, 2023
  12. Oswald BuddenhagenSep 21, 2023
  13. Phillip WoodSep 18, 2023
  14. Junio C HamanoSep 18, 2023
  15. Phillip WoodSep 18, 2023
  16. René ScharfeOct 3, 2023
  17. Junio C HamanoOct 3, 2023
  18. René ScharfeSep 19, 2023
  19. Junio C HamanoSep 11, 2023
  20. René ScharfeSep 11, 2023
  21. Oswald BuddenhagenSep 19, 2023
  22. René ScharfeSep 20, 2023
  23. Oswald BuddenhagenSep 21, 2023
  24. René ScharfeOct 3, 2023
  25. Oswald BuddenhagenOct 3, 2023
  26. René ScharfeOct 3, 2023
  27. Oswald BuddenhagenOct 3, 2023
  28. Taylor BlauSep 10, 2023
  29. René ScharfeSep 11, 2023
  30. Junio C HamanoSep 11, 2023
  31. Oswald BuddenhagenSep 11, 2023
  32. Kristoffer HaugsbakkSep 18, 2023
  33. René ScharfeSep 18, 2023
  34. Oswald BuddenhagenSep 18, 2023
  35. Junio C HamanoSep 18, 2023
  36. René ScharfeSep 20, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.