git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Johan Herland <johan@herland.net>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Johan Herland <johan@herland.net>
Subject: [PATCHv5 7/7] Improve error handling when parsing dirstat parameters
Date: Thu, 28 Apr 2011 03:17:22 +0200	[thread overview]
Message-ID: <1303953442-26536-8-git-send-email-johan@herland.net> (raw)
In-Reply-To: <1303953442-26536-1-git-send-email-johan@herland.net>

When encountering errors or unknown tokens while parsing parameters to the
--dirstat option, it makes sense to die() with an error message informing
the user of which parameter did not make sense. However, when parsing the
diff.dirstat config variable, we cannot simply die(), but should instead
(after warning the user) ignore the erroneous or unrecognized parameter.
After all, future Git versions might add more dirstat parameters, and
using two different Git versions on the same repo should not cripple the
older Git version just because of a parameter that is only understood by
a more recent Git version.

This patch fixes the issue by refactoring the dirstat parameter parsing
so that parse_dirstat_params() keeps on parsing parameters, even if an
earlier parameter was not recognized. When parsing has finished, it returns
zero if all parameters were successfully parsed, and non-zero if one or
more parameters were not recognized.

The parse_dirstat_params() callers then decide (based on the return value
from parse_dirstat_params()) whether to warn and ignore (in case of
diff.dirstat), or to warn and die (in case of --dirstat).

The patch also adds a couple of tests verifying the correct behavior of
--dirstat and diff.dirstat in the face of unknown (possibly future) dirstat
parameters.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johan Herland <johan@herland.net>
---
 diff.c                  |   52 ++++++++++++++++++++++------------------------
 t/t4047-diff-dirstat.sh |   30 +++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 27 deletions(-)

