@@ -1149,7 +1149,6 @@ struct checkdiff_t {
1149
1149
struct diff_options * o ;
1150
1150
unsigned ws_rule ;
1151
1151
unsigned status ;
1152
- int trailing_blanks_start ;
1153
1152
};
1154
1153
1155
1154
static int is_conflict_marker (const char * line , unsigned long len )
@@ -1193,10 +1192,6 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
1193
1192
if (line [0 ] == '+' ) {
1194
1193
unsigned bad ;
1195
1194
data -> lineno ++ ;
1196
- if (!ws_blank_line (line + 1 , len - 1 , data -> ws_rule ))
1197
- data -> trailing_blanks_start = 0 ;
1198
- else if (!data -> trailing_blanks_start )
1199
- data -> trailing_blanks_start = data -> lineno ;
1200
1195
if (is_conflict_marker (line + 1 , len - 1 )) {
1201
1196
data -> status |= 1 ;
1202
1197
fprintf (data -> o -> file ,
@@ -1216,14 +1211,12 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)
1216
1211
data -> o -> file , set , reset , ws );
1217
1212
} else if (line [0 ] == ' ' ) {
1218
1213
data -> lineno ++ ;
1219
- data -> trailing_blanks_start = 0 ;
1220
1214
} else if (line [0 ] == '@' ) {
1221
1215
char * plus = strchr (line , '+' );
1222
1216
if (plus )
1223
1217
data -> lineno = strtol (plus , NULL , 10 ) - 1 ;
1224
1218
else
1225
1219
die ("invalid diff" );
1226
- data -> trailing_blanks_start = 0 ;
1227
1220
}
1228
1221
}
1229
1222
@@ -1437,6 +1430,44 @@ static const struct funcname_pattern_entry *diff_funcname_pattern(struct diff_fi
1437
1430
return NULL ;
1438
1431
}
1439
1432
1433
+ static int count_trailing_blank (mmfile_t * mf , unsigned ws_rule )
1434
+ {
1435
+ char * ptr = mf -> ptr ;
1436
+ long size = mf -> size ;
1437
+ int cnt = 0 ;
1438
+
1439
+ if (!size )
1440
+ return cnt ;
1441
+ ptr += size - 1 ; /* pointing at the very end */
1442
+ if (* ptr != '\n' )
1443
+ ; /* incomplete line */
1444
+ else
1445
+ ptr -- ; /* skip the last LF */
1446
+ while (mf -> ptr < ptr ) {
1447
+ char * prev_eol ;
1448
+ for (prev_eol = ptr ; mf -> ptr <= prev_eol ; prev_eol -- )
1449
+ if (* prev_eol == '\n' )
1450
+ break ;
1451
+ if (!ws_blank_line (prev_eol + 1 , ptr - prev_eol , ws_rule ))
1452
+ break ;
1453
+ cnt ++ ;
1454
+ ptr = prev_eol - 1 ;
1455
+ }
1456
+ return cnt ;
1457
+ }
1458
+
1459
+ static int adds_blank_at_eof (mmfile_t * mf1 , mmfile_t * mf2 , unsigned ws_rule )
1460
+ {
1461
+ int l1 , l2 , at ;
1462
+ l1 = count_trailing_blank (mf1 , ws_rule );
1463
+ l2 = count_trailing_blank (mf2 , ws_rule );
1464
+ if (l2 <= l1 )
1465
+ return 0 ;
1466
+ /* starting where? */
1467
+ at = count_lines (mf1 -> ptr , mf1 -> size );
1468
+ return (at - l1 ) + 1 ; /* the line number counts from 1 */
1469
+ }
1470
+
1440
1471
static void builtin_diff (const char * name_a ,
1441
1472
const char * name_b ,
1442
1473
struct diff_filespec * one ,
@@ -1650,15 +1681,16 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
1650
1681
ecb .priv = & data ;
1651
1682
xdi_diff (& mf1 , & mf2 , & xpp , & xecfg , & ecb );
1652
1683
1653
- if ((data .ws_rule & WS_BLANK_AT_EOF ) &&
1654
- data .trailing_blanks_start ) {
1655
- static char * err ;
1656
-
1657
- if (!err )
1658
- err = whitespace_error_string (WS_BLANK_AT_EOF );
1659
- fprintf (o -> file , "%s:%d: %s\n" ,
1660
- data .filename , data .trailing_blanks_start , err );
1661
- data .status = 1 ; /* report errors */
1684
+ if (data .ws_rule & WS_BLANK_AT_EOF ) {
1685
+ int blank_at_eof = adds_blank_at_eof (& mf1 , & mf2 , data .ws_rule );
1686
+ if (blank_at_eof ) {
1687
+ static char * err ;
1688
+ if (!err )
1689
+ err = whitespace_error_string (WS_BLANK_AT_EOF );
1690
+ fprintf (o -> file , "%s:%d: %s.\n" ,
1691
+ data .filename , blank_at_eof , err );
1692
+ data .status = 1 ; /* report errors */
1693
+ }
1662
1694
}
1663
1695
}
1664
1696
free_and_return :
0 commit comments