зеркало из https://github.com/microsoft/git.git
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:
Коммит
61ea1fe363
82
diff.c
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче