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

[PATCH] parse-options: catch some likely in presense of aggregated options.

From
Pierre Habouzit <madcoder@debian.org>
Date
Jan 26, 2008, 11:26 UTC
Message-ID
<20080126112657.GB13922@artemis.madism.org>
In-Reply-To
<20080126104216.GA13922@artemis.madism.org>

If options are aggregated, and that the whole token looks like (is the exact prefix of length >= 3 of) a long option, then parse_options rejects it.

The typo check isn't performed if there is no aggregation, because the stuck for is the recommended one, hence if we have `-o` being a valid short option that takes an argument, and --option a long one, then we _MUST_ accept -option as it is our official recommended form.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 parse-options.c          |   30 ++++++++++++++++++++++++++++--
 t/t0040-parse-options.sh |   11 +++++++++++
 test-parse-options.c     |    1 +
 3 files changed, 40 insertions(+), 2 deletions(-)
    On Sat, Jan 26, 2008 at 10:42:16AM +0000, Pierre Habouzit wrote:
    >   I agree, I think that we should refuse things where the string after a
    > /one/ dash starts with 3 or more consecutive characters that are also
    > the beginning of a long option. I think that 2 is usually a bit "short"
    > to assume that it's a typo. I'll provide a patch soon
    Here it is, and we have now:
      $ git commit -amend
      error: did you mean `--amend` (with two dashes ?)
diff --git a/parse-options.c b/parse-options.c
index 7a08a0c..d9562ba 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -216,6 +216,26 @@ is_abbreviated:
 	return error("unknown option `%s'", arg);
 }
 
+void check_typos(const char *arg, const struct option *options)
+{
+	if (strlen(arg) < 3)
+		return;
+
+	if (!prefixcmp(arg, "no-")) {
+		error ("did you mean `--%s` (with two dashes ?)", arg);
+		exit(129);
+	}
+
+	for (; options->type != OPTION_END; options++) {
+		if (!options->long_name)
+			continue;
+		if (!prefixcmp(options->long_name, arg)) {
+			error ("did you mean `--%s` (with two dashes ?)", arg);
+			exit(129);
+		}
+	}
+}
+
 static NORETURN void usage_with_options_internal(const char * const *,
                                                  const struct option *, int);
 
@@ -235,12 +255,18 @@ int parse_options(int argc, const char **argv, const struct option *options,
 
 		if (arg[1] != '-') {
 			args.opt = arg + 1;
-			do {
+			if (*args.opt == 'h')
+				usage_with_options(usagestr, options);
+			if (parse_short_opt(&args, options) < 0)
+				usage_with_options(usagestr, options);
+			if (args.opt)
+				check_typos(arg + 1, options);
+			while (args.opt) {
 				if (*args.opt == 'h')
 					usage_with_options(usagestr, options);
 				if (parse_short_opt(&args, options) < 0)
 					usage_with_options(usagestr, options);
-			} while (args.opt);
+			}
 			continue;
 		}
 
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 462fdf2..0a3b55d 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -19,6 +19,7 @@ string options
                           get a string
     --string2 <str>       get another string
     --st <st>             get another string (pervert ordering)
+    -o <str>              get another string
 
 EOF
 
@@ -103,4 +104,14 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' '
 	git diff expect output
 '
 
+cat > expect.err << EOF
+error: did you mean \`--boolean\` (with two dashes ?)
+EOF
+
+test_expect_success 'detect possible typos' '
+	! test-parse-options -boolean > output 2> output.err &&
+	test ! -s output &&
+	git diff expect.err output.err
+'
+
 test_done
diff --git a/test-parse-options.c b/test-parse-options.c
index 4d3e2ec..eed8a02 100644
--- a/test-parse-options.c
+++ b/test-parse-options.c
@@ -19,6 +19,7 @@ int main(int argc, const char **argv)
 		OPT_STRING('s', "string", &string, "string", "get a string"),
 		OPT_STRING(0, "string2", &string, "str", "get another string"),
 		OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"),
+		OPT_STRING('o', NULL, &string, "str", "get another string"),
 		OPT_END(),
 	};
 	int i;
-- 
1.5.4.rc4.24.g5232a
Previous: Pierre Habouzit
Message 11 of 11 in “Check for -amend as a common wrong usage of --amend.”
  1. Check for -amend as a common wrong usage of --amend.Pascal Obry, Jan 24, 2008
  2. Pascal ObryJan 24, 2008
  3. Jörg SommerJan 26, 2008
  4. Johannes SchindelinJan 24, 2008
  5. Pascal ObryJan 24, 2008
  6. Charles BaileyJan 24, 2008
  7. Pascal ObryJan 24, 2008
  8. Joey HessJan 24, 2008
  9. Junio C HamanoJan 26, 2008
  10. Pierre HabouzitJan 26, 2008
  11. parse-options: catch some likely in presense of aggregated options.Pierre Habouzit, Jan 26, 2008

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.