diff options
author | Russell Belfer <rb@github.com> | 2013-12-03 16:45:39 -0800 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2013-12-11 10:57:49 -0800 |
commit | 96869a4edb2872934e0e167a726ab240f4270fea (patch) | |
tree | 2d770414acef2d1d45a609e004c0aa6fa56d06d7 /src/diff_xdiff.c | |
parent | 9f77b3f6f5ce6944ec49dfc666ef6b8df0af0c6b (diff) | |
download | libgit2-96869a4edb2872934e0e167a726ab240f4270fea.tar.gz |
Improve GIT_EUSER handling
This adds giterr_user_cancel to return GIT_EUSER and clear any
error message that is sitting around. As a result of using that
in places, we need to be more thorough with capturing errors that
happen inside a callback when used internally. To help with that,
this also adds giterr_capture and giterr_restore so that when we
internally use a foreach-type function that clears errors and
converts them to GIT_EUSER, it is easier to restore not just the
return value, but the actual error message text.
Diffstat (limited to 'src/diff_xdiff.c')
-rw-r--r-- | src/diff_xdiff.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c index e0bc11f7f..c6ca48882 100644 --- a/src/diff_xdiff.c +++ b/src/diff_xdiff.c @@ -28,25 +28,29 @@ static int git_xdiff_parse_hunk(git_diff_hunk *hunk, const char *header) { /* expect something of the form "@@ -%d[,%d] +%d[,%d] @@" */ if (*header != '@') - return -1; + goto fail; if (git_xdiff_scan_int(&header, &hunk->old_start) < 0) - return -1; + goto fail; if (*header == ',') { if (git_xdiff_scan_int(&header, &hunk->old_lines) < 0) - return -1; + goto fail; } else hunk->old_lines = 1; if (git_xdiff_scan_int(&header, &hunk->new_start) < 0) - return -1; + goto fail; if (*header == ',') { if (git_xdiff_scan_int(&header, &hunk->new_lines) < 0) - return -1; + goto fail; } else hunk->new_lines = 1; if (hunk->old_start < 0 || hunk->new_start < 0) - return -1; + goto fail; return 0; + +fail: + giterr_set(GITERR_INVALID, "Malformed hunk header from xdiff"); + return -1; } typedef struct { @@ -123,7 +127,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) if (output->hunk_cb != NULL && output->hunk_cb(delta, &info->hunk, output->payload)) - output->error = GIT_EUSER; + return (output->error = giterr_user_cancel()); info->old_lineno = info->hunk.old_start; info->new_lineno = info->hunk.new_start; @@ -149,7 +153,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) if (!output->error && output->data_cb != NULL && output->data_cb(delta, &info->hunk, &line, output->payload)) - output->error = GIT_EUSER; + output->error = giterr_user_cancel(); } if (len == 3 && !output->error) { @@ -171,7 +175,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len) if (!output->error && output->data_cb != NULL && output->data_cb(delta, &info->hunk, &line, output->payload)) - output->error = GIT_EUSER; + output->error = giterr_user_cancel(); } return output->error; @@ -219,11 +223,9 @@ void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts) xo->output.diff_cb = git_xdiff; - memset(&xo->config, 0, sizeof(xo->config)); xo->config.ctxlen = opts ? opts->context_lines : 3; xo->config.interhunkctxlen = opts ? opts->interhunk_lines : 0; - memset(&xo->params, 0, sizeof(xo->params)); if (flags & GIT_DIFF_IGNORE_WHITESPACE) xo->params.flags |= XDF_WHITESPACE_FLAGS; if (flags & GIT_DIFF_IGNORE_WHITESPACE_CHANGE) @@ -236,6 +238,5 @@ void git_xdiff_init(git_xdiff_output *xo, const git_diff_options *opts) if (flags & GIT_DIFF_MINIMAL) xo->params.flags |= XDF_NEED_MINIMAL; - memset(&xo->callback, 0, sizeof(xo->callback)); xo->callback.outf = git_xdiff_cb; } |