All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] diff: differentiate error handling in parse_color_moved_ws
@ 2018-11-02 21:23 Stefan Beller
  2018-11-03  1:21 ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Beller @ 2018-11-02 21:23 UTC (permalink / raw)
  To: git; +Cc: Stefan Beller

As we check command line options more strictly and allow configuration
variables to be parsed more leniently, we need take different actions
based on whether an unknown value is given on the command line or in the
config.

Move the die() call out of parse_color_moved_ws into the parsing
of command line options. As the function returns a bit field, change
its signature to return an unsigned instead of an int; add a new bit
to signal errors. Once the error is signaled, we discard the other
bits, such that it doesn't matter if the error bit overlaps with any
other bit.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

This is a fresh attempt to cleanup the sloppy part that was mentioned
in https://public-inbox.org/git/xmqqa7nkf6o4.fsf@gitster-ct.c.googlers.com/

Another thing to follow up is to have color-moved-ws imply color-moved.

Thanks,
Stefan


 diff.c | 21 ++++++++++++++-------
 diff.h |  3 ++-
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/diff.c b/diff.c
index 8647db3d30..f21f8b0332 100644
--- a/diff.c
+++ b/diff.c
@@ -291,7 +291,7 @@ static int parse_color_moved(const char *arg)
 		return error(_("color moved setting must be one of 'no', 'default', 'blocks', 'zebra', 'dimmed-zebra', 'plain'"));
 }
 
-static int parse_color_moved_ws(const char *arg)
+static unsigned parse_color_moved_ws(const char *arg)
 {
 	int ret = 0;
 	struct string_list l = STRING_LIST_INIT_DUP;
@@ -312,15 +312,19 @@ static int parse_color_moved_ws(const char *arg)
 			ret |= XDF_IGNORE_WHITESPACE;
 		else if (!strcmp(sb.buf, "allow-indentation-change"))
 			ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE;
-		else
+		else {
+			ret |= COLOR_MOVED_WS_ERROR;
 			error(_("ignoring unknown color-moved-ws mode '%s'"), sb.buf);
+		}
 
 		strbuf_release(&sb);
 	}
 
 	if ((ret & COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE) &&
-	    (ret & XDF_WHITESPACE_FLAGS))
-		die(_("color-moved-ws: allow-indentation-change cannot be combined with other white space modes"));
+	    (ret & XDF_WHITESPACE_FLAGS)) {
+		error(_("color-moved-ws: allow-indentation-change cannot be combined with other white space modes"));
+		ret |= COLOR_MOVED_WS_ERROR;
+	}
 
 	string_list_clear(&l, 0);
 
@@ -341,8 +345,8 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 	if (!strcmp(var, "diff.colormovedws")) {
-		int cm = parse_color_moved_ws(value);
-		if (cm < 0)
+		unsigned cm = parse_color_moved_ws(value);
+		if (cm & COLOR_MOVED_WS_ERROR)
 			return -1;
 		diff_color_moved_ws_default = cm;
 		return 0;
@@ -5035,7 +5039,10 @@ int diff_opt_parse(struct diff_options *options,
 			die("bad --color-moved argument: %s", arg);
 		options->color_moved = cm;
 	} else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
-		options->color_moved_ws_handling = parse_color_moved_ws(arg);
+		unsigned cm = parse_color_moved_ws(arg);
+		if (cm & COLOR_MOVED_WS_ERROR)
+			die("bad --color-moved-ws argument: %s", arg);
+		options->color_moved_ws_handling = cm;
 	} else if (skip_to_optional_arg_default(arg, "--color-words", &options->word_regex, NULL)) {
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
diff --git a/diff.h b/diff.h
index ce5e8a8183..9e8061ca29 100644
--- a/diff.h
+++ b/diff.h
@@ -225,7 +225,8 @@ struct diff_options {
 
 	/* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */
 	#define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5)
-	int color_moved_ws_handling;
+	#define COLOR_MOVED_WS_ERROR (1<<0)
+	unsigned color_moved_ws_handling;
 
 	struct repository *repo;
 };
-- 
2.19.1.930.g4563a0d9d0-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] diff: differentiate error handling in parse_color_moved_ws
  2018-11-02 21:23 [PATCH] diff: differentiate error handling in parse_color_moved_ws Stefan Beller
