Skip to content

Commit 7f7ee2f

Browse files
committed
diff -B: colour whitespace errors
We used to send the old and new contents more or less straight out to the output with only the original "old is red, new is green" colouring. Now all the necessary support routines have been prepared, call them with a line of data at a time from the output code and have them check and color whitespace errors in exactly the same way as they are called from the low level diff callback routines. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 018cff7 commit 7f7ee2f

File tree

1 file changed

+49
-26
lines changed

1 file changed

+49
-26
lines changed

diff.c

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -296,28 +296,6 @@ static void print_line_count(FILE *file, int count)
296296
}
297297
}
298298

299-
static void copy_file_with_prefix(FILE *file,
300-
int prefix, const char *data, int size,
301-
const char *set, const char *reset)
302-
{
303-
int ch, nl_just_seen = 1;
304-
while (0 < size--) {
305-
ch = *data++;
306-
if (nl_just_seen) {
307-
fputs(set, file);
308-
putc(prefix, file);
309-
}
310-
if (ch == '\n') {
311-
nl_just_seen = 1;
312-
fputs(reset, file);
313-
} else
314-
nl_just_seen = 0;
315-
putc(ch, file);
316-
}
317-
if (!nl_just_seen)
318-
fprintf(file, "%s\n\\ No newline at end of file\n", reset);
319-
}
320-
321299
static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
322300
{
323301
if (!DIFF_FILE_VALID(one)) {
@@ -447,6 +425,38 @@ static void emit_add_line(const char *reset,
447425
}
448426
}
449427

428+
static void emit_rewrite_lines(struct emit_callback *ecb,
429+
int prefix, const char *data, int size)
430+
{
431+
const char *endp = NULL;
432+
static const char *nneof = " No newline at end of file\n";
433+
const char *old = diff_get_color(ecb->color_diff, DIFF_FILE_OLD);
434+
const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET);
435+
436+
while (0 < size) {
437+
int len;
438+
439+
endp = memchr(data, '\n', size);
440+
len = endp ? (endp - data + 1) : size;
441+
if (prefix != '+') {
442+
ecb->lno_in_preimage++;
443+
emit_line_0(ecb->file, old, reset, '-',
444+
data, len);
445+
} else {
446+
ecb->lno_in_postimage++;
447+
emit_add_line(reset, ecb, data, len);
448+
}
449+
size -= len;
450+
data += len;
451+
}
452+
if (!endp) {
453+
const char *plain = diff_get_color(ecb->color_diff,
454+
DIFF_PLAIN);
455+
emit_line_0(ecb->file, plain, reset, '\\',
456+
nneof, strlen(nneof));
457+
}
458+
}
459+
450460
static void emit_rewrite_diff(const char *name_a,
451461
const char *name_b,
452462
struct diff_filespec *one,
@@ -458,10 +468,23 @@ static void emit_rewrite_diff(const char *name_a,
458468
const char *name_a_tab, *name_b_tab;
459469
const char *metainfo = diff_get_color(color_diff, DIFF_METAINFO);
460470
const char *fraginfo = diff_get_color(color_diff, DIFF_FRAGINFO);
461-
const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
462-
const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
463471
const char *reset = diff_get_color(color_diff, DIFF_RESET);
464472
static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;
473+
struct emit_callback ecbdata;
474+
475+
memset(&ecbdata, 0, sizeof(ecbdata));
476+
ecbdata.color_diff = color_diff;
477+
ecbdata.found_changesp = &o->found_changes;
478+
ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a);
479+
ecbdata.file = o->file;
480+
if (ecbdata.ws_rule & WS_BLANK_AT_EOF) {
481+
mmfile_t mf1, mf2;
482+
fill_mmfile(&mf1, one);
483+
fill_mmfile(&mf2, two);
484+
check_blank_at_eof(&mf1, &mf2, &ecbdata);
485+
}
486+
ecbdata.lno_in_preimage = 1;
487+
ecbdata.lno_in_postimage = 1;
465488

466489
name_a += (*name_a == '/');
467490
name_b += (*name_b == '/');
@@ -486,9 +509,9 @@ static void emit_rewrite_diff(const char *name_a,
486509
print_line_count(o->file, lc_b);
487510
fprintf(o->file, " @@%s\n", reset);
488511
if (lc_a)
489-
copy_file_with_prefix(o->file, '-', one->data, one->size, old, reset);
512+
emit_rewrite_lines(&ecbdata, '-', one->data, one->size);
490513
if (lc_b)
491-
copy_file_with_prefix(o->file, '+', two->data, two->size, new, reset);
514+
emit_rewrite_lines(&ecbdata, '+', two->data, two->size);
492515
}
493516

494517
struct diff_words_buffer {

0 commit comments

Comments
 (0)