dir.c:trim_trailing_spaces(): fix for " \ " sequence
Discard the unnecessary 'nr_spaces' variable, remove 'strlen()' and improve the 'if' structure. Switch to pointers instead of integers to control the loop. Slightly more rare occurrences of 'text \ ' with a backslash in between spaces are handled correctly. Namely, the code in 7e2e4b37 (dir: ignore trailing spaces in exclude patterns, 2014-02-09) does not reset 'last_space' when a backslash is encountered and the above line stays intact as a result. Add a test at the end of t/t0008-ignores.sh to exhibit this behavior. Signed-off-by: Pasha Bolokhov <pasha.bolokhov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pasha Bolokhov committed
Jun 2, 2014 at 15:36 UTC
e61a6c1d8272f9d7bdc861ed28bfac5fb7e33556
2 files changed
+42
-15
dir.c
+19
-15
@@ -508,21 +508,25 @@ void clear_exclude_list(struct exclude_list *el)
508
509
static void trim_trailing_spaces(char *buf)
510
{
511
- int i, last_space = -1, nr_spaces, len = strlen(buf);
512
- for (i = 0; i < len; i++)
513
- if (buf[i] == '\\')
514
- i++;
515
- else if (buf[i] == ' ') {
516
- if (last_space == -1) {
517
- last_space = i;
518
- nr_spaces = 1;
519
- } else
520
- nr_spaces++;
521
- } else
522
- last_space = -1;
523
-
524
- if (last_space != -1 && last_space + nr_spaces == len)
525
- buf[last_space] = '\0';
511
+ char *p, *last_space = NULL;
512
+
513
+ for (p = buf; *p; p++)
514
+ switch (*p) {
515
+ case ' ':
516
+ if (!last_space)
517
+ last_space = p;
518
+ break;
519
+ case '\\':
520
+ p++;
521
+ if (!*p)
522
+ return;
523
+ /* fallthrough */
524
+ default:
525
+ last_space = NULL;
526
+ }
527
+
528
+ if (last_space)
529
+ *last_space = '\0';
530
}
531
532
int add_excludes_from_file_to_list(const char *fname,
t/t0008-ignores.sh
+23
@@ -806,4 +806,27 @@ test_expect_success !MINGW 'quoting allows trailing whitespace' '
806
test_cmp err.expect err
807
'
808
809
+test_expect_success NOT_MINGW,NOT_CYGWIN 'correct handling of backslashes' '
810
+ rm -rf whitespace &&
811
+ mkdir whitespace &&
812
+ >"whitespace/trailing 1 " &&
813
+ >"whitespace/trailing 2 \\\\" &&
814
+ >"whitespace/trailing 3 \\\\" &&
815
+ >"whitespace/trailing 4 \\ " &&
816
+ >"whitespace/trailing 5 \\ \\ " &&
817
+ >"whitespace/trailing 6 \\a\\" &&
818
+ >whitespace/untracked &&
819
+ echo "whitespace/trailing 1 \\ " >ignore &&
820
+ echo "whitespace/trailing 2 \\\\\\\\\\\\\\\\" >>ignore &&
821
+ echo "whitespace/trailing 3 \\\\\\\\\\\\\\\\ " >>ignore &&
822
+ echo "whitespace/trailing 4 \\\\\\\\\\\\ " >>ignore &&
823
+ echo "whitespace/trailing 5 \\\\\\\\ \\\\\\\\\\\\ " >>ignore &&
824
+ echo "whitespace/trailing 6 \\\\\\\\a\\\\\\\\" >>ignore &&
825
+ echo whitespace/untracked >expect &&
826
+ >err.expect &&
827
+ git ls-files -o -X ignore whitespace >actual 2>err &&
828
+ test_cmp expect actual &&
829
+ test_cmp err.expect err
830
+'
831
+
832
test_done