From acb725772964ee11656543a28c303e9aa6d092c5 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Tue, 28 Mar 2006 03:23:31 +0100 Subject: [PATCH] xdiff: Show function names in hunk headers. The speed of the built-in diff generator is nice; but the function names shown by `diff -p' are /really/ nice. And I hate having to choose. So, we hack xdiff to find the function names and print them. xdiff has grown a flag to say whether to dig up the function names. The builtin_diff function passes this flag unconditionally. I suppose it could parse GIT_DIFF_OPTS, but it doesn't at the moment. I've also reintroduced the `function name' into the test suite, from which it was removed in commit 3ce8f089. The function names are parsed by a particularly stupid algorithm at the moment: it just tries to find a line in the `old' file, from before the start of the hunk, whose first character looks plausible. Still, it's most definitely a start. Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano --- diff.c | 1 + t/t4001-diff-rename.sh | 2 +- xdiff/xdiff.h | 3 +++ xdiff/xemit.c | 41 ++++++++++++++++++++++++++++++++++++++++- xdiff/xinclude.h | 1 + xdiff/xutils.c | 15 ++++++++++++--- xdiff/xutils.h | 3 ++- 7 files changed, 60 insertions(+), 6 deletions(-) diff --git a/diff.c b/diff.c index 5eae0947..8b37477a 100644 --- a/diff.c +++ b/diff.c @@ -267,6 +267,7 @@ static void builtin_diff(const char *name_a, ecbdata.label_path = lbl; xpp.flags = XDF_NEED_MINIMAL; xecfg.ctxlen = 3; + xecfg.flags = XDL_EMIT_FUNCNAMES; if (!diffopts) ; else if (!strncmp(diffopts, "--unified=", 10)) diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 08c11319..2e3c20d6 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -49,7 +49,7 @@ rename from path0 rename to path1 --- a/path0 +++ b/path1 -@@ -8,7 +8,7 @@ +@@ -8,7 +8,7 @@ Line 7 Line 8 Line 9 Line 10 diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 71cb9391..2540e8a2 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -35,6 +35,8 @@ extern "C" { #define XDL_PATCH_MODEMASK ((1 << 8) - 1) #define XDL_PATCH_IGNOREBSPACE (1 << 8) +#define XDL_EMIT_FUNCNAMES (1 << 0) + #define XDL_MMB_READONLY (1 << 0) #define XDL_MMF_ATOMIC (1 << 0) @@ -65,6 +67,7 @@ typedef struct s_xdemitcb { typedef struct s_xdemitconf { long ctxlen; + unsigned long flags; } xdemitconf_t; typedef struct s_bdiffparam { diff --git a/xdiff/xemit.c b/xdiff/xemit.c index 2e5d54cf..ad5bfb19 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -69,10 +69,43 @@ static xdchange_t *xdl_get_hunk(xdchange_t *xscr, xdemitconf_t const *xecfg) { } +static void xdl_find_func(xdfile_t *xf, long i, char *buf, long sz, long *ll) { + + /* + * Be quite stupid about this for now. Find a line in the old file + * before the start of the hunk (and context) which starts with a + * plausible character. + */ + + const char *rec; + long len; + + *ll = 0; + while (i-- > 0) { + len = xdl_get_rec(xf, i, &rec); + if (len > 0 && + (isalpha((unsigned char)*rec) || /* identifier? */ + *rec == '_' || /* also identifier? */ + *rec == '(' || /* lisp defun? */ + *rec == '#')) { /* #define? */ + if (len > sz) + len = sz; + if (len && rec[len - 1] == '\n') + len--; + memcpy(buf, rec, len); + *ll = len; + return; + } + } +} + + int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg) { long s1, s2, e1, e2, lctx; xdchange_t *xch, *xche; + char funcbuf[40]; + long funclen = 0; for (xch = xche = xscr; xch; xch = xche->next) { xche = xdl_get_hunk(xch, xecfg); @@ -90,7 +123,13 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, /* * Emit current hunk header. */ - if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, ecb) < 0) + + if (xecfg->flags & XDL_EMIT_FUNCNAMES) { + xdl_find_func(&xe->xdf1, s1, funcbuf, + sizeof(funcbuf), &funclen); + } + if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2, + funcbuf, funclen, ecb) < 0) return -1; /* diff --git a/xdiff/xinclude.h b/xdiff/xinclude.h index 9490fc56..04a9da82 100644 --- a/xdiff/xinclude.h +++ b/xdiff/xinclude.h @@ -23,6 +23,7 @@ #if !defined(XINCLUDE_H) #define XINCLUDE_H +#include #include #include #include diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 8221806f..afaada1e 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -235,7 +235,8 @@ long xdl_atol(char const *str, char const **next) { } -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb) { +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, xdemitcb_t *ecb) { int nb = 0; mmbuffer_t mb; char buf[128]; @@ -264,8 +265,16 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb) { nb += xdl_num_out(buf + nb, c2); } - memcpy(buf + nb, " @@\n", 4); - nb += 4; + memcpy(buf + nb, " @@", 3); + nb += 3; + if (func && funclen) { + buf[nb++] = ' '; + if (funclen > sizeof(buf) - nb - 1) + funclen = sizeof(buf) - nb - 1; + memcpy(buf + nb, func, funclen); + nb += funclen; + } + buf[nb++] = '\n'; mb.ptr = buf; mb.size = nb; diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 428a4bb1..55b0d39f 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -36,7 +36,8 @@ unsigned long xdl_hash_record(char const **data, char const *top); unsigned int xdl_hashbits(unsigned int size); int xdl_num_out(char *out, long val); long xdl_atol(char const *str, char const **next); -int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, xdemitcb_t *ecb); +int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, + const char *func, long funclen, xdemitcb_t *ecb); -- 2.11.0