All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 2/2] builtin-apply: teach whitespace_rules
Date: Fri, 23 Nov 2007 20:25:56 -0800	[thread overview]
Message-ID: <7v4pfcs20b.fsf@gitster.siamese.dyndns.org> (raw)
In-Reply-To: <7v8x4os223.fsf@gitster.siamese.dyndns.org> (Junio C. Hamano's message of "Fri, 23 Nov 2007 20:24:52 -0800")

We earlier introduced core.whitespace to allow users to tweak the
definition of what the "whitespace errors" are, for the purpose of diff
output highlighting.  This teaches the same to git-apply, so that the
command can both detect (when --whitespace=warn option is given) and fix
(when --whitespace=fix option is given) as configured.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-apply.c          |   68 +++++++++++++++++-------
 t/t4124-apply-ws-rule.sh |  133 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+), 19 deletions(-)
 create mode 100755 t/t4124-apply-ws-rule.sh

diff --git a/builtin-apply.c b/builtin-apply.c
index eb09bfe..e04b493 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -910,23 +910,35 @@ static void check_whitespace(const char *line, int len)
 	 * this function.  That is, an addition of an empty line would
 	 * check the '+' here.  Sneaky...
 	 */
-	if (isspace(line[len-2]))
+	if ((whitespace_rule & WS_TRAILING_SPACE) && isspace(line[len-2]))
 		goto error;
 
 	/*
 	 * Make sure that there is no space followed by a tab in
 	 * indentation.
 	 */
-	err = "Space in indent is followed by a tab";
-	for (i = 1; i < len; i++) {
-		if (line[i] == '\t') {
-			if (seen_space)
-				goto error;
-		}
-		else if (line[i] == ' ')
-			seen_space = 1;
-		else
-			break;
+	if (whitespace_rule & WS_SPACE_BEFORE_TAB) {
+		err = "Space in indent is followed by a tab";
+		for (i = 1; i < len; i++) {
+			if (line[i] == '\t') {
+				if (seen_space)
+					goto error;
+			}
+			else if (line[i] == ' ')
+				seen_space = 1;
+			else
+				break;
+		}
+	}
+
+	/*
+	 * Make sure that the indentation does not contain more than
+	 * 8 spaces.
+	 */
+	if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
+	    (8 < len) && !strncmp("+        ", line, 9)) {
+		err = "Indent more than 8 places with spaces";
+		goto error;
 	}
 	return;
 
@@ -1581,7 +1593,8 @@ static int apply_line(char *output, const char *patch, int plen)
 	/*
 	 * Strip trailing whitespace
 	 */
-	if (1 < plen && isspace(patch[plen-1])) {
+	if ((whitespace_rule & WS_TRAILING_SPACE) &&
+	    (1 < plen && isspace(patch[plen-1]))) {
 		if (patch[plen] == '\n')
 			add_nl_to_tail = 1;
 		plen--;
@@ -1597,11 +1610,16 @@ static int apply_line(char *output, const char *patch, int plen)
 		char ch = patch[i];
 		if (ch == '\t') {
 			last_tab_in_indent = i;
-			if (0 <= last_space_in_indent)
+			if ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&
+			    0 <= last_space_in_indent)
+			    need_fix_leading_space = 1;
+		} else if (ch == ' ') {
+			last_space_in_indent = i;
+			if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
+			    last_tab_in_indent < 0 &&
+			    8 <= i)
 				need_fix_leading_space = 1;
 		}
-		else if (ch == ' ')
-			last_space_in_indent = i;
 		else
 			break;
 	}
