# [PATCH] Tech 'git-apply' that spaces before a tab are candidate for stripping

2 messages from 2007-05-19 to 2007-05-20. Participants: Marco Costalba, Junio C Hamano.
Thread: https://gitlist.dev/t/8225

## Marco Costalba, 2007-05-19 16:44

Subject: [PATCH] Tech 'git-apply' that spaces before a tab are candidate for stripping
Message-ID: <e5bfff550705190944y44cb57baiccb139b1d649face@mail.gmail.com>
URL: https://gitlist.dev/e/e5bfff550705190944y44cb57baiccb139b1d649face%40mail.gmail.com

```
Currently 'git-apply' identify as stealth space a line starting with
spaces followed by a tab.

This patch updates the algorithm to find spaces + tab also in the
middle of a line and not only at the beginning.

As example lines like

"#define MY_VALUE   \t 1"

are now identified and cleaned up if option '--whitespace=strip' is
used.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
---

There are a bunch of this type in current git tree.

  builtin-apply.c |   72 ++++++++++++++++++++++++++++++------------------------
 1 files changed, 40 insertions(+), 32 deletions(-)

diff --git a/builtin-apply.c b/builtin-apply.c
index f17f838..9e82757 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -1586,6 +1586,32 @@ static void remove_last_line(const char **rbuf,
int *rsize)
  	*rsize = offset + 1;
 }

+static int copy_line(char **output_ptr, const char *patch, int start, int len)
+{
+	char *output = *output_ptr;
+	int space_start = 0;
+	int i, end = start + len;
+
+	for (i = start; i < end; i++) {
+
+		char ch = patch[i];
+
+		if (ch == ' ' && !space_start)
+			space_start = i;
+
+		else if (space_start && ch != ' ') {
+			if (ch == '\t') {
+				*output_ptr = output - (i - space_start);
+				return space_start;
+			}
+			space_start = 0;
+		}
+		*output++ = ch;
+	}
+	*output_ptr = output;
+	return 0;
+}
+
 struct buffer_desc {
 	char *buffer;
 	unsigned long size;
@@ -1602,17 +1628,14 @@ static int apply_line(char *output, const char
*patch, int plen)
 	int i;
 	int add_nl_to_tail = 0;
 	int fixed = 0;
-	int last_tab_in_indent = -1;
-	int last_space_in_indent = -1;
-	int need_fix_leading_space = 0;
-	char *buf;
+	int space_start;
+	const char *old = output;

 	if ((new_whitespace != strip_whitespace) || !whitespace_error ||
 	    *patch != '+') {
 		memcpy(output, patch + 1, plen);
 		return plen;
 	}
-
 	if (1 < plen && isspace(patch[plen-1])) {
 		if (patch[plen] == '\n')
 			add_nl_to_tail = 1;
@@ -1621,44 +1644,29 @@ static int apply_line(char *output, const char
*patch, int plen)
 			plen--;
 		fixed = 1;
 	}
+	space_start = copy_line(&output, patch, 1, plen);
+	while (space_start) {

-	for (i = 1; i < plen; i++) {
-		char ch = patch[i];
-		if (ch == '\t') {
-			last_tab_in_indent = i;
-			if (0 <= last_space_in_indent)
-				need_fix_leading_space = 1;
-		}
-		else if (ch == ' ')
-			last_space_in_indent = i;
-		else
-			break;
-	}
-
-	buf = output;
-	if (need_fix_leading_space) {
-		/* between patch[1..last_tab_in_indent] strip the
-		 * funny spaces, updating them to tab as needed.
+		/* strip the funny spaces, updating them to tab as needed
+		 * strip is done one space sequence at time, until line end
 		 */
-		for (i = 1; i < last_tab_in_indent; i++, plen--) {
+		fixed = 1;
+		for (i = space_start; i < plen + 1; i++) {
+
 			char ch = patch[i];
 			if (ch != ' ')
-				*output++ = ch;
+				break;
 			else if ((i % 8) == 0)
 				*output++ = '\t';
 		}
-		fixed = 1;
-		i = last_tab_in_indent;
+		space_start = copy_line(&output, patch, i, plen + 1 - i);
 	}
-	else
-		i = 1;
-
-	memcpy(output, patch + i, plen);
 	if (add_nl_to_tail)
-		output[plen++] = '\n';
+		*output++ = '\n';
 	if (fixed)
 		applied_after_stripping++;
-	return output + plen - buf;
+
+	return output - old;
 }

 static int apply_one_fragment(struct buffer_desc *desc, struct
fragment *frag, int inaccurate_eof)
-- 
1.5.2.rc3.88.g4c3ba-dirty

```

## Junio C Hamano, 2007-05-20 07:53

Subject: Re: [PATCH] Tech 'git-apply' that spaces before a tab are candidate for stripping
Message-ID: <7v8xbkrkwo.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7v8xbkrkwo.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <e5bfff550705190944y44cb57baiccb139b1d649face@mail.gmail.com>

```
"Marco Costalba" <mcostalba@gmail.com> writes:

> Currently 'git-apply' identify as stealth space a line starting with
> spaces followed by a tab.
>
> This patch updates the algorithm to find spaces + tab also in the
> middle of a line and not only at the beginning.
>
> As example lines like
>
> "#define MY_VALUE   \t 1"
>
> are now identified and cleaned up if option '--whitespace=strip' is
> used.

I specifically did not want to do the above, as it would also
munge something like this:

	const char string[] = "abc <HT> de";

```
