@@ -174,6 +174,154 @@ static struct diff_tempfile {
174174 char tmp_path [PATH_MAX ];
175175} diff_temp [2 ];
176176
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+
177325static struct diff_tempfile * claim_diff_tempfile (void ) {
178326 int i ;
179327 for (i = 0 ; i < ARRAY_SIZE (diff_temp ); i ++ )
@@ -201,29 +349,6 @@ static void remove_tempfile_on_signal(int signo)
201349 raise (signo );
202350}
203351
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-
227352static void print_line_count (FILE * file , int count )
228353{
229354 switch (count ) {
@@ -337,21 +462,6 @@ static void emit_rewrite_diff(const char *name_a,
337462 copy_file_with_prefix (o -> file , '+' , data_two , size_two , new , reset );
338463}
339464
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-
355465struct diff_words_buffer {
356466 mmfile_t text ;
357467 long alloc ;
@@ -529,22 +639,6 @@ static void diff_words_show(struct diff_words_data *diff_words)
529639 diff_words -> minus .text .size = diff_words -> plus .text .size = 0 ;
530640}
531641
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-
548642static void free_diff_words_data (struct emit_callback * ecbdata )
549643{
550644 if (ecbdata -> diff_words ) {
@@ -570,55 +664,6 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix)
570664 return "" ;
571665}
572666
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-
622667static unsigned long sane_truncate_line (struct emit_callback * ecb , char * line , unsigned long len )
623668{
624669 const char * cp ;
@@ -1450,51 +1495,6 @@ static const char *get_textconv(struct diff_filespec *one)
14501495 return one -> driver -> textconv ;
14511496}
14521497
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-
14981498static void builtin_diff (const char * name_a ,
14991499 const char * name_b ,
15001500 struct diff_filespec * one ,
0 commit comments