diff --git a/diff.c b/diff.c
index 8703763..1ce21f1 100644
--- a/diff.c
+++ b/diff.c
@@ -70,49 +70,46 @@ static int parse_diff_color_slot(const char *var, int ofs)
 static int parse_dirstat_params(struct diff_options *options, const char *params)
 {
 	const char *p = params;
+	int p_len, ret = 0;
+
 	while (*p) {
-		if (!prefixcmp(p, "changes")) {
-			p += 7;
+		p_len = strchrnul(p, ',') - p;
+		if (!memcmp(p, "changes", p_len)) {
 			DIFF_OPT_CLR(options, DIRSTAT_BY_LINE);
 			DIFF_OPT_CLR(options, DIRSTAT_BY_FILE);
-		} else if (!prefixcmp(p, "lines")) {
-			p += 5;
+		} else if (!memcmp(p, "lines", p_len)) {
 			DIFF_OPT_SET(options, DIRSTAT_BY_LINE);
 			DIFF_OPT_CLR(options, DIRSTAT_BY_FILE);
-		} else if (!prefixcmp(p, "files")) {
-			p += 5;
+		} else if (!memcmp(p, "files", p_len)) {
 			DIFF_OPT_CLR(options, DIRSTAT_BY_LINE);
 			DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
-		} else if (!prefixcmp(p, "noncumulative")) {
-			p += 13;
+		} else if (!memcmp(p, "noncumulative", p_len)) {
 			DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
-		} else if (!prefixcmp(p, "cumulative")) {
-			p += 10;
+		} else if (!memcmp(p, "cumulative", p_len)) {
 			DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
 		} else if (isdigit(*p)) {
 			char *end;
-			options->dirstat_permille = strtoul(p, &end, 10) * 10;
-			p = end;
-			if (*p == '.' && isdigit(*++p)) {
+			int permille = strtoul(p, &end, 10) * 10;
+			if (*end == '.' && isdigit(*++end)) {
 				/* only use first digit */
-				options->dirstat_permille += *p - '0';
+				permille += *end - '0';
 				/* .. and ignore any further digits */
-				while (isdigit(*++p))
+				while (isdigit(*++end))
 					; /* nothing */
 			}
+			if (end - p == p_len)
+				options->dirstat_permille = permille;
+			else
+				ret = error("Failed to parse dirstat cut-off percentage '%.*s'", p_len, p);
 		} else
-			return error("Unknown --dirstat parameter '%s'", p);
-
-		if (*p) {
-			/* more parameters, swallow separator */
-			if (*p != ',')
-				return error("Missing comma separator at char "
-					"%"PRIuMAX" of '%s'",
-					(uintmax_t) (p - params), params);
-			p++;
-		}
+			ret = error("Unknown dirstat parameter '%.*s'", p_len, p);
+
+		p += p_len;
+
+		if (*p)
+			p++; /* more parameters, swallow separator */
 	}
-	return 0;
+	return ret;
 }
 
 static int git_config_rename(const char *var, const char *value)
@@ -196,7 +193,8 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
 
 	if (!strcmp(var, "diff.dirstat")) {
 		default_diff_options.dirstat_permille = diff_dirstat_permille_default;
-		(void) parse_dirstat_params(&default_diff_options, value);
+		if (parse_dirstat_params(&default_diff_options, value))
+			warning("Found errors in 'diff.dirstat' config variable");
 		diff_dirstat_permille_default = default_diff_options.dirstat_permille;
 		return 0;
 	}
diff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh
index 8ca1d58..20a59ac 100755
--- a/t/t4047-diff-dirstat.sh
+++ b/t/t4047-diff-dirstat.sh
@@ -932,4 +932,34 @@ test_expect_success 'diff.dirstat=0,lines' '
 	test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
 '
 
+test_expect_success '--dirstat=future_param,lines,0 should fail loudly' '
+	test_must_fail git diff --dirstat=future_param,lines,0 HEAD^..HEAD >actual_diff_dirstat 2>actual_error &&
+	test_cmp /dev/null actual_diff_dirstat &&
+	grep -q "future_param" actual_error &&
+	grep -q "\--dirstat" actual_error &&
+	test_must_fail git diff --dirstat=future_param,lines,0 -M HEAD^..HEAD >actual_diff_dirstat_M 2>actual_error &&
+	test_cmp /dev/null actual_diff_dirstat_M &&
+	grep -q "future_param" actual_error &&
+	grep -q "\--dirstat" actual_error &&
+	test_must_fail git diff --dirstat=future_param,lines,0 -C -C HEAD^..HEAD >actual_diff_dirstat_CC 2>actual_error &&
+	test_cmp /dev/null actual_diff_dirstat_CC &&
+	grep -q "future_param" actual_error &&
+	grep -q "\--dirstat" actual_error
+'
+
+test_expect_success 'diff.dirstat=future_param,0,lines should warn, but still work' '
+	git -c diff.dirstat=future_param,0,lines diff --dirstat HEAD^..HEAD >actual_diff_dirstat 2>actual_error &&
+	test_cmp expect_diff_dirstat actual_diff_dirstat &&
+	grep -q "future_param" actual_error &&
+	grep -q "diff.dirstat" actual_error &&
+	git -c diff.dirstat=future_param,0,lines diff --dirstat -M HEAD^..HEAD >actual_diff_dirstat_M 2>actual_error &&
+	test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
+	grep -q "future_param" actual_error &&
+	grep -q "diff.dirstat" actual_error &&
+	git -c diff.dirstat=future_param,0,lines diff --dirstat -C -C HEAD^..HEAD >actual_diff_dirstat_CC 2>actual_error &&
+	test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC &&
+	grep -q "future_param" actual_error &&
+	grep -q "diff.dirstat" actual_error
+'
+
 test_done
-- 
1.7.5.rc1.3.g4d7b

  parent reply	other threads:[~2011-04-28  1:17 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-07 13:49 BUG? in --dirstat when rearranging lines in a file Johan Herland
2011-04-07 14:56 ` Linus Torvalds
2011-04-07 22:43   ` Junio C Hamano
2011-04-07 22:59     ` Linus Torvalds
2011-04-08 14:46   ` Johan Herland
2011-04-08 14:48     ` [PATCH 1/3] --dirstat: Document shortcomings compared to --stat or regular diff Johan Herland
2011-04-08 19:50       ` Junio C Hamano
2011-04-08 14:50     ` [PATCH 2/3] --dirstat-by-file: Make it faster and more correct Johan Herland
2011-04-08 14:55     ` [RFC/PATCH 3/3] Teach --dirstat to not completely ignore rearranged lines Johan Herland
2011-04-08 15:04     ` BUG? in --dirstat when rearranging lines in a file Linus Torvalds
2011-04-08 19:56       ` Junio C Hamano
2011-04-10 22:48         ` [PATCHv2 0/3] --dirstat fixes Johan Herland
2011-04-10 22:48           ` [PATCHv2 1/3] --dirstat: Describe non-obvious differences relative to --stat or regular diff Johan Herland
2011-04-10 22:48           ` [PATCHv2 2/3] --dirstat-by-file: Make it faster and more correct Johan Herland
2011-04-11 18:14             ` Junio C Hamano
2011-04-10 22:48           ` [PATCHv2 3/3] Teach --dirstat to not completely ignore rearranged lines within a file Johan Herland
2011-04-11 21:38             ` Junio C Hamano
2011-04-11 21:56               ` Johan Herland
2011-04-11 22:08                 ` Junio C Hamano
2011-04-12  9:22                   ` Johan Herland
2011-04-12  9:24                     ` [PATCH 4/3] --dirstat: In case of renames, use target filename instead of source filename Johan Herland
2011-04-12 14:59                       ` Linus Torvalds
2011-04-12  9:26                     ` [RFC/PATCH 5/3] Alternative --dirstat implementation, based on diffstat analysis Johan Herland
2011-04-12 14:46                       ` Linus Torvalds
2011-04-12 15:08                         ` Linus Torvalds
2011-04-12 22:03                           ` Johan Herland
2011-04-12 22:12                             ` Linus Torvalds
2011-04-12 22:22                             ` Junio C Hamano
2011-04-26  0:01                         ` [PATCH 0/6] --dirstat fixes, part 2 Johan Herland
2011-04-26  0:01                           ` [PATCH 1/6] Add several testcases for --dirstat and friends Johan Herland
2011-04-26  0:01                           ` [PATCH 2/6] Make --dirstat=0 output directories that contribute < 0.1% of changes Johan Herland
2011-04-26  0:01                           ` [PATCH 3/6] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file Johan Herland
2011-04-26 16:36                             ` Junio C Hamano
2011-04-27  2:02                               ` Johan Herland
2011-04-27  4:53                                 ` Junio C Hamano
2011-04-27 20:51                                 ` Junio C Hamano
2011-04-27 21:01                                   ` Junio C Hamano
2011-04-26  0:01                           ` [PATCH 4/6] Add config variable for specifying default --dirstat behavior Johan Herland
2011-04-26 16:43                             ` Junio C Hamano
2011-04-27  2:02                               ` Johan Herland
2011-04-26  0:01                           ` [PATCH 5/6] Use floating point for --dirstat percentages Johan Herland
2011-04-26 16:52                             ` Junio C Hamano
2011-04-27  2:02                               ` Johan Herland
2011-04-27  4:42                                 ` Junio C Hamano
2011-04-27  4:53                                   ` Linus Torvalds
2011-04-27  5:20                                     ` Junio C Hamano
2011-04-26  0:01                           ` [PATCH 6/6] New --dirstat=lines mode, doing dirstat analysis based on diffstat Johan Herland
2011-04-26 16:59                             ` Junio C Hamano
2011-04-27  2:02                               ` Johan Herland
2011-04-26  0:15                           ` [PATCH 0/6] --dirstat fixes, part 2 Linus Torvalds
2011-04-27  2:12                           ` [PATCHv2 " Johan Herland
2011-04-27  2:12                             ` [PATCHv2 1/6] Add several testcases for --dirstat and friends Johan Herland
2011-04-27  2:12                             ` [PATCHv2 2/6] Make --dirstat=0 output directories that contribute < 0.1% of changes Johan Herland
2011-04-27  2:12                             ` [PATCHv2 3/6] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file Johan Herland
2011-04-27  2:12                             ` [PATCHv2 4/6] Add config variable for specifying default --dirstat behavior Johan Herland
2011-04-27  2:12                             ` [PATCHv2 5/6] Use floating point for --dirstat percentages Johan Herland
2011-04-27  2:45                               ` Linus Torvalds
2011-04-27  2:12                             ` [PATCHv2 6/6] New --dirstat=lines mode, doing dirstat analysis based on diffstat Johan Herland
2011-04-27  8:24                             ` [PATCHv3 0/6] --dirstat fixes, part 2 Johan Herland
2011-04-27  8:24                               ` [PATCHv3 1/6] Add several testcases for --dirstat and friends Johan Herland
2011-04-27  8:24                               ` [PATCHv3 2/6] Make --dirstat=0 output directories that contribute < 0.1% of changes Johan Herland
2011-04-27  8:24                               ` [PATCHv3 3/6] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file Johan Herland
2011-04-27  8:24                               ` [PATCHv3 4/6] Add config variable for specifying default --dirstat behavior Johan Herland
2011-04-27  8:24                               ` [PATCHv3 5/6] Allow specifying --dirstat cut-off percentage as a floating point number Johan Herland
2011-04-27  8:37                                 ` Linus Torvalds
2011-04-27 10:29                                   ` [PATCHv4 " Johan Herland
2011-04-27  8:24                               ` [PATCHv3 6/6] New --dirstat=lines mode, doing dirstat analysis based on diffstat Johan Herland
2011-04-28  1:17                               ` [PATCHv5 0/7] --dirstat fixes, part 2 Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 1/7] Add several testcases for --dirstat and friends Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 2/7] Make --dirstat=0 output directories that contribute < 0.1% of changes Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 3/7] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 4/7] Add config variable for specifying default --dirstat behavior Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 5/7] Allow specifying --dirstat cut-off percentage as a floating point number Johan Herland
2011-04-28  1:17                                 ` [PATCHv5 6/7] New --dirstat=lines mode, doing dirstat analysis based on diffstat Johan Herland
2011-04-28  1:17                                 ` Johan Herland [this message]
2011-04-28 18:41                                   ` [PATCHv5 7/7] Improve error handling when parsing dirstat parameters Junio C Hamano
2011-04-28 19:20                                     ` Junio C Hamano
2011-04-28 23:16                                       ` Johan Herland
2011-04-28 23:13                                     ` Johan Herland
2011-04-29  4:06                                       ` Junio C Hamano
2011-04-29  9:36                                         ` [PATCHv6 0/8] --dirstat fixes, part 2 Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 1/8] Add several testcases for --dirstat and friends Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 2/8] Make --dirstat=0 output directories that contribute < 0.1% of changes Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 3/8] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 4/8] Add config variable for specifying default --dirstat behavior Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 5/8] Allow specifying --dirstat cut-off percentage as a floating point number Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 6/8] New --dirstat=lines mode, doing dirstat analysis based on diffstat Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 7/8] Improve error handling when parsing dirstat parameters Johan Herland
2011-04-29  9:36                                           ` [PATCHv6 8/8] Mark dirstat error messages for translation Johan Herland
2011-04-12 18:34                       ` [RFC/PATCH 5/3] Alternative --dirstat implementation, based on diffstat analysis Junio C Hamano
2011-04-10 23:17           ` [PATCHv2 0/3] --dirstat fixes Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1303953442-26536-8-git-send-email-johan@herland.net \
    --to=johan@herland.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).