@ 2018-11-03  1:21 ` Junio C Hamano
  2018-11-05  6:12   ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2018-11-03  1:21 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

>  
> -static int parse_color_moved_ws(const char *arg)
> +static unsigned parse_color_moved_ws(const char *arg)
>  {
>  	int ret = 0;
>  	struct string_list l = STRING_LIST_INIT_DUP;
> @@ -312,15 +312,19 @@ static int parse_color_moved_ws(const char *arg)
>  			ret |= XDF_IGNORE_WHITESPACE;
>  		else if (!strcmp(sb.buf, "allow-indentation-change"))
>  			ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE;
> -		else
> +		else {
> +			ret |= COLOR_MOVED_WS_ERROR;
>  			error(_("ignoring unknown color-moved-ws mode '%s'"), sb.buf);
> +		}
> ...  
>  	} else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
> -		options->color_moved_ws_handling = parse_color_moved_ws(arg);
> +		unsigned cm = parse_color_moved_ws(arg);
> +		if (cm & COLOR_MOVED_WS_ERROR)
> +			die("bad --color-moved-ws argument: %s", arg);
> +		options->color_moved_ws_handling = cm;

Excellent.

Will queue.  Perhaps a test or two can follow to ensure a bad value
from config does not kill while a command line does?

Thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] diff: differentiate error handling in parse_color_moved_ws
  2018-11-03  1:21 ` Junio C Hamano
@ 2018-11-05  6:12   ` Junio C Hamano
  2018-11-05 18:19     ` Stefan Beller
  0 siblings, 1 reply; 6+ messages in thread
From: Junio C Hamano @ 2018-11-05  6:12 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> Stefan Beller <sbeller@google.com> writes:
>
>>  
>> -static int parse_color_moved_ws(const char *arg)
>> +static unsigned parse_color_moved_ws(const char *arg)
>>  {
>>  	int ret = 0;
>>  	struct string_list l = STRING_LIST_INIT_DUP;
>> @@ -312,15 +312,19 @@ static int parse_color_moved_ws(const char *arg)
>>  			ret |= XDF_IGNORE_WHITESPACE;
>>  		else if (!strcmp(sb.buf, "allow-indentation-change"))
>>  			ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE;
>> -		else
>> +		else {
>> +			ret |= COLOR_MOVED_WS_ERROR;
>>  			error(_("ignoring unknown color-moved-ws mode '%s'"), sb.buf);
>> +		}
>> ...  
>>  	} else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
>> -		options->color_moved_ws_handling = parse_color_moved_ws(arg);
>> +		unsigned cm = parse_color_moved_ws(arg);
>> +		if (cm & COLOR_MOVED_WS_ERROR)
>> +			die("bad --color-moved-ws argument: %s", arg);
>> +		options->color_moved_ws_handling = cm;
>
> Excellent.
>
> Will queue.  Perhaps a test or two can follow to ensure a bad value
> from config does not kill while a command line does?

Wait.  This does not fix

	git -c diff.colormovedws=nonsense diff

that dies with an error message---it should ignore the config and at
moat issue a warning.

The command line handling of

	git diff --color-moved-ws=nonsense

does correctly die, but it first says "error: ignoring" before
saying "fatal: bad argument", which is suboptimal.

