@@ -491,6 +491,8 @@ struct emit_callback {
491
491
struct xdiff_emit_state xm ;
492
492
int color_diff ;
493
493
unsigned ws_rule ;
494
+ int blank_at_eof ;
495
+ int lno_in_preimage ;
494
496
sane_truncate_fn truncate ;
495
497
const char * * label_path ;
496
498
struct diff_words_data * diff_words ;
@@ -547,6 +549,12 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons
547
549
548
550
if (!* ws )
549
551
emit_line (ecbdata -> file , set , reset , line , len );
552
+ else if ((ecbdata -> ws_rule & WS_BLANK_AT_EOF ) &&
553
+ ecbdata -> blank_at_eof &&
554
+ (ecbdata -> blank_at_eof <= ecbdata -> lno_in_preimage ) &&
555
+ ws_blank_line (line + 1 , len - 1 , ecbdata -> ws_rule ))
556
+ /* Blank line at EOF */
557
+ emit_line (ecbdata -> file , ws , reset , line , len );
550
558
else {
551
559
/* Emit just the prefix, then the rest. */
552
560
emit_line (ecbdata -> file , set , reset , line , 1 );
@@ -573,9 +581,16 @@ static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, u
573
581
return allot - l ;
574
582
}
575
583
584
+ static int find_preimage_lno (const char * line )
585
+ {
586
+ char * p = strchr (line , '-' );
587
+ if (!p )
588
+ return 0 ; /* should not happen */
589
+ return strtol (p + 1 , NULL , 10 );
590
+ }
591
+
576
592
static void fn_out_consume (void * priv , char * line , unsigned long len )
577
593
{
578
- int color ;
579
594
struct emit_callback * ecbdata = priv ;
580
595
const char * meta = diff_get_color (ecbdata -> color_diff , DIFF_METAINFO );
581
596
const char * plain = diff_get_color (ecbdata -> color_diff , DIFF_PLAIN );
@@ -598,6 +613,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
598
613
599
614
if (line [0 ] == '@' ) {
600
615
len = sane_truncate_line (ecbdata , line , len );
616
+ ecbdata -> lno_in_preimage = find_preimage_lno (line );
601
617
emit_line (ecbdata -> file ,
602
618
diff_get_color (ecbdata -> color_diff , DIFF_FRAGINFO ),
603
619
reset , line , len );
@@ -611,7 +627,6 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
611
627
return ;
612
628
}
613
629
614
- color = DIFF_PLAIN ;
615
630
if (ecbdata -> diff_words ) {
616
631
if (line [0 ] == '-' ) {
617
632
diff_words_append (line , len ,
@@ -630,14 +645,13 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
630
645
emit_line (ecbdata -> file , plain , reset , line , len );
631
646
return ;
632
647
}
633
- if (line [0 ] == '-' )
634
- color = DIFF_FILE_OLD ;
635
- else if (line [0 ] == '+' )
636
- color = DIFF_FILE_NEW ;
637
- if (color != DIFF_FILE_NEW ) {
638
- emit_line (ecbdata -> file ,
639
- diff_get_color (ecbdata -> color_diff , color ),
640
- reset , line , len );
648
+
649
+ if (line [0 ] != '+' ) {
650
+ const char * color =
651
+ diff_get_color (ecbdata -> color_diff ,
652
+ line [0 ] == '-' ? DIFF_FILE_OLD : DIFF_PLAIN );
653
+ ecbdata -> lno_in_preimage ++ ;
654
+ emit_line (ecbdata -> file , color , reset , line , len );
641
655
return ;
642
656
}
643
657
emit_add_line (reset , ecbdata , line , len );
@@ -1557,6 +1571,9 @@ static void builtin_diff(const char *name_a,
1557
1571
ecbdata .color_diff = DIFF_OPT_TST (o , COLOR_DIFF );
1558
1572
ecbdata .found_changesp = & o -> found_changes ;
1559
1573
ecbdata .ws_rule = whitespace_rule (name_b ? name_b : name_a );
1574
+ if (ecbdata .ws_rule & WS_BLANK_AT_EOF )
1575
+ ecbdata .blank_at_eof =
1576
+ adds_blank_at_eof (& mf1 , & mf2 , ecbdata .ws_rule );
1560
1577
ecbdata .file = o -> file ;
1561
1578
xpp .flags = XDF_NEED_MINIMAL | o -> xdl_opts ;
1562
1579
xecfg .ctxlen = o -> context ;
0 commit comments