Merge branch 'sb/diff-color-moved-use-xdl-recmatch'

Instead of using custom line comparison and hashing functions to
implement "moved lines" coloring in the diff output, use the pair
of these functions from lower-layer xdiff/ code.

* sb/diff-color-moved-use-xdl-recmatch:
  diff.c: get rid of duplicate implementation
  xdiff-interface: export comparing and hashing strings
This commit is contained in:
Junio C Hamano 2017-11-06 13:11:24 +09:00
Родитель 7a55427094 01be97c2b2
Коммит 61ea1fe363
3 изменённых файлов: 32 добавлений и 78 удалений

82
diff.c
Просмотреть файл

@ -707,88 +707,14 @@ struct moved_entry {
struct moved_entry *next_line;
};
static int next_byte(const char **cp, const char **endp,
const struct diff_options *diffopt)
{
int retval;
if (*cp >= *endp)
return -1;
if (isspace(**cp)) {
if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_CHANGE)) {
while (*cp < *endp && isspace(**cp))
(*cp)++;
/*
* After skipping a couple of whitespaces,
* we still have to account for one space.
*/
return (int)' ';
}
if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE)) {
while (*cp < *endp && isspace(**cp))
(*cp)++;
/*
* return the first non-ws character via the usual
* below, unless we ate all of the bytes
*/
if (*cp >= *endp)
return -1;
}
}
retval = (unsigned char)(**cp);
(*cp)++;
return retval;
}
static int moved_entry_cmp(const struct diff_options *diffopt,
const struct moved_entry *a,
const struct moved_entry *b,
const void *keydata)
{
const char *ap = a->es->line, *ae = a->es->line + a->es->len;
const char *bp = b->es->line, *be = b->es->line + b->es->len;
if (!(diffopt->xdl_opts & XDF_WHITESPACE_FLAGS))
return a->es->len != b->es->len || memcmp(ap, bp, a->es->len);
if (DIFF_XDL_TST(diffopt, IGNORE_WHITESPACE_AT_EOL)) {
while (ae > ap && isspace(ae[-1]))
ae--;
while (be > bp && isspace(be[-1]))
be--;
}
while (1) {
int ca, cb;
ca = next_byte(&ap, &ae, diffopt);
cb = next_byte(&bp, &be, diffopt);
if (ca != cb)
return 1;
if (ca < 0)
return 0;
}
}
static unsigned get_string_hash(struct emitted_diff_symbol *es, struct diff_options *o)
{
if (o->xdl_opts & XDF_WHITESPACE_FLAGS) {
static struct strbuf sb = STRBUF_INIT;
const char *ap = es->line, *ae = es->line + es->len;
int c;
strbuf_reset(&sb);
while (ae > ap && isspace(ae[-1]))
ae--;
while ((c = next_byte(&ap, &ae, o)) >= 0)
strbuf_addch(&sb, c);
return memhash(sb.buf, sb.len);
} else {
return memhash(es->line, es->len);
}
return !xdiff_compare_lines(a->es->line, a->es->len,
b->es->line, b->es->len,
diffopt->xdl_opts);
}
static struct moved_entry *prepare_entry(struct diff_options *o,
@ -797,7 +723,7 @@ static struct moved_entry *prepare_entry(struct diff_options *o,
struct moved_entry *ret = xmalloc(sizeof(*ret));
struct emitted_diff_symbol *l = &o->emitted_symbols->buf[line_no];
ret->ent.hash = get_string_hash(l, o);
ret->ent.hash = xdiff_hash_string(l->line, l->len, o->xdl_opts);
ret->es = l;
ret->next_line = NULL;

Просмотреть файл

@ -5,6 +5,7 @@
#include "xdiff/xdiffi.h"
#include "xdiff/xemit.h"
#include "xdiff/xmacros.h"
#include "xdiff/xutils.h"
struct xdiff_emit_state {
xdiff_emit_consume_fn consume;
@ -296,6 +297,17 @@ void xdiff_clear_find_func(xdemitconf_t *xecfg)
}
}
unsigned long xdiff_hash_string(const char *s, size_t len, long flags)
{
return xdl_hash_record(&s, s + len, flags);
}
int xdiff_compare_lines(const char *l1, long s1,
const char *l2, long s2, long flags)
{
return xdl_recmatch(l1, s1, l2, s2, flags);
}
int git_xmerge_style = -1;
int git_xmerge_config(const char *var, const char *value, void *cb)

Просмотреть файл

@ -29,4 +29,20 @@ extern void xdiff_clear_find_func(xdemitconf_t *xecfg);
extern int git_xmerge_config(const char *var, const char *value, void *cb);
extern int git_xmerge_style;
/*
* Compare the strings l1 with l2 which are of size s1 and s2 respectively.
* Returns 1 if the strings are deemed equal, 0 otherwise.
* The `flags` given as XDF_WHITESPACE_FLAGS determine how white spaces
* are treated for the comparision.
*/
extern int xdiff_compare_lines(const char *l1, long s1,
const char *l2, long s2, long flags);
/*
* Returns a hash of the string s of length len.
* The `flags` given as XDF_WHITESPACE_FLAGS determine how white spaces
* are treated for the hash.
*/
extern unsigned long xdiff_hash_string(const char *s, size_t len, long flags);
#endif