@@ -174,6 +174,154 @@ static struct diff_tempfile {
174
174
char tmp_path [PATH_MAX ];
175
175
} diff_temp [2 ];
176
176
177
+ typedef unsigned long (* sane_truncate_fn )(char * line , unsigned long len );
178
+
179
+ struct emit_callback {
180
+ int color_diff ;
181
+ unsigned ws_rule ;
182
+ int blank_at_eof_in_preimage ;
183
+ int blank_at_eof_in_postimage ;
184
+ int lno_in_preimage ;
185
+ int lno_in_postimage ;
186
+ sane_truncate_fn truncate ;
187
+ const char * * label_path ;
188
+ struct diff_words_data * diff_words ;
189
+ int * found_changesp ;
190
+ FILE * file ;
191
+ };
192
+
193
+ static int count_lines (const char * data , int size )
194
+ {
195
+ int count , ch , completely_empty = 1 , nl_just_seen = 0 ;
196
+ count = 0 ;
197
+ while (0 < size -- ) {
198
+ ch = * data ++ ;
199
+ if (ch == '\n' ) {
200
+ count ++ ;
201
+ nl_just_seen = 1 ;
202
+ completely_empty = 0 ;
203
+ }
204
+ else {
205
+ nl_just_seen = 0 ;
206
+ completely_empty = 0 ;
207
+ }
208
+ }
209
+ if (completely_empty )
210
+ return 0 ;
211
+ if (!nl_just_seen )
212
+ count ++ ; /* no trailing newline */
213
+ return count ;
214
+ }
215
+
216
+ static int fill_mmfile (mmfile_t * mf , struct diff_filespec * one )
217
+ {
218
+ if (!DIFF_FILE_VALID (one )) {
219
+ mf -> ptr = (char * )"" ; /* does not matter */
220
+ mf -> size = 0 ;
221
+ return 0 ;
222
+ }
223
+ else if (diff_populate_filespec (one , 0 ))
224
+ return -1 ;
225
+
226
+ mf -> ptr = one -> data ;
227
+ mf -> size = one -> size ;
228
+ return 0 ;
229
+ }
230
+
231
+ static int count_trailing_blank (mmfile_t * mf , unsigned ws_rule )
232
+ {
233
+ char * ptr = mf -> ptr ;
234
+ long size = mf -> size ;
235
+ int cnt = 0 ;
236
+
237
+ if (!size )
238
+ return cnt ;
239
+ ptr += size - 1 ; /* pointing at the very end */
240
+ if (* ptr != '\n' )
241
+ ; /* incomplete line */
242
+ else
243
+ ptr -- ; /* skip the last LF */
244
+ while (mf -> ptr < ptr ) {
245
+ char * prev_eol ;
246
+ for (prev_eol = ptr ; mf -> ptr <= prev_eol ; prev_eol -- )
247
+ if (* prev_eol == '\n' )
248
+ break ;
249
+ if (!ws_blank_line (prev_eol + 1 , ptr - prev_eol , ws_rule ))
250
+ break ;
251
+ cnt ++ ;
252
+ ptr = prev_eol - 1 ;
253
+ }
254
+ return cnt ;
255
+ }
256
+
257
+ static void check_blank_at_eof (mmfile_t * mf1 , mmfile_t * mf2 ,
258
+ struct emit_callback * ecbdata )
259
+ {
260
+ int l1 , l2 , at ;
261
+ unsigned ws_rule = ecbdata -> ws_rule ;
262
+ l1 = count_trailing_blank (mf1 , ws_rule );
263
+ l2 = count_trailing_blank (mf2 , ws_rule );
264
+ if (l2 <= l1 ) {
265
+ ecbdata -> blank_at_eof_in_preimage = 0 ;
266
+ ecbdata -> blank_at_eof_in_postimage = 0 ;
267
+ return ;
268
+ }
269
+ at = count_lines (mf1 -> ptr , mf1 -> size );
270
+ ecbdata -> blank_at_eof_in_preimage = (at - l1 ) + 1 ;
271
+
272
+ at = count_lines (mf2 -> ptr , mf2 -> size );
273
+ ecbdata -> blank_at_eof_in_postimage = (at - l2 ) + 1 ;
274
+ }
275
+
276
+ static void emit_line (FILE * file , const char * set , const char * reset , const char * line , int len )
277
+ {
278
+ int has_trailing_newline , has_trailing_carriage_return ;
279
+
280
+ has_trailing_newline = (len > 0 && line [len - 1 ] == '\n' );
281
+ if (has_trailing_newline )
282
+ len -- ;
283
+ has_trailing_carriage_return = (len > 0 && line [len - 1 ] == '\r' );
284
+ if (has_trailing_carriage_return )
285
+ len -- ;
286
+
287
+ fputs (set , file );
288
+ fwrite (line , len , 1 , file );
289
+ fputs (reset , file );
290
+ if (has_trailing_carriage_return )
291
+ fputc ('\r' , file );
292
+ if (has_trailing_newline )
293
+ fputc ('\n' , file );
294
+ }
295
+
296
+ static int new_blank_line_at_eof (struct emit_callback * ecbdata , const char * line , int len )
297
+ {
298
+ if (!((ecbdata -> ws_rule & WS_BLANK_AT_EOF ) &&
299
+ ecbdata -> blank_at_eof_in_preimage &&
300
+ ecbdata -> blank_at_eof_in_postimage &&
301
+ ecbdata -> blank_at_eof_in_preimage <= ecbdata -> lno_in_preimage &&
302
+ ecbdata -> blank_at_eof_in_postimage <= ecbdata -> lno_in_postimage ))
303
+ return 0 ;
304
+ return ws_blank_line (line + 1 , len - 1 , ecbdata -> ws_rule );
305
+ }
306
+
307
+ static void emit_add_line (const char * reset , struct emit_callback * ecbdata , const char * line , int len )
308
+ {
309
+ const char * ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
310
+ const char * set = diff_get_color (ecbdata -> color_diff , DIFF_FILE_NEW );
311
+
312
+ if (!* ws )
313
+ emit_line (ecbdata -> file , set , reset , line , len );
314
+ else if (new_blank_line_at_eof (ecbdata , line , len ))
315
+ /* Blank line at EOF - paint '+' as well */
316
+ emit_line (ecbdata -> file , ws , reset , line , len );
317
+ else {
318
+ /* Emit just the prefix, then the rest. */
319
+ emit_line (ecbdata -> file , set , reset , line , 1 );
320
+ ws_check_emit (line + 1 , len - 1 , ecbdata -> ws_rule ,
321
+ ecbdata -> file , set , reset , ws );
322
+ }
323
+ }
324
+
177
325
static struct diff_tempfile * claim_diff_tempfile (void ) {
178
326
int i ;
179
327
for (i = 0 ; i < ARRAY_SIZE (diff_temp ); i ++ )
@@ -201,29 +349,6 @@ static void remove_tempfile_on_signal(int signo)
201
349
raise (signo );
202
350
}
203
351
204
- static int count_lines (const char * data , int size )
205
- {
206
- int count , ch , completely_empty = 1 , nl_just_seen = 0 ;
207
- count = 0 ;
208
- while (0 < size -- ) {
209
- ch = * data ++ ;
210
- if (ch == '\n' ) {
211
- count ++ ;
212
- nl_just_seen = 1 ;
213
- completely_empty = 0 ;
214
- }
215
- else {
216
- nl_just_seen = 0 ;
217
- completely_empty = 0 ;
218
- }
219
- }
220
- if (completely_empty )
221
- return 0 ;
222
- if (!nl_just_seen )
223
- count ++ ; /* no trailing newline */
224
- return count ;
225
- }
226
-
227
352
static void print_line_count (FILE * file , int count )
228
353
{
229
354
switch (count ) {
@@ -337,21 +462,6 @@ static void emit_rewrite_diff(const char *name_a,
337
462
copy_file_with_prefix (o -> file , '+' , data_two , size_two , new , reset );
338
463
}
339
464
340
- static int fill_mmfile (mmfile_t * mf , struct diff_filespec * one )
341
- {
342
- if (!DIFF_FILE_VALID (one )) {
343
- mf -> ptr = (char * )"" ; /* does not matter */
344
- mf -> size = 0 ;
345
- return 0 ;
346
- }
347
- else if (diff_populate_filespec (one , 0 ))
348
- return -1 ;
349
-
350
- mf -> ptr = one -> data ;
351
- mf -> size = one -> size ;
352
- return 0 ;
353
- }
354
-
355
465
struct diff_words_buffer {
356
466
mmfile_t text ;
357
467
long alloc ;
@@ -529,22 +639,6 @@ static void diff_words_show(struct diff_words_data *diff_words)
529
639
diff_words -> minus .text .size = diff_words -> plus .text .size = 0 ;
530
640
}
531
641
532
- typedef unsigned long (* sane_truncate_fn )(char * line , unsigned long len );
533
-
534
- struct emit_callback {
535
- int color_diff ;
536
- unsigned ws_rule ;
537
- int blank_at_eof_in_preimage ;
538
- int blank_at_eof_in_postimage ;
539
- int lno_in_preimage ;
540
- int lno_in_postimage ;
541
- sane_truncate_fn truncate ;
542
- const char * * label_path ;
543
- struct diff_words_data * diff_words ;
544
- int * found_changesp ;
545
- FILE * file ;
546
- };
547
-
548
642
static void free_diff_words_data (struct emit_callback * ecbdata )
549
643
{
550
644
if (ecbdata -> diff_words ) {
@@ -570,55 +664,6 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
570
664
return "" ;
571
665
}
572
666
573
- static void emit_line (FILE * file , const char * set , const char * reset , const char * line , int len )
574
- {
575
- int has_trailing_newline , has_trailing_carriage_return ;
576
-
577
- has_trailing_newline = (len > 0 && line [len - 1 ] == '\n' );
578
- if (has_trailing_newline )
579
- len -- ;
580
- has_trailing_carriage_return = (len > 0 && line [len - 1 ] == '\r' );
581
- if (has_trailing_carriage_return )
582
- len -- ;
583
-
584
- fputs (set , file );
585
- fwrite (line , len , 1 , file );
586
- fputs (reset , file );
587
- if (has_trailing_carriage_return )
588
- fputc ('\r' , file );
589
- if (has_trailing_newline )
590
- fputc ('\n' , file );
591
- }
592
-
593
- static int new_blank_line_at_eof (struct emit_callback * ecbdata , const char * line , int len )
594
- {
595
- if (!((ecbdata -> ws_rule & WS_BLANK_AT_EOF ) &&
596
- ecbdata -> blank_at_eof_in_preimage &&
597
- ecbdata -> blank_at_eof_in_postimage &&
598
- ecbdata -> blank_at_eof_in_preimage <= ecbdata -> lno_in_preimage &&
599
- ecbdata -> blank_at_eof_in_postimage <= ecbdata -> lno_in_postimage ))
600
- return 0 ;
601
- return ws_blank_line (line + 1 , len - 1 , ecbdata -> ws_rule );
602
- }
603
-
604
- static void emit_add_line (const char * reset , struct emit_callback * ecbdata , const char * line , int len )
605
- {
606
- const char * ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
607
- const char * set = diff_get_color (ecbdata -> color_diff , DIFF_FILE_NEW );
608
-
609
- if (!* ws )
610
- emit_line (ecbdata -> file , set , reset , line , len );
611
- else if (new_blank_line_at_eof (ecbdata , line , len ))
612
- /* Blank line at EOF - paint '+' as well */
613
- emit_line (ecbdata -> file , ws , reset , line , len );
614
- else {
615
- /* Emit just the prefix, then the rest. */
616
- emit_line (ecbdata -> file , set , reset , line , 1 );
617
- ws_check_emit (line + 1 , len - 1 , ecbdata -> ws_rule ,
618
- ecbdata -> file , set , reset , ws );
619
- }
620
- }
621
-
622
667
static unsigned long sane_truncate_line (struct emit_callback * ecb , char * line , unsigned long len )
623
668
{
624
669
const char * cp ;
@@ -1450,51 +1495,6 @@ static const char *get_textconv(struct diff_filespec *one)
1450
1495
return one -> driver -> textconv ;
1451
1496
}
1452
1497
1453
- static int count_trailing_blank (mmfile_t * mf , unsigned ws_rule )
1454
- {
1455
- char * ptr = mf -> ptr ;
1456
- long size = mf -> size ;
1457
- int cnt = 0 ;
1458
-
1459
- if (!size )
1460
- return cnt ;
1461
- ptr += size - 1 ; /* pointing at the very end */
1462
- if (* ptr != '\n' )
1463
- ; /* incomplete line */
1464
- else
1465
- ptr -- ; /* skip the last LF */
1466
- while (mf -> ptr < ptr ) {
1467
- char * prev_eol ;
1468
- for (prev_eol = ptr ; mf -> ptr <= prev_eol ; prev_eol -- )
1469
- if (* prev_eol == '\n' )
1470
- break ;
1471
- if (!ws_blank_line (prev_eol + 1 , ptr - prev_eol , ws_rule ))
1472
- break ;
1473
- cnt ++ ;
1474
- ptr = prev_eol - 1 ;
1475
- }
1476
- return cnt ;
1477
- }
1478
-
1479
- static void check_blank_at_eof (mmfile_t * mf1 , mmfile_t * mf2 ,
1480
- struct emit_callback * ecbdata )
1481
- {
1482
- int l1 , l2 , at ;
1483
- unsigned ws_rule = ecbdata -> ws_rule ;
1484
- l1 = count_trailing_blank (mf1 , ws_rule );
1485
- l2 = count_trailing_blank (mf2 , ws_rule );
1486
- if (l2 <= l1 ) {
1487
- ecbdata -> blank_at_eof_in_preimage = 0 ;
1488
- ecbdata -> blank_at_eof_in_postimage = 0 ;
1489
- return ;
1490
- }
1491
- at = count_lines (mf1 -> ptr , mf1 -> size );
1492
- ecbdata -> blank_at_eof_in_preimage = (at - l1 ) + 1 ;
1493
-
1494
- at = count_lines (mf2 -> ptr , mf2 -> size );
1495
- ecbdata -> blank_at_eof_in_postimage = (at - l2 ) + 1 ;
1496
- }
1497
-
1498
1498
static void builtin_diff (const char * name_a ,
1499
1499
const char * name_b ,
1500
1500
struct diff_filespec * one ,
0 commit comments