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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 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

Attachment: pgpQRHGLfSiVf.pgp
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux