@@ -241,6 +241,23 @@ static struct diff_tempfile {
241241 char tmp_path [PATH_MAX ];
242242} diff_temp [2 ];
243243
244+ typedef unsigned long (* sane_truncate_fn )(char * line , unsigned long len );
245+
246+ struct emit_callback {
247+ struct xdiff_emit_state xm ;
248+ int color_diff ;
249+ unsigned ws_rule ;
250+ int blank_at_eof_in_preimage ;
251+ int blank_at_eof_in_postimage ;
252+ int lno_in_preimage ;
253+ int lno_in_postimage ;
254+ sane_truncate_fn truncate ;
255+ const char * * label_path ;
256+ struct diff_words_data * diff_words ;
257+ int * found_changesp ;
258+ FILE * file ;
259+ };
260+
244261static int count_lines (const char * data , int size )
245262{
246263 int count , ch , completely_empty = 1 , nl_just_seen = 0 ;
@@ -301,6 +318,114 @@ static void copy_file_with_prefix(FILE *file,
301318 fprintf (file , "%s\n\\ No newline at end of file\n" , reset );
302319}
303320
321+ static int fill_mmfile (mmfile_t * mf , struct diff_filespec * one )
322+ {
323+ if (!DIFF_FILE_VALID (one )) {
324+ mf -> ptr = (char * )"" ; /* does not matter */
325+ mf -> size = 0 ;
326+ return 0 ;
327+ }
328+ else if (diff_populate_filespec (one , 0 ))
329+ return -1 ;
330+ mf -> ptr = one -> data ;
331+ mf -> size = one -> size ;
332+ return 0 ;
333+ }
334+
335+ static int count_trailing_blank (mmfile_t * mf , unsigned ws_rule )
336+ {
337+ char * ptr = mf -> ptr ;
338+ long size = mf -> size ;
339+ int cnt = 0 ;
340+
341+ if (!size )
342+ return cnt ;
343+ ptr += size - 1 ; /* pointing at the very end */
344+ if (* ptr != '\n' )
345+ ; /* incomplete line */
346+ else
347+ ptr -- ; /* skip the last LF */
348+ while (mf -> ptr < ptr ) {
349+ char * prev_eol ;
350+ for (prev_eol = ptr ; mf -> ptr <= prev_eol ; prev_eol -- )
351+ if (* prev_eol == '\n' )
352+ break ;
353+ if (!ws_blank_line (prev_eol + 1 , ptr - prev_eol , ws_rule ))
354+ break ;
355+ cnt ++ ;
356+ ptr = prev_eol - 1 ;
357+ }
358+ return cnt ;
359+ }
360+
361+ static void check_blank_at_eof (mmfile_t * mf1 , mmfile_t * mf2 ,
362+ struct emit_callback * ecbdata )
363+ {
364+ int l1 , l2 , at ;
365+ unsigned ws_rule = ecbdata -> ws_rule ;
366+ l1 = count_trailing_blank (mf1 , ws_rule );
367+ l2 = count_trailing_blank (mf2 , ws_rule );
368+ if (l2 <= l1 ) {
369+ ecbdata -> blank_at_eof_in_preimage = 0 ;
370+ ecbdata -> blank_at_eof_in_postimage = 0 ;
371+ return ;
372+ }
373+ at = count_lines (mf1 -> ptr , mf1 -> size );
374+ ecbdata -> blank_at_eof_in_preimage = (at - l1 ) + 1 ;
375+
376+ at = count_lines (mf2 -> ptr , mf2 -> size );
377+ ecbdata -> blank_at_eof_in_postimage = (at - l2 ) + 1 ;
378+ }
379+
380+ static void emit_line (FILE * file , const char * set , const char * reset , const char * line , int len )
381+ {
382+ int has_trailing_newline , has_trailing_carriage_return ;
383+
384+ has_trailing_newline = (len > 0 && line [len - 1 ] == '\n' );
385+ if (has_trailing_newline )
386+ len -- ;
387+ has_trailing_carriage_return = (len > 0 && line [len - 1 ] == '\r' );
388+ if (has_trailing_carriage_return )
389+ len -- ;
390+
391+ fputs (set , file );
392+ fwrite (line , len , 1 , file );
393+ fputs (reset , file );
394+ if (has_trailing_carriage_return )
395+ fputc ('\r' , file );
396+ if (has_trailing_newline )
397+ fputc ('\n' , file );
398+ }
399+
400+ static int new_blank_line_at_eof (struct emit_callback * ecbdata , const char * line , int len )
401+ {
402+ if (!((ecbdata -> ws_rule & WS_BLANK_AT_EOF ) &&
403+ ecbdata -> blank_at_eof_in_preimage &&
404+ ecbdata -> blank_at_eof_in_postimage &&
405+ ecbdata -> blank_at_eof_in_preimage <= ecbdata -> lno_in_preimage &&
406+ ecbdata -> blank_at_eof_in_postimage <= ecbdata -> lno_in_postimage ))
407+ return 0 ;
408+ return ws_blank_line (line + 1 , len - 1 , ecbdata -> ws_rule );
409+ }
410+
411+ static void emit_add_line (const char * reset , struct emit_callback * ecbdata , const char * line , int len )
412+ {
413+ const char * ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
414+ const char * set = diff_get_color (ecbdata -> color_diff , DIFF_FILE_NEW );
415+
416+ if (!* ws )
417+ emit_line (ecbdata -> file , set , reset , line , len );
418+ else if (new_blank_line_at_eof (ecbdata , line , len ))
419+ /* Blank line at EOF - paint '+' as well */
420+ emit_line (ecbdata -> file , ws , reset , line , len );
421+ else {
422+ /* Emit just the prefix, then the rest. */
423+ emit_line (ecbdata -> file , set , reset , line , 1 );
424+ ws_check_emit (line + 1 , len - 1 , ecbdata -> ws_rule ,
425+ ecbdata -> file , set , reset , ws );
426+ }
427+ }
428+
304429static void emit_rewrite_diff (const char * name_a ,
305430 const char * name_b ,
306431 struct diff_filespec * one ,
@@ -345,20 +470,6 @@ static void emit_rewrite_diff(const char *name_a,
345470 copy_file_with_prefix (o -> file , '+' , two -> data , two -> size , new , reset );
346471}
347472
348- static int fill_mmfile (mmfile_t * mf , struct diff_filespec * one )
349- {
350- if (!DIFF_FILE_VALID (one )) {
351- mf -> ptr = (char * )"" ; /* does not matter */
352- mf -> size = 0 ;
353- return 0 ;
354- }
355- else if (diff_populate_filespec (one , 0 ))
356- return -1 ;
357- mf -> ptr = one -> data ;
358- mf -> size = one -> size ;
359- return 0 ;
360- }
361-
362473struct diff_words_buffer {
363474 mmfile_t text ;
364475 long alloc ;
@@ -485,23 +596,6 @@ static void diff_words_show(struct diff_words_data *diff_words)
485596 }
486597}
487598
488- typedef unsigned long (* sane_truncate_fn )(char * line , unsigned long len );
489-
490- struct emit_callback {
491- struct xdiff_emit_state xm ;
492- int color_diff ;
493- unsigned ws_rule ;
494- int blank_at_eof_in_preimage ;
495- int blank_at_eof_in_postimage ;
496- int lno_in_preimage ;
497- int lno_in_postimage ;
498- sane_truncate_fn truncate ;
499- const char * * label_path ;
500- struct diff_words_data * diff_words ;
501- int * found_changesp ;
502- FILE * file ;
503- };
504-
505599static void free_diff_words_data (struct emit_callback * ecbdata )
506600{
507601 if (ecbdata -> diff_words ) {
@@ -524,55 +618,6 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
524618 return "" ;
525619}
526620
527- static void emit_line (FILE * file , const char * set , const char * reset , const char * line , int len )
528- {
529- int has_trailing_newline , has_trailing_carriage_return ;
530-
531- has_trailing_newline = (len > 0 && line [len - 1 ] == '\n' );
532- if (has_trailing_newline )
533- len -- ;
534- has_trailing_carriage_return = (len > 0 && line [len - 1 ] == '\r' );
535- if (has_trailing_carriage_return )
536- len -- ;
537-
538- fputs (set , file );
539- fwrite (line , len , 1 , file );
540- fputs (reset , file );
541- if (has_trailing_carriage_return )
542- fputc ('\r' , file );
543- if (has_trailing_newline )
544- fputc ('\n' , file );
545- }
546-
547- static int new_blank_line_at_eof (struct emit_callback * ecbdata , const char * line , int len )
548- {
549- if (!((ecbdata -> ws_rule & WS_BLANK_AT_EOF ) &&
550- ecbdata -> blank_at_eof_in_preimage &&
551- ecbdata -> blank_at_eof_in_postimage &&
552- ecbdata -> blank_at_eof_in_preimage <= ecbdata -> lno_in_preimage &&
553- ecbdata -> blank_at_eof_in_postimage <= ecbdata -> lno_in_postimage ))
554- return 0 ;
555- return ws_blank_line (line + 1 , len - 1 , ecbdata -> ws_rule );
556- }
557-
558- static void emit_add_line (const char * reset , struct emit_callback * ecbdata , const char * line , int len )
559- {
560- const char * ws = diff_get_color (ecbdata -> color_diff , DIFF_WHITESPACE );
561- const char * set = diff_get_color (ecbdata -> color_diff , DIFF_FILE_NEW );
562-
563- if (!* ws )
564- emit_line (ecbdata -> file , set , reset , line , len );
565- else if (new_blank_line_at_eof (ecbdata , line , len ))
566- /* Blank line at EOF - paint '+' as well */
567- emit_line (ecbdata -> file , ws , reset , line , len );
568- else {
569- /* Emit just the prefix, then the rest. */
570- emit_line (ecbdata -> file , set , reset , line , 1 );
571- ws_check_emit (line + 1 , len - 1 , ecbdata -> ws_rule ,
572- ecbdata -> file , set , reset , ws );
573- }
574- }
575-
576621static unsigned long sane_truncate_line (struct emit_callback * ecb , char * line , unsigned long len )
577622{
578623 const char * cp ;
@@ -1464,51 +1509,6 @@ static const struct funcname_pattern_entry *diff_funcname_pattern(struct diff_fi
14641509 return NULL ;
14651510}
14661511
1467- static int count_trailing_blank (mmfile_t * mf , unsigned ws_rule )
1468- {
1469- char * ptr = mf -> ptr ;
1470- long size = mf -> size ;
1471- int cnt = 0 ;
1472-
1473- if (!size )
1474- return cnt ;
1475- ptr += size - 1 ; /* pointing at the very end */
1476- if (* ptr != '\n' )
1477- ; /* incomplete line */
1478- else
1479- ptr -- ; /* skip the last LF */
1480- while (mf -> ptr < ptr ) {
1481- char * prev_eol ;
1482- for (prev_eol = ptr ; mf -> ptr <= prev_eol ; prev_eol -- )
1483- if (* prev_eol == '\n' )
1484- break ;
1485- if (!ws_blank_line (prev_eol + 1 , ptr - prev_eol , ws_rule ))
1486- break ;
1487- cnt ++ ;
1488- ptr = prev_eol - 1 ;
1489- }
1490- return cnt ;
1491- }
1492-
1493- static void check_blank_at_eof (mmfile_t * mf1 , mmfile_t * mf2 ,
1494- struct emit_callback * ecbdata )
1495- {
1496- int l1 , l2 , at ;
1497- unsigned ws_rule = ecbdata -> ws_rule ;
1498- l1 = count_trailing_blank (mf1 , ws_rule );
1499- l2 = count_trailing_blank (mf2 , ws_rule );
1500- if (l2 <= l1 ) {
1501- ecbdata -> blank_at_eof_in_preimage = 0 ;
1502- ecbdata -> blank_at_eof_in_postimage = 0 ;
1503- return ;
1504- }
1505- at = count_lines (mf1 -> ptr , mf1 -> size );
1506- ecbdata -> blank_at_eof_in_preimage = (at - l1 ) + 1 ;
1507-
1508- at = count_lines (mf2 -> ptr , mf2 -> size );
1509- ecbdata -> blank_at_eof_in_postimage = (at - l2 ) + 1 ;
1510- }
1511-
15121512static void builtin_diff (const char * name_a ,
15131513 const char * name_b ,
15141514 struct diff_filespec * one ,
0 commit comments