@@ -491,6 +491,8 @@ struct emit_callback {
491491 struct xdiff_emit_state xm ;
492492 int color_diff ;
493493 unsigned ws_rule ;
494+ int blank_at_eof ;
495+ int lno_in_preimage ;
494496 sane_truncate_fn truncate ;
495497 const char * * label_path ;
496498 struct diff_words_data * diff_words ;
@@ -547,6 +549,12 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons
547549
548550 if (!* ws )
549551 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 );
550558 else {
551559 /* Emit just the prefix, then the rest. */
552560 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
573581 return allot - l ;
574582}
575583
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+
576592static void fn_out_consume (void * priv , char * line , unsigned long len )
577593{
578- int color ;
579594 struct emit_callback * ecbdata = priv ;
580595 const char * meta = diff_get_color (ecbdata -> color_diff , DIFF_METAINFO );
581596 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)
598613
599614 if (line [0 ] == '@' ) {
600615 len = sane_truncate_line (ecbdata , line , len );
616+ ecbdata -> lno_in_preimage = find_preimage_lno (line );
601617 emit_line (ecbdata -> file ,
602618 diff_get_color (ecbdata -> color_diff , DIFF_FRAGINFO ),
603619 reset , line , len );
@@ -611,7 +627,6 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
611627 return ;
612628 }
613629
614- color = DIFF_PLAIN ;
615630 if (ecbdata -> diff_words ) {
616631 if (line [0 ] == '-' ) {
617632 diff_words_append (line , len ,
@@ -630,14 +645,13 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
630645 emit_line (ecbdata -> file , plain , reset , line , len );
631646 return ;
632647 }
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 );
641655 return ;
642656 }
643657 emit_add_line (reset , ecbdata , line , len );
@@ -1557,6 +1571,9 @@ static void builtin_diff(const char *name_a,
15571571 ecbdata .color_diff = DIFF_OPT_TST (o , COLOR_DIFF );
15581572 ecbdata .found_changesp = & o -> found_changes ;
15591573 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 );
15601577 ecbdata .file = o -> file ;
15611578 xpp .flags = XDF_NEED_MINIMAL | o -> xdl_opts ;
15621579 xecfg .ctxlen = o -> context ;
0 commit comments