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>
This commit is contained in:
Stefan Beller 2017-06-29 17:07:03 -07:00 committed by Junio C Hamano
parent 0911c475c8
commit bd033291d5

79
diff.c
View file

@ -570,6 +570,7 @@ enum diff_symbol {
DIFF_SYMBOL_STATS_SUMMARY_ABBREV,
DIFF_SYMBOL_STATS_SUMMARY_INSERTS_DELETES,
DIFF_SYMBOL_STATS_LINE,
DIFF_SYMBOL_WORD_DIFF,
DIFF_SYMBOL_SUBMODULE_ADD,
DIFF_SYMBOL_SUBMODULE_DEL,
DIFF_SYMBOL_SUBMODULE_UNTRACKED,
@ -762,6 +763,9 @@ static void emit_diff_symbol(struct diff_options *o, enum diff_symbol s,
case DIFF_SYMBOL_STATS_SUMMARY_ABBREV:
emit_line(o, "", "", " ...\n", strlen(" ...\n"));
break;
case DIFF_SYMBOL_WORD_DIFF:
fprintf(o->file, "%.*s", len, line);
break;
default:
die("BUG: unknown diff symbol");
}
@ -1092,37 +1096,49 @@ struct diff_words_data {
struct diff_words_style *style;
};
static int fn_out_diff_words_write_helper(FILE *fp,
static int fn_out_diff_words_write_helper(struct diff_options *o,
struct diff_words_style_elem *st_el,
const char *newline,
size_t count, const char *buf,
const char *line_prefix)
size_t count, const char *buf)
{
int print = 0;
struct strbuf sb = STRBUF_INIT;
while (count) {
char *p = memchr(buf, '\n', count);
if (print)
fputs(line_prefix, fp);
strbuf_addstr(&sb, diff_line_prefix(o));
if (p != buf) {
if (st_el->color && fputs(st_el->color, fp) < 0)
return -1;
if (fputs(st_el->prefix, fp) < 0 ||
fwrite(buf, p ? p - buf : count, 1, fp) != 1 ||
fputs(st_el->suffix, fp) < 0)
return -1;
if (st_el->color && *st_el->color
&& fputs(GIT_COLOR_RESET, fp) < 0)
return -1;
const char *reset = st_el->color && *st_el->color ?
GIT_COLOR_RESET : NULL;
if (st_el->color && *st_el->color)
strbuf_addstr(&sb, st_el->color);
strbuf_addstr(&sb, st_el->prefix);
strbuf_add(&sb, buf, p ? p - buf : count);
strbuf_addstr(&sb, st_el->suffix);
if (reset)
strbuf_addstr(&sb, reset);
}
if (!p)
return 0;
if (fputs(newline, fp) < 0)
return -1;
goto out;
strbuf_addstr(&sb, newline);
count -= p + 1 - buf;
buf = p + 1;
print = 1;
if (count) {
emit_diff_symbol(o, DIFF_SYMBOL_WORD_DIFF,
sb.buf, sb.len, 0);
strbuf_reset(&sb);
}
}
out:
if (sb.len)
emit_diff_symbol(o, DIFF_SYMBOL_WORD_DIFF,
sb.buf, sb.len, 0);
strbuf_release(&sb);
return 0;
}
@ -1204,24 +1220,20 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len)
fputs(line_prefix, diff_words->opt->file);
}
if (diff_words->current_plus != plus_begin) {
fn_out_diff_words_write_helper(diff_words->opt->file,
fn_out_diff_words_write_helper(diff_words->opt,
&style->ctx, style->newline,
plus_begin - diff_words->current_plus,
diff_words->current_plus, line_prefix);
if (*(plus_begin - 1) == '\n')
fputs(line_prefix, diff_words->opt->file);
diff_words->current_plus);
}
if (minus_begin != minus_end) {
fn_out_diff_words_write_helper(diff_words->opt->file,
fn_out_diff_words_write_helper(diff_words->opt,
&style->old, style->newline,
minus_end - minus_begin, minus_begin,
line_prefix);
minus_end - minus_begin, minus_begin);
}
if (plus_begin != plus_end) {
fn_out_diff_words_write_helper(diff_words->opt->file,
fn_out_diff_words_write_helper(diff_words->opt,
&style->new, style->newline,
plus_end - plus_begin, plus_begin,
line_prefix);
plus_end - plus_begin, plus_begin);
}
diff_words->current_plus = plus_end;
@ -1315,11 +1327,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
/* special case: only removal */
if (!diff_words->plus.text.size) {
fputs(line_prefix, diff_words->opt->file);
fn_out_diff_words_write_helper(diff_words->opt->file,
emit_diff_symbol(diff_words->opt, DIFF_SYMBOL_WORD_DIFF,
line_prefix, strlen(line_prefix), 0);
fn_out_diff_words_write_helper(diff_words->opt,
&style->old, style->newline,
diff_words->minus.text.size,
diff_words->minus.text.ptr, line_prefix);
diff_words->minus.text.ptr);
diff_words->minus.text.size = 0;
return;
}
@ -1342,12 +1355,12 @@ static void diff_words_show(struct diff_words_data *diff_words)
if (diff_words->current_plus != diff_words->plus.text.ptr +
diff_words->plus.text.size) {
if (color_words_output_graph_prefix(diff_words))
fputs(line_prefix, diff_words->opt->file);
fn_out_diff_words_write_helper(diff_words->opt->file,
emit_diff_symbol(diff_words->opt, DIFF_SYMBOL_WORD_DIFF,
line_prefix, strlen(line_prefix), 0);
fn_out_diff_words_write_helper(diff_words->opt,
&style->ctx, style->newline,
diff_words->plus.text.ptr + diff_words->plus.text.size
- diff_words->current_plus, diff_words->current_plus,
line_prefix);
- diff_words->current_plus, diff_words->current_plus);
}
diff_words->minus.text.size = diff_words->plus.text.size = 0;
}