So, not so excellent (yet) X-<.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] diff: differentiate error handling in parse_color_moved_ws
  2018-11-05  6:12   ` Junio C Hamano
@ 2018-11-05 18:19     ` Stefan Beller
  2018-11-13 21:33       ` [PATCH] diff: align move detection error handling with other options Stefan Beller
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Beller @ 2018-11-05 18:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

On Sun, Nov 4, 2018 at 10:12 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Junio C Hamano <gitster@pobox.com> writes:
>
> > Stefan Beller <sbeller@google.com> writes:
> >
> >>
> >> -static int parse_color_moved_ws(const char *arg)
> >> +static unsigned parse_color_moved_ws(const char *arg)
> >>  {
> >>      int ret = 0;
> >>      struct string_list l = STRING_LIST_INIT_DUP;
> >> @@ -312,15 +312,19 @@ static int parse_color_moved_ws(const char *arg)
> >>                      ret |= XDF_IGNORE_WHITESPACE;
> >>              else if (!strcmp(sb.buf, "allow-indentation-change"))
> >>                      ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE;
> >> -            else
> >> +            else {
> >> +                    ret |= COLOR_MOVED_WS_ERROR;
> >>                      error(_("ignoring unknown color-moved-ws mode '%s'"), sb.buf);
> >> +            }
> >> ...
> >>      } else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
> >> -            options->color_moved_ws_handling = parse_color_moved_ws(arg);
> >> +            unsigned cm = parse_color_moved_ws(arg);
> >> +            if (cm & COLOR_MOVED_WS_ERROR)
> >> +                    die("bad --color-moved-ws argument: %s", arg);
> >> +            options->color_moved_ws_handling = cm;
> >
> > Excellent.
> >
> > Will queue.  Perhaps a test or two can follow to ensure a bad value
> > from config does not kill while a command line does?
>
> Wait.  This does not fix
>
>         git -c diff.colormovedws=nonsense diff
>
> that dies with an error message---it should ignore the config and at
> moat issue a warning.

$ git -c core.abbrev=41 diff
error: abbrev length out of range: 41
fatal: unable to parse 'core.abbrev' from command-line config
$ ./git -c  diff.colormovedws=nonsense diff HEAD
error: ignoring unknown color-moved-ws mode 'nonsense'
fatal: unable to parse 'diff.colormovedws' from command-line config

Ah, I see the issue there. We actually have to return 'success' to the
config machinery after the warning claiming ignoring the setting or
we'd have to reword the warning to state we're not ignoring the bogus
setting.

> The command line handling of
>
>         git diff --color-moved-ws=nonsense
>
> does correctly die, but it first says "error: ignoring" before
> saying "fatal: bad argument", which is suboptimal.

So to find the analogous here, maybe:

$ git diff --color=bogus
error: option `color' expects "always", "auto", or "never"

> So, not so excellent (yet) X-<.

So to reach excellence, we'd want to reword the warning
message and a test.

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] diff: align move detection error handling with other options
  2018-11-05 18:19     ` Stefan Beller
@ 2018-11-13 21:33       ` Stefan Beller
  2018-11-14  7:27         ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Stefan Beller @ 2018-11-13 21:33 UTC (permalink / raw)
  To: gitster; +Cc: git, Stefan Beller

This changes the error handling for the options --color-moved-ws
and --color-moved-ws to be like the rest of the options.

Move the die() call out of parse_color_moved_ws into the parsing
of command line options. As the function returns a bit field, change
its signature to return an unsigned instead of an int; add a new bit
to signal errors. Once the error is signaled, we discard the other
bits, such that it doesn't matter if the error bit overlaps with any
other bit.

Signed-off-by: Stefan Beller <sbeller@google.com>
---

c.f.
./git -c diff.colormovedws=bogus diff HEAD
error: unknown color-moved-ws mode 'bogus'
fatal: unable to parse 'diff.colormovedws' from command-line config
./git -c core.abbrev=41 diff
error: abbrev length out of range: 41
fatal: unable to parse 'core.abbrev' from command-line config