@@ -1609,11 +1627,21 @@ static int apply_line(char *output, const char *patch, int plen)
 	buf = output;
 	if (need_fix_leading_space) {
 		int consecutive_spaces = 0;
+		int last = last_tab_in_indent + 1;
+
+		if (whitespace_rule & WS_INDENT_WITH_NON_TAB) {
+			/* have "last" point at one past the indent */
+			if (last_tab_in_indent < last_space_in_indent)
+				last = last_space_in_indent + 1;
+			else
+				last = last_tab_in_indent + 1;
+		}
+
 		/*
-		 * between patch[1..last_tab_in_indent] strip the
-		 * funny spaces, updating them to tab as needed.
+		 * between patch[1..last], strip the funny spaces,
+		 * updating them to tab as needed.
 		 */
-		for (i = 1; i < last_tab_in_indent; i++, plen--) {
+		for (i = 1; i < last; i++, plen--) {
 			char ch = patch[i];
 			if (ch != ' ') {
 				consecutive_spaces = 0;
@@ -1626,8 +1654,10 @@ static int apply_line(char *output, const char *patch, int plen)
 				}
 			}
 		}
+		while (0 < consecutive_spaces--)
+			*output++ = ' ';
 		fixed = 1;
-		i = last_tab_in_indent;
+		i = last;
 	}
 	else
 		i = 1;
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
new file mode 100755
index 0000000..f53ac46
--- /dev/null
+++ b/t/t4124-apply-ws-rule.sh
@@ -0,0 +1,133 @@
+#!/bin/sh
+
+test_description='core.whitespace rules and git-apply'
+
+. ./test-lib.sh
+
+prepare_test_file () {
+
+	# A line that has character X is touched iff RULE is in effect:
+	#       X  RULE
+	#   	!  trailing-space
+	#   	@  space-before-tab
+	#   	#  indent-with-non-tab
+	sed -e "s/_/ /g" -e "s/>/	/" <<-\EOF
+		An_SP in an ordinary line>and a HT.
+		>A HT.
+		_>A SP and a HT (@).
+		_>_A SP, a HT and a SP (@).
+		_______Seven SP.
+		________Eight SP (#).
+		_______>Seven SP and a HT (@).
+		________>Eight SP and a HT (@#).
+		_______>_Seven SP, a HT and a SP (@).
+		________>_Eight SP, a HT and a SP (@#).
+		_______________Fifteen SP (#).
+		_______________>Fifteen SP and a HT (@#).
+		________________Sixteen SP (#).
+		________________>Sixteen SP and a HT (@#).
+		_____a__Five SP, a non WS, two SP.
+		A line with a (!) trailing SP_
+		A line with a (!) trailing HT>
+	EOF
+}
+
+apply_patch () {
+	>target &&
+	sed -e "s|\([ab]\)/file|\1/target|" <patch |
+	git apply "$@"
+}
+
+test_fix () {
+
+	# fix should not barf
+	apply_patch --whitespace=fix || return 1
+
+	# find touched lines
+	diff file target | sed -n -e "s/^> //p" >fixed
+
+	# the changed lines are all expeced to change
+	fixed_cnt=$(wc -l <fixed)
+	case "$1" in
+	'') expect_cnt=$fixed_cnt ;;
+	?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;;
+	esac
+	test $fixed_cnt -eq $expect_cnt || return 1
+
+	# and we are not missing anything
+	case "$1" in
+	'') expect_cnt=0 ;;
+	?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;;
+	esac
+	test $fixed_cnt -eq $expect_cnt || return 1
+
+	# Get the patch actually applied
+	git diff-files -p target >fixed-patch
+	test -s fixed-patch && return 0
+
+	# Make sure it is complaint-free
+	>target
+	git apply --whitespace=error-all <fixed-patch
+
+}
+
+test_expect_success setup '
+
+	>file &&
+	git add file &&
+	prepare_test_file >file &&
+	git diff-files -p >patch &&
+	>target &&
+	git add target
+
+'
+
+test_expect_success 'whitespace=nowarn, default rule' '
+
+	apply_patch --whitespace=nowarn &&
+	diff file target
+
+'
+
+test_expect_success 'whitespace=warn, default rule' '
+
+	apply_patch --whitespace=warn &&
+	diff file target
+
+'
+
+test_expect_success 'whitespace=error-all, default rule' '
+
+	apply_patch --whitespace=error-all && return 1
+	test -s target && return 1
+	: happy
+
+'
+
+test_expect_success 'whitespace=error-all, no rule' '
+
+	git config core.whitespace -trailing,-space-before,-indent &&
+	apply_patch --whitespace=error-all &&
+	diff file target
+
+'
+
+for t in - ''
+do
+	case "$t" in '') tt='!' ;; *) tt= ;; esac
+	for s in - ''
+	do
+		case "$s" in '') ts='@' ;; *) ts= ;; esac
+		for i in - ''
+		do
+			case "$i" in '') ti='#' ;; *) ti= ;; esac
+			rule=${t}trailing,${s}space,${i}indent &&
+			test_expect_success "rule=$rule" '
+				git config core.whitespace "$rule" &&
+				test_fix "$tt$ts$ti"
+			'
+		done
+	done
+done
+
+test_done
-- 
1.5.3.6.1991.ge56ac

  reply	other threads:[~2007-11-24  4:26 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-24  4:24 [PATCH 1/2] builtin-apply: rename "whitespace" variables and fix styles Junio C Hamano
2007-11-24  4:25 ` Junio C Hamano [this message]
2007-11-24 20:09   ` [PATCH 3/2] core.whitespace: documentation updates Junio C Hamano
2007-11-24 20:22     ` J. Bruce Fields
2007-11-24 21:42       ` Junio C Hamano
2007-11-25 21:58         ` J. Bruce Fields
2007-12-06  9:04           ` Junio C Hamano
2007-12-06 19:18             ` J. Bruce Fields
2007-12-16  3:48             ` J. Bruce Fields
2007-12-16  3:48               ` [PATCH] whitespace: fix off-by-one error in non-space-in-indent checking J. Bruce Fields
2007-12-16  3:48                 ` [PATCH] whitespace: reorganize initial-indent check J. Bruce Fields
2007-12-16  3:48                   ` [PATCH] whitespace: minor cleanup J. Bruce Fields
2007-12-16  3:48                     ` [PATCH] whitespace: fix initial-indent checking J. Bruce Fields
2007-12-16  3:48                       ` [PATCH] whitespace: more accurate initial-indent highlighting J. Bruce Fields
2007-12-16  3:48                         ` [PATCH] whitespace: fix config.txt description of indent-with-non-tab J. Bruce Fields
2007-12-16  3:54                       ` [PATCH] whitespace: fix initial-indent checking J. Bruce Fields
2007-12-16 20:40                         ` Junio C Hamano
2007-12-16 21:19                           ` J. Bruce Fields
2007-12-16  9:08                       ` Jakub Narebski
2007-12-16 10:00                         ` Wincent Colaiuta
2007-12-16 16:26                           ` J. Bruce Fields
2007-12-16 18:16                             ` Jakub Narebski
2007-12-16 18:24                               ` Jakub Narebski
2007-12-16 19:59                               ` J. Bruce Fields
2007-12-16 20:31                                 ` Jakub Narebski
2007-12-16 21:00                                 ` Junio C Hamano
2007-12-16 19:43                             ` Junio C Hamano
2007-12-16 10:02                   ` [PATCH] whitespace: reorganize initial-indent check Wincent Colaiuta
2007-12-16 16:31                     ` J. Bruce Fields
2007-12-16 16:31                       ` [PATCH 1/6] whitespace: fix off-by-one error in non-space-in-indent checking J. Bruce Fields
2007-12-16 16:31                         ` [PATCH 2/6] whitespace: reorganize initial-indent check J. Bruce Fields
2007-12-16 16:31                           ` [PATCH 3/6] whitespace: minor cleanup J. Bruce Fields
2007-12-16 16:31                             ` [PATCH 4/6] whitespace: fix initial-indent checking J. Bruce Fields
2007-12-16 16:31                               ` [PATCH 5/6] whitespace: more accurate initial-indent highlighting J. Bruce Fields
2007-12-16 16:31                                 ` [PATCH 6/6] whitespace: fix config.txt description of indent-with-non-tab J. Bruce Fields
2007-12-16 17:58                                   ` builtin-apply whitespace J. Bruce Fields
2007-12-16 17:58                                     ` [PATCH 1/2] builtin-apply: minor cleanup of whitespace detection J. Bruce Fields
2007-12-16 17:58                                       ` [PATCH 2/2] builtin-apply: stronger indent-with-on-tab fixing J. Bruce Fields
2007-12-17  8:00                                 ` [PATCH 5/6] whitespace: more accurate initial-indent highlighting Wincent Colaiuta
2007-12-17  8:04                                   ` Junio C Hamano
2007-12-18  0:32                                     ` Jakub Narebski
2007-12-18  0:51                                       ` Junio C Hamano
2007-12-16 21:06                     ` [PATCH] whitespace: reorganize initial-indent check Junio C Hamano

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

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

  git send-email \
    --in-reply-to=7v4pfcs20b.fsf@gitster.siamese.dyndns.org \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.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.
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.