diff.c: convert word diffing to use emit_diff_symbol
The word diffing is not line oriented and would need some serious effort to be transformed into a line oriented approach, so just go with a symbol DIFF_SYMBOL_WORD_DIFF that is a partial line. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Stefan Beller committed
Jun 29, 2017 at 17:07 UTC
bd033291d5a3e62979e28fd939dcd8caad510e9c
1 file changed
+46
-33
diff.c
+46
-33
@@ -570,6 +570,7 @@ enum diff_symbol {
570
DIFF_SYMBOL_STATS_SUMMARY_ABBREV,
571
DIFF_SYMBOL_STATS_SUMMARY_INSERTS_DELETES,
572
DIFF_SYMBOL_STATS_LINE,
573
+ DIFF_SYMBOL_WORD_DIFF,
574
DIFF_SYMBOL_SUBMODULE_ADD,
575
DIFF_SYMBOL_SUBMODULE_DEL,
576
DIFF_SYMBOL_SUBMODULE_UNTRACKED,
@@ -762,6 +763,9 @@ static void emit_diff_symbol(struct diff_options *o, enum diff_symbol s,
763
case DIFF_SYMBOL_STATS_SUMMARY_ABBREV:
764
emit_line(o, "", "", " ...\n", strlen(" ...\n"));
765
break;
766
+ case DIFF_SYMBOL_WORD_DIFF:
767
+ fprintf(o->file, "%.*s", len, line);
768
+ break;
769
default:
770
die("BUG: unknown diff symbol");
771
}
@@ -1092,37 +1096,49 @@ struct diff_words_data {
1096
struct diff_words_style *style;
1097
};
1098
1095
-static int fn_out_diff_words_write_helper(FILE *fp,
1099
+static int fn_out_diff_words_write_helper(struct diff_options *o,
1100
struct diff_words_style_elem *st_el,
1101
const char *newline,
1098
- size_t count, const char *buf,
1099
- const char *line_prefix)
1102
+ size_t count, const char *buf)
1103
{
1104
int print = 0;
1105
+ struct strbuf sb = STRBUF_INIT;
1106
1107
while (count) {
1108
char *p = memchr(buf, '\n', count);
1109
if (print)
1106
- fputs(line_prefix, fp);
1110
+ strbuf_addstr(&sb, diff_line_prefix(o));
1111
+
1112
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);
1122
}
1123
if (!p)
1119
- return 0;
1120
- if (fputs(newline, fp) < 0)
1121
- return -1;
1124
+ goto out;
1125
+
1126
+ strbuf_addstr(&sb, newline);
1127
count -= p + 1 - buf;
1128
buf = p + 1;
1129
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
+ }
1135
}
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);
1142
return 0;
1143
}
1144
@@ -1204,24 +1220,20 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)
1220
fputs(line_prefix, diff_words->opt->file);
1221
}
1222
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,
1224
&style->ctx, style->newline,
1225
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);
1227
}
1228
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,
1230
&style->old, style->newline,
1217
- minus_end - minus_begin, minus_begin,
1218
- line_prefix);
1231
+ minus_end - minus_begin, minus_begin);
1232
}
1233
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,
1235
&style->new, style->newline,
1223
- plus_end - plus_begin, plus_begin,
1224
- line_prefix);
1236
+ plus_end - plus_begin, plus_begin);
1237
}
1238
1239
diff_words->current_plus = plus_end;
@@ -1315,11 +1327,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
1327
1328
/* special case: only removal */
1329
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,
1333
&style->old, style->newline,
1334
diff_words->minus.text.size,
1322
- diff_words->minus.text.ptr, line_prefix);
1335
+ diff_words->minus.text.ptr);
1336
diff_words->minus.text.size = 0;
1337
return;
1338
}
@@ -1342,12 +1355,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
1355
if (diff_words->current_plus != diff_words->plus.text.ptr +
1356
diff_words->plus.text.size) {
1357
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,
1361
&style->ctx, style->newline,
1362
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);
1364
}
1365
diff_words->minus.text.size = diff_words->plus.text.size = 0;
1366
}