./git diff --color=bogus
error: option `color' expects "always", "auto", or "never"
./git -c diff.colormovedws=bogus diff HEAD
error: unknown color-moved-ws mode 'bogus'
fatal: unable to parse 'diff.colormovedws' from command-line config


 diff.c                     | 25 ++++++++++++++++---------
 diff.h                     |  3 ++-
 t/t4015-diff-whitespace.sh | 18 ++++++++++++++++++
 3 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/diff.c b/diff.c
index 8647db3d30..d7d467b605 100644
--- a/diff.c
+++ b/diff.c
@@ -291,7 +291,7 @@ static int parse_color_moved(const char *arg)
 		return error(_("color moved setting must be one of 'no', 'default', 'blocks', 'zebra', 'dimmed-zebra', 'plain'"));
 }
 
-static int parse_color_moved_ws(const char *arg)
+static unsigned parse_color_moved_ws(const char *arg)
 {
 	int ret = 0;
 	struct string_list l = STRING_LIST_INIT_DUP;
@@ -312,15 +312,19 @@ static int parse_color_moved_ws(const char *arg)
 			ret |= XDF_IGNORE_WHITESPACE;
 		else if (!strcmp(sb.buf, "allow-indentation-change"))
 			ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE;
-		else
-			error(_("ignoring unknown color-moved-ws mode '%s'"), sb.buf);
+		else {
+			ret |= COLOR_MOVED_WS_ERROR;
+			error(_("unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', 'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'"), sb.buf);
+		}
 
 		strbuf_release(&sb);
 	}
 
 	if ((ret & COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE) &&
-	    (ret & XDF_WHITESPACE_FLAGS))
-		die(_("color-moved-ws: allow-indentation-change cannot be combined with other white space modes"));
+	    (ret & XDF_WHITESPACE_FLAGS)) {
+		error(_("color-moved-ws: allow-indentation-change cannot be combined with other white space modes"));
+		ret |= COLOR_MOVED_WS_ERROR;
+	}
 
 	string_list_clear(&l, 0);
 
@@ -341,8 +345,8 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 	if (!strcmp(var, "diff.colormovedws")) {
-		int cm = parse_color_moved_ws(value);
-		if (cm < 0)
+		unsigned cm = parse_color_moved_ws(value);
+		if (cm & COLOR_MOVED_WS_ERROR)
 			return -1;
 		diff_color_moved_ws_default = cm;
 		return 0;
@@ -5032,10 +5036,13 @@ int diff_opt_parse(struct diff_options *options,
 	else if (skip_prefix(arg, "--color-moved=", &arg)) {
 		int cm = parse_color_moved(arg);
 		if (cm < 0)
-			die("bad --color-moved argument: %s", arg);
+			return error("bad --color-moved argument: %s", arg);
 		options->color_moved = cm;
 	} else if (skip_prefix(arg, "--color-moved-ws=", &arg)) {
-		options->color_moved_ws_handling = parse_color_moved_ws(arg);
+		unsigned cm = parse_color_moved_ws(arg);
+		if (cm & COLOR_MOVED_WS_ERROR)
+			return -1;
+		options->color_moved_ws_handling = cm;
 	} else if (skip_to_optional_arg_default(arg, "--color-words", &options->word_regex, NULL)) {
 		options->use_color = 1;
 		options->word_diff = DIFF_WORDS_COLOR;
diff --git a/diff.h b/diff.h
index ce5e8a8183..9e8061ca29 100644
--- a/diff.h
+++ b/diff.h
@@ -225,7 +225,8 @@ struct diff_options {
 
 	/* XDF_WHITESPACE_FLAGS regarding block detection are set at 2, 3, 4 */
 	#define COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE (1<<5)
-	int color_moved_ws_handling;
+	#define COLOR_MOVED_WS_ERROR (1<<0)
+	unsigned color_moved_ws_handling;
 
 	struct repository *repo;
 };
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index a9fb226c5a..9a3e4fdfec 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -1890,6 +1890,24 @@ test_expect_success 'compare whitespace delta across moved blocks' '
 	test_cmp expected actual
 '
 
+test_expect_success 'bogus settings in move detection erroring out' '
+	test_must_fail git diff --color-moved=bogus 2>err &&
+	test_i18ngrep "must be one of" err &&
+	test_i18ngrep bogus err &&
+
+	test_must_fail git -c diff.colormoved=bogus diff 2>err &&
+	test_i18ngrep "must be one of" err &&
+	test_i18ngrep "from command-line config" err &&
+
+	test_must_fail git diff --color-moved-ws=bogus 2>err &&
+	test_i18ngrep "possible values" err &&
+	test_i18ngrep bogus err &&
+
+	test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
+	test_i18ngrep "possible values" err &&
+	test_i18ngrep "from command-line config" err
+'
+
 test_expect_success 'compare whitespace delta incompatible with other space options' '
 	test_must_fail git diff \
 		--color-moved-ws=allow-indentation-change,ignore-all-space \
-- 
2.19.1.1215.g8438c0b245-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] diff: align move detection error handling with other options
  2018-11-13 21:33       ` [PATCH] diff: align move detection error handling with other options Stefan Beller
