summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-05-29 21:52:21 -0700
committerRussell Belfer <rb@github.com>2013-06-05 12:13:54 -0700
commitaad6967be1025b1819c3ba25163d7f69fc814130 (patch)
tree8cc25530ff9ae392545e5764df84fd9a29d3d8fb
parent2e1fa15fcd69ba41bb25be92e2218a5ff3dd47fb (diff)
downloadlibgit2-aad6967be1025b1819c3ba25163d7f69fc814130.tar.gz
Basic function context header
This implements a basic callback to extract function context for a diff. It always uses the same search heuristic right now with no regular expressions or language-specific variants. Those will come next, I think.
-rw-r--r--src/diff_output.c83
1 files changed, 67 insertions, 16 deletions
diff --git a/src/diff_output.c b/src/diff_output.c
index 8dd110cbf..bcd39f093 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -196,26 +196,77 @@ static int diff_delta_is_binary_by_size(
return 0;
}
-static void setup_xdiff_options(
- const git_diff_options *opts, xdemitconf_t *cfg, xpparam_t *param)
+static long diff_context_find(
+ const char *line,
+ long line_len,
+ char *out,
+ long out_size,
+ void *payload)
+{
+ diff_context *ctxt = payload;
+ const char *scan;
+ bool found_paren = false;
+
+ if (line_len > 0 && line[line_len - 1] == '\n')
+ line_len--;
+ if (line_len > 0 && line[line_len - 1] == '\r')
+ line_len--;
+ if (!line_len)
+ return -1;
+
+ if (!isalpha(*line))
+ return -1;
+
+ for (scan = &line[line_len - 1]; scan > line && *scan != '('; --scan)
+ /* search backward for ( */;
+ if (scan != line) {
+ found_paren = true;
+ line_len = scan - line;
+
+ for (--scan; scan > line && !isalpha(*scan); --scan)
+ --line_len;
+ }
+
+ if (!line_len)
+ return -1;
+
+ if (out_size > line_len) {
+ memcpy(out, line, line_len);
+
+ if (found_paren)
+ out[line_len++] = '(';
+ out[line_len] = '\0';
+ } else {
+ memcpy(out, line, out_size);
+ line_len = out_size;
+ }
+
+ return line_len;
+}
+
+static void setup_xdiff_options(diff_context *ctxt)
{
- memset(cfg, 0, sizeof(xdemitconf_t));
- memset(param, 0, sizeof(xpparam_t));
+ memset(&ctxt->xdiff_config, 0, sizeof(ctxt->xdiff_config));
+ memset(&ctxt->xdiff_params, 0, sizeof(ctxt->xdiff_params));
+
+ ctxt->xdiff_config.ctxlen =
+ (!ctxt->opts) ? 3 : ctxt->opts->context_lines;
+ ctxt->xdiff_config.interhunkctxlen =
+ (!ctxt->opts) ? 0 : ctxt->opts->interhunk_lines;
- cfg->ctxlen =
- (!opts) ? 3 : opts->context_lines;
- cfg->interhunkctxlen =
- (!opts) ? 0 : opts->interhunk_lines;
+ ctxt->xdiff_config.flags = XDL_EMIT_FUNCNAMES;
+ ctxt->xdiff_config.find_func = diff_context_find;
+ ctxt->xdiff_config.find_func_priv = ctxt;
- if (!opts)
+ if (!ctxt->opts)
return;
- if (opts->flags & GIT_DIFF_IGNORE_WHITESPACE)
- param->flags |= XDF_WHITESPACE_FLAGS;
- if (opts->flags & GIT_DIFF_IGNORE_WHITESPACE_CHANGE)
- param->flags |= XDF_IGNORE_WHITESPACE_CHANGE;
- if (opts->flags & GIT_DIFF_IGNORE_WHITESPACE_EOL)
- param->flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
+ if (ctxt->opts->flags & GIT_DIFF_IGNORE_WHITESPACE)
+ ctxt->xdiff_params.flags |= XDF_WHITESPACE_FLAGS;
+ if (ctxt->opts->flags & GIT_DIFF_IGNORE_WHITESPACE_CHANGE)
+ ctxt->xdiff_params.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
+ if (ctxt->opts->flags & GIT_DIFF_IGNORE_WHITESPACE_EOL)
+ ctxt->xdiff_params.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
}
@@ -499,7 +550,7 @@ static int diff_context_init(
ctxt->payload = payload;
ctxt->error = 0;
- setup_xdiff_options(ctxt->opts, &ctxt->xdiff_config, &ctxt->xdiff_params);
+ setup_xdiff_options(ctxt);
return 0;
}