diff options
| author | Russell Belfer <rb@github.com> | 2013-10-21 13:42:42 -0700 |
|---|---|---|
| committer | Russell Belfer <rb@github.com> | 2013-10-21 13:42:42 -0700 |
| commit | 3b5f795446601868d52d09ebac70ae3b7aee157a (patch) | |
| tree | ba900c737284e65c172fde7284af3f309b0a0078 /src/diff_patch.c | |
| parent | 74a627f04528f7e02f69d8d7947820582ce7ca15 (diff) | |
| download | libgit2-3b5f795446601868d52d09ebac70ae3b7aee157a.tar.gz | |
Create git_diff_line and extend git_diff_hunk
Instead of having functions with so very many parameters to pass
hunk and line data, this takes the existing git_diff_hunk struct
and extends it with more hunk data, plus adds a git_diff_line.
Those structs are used to pass back hunk and line data instead of
the old APIs that took tons of parameters.
Some work that was previously only being done for git_diff_patch
creation (scanning the diff content for exact line counts) is now
done for all callbacks, but the performance difference should not
be noticable.
Diffstat (limited to 'src/diff_patch.c')
| -rw-r--r-- | src/diff_patch.c | 133 |
1 files changed, 26 insertions, 107 deletions
diff --git a/src/diff_patch.c b/src/diff_patch.c index 951368200..cc49d68eb 100644 --- a/src/diff_patch.c +++ b/src/diff_patch.c @@ -12,23 +12,10 @@ #include "diff_xdiff.h" #include "fileops.h" -/* cached information about a single span in a diff */ -typedef struct diff_patch_line diff_patch_line; -struct diff_patch_line { - const char *ptr; - size_t len; - size_t lines; - size_t oldno; - size_t newno; - char origin; -}; - /* cached information about a hunk in a diff */ typedef struct diff_patch_hunk diff_patch_hunk; struct diff_patch_hunk { git_diff_hunk hunk; - char header[128]; - size_t header_len; size_t line_start; size_t line_count; }; @@ -42,8 +29,7 @@ struct git_patch { git_diff_file_content nfile; uint32_t flags; git_array_t(diff_patch_hunk) hunks; - git_array_t(diff_patch_line) lines; - size_t oldno, newno; + git_array_t(git_diff_line) lines; size_t content_size, context_size, header_size; git_pool flattened; }; @@ -57,7 +43,8 @@ enum { GIT_DIFF_PATCH_FLATTENED = (1 << 5), }; -static void diff_output_init(git_diff_output*, const git_diff_options*, +static void diff_output_init( + git_diff_output*, const git_diff_options*, git_diff_file_cb, git_diff_hunk_cb, git_diff_line_cb, void*); static void diff_output_to_patch(git_diff_output *, git_patch *); @@ -81,7 +68,7 @@ static void diff_patch_init_common(git_patch *patch) diff_patch_update_binary(patch); if ((patch->delta->flags & GIT_DIFF_FLAG_BINARY) != 0) - patch->flags |= GIT_DIFF_PATCH_LOADED; /* set LOADED but not DIFFABLE */ + patch->flags |= GIT_DIFF_PATCH_LOADED; /* LOADED but not DIFFABLE */ patch->flags |= GIT_DIFF_PATCH_INITIALIZED; @@ -687,7 +674,7 @@ int git_patch_line_stats( memset(totals, 0, sizeof(totals)); for (idx = 0; idx < git_array_size(patch->lines); ++idx) { - diff_patch_line *line = git_array_get(patch->lines, idx); + git_diff_line *line = git_array_get(patch->lines, idx); if (!line) continue; @@ -721,8 +708,6 @@ static int diff_error_outofrange(const char *thing) int git_patch_get_hunk( const git_diff_hunk **out, - const char **header, - size_t *header_len, size_t *lines_in_hunk, git_patch *patch, size_t hunk_idx) @@ -734,15 +719,11 @@ int git_patch_get_hunk( if (!hunk) { if (out) *out = NULL; - if (header) *header = NULL; - if (header_len) *header_len = 0; if (lines_in_hunk) *lines_in_hunk = 0; return diff_error_outofrange("hunk"); } if (out) *out = &hunk->hunk; - if (header) *header = hunk->header; - if (header_len) *header_len = hunk->header_len; if (lines_in_hunk) *lines_in_hunk = hunk->line_count; return 0; } @@ -758,49 +739,30 @@ int git_patch_num_lines_in_hunk(git_patch *patch, size_t hunk_idx) } int git_patch_get_line_in_hunk( - char *line_origin, - const char **content, - size_t *content_len, - int *old_lineno, - int *new_lineno, + const git_diff_line **out, git_patch *patch, size_t hunk_idx, size_t line_of_hunk) { diff_patch_hunk *hunk; - diff_patch_line *line; - const char *thing; + git_diff_line *line; assert(patch); if (!(hunk = git_array_get(patch->hunks, hunk_idx))) { - thing = "hunk"; - goto notfound; + if (out) *out = NULL; + return diff_error_outofrange("hunk"); } if (line_of_hunk >= hunk->line_count || !(line = git_array_get( patch->lines, hunk->line_start + line_of_hunk))) { - thing = "line"; - goto notfound; + if (out) *out = NULL; + return diff_error_outofrange("line"); } - if (line_origin) *line_origin = line->origin; - if (content) *content = line->ptr; - if (content_len) *content_len = line->len; - if (old_lineno) *old_lineno = (int)line->oldno; - if (new_lineno) *new_lineno = (int)line->newno; - + if (out) *out = line; return 0; - -notfound: - if (line_origin) *line_origin = GIT_DIFF_LINE_CONTEXT; - if (content) *content = NULL; - if (content_len) *content_len = 0; - if (old_lineno) *old_lineno = -1; - if (new_lineno) *new_lineno = -1; - - return diff_error_outofrange(thing); } size_t git_patch_size( @@ -880,18 +842,16 @@ int git_patch__invoke_callbacks( for (i = 0; !error && i < git_array_size(patch->hunks); ++i) { diff_patch_hunk *h = git_array_get(patch->hunks, i); - error = hunk_cb( - patch->delta, &h->hunk, h->header, h->header_len, payload); + error = hunk_cb(patch->delta, &h->hunk, payload); if (!line_cb) continue; for (j = 0; !error && j < h->line_count; ++j) { - diff_patch_line *l = + git_diff_line *l = git_array_get(patch->lines, h->line_start + j); - error = line_cb( - patch->delta, &h->hunk, l->origin, l->ptr, l->len, payload); + error = line_cb(patch->delta, &h->hunk, l, payload); } } @@ -911,8 +871,6 @@ static int diff_patch_file_cb( static int diff_patch_hunk_cb( const git_diff_delta *delta, const git_diff_hunk *hunk_, - const char *header, - size_t header_len, void *payload) { git_patch *patch = payload; @@ -925,34 +883,23 @@ static int diff_patch_hunk_cb( memcpy(&hunk->hunk, hunk_, sizeof(hunk->hunk)); - assert(header_len + 1 < sizeof(hunk->header)); - memcpy(&hunk->header, header, header_len); - hunk->header[header_len] = '\0'; - hunk->header_len = header_len; - - patch->header_size += header_len; + patch->header_size += hunk_->header_len; hunk->line_start = git_array_size(patch->lines); hunk->line_count = 0; - patch->oldno = hunk_->old_start; - patch->newno = hunk_->new_start; - return 0; } static int diff_patch_line_cb( const git_diff_delta *delta, const git_diff_hunk *hunk_, - char line_origin, - const char *content, - size_t content_len, + const git_diff_line *line_, void *payload) { git_patch *patch = payload; diff_patch_hunk *hunk; - diff_patch_line *line; - const char *content_end = content + content_len; + git_diff_line *line; GIT_UNUSED(delta); GIT_UNUSED(hunk_); @@ -963,48 +910,20 @@ static int diff_patch_line_cb( line = git_array_alloc(patch->lines); GITERR_CHECK_ALLOC(line); - line->ptr = content; - line->len = content_len; - line->origin = line_origin; + memcpy(line, line_, sizeof(*line)); /* do some bookkeeping so we can provide old/new line numbers */ - line->lines = 0; - while (content < content_end) - if (*content++ == '\n') - ++line->lines; + patch->content_size += line->content_len; - patch->content_size += content_len; - - switch (line_origin) { - case GIT_DIFF_LINE_ADDITION: - patch->content_size += 1; - case GIT_DIFF_LINE_DEL_EOFNL: - line->oldno = -1; - line->newno = patch->newno; - patch->newno += line->lines; - break; - case GIT_DIFF_LINE_DELETION: + if (line->origin == GIT_DIFF_LINE_ADDITION || + line->origin == GIT_DIFF_LINE_DELETION) patch->content_size += 1; - case GIT_DIFF_LINE_ADD_EOFNL: - line->oldno = patch->oldno; - line->newno = -1; - patch->oldno += line->lines; - break; - case GIT_DIFF_LINE_CONTEXT: + else if (line->origin == GIT_DIFF_LINE_CONTEXT) { patch->content_size += 1; - patch->context_size += 1; - case GIT_DIFF_LINE_CONTEXT_EOFNL: - patch->context_size += content_len; - line->oldno = patch->oldno; - line->newno = patch->newno; - patch->oldno += line->lines; - patch->newno += line->lines; - break; - default: - assert(false); - break; - } + patch->context_size += line->content_len + 1; + } else if (line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL) + patch->context_size += line->content_len; hunk->line_count++; |
