@@ -570,6 +570,7 @@ enum diff_symbol {
570570 DIFF_SYMBOL_STATS_SUMMARY_ABBREV ,
571571 DIFF_SYMBOL_STATS_SUMMARY_INSERTS_DELETES ,
572572 DIFF_SYMBOL_STATS_LINE ,
573+ DIFF_SYMBOL_WORD_DIFF ,
573574 DIFF_SYMBOL_SUBMODULE_ADD ,
574575 DIFF_SYMBOL_SUBMODULE_DEL ,
575576 DIFF_SYMBOL_SUBMODULE_UNTRACKED ,
@@ -762,6 +763,9 @@ static void emit_diff_symbol(struct diff_options *o, enum diff_symbol s,
762763 case DIFF_SYMBOL_STATS_SUMMARY_ABBREV :
763764 emit_line (o , "" , "" , " ...\n" , strlen (" ...\n" ));
764765 break ;
766+ case DIFF_SYMBOL_WORD_DIFF :
767+ fprintf (o -> file , "%.*s" , len , line );
768+ break ;
765769 default :
766770 die ("BUG: unknown diff symbol" );
767771 }
@@ -1092,37 +1096,49 @@ struct diff_words_data {
10921096 struct diff_words_style * style ;
10931097};
10941098
1095- static int fn_out_diff_words_write_helper (FILE * fp ,
1099+ static int fn_out_diff_words_write_helper (struct diff_options * o ,
10961100 struct diff_words_style_elem * st_el ,
10971101 const char * newline ,
1098- size_t count , const char * buf ,
1099- const char * line_prefix )
1102+ size_t count , const char * buf )
11001103{
11011104 int print = 0 ;
1105+ struct strbuf sb = STRBUF_INIT ;
11021106
11031107 while (count ) {
11041108 char * p = memchr (buf , '\n' , count );
11051109 if (print )
1106- fputs (line_prefix , fp );
1110+ strbuf_addstr (& sb , diff_line_prefix (o ));
1111+
11071112 if (p != buf ) {
1108- if ( st_el -> color && fputs ( st_el -> color , fp ) < 0 )
1109- return -1 ;
1110- if (fputs ( st_el -> prefix , fp ) < 0 ||
1111- fwrite ( buf , p ? p - buf : count , 1 , fp ) != 1 ||
1112- fputs ( st_el -> suffix , fp ) < 0 )
1113- return -1 ;
1114- if ( st_el -> color && * st_el -> color
1115- && fputs ( GIT_COLOR_RESET , fp ) < 0 )
1116- return -1 ;
1113+ const char * reset = st_el -> color && * st_el -> color ?
1114+ GIT_COLOR_RESET : NULL ;
1115+ if (st_el -> color && * st_el -> color )
1116+ strbuf_addstr ( & sb , st_el -> color );
1117+ strbuf_addstr ( & sb , st_el -> prefix );
1118+ strbuf_add ( & sb , buf , p ? p - buf : count ) ;
1119+ strbuf_addstr ( & sb , st_el -> suffix );
1120+ if ( reset )
1121+ strbuf_addstr ( & sb , reset ) ;
11171122 }
11181123 if (!p )
1119- return 0 ;
1120- if ( fputs ( newline , fp ) < 0 )
1121- return -1 ;
1124+ goto out ;
1125+
1126+ strbuf_addstr ( & sb , newline ) ;
11221127 count -= p + 1 - buf ;
11231128 buf = p + 1 ;
11241129 print = 1 ;
1130+ if (count ) {
1131+ emit_diff_symbol (o , DIFF_SYMBOL_WORD_DIFF ,
1132+ sb .buf , sb .len , 0 );
1133+ strbuf_reset (& sb );
1134+ }
11251135 }
1136+
1137+ out :
1138+ if (sb .len )
1139+ emit_diff_symbol (o , DIFF_SYMBOL_WORD_DIFF ,
1140+ sb .buf , sb .len , 0 );
1141+ strbuf_release (& sb );
11261142 return 0 ;
11271143}
11281144
@@ -1204,24 +1220,20 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)
12041220 fputs (line_prefix , diff_words -> opt -> file );
12051221 }
12061222 if (diff_words -> current_plus != plus_begin ) {
1207- fn_out_diff_words_write_helper (diff_words -> opt -> file ,
1223+ fn_out_diff_words_write_helper (diff_words -> opt ,
12081224 & style -> ctx , style -> newline ,
12091225 plus_begin - diff_words -> current_plus ,
1210- diff_words -> current_plus , line_prefix );
1211- if (* (plus_begin - 1 ) == '\n' )
1212- fputs (line_prefix , diff_words -> opt -> file );
1226+ diff_words -> current_plus );
12131227 }
12141228 if (minus_begin != minus_end ) {
1215- fn_out_diff_words_write_helper (diff_words -> opt -> file ,
1229+ fn_out_diff_words_write_helper (diff_words -> opt ,
12161230 & style -> old , style -> newline ,
1217- minus_end - minus_begin , minus_begin ,
1218- line_prefix );
1231+ minus_end - minus_begin , minus_begin );
12191232 }
12201233 if (plus_begin != plus_end ) {
1221- fn_out_diff_words_write_helper (diff_words -> opt -> file ,
1234+ fn_out_diff_words_write_helper (diff_words -> opt ,
12221235 & style -> new , style -> newline ,
1223- plus_end - plus_begin , plus_begin ,
1224- line_prefix );
1236+ plus_end - plus_begin , plus_begin );
12251237 }
12261238
12271239 diff_words -> current_plus = plus_end ;
@@ -1315,11 +1327,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
13151327
13161328 /* special case: only removal */
13171329 if (!diff_words -> plus .text .size ) {
1318- fputs (line_prefix , diff_words -> opt -> file );
1319- fn_out_diff_words_write_helper (diff_words -> opt -> file ,
1330+ emit_diff_symbol (diff_words -> opt , DIFF_SYMBOL_WORD_DIFF ,
1331+ line_prefix , strlen (line_prefix ), 0 );
1332+ fn_out_diff_words_write_helper (diff_words -> opt ,
13201333 & style -> old , style -> newline ,
13211334 diff_words -> minus .text .size ,
1322- diff_words -> minus .text .ptr , line_prefix );
1335+ diff_words -> minus .text .ptr );
13231336 diff_words -> minus .text .size = 0 ;
13241337 return ;
13251338 }
@@ -1342,12 +1355,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
13421355 if (diff_words -> current_plus != diff_words -> plus .text .ptr +
13431356 diff_words -> plus .text .size ) {
13441357 if (color_words_output_graph_prefix (diff_words ))
1345- fputs (line_prefix , diff_words -> opt -> file );
1346- fn_out_diff_words_write_helper (diff_words -> opt -> file ,
1358+ emit_diff_symbol (diff_words -> opt , DIFF_SYMBOL_WORD_DIFF ,
1359+ line_prefix , strlen (line_prefix ), 0 );
1360+ fn_out_diff_words_write_helper (diff_words -> opt ,
13471361 & style -> ctx , style -> newline ,
13481362 diff_words -> plus .text .ptr + diff_words -> plus .text .size
1349- - diff_words -> current_plus , diff_words -> current_plus ,
1350- line_prefix );
1363+ - diff_words -> current_plus , diff_words -> current_plus );
13511364 }
13521365 diff_words -> minus .text .size = diff_words -> plus .text .size = 0 ;
13531366}
0 commit comments