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@xxxxxxxxx> --- 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 - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html