@ 2018-11-14  7:27         ` Junio C Hamano
  0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2018-11-14  7:27 UTC (permalink / raw)
  To: Stefan Beller; +Cc: git

Stefan Beller <sbeller@google.com> writes:

>Subject: Re: [PATCH] diff: align move detection error handling with other options

When sending an updated version of existing topic, please make sure
you indicate as such with v$n etc.  I will assume that this is to
replace the patch queued on sb/diff-color-moved-config-option-fixup
topic.  Please do not assume that all messages on the References:
header are visible in the readers' MUA to show which thread it is a
response to.  At least a hint like v$n (or mentioning the name of
the topic branch if the previous round is already in 'pu') would
make the reader realize that the References: header can be used if
the reader wants to find in what context the patch is relevant,
especially when redoing a change whose previous round is more than a
week old, as we see too many changes in a day already.

> This changes the error handling for the options --color-moved-ws
> and --color-moved-ws to be like the rest of the options.
>
> Move the die() call out of parse_color_moved_ws into the parsing
> of command line options. As the function returns a bit field, change
> its signature to return an unsigned instead of an int; add a new bit
> to signal errors. Once the error is signaled, we discard the other
> bits, such that it doesn't matter if the error bit overlaps with any
> other bit.

OK.  That sound better than the original.

>
> Signed-off-by: Stefan Beller <sbeller@google.com>
> ---
>
> c.f.
> ./git -c diff.colormovedws=bogus diff HEAD
> error: unknown color-moved-ws mode 'bogus'
> fatal: unable to parse 'diff.colormovedws' from command-line config

These double messages may be something we want to fix eventually,
but I think that the issue is not specific to the config callback of
diff API, but something the config API needs to support to allow its
users produce a better single message (the first part is merely
giving a more detailed explanation why Git was unable to parse, and
should ideally be folded into the second part).

More generally, even if git_diff_ui_config() was called, as long as
we do not do the "--color-moved" and "--color-moved-ws" operations,
the user shouldn't even get an "unknown mode" message, let alone
"fatal".  The above (and other existing uses of "return -1"s in the
same config callback) should actually become an example of what not
to do, as "diff HEAD" does not *care* what value that variable has.

But again, fixing that anti-pattern is a much larger change.  Once
we move diff.c to the more modern git_config_get*() based interface,
instead of the old style git_config() callback based interface, it
would become easier to update it so that the complaint will be given
(and kill the command) only when a variable whose value actually
_matters_ is unparsable.

Thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-11-14  7:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-02 21:23 [PATCH] diff: differentiate error handling in parse_color_moved_ws Stefan Beller
2018-11-03  1:21 ` Junio C Hamano
2018-11-05  6:12   ` Junio C Hamano
2018-11-05 18:19     ` Stefan Beller
2018-11-13 21:33       ` [PATCH] diff: align move detection error handling with other options Stefan Beller
2018-11-14  7:27         ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.