summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-10-21 13:42:42 -0700
committerRussell Belfer <rb@github.com>2013-10-21 13:42:42 -0700
commit3b5f795446601868d52d09ebac70ae3b7aee157a (patch)
treeba900c737284e65c172fde7284af3f309b0a0078
parent74a627f04528f7e02f69d8d7947820582ce7ca15 (diff)
downloadlibgit2-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.
-rw-r--r--examples/diff.c28
-rw-r--r--examples/log.c16
-rw-r--r--include/git2/diff.h31
-rw-r--r--include/git2/patch.h17
-rw-r--r--src/diff_patch.c133
-rw-r--r--src/diff_print.c93
-rw-r--r--src/diff_xdiff.c81
-rw-r--r--tests-clar/diff/blob.c20
-rw-r--r--tests-clar/diff/diff_helpers.c58
-rw-r--r--tests-clar/diff/diff_helpers.h10
-rw-r--r--tests-clar/diff/diffiter.c28
-rw-r--r--tests-clar/diff/patch.c223
-rw-r--r--tests-clar/diff/tree.c19
-rw-r--r--tests-clar/diff/workdir.c21
14 files changed, 360 insertions, 418 deletions
diff --git a/examples/diff.c b/examples/diff.c
index 2542f4269..694621f1e 100644
--- a/examples/diff.c
+++ b/examples/diff.c
@@ -45,25 +45,23 @@ char *colors[] = {
static int printer(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char usage,
- const char *line,
- size_t line_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *data)
{
int *last_color = data, color = 0;
- (void)delta; (void)range; (void)line_len;
+ (void)delta; (void)hunk;
if (*last_color >= 0) {
- switch (usage) {
- case GIT_DIFF_LINE_ADDITION: color = 3; break;
- case GIT_DIFF_LINE_DELETION: color = 2; break;
+ switch (line->origin) {
+ case GIT_DIFF_LINE_ADDITION: color = 3; break;
+ case GIT_DIFF_LINE_DELETION: color = 2; break;
case GIT_DIFF_LINE_ADD_EOFNL: color = 3; break;
case GIT_DIFF_LINE_DEL_EOFNL: color = 2; break;
- case GIT_DIFF_LINE_FILE_HDR: color = 1; break;
- case GIT_DIFF_LINE_HUNK_HDR: color = 4; break;
- default: color = 0;
+ case GIT_DIFF_LINE_FILE_HDR: color = 1; break;
+ case GIT_DIFF_LINE_HUNK_HDR: color = 4; break;
+ default: break;
}
if (color != *last_color) {
if (*last_color == 1 || color == 1)
@@ -73,7 +71,13 @@ static int printer(
}
}
- fputs(line, stdout);
+ if (line->origin == GIT_DIFF_LINE_CONTEXT ||
+ line->origin == GIT_DIFF_LINE_ADDITION ||
+ line->origin == GIT_DIFF_LINE_DELETION)
+ fputc(line->origin, stdout);
+
+ fwrite(line->content, 1, line->content_len, stdout);
+
return 0;
}
diff --git a/examples/log.c b/examples/log.c
index 30de16ae9..4c2df07c9 100644
--- a/examples/log.c
+++ b/examples/log.c
@@ -184,14 +184,18 @@ static void print_commit(git_commit *commit)
static int print_diff(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char usage,
- const char *line,
- size_t line_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *data)
{
- (void)delta; (void)range; (void)usage; (void)line_len; (void)data;
- fputs(line, stdout);
+ (void)delta; (void)hunk; (void)data;
+
+ if (line->origin == GIT_DIFF_LINE_CONTEXT ||
+ line->origin == GIT_DIFF_LINE_ADDITION ||
+ line->origin == GIT_DIFF_LINE_DELETION)
+ fputc(line->origin, stdout);
+
+ fwrite(line->content, 1, line->content_len, stdout);
return 0;
}
diff --git a/include/git2/diff.h b/include/git2/diff.h
index f1572cbd5..ed9f71355 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -385,10 +385,12 @@ typedef int (*git_diff_file_cb)(
*/
typedef struct git_diff_hunk git_diff_hunk;
struct git_diff_hunk {
- int old_start; /** Starting line number in old_file */
- int old_lines; /** Number of lines in old_file */
- int new_start; /** Starting line number in new_file */
- int new_lines; /** Number of lines in new_file */
+ int old_start; /** Starting line number in old_file */
+ int old_lines; /** Number of lines in old_file */
+ int new_start; /** Starting line number in new_file */
+ int new_lines; /** Number of lines in new_file */
+ size_t header_len; /** Number of bytes in header text */
+ char header[128]; /** Header text, NUL-byte terminated */
};
/**
@@ -397,8 +399,6 @@ struct git_diff_hunk {
typedef int (*git_diff_hunk_cb)(
const git_diff_delta *delta,
const git_diff_hunk *hunk,
- const char *header,
- size_t header_len,
void *payload);
/**
@@ -429,6 +429,19 @@ typedef enum {
} git_diff_line_t;
/**
+ * Structure describing a line (or data span) of a diff.
+ */
+typedef struct git_diff_line git_diff_line;
+struct git_diff_line {
+ char origin; /** A git_diff_line_t value */
+ int old_lineno; /** Line number in old file or -1 for added line */
+ int new_lineno; /** Line number in new file or -1 for deleted line */
+ int num_lines; /** Number of newline characters in content */
+ size_t content_len; /** Number of bytes of data */
+ const char *content; /** Pointer to diff text, not NUL-byte terminated */
+};
+
+/**
* When iterating over a diff, callback that will be made per text diff
* line. In this context, the provided range will be NULL.
*
@@ -438,10 +451,8 @@ typedef enum {
*/
typedef int (*git_diff_line_cb)(
const git_diff_delta *delta, /** delta that contains this data */
- const git_diff_hunk *hunk, /** range of lines containing this data */
- char line_origin, /** git_diff_t value from above */
- const char *content, /** diff data - not NUL terminated */
- size_t content_len, /** number of bytes of diff data */
+ const git_diff_hunk *hunk, /** hunk containing this data */
+ const git_diff_line *line, /** line data */
void *payload); /** user reference data */
/**
diff --git a/include/git2/patch.h b/include/git2/patch.h
index 9836245de..6a6ad92d7 100644
--- a/include/git2/patch.h
+++ b/include/git2/patch.h
@@ -150,9 +150,6 @@ GIT_EXTERN(int) git_patch_line_stats(
* as NULL if you don't care about that particular piece of information.
*
* @param out Output pointer to git_diff_hunk of hunk
- * @param header Output pointer to header string for hunk. Unlike the
- * content pointer for each line, this will be NUL-terminated
- * @param header_len Output value of characters in header string
* @param lines_in_hunk Output count of total lines in this hunk
* @param patch Input pointer to patch object
* @param hunk_idx Input index of hunk to get information about
@@ -160,8 +157,6 @@ GIT_EXTERN(int) git_patch_line_stats(
*/
GIT_EXTERN(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);
@@ -185,22 +180,14 @@ GIT_EXTERN(int) git_patch_num_lines_in_hunk(
* index larger than the number of hunks or a line index larger than
* the number of lines in the hunk, this will return -1.
*
- * @param line_origin A GIT_DIFF_LINE constant from above
- * @param content Pointer to content of diff line, not NUL-terminated
- * @param content_len Number of characters in content
- * @param old_lineno Line number in old file or -1 if line is added
- * @param new_lineno Line number in new file or -1 if line is deleted
+ * @param out The git_diff_line data for this line
* @param patch The patch to look in
* @param hunk_idx The index of the hunk
* @param line_of_hunk The index of the line in the hunk
* @return 0 on success, <0 on failure
*/
GIT_EXTERN(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 --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++;
diff --git a/src/diff_print.c b/src/diff_print.c
index a6423d92b..b04b11515 100644
--- a/src/diff_print.c
+++ b/src/diff_print.c
@@ -17,6 +17,7 @@ typedef struct {
git_buf *buf;
uint32_t flags;
int oid_strlen;
+ git_diff_line line;
} diff_print_info;
static int diff_print_info_init(
@@ -51,6 +52,11 @@ static int diff_print_info_init(
else if (pi->oid_strlen > GIT_OID_HEXSZ + 1)
pi->oid_strlen = GIT_OID_HEXSZ + 1;
+ memset(&pi->line, 0, sizeof(pi->line));
+ pi->line.old_lineno = -1;
+ pi->line.new_lineno = -1;
+ pi->line.num_lines = 1;
+
return 0;
}
@@ -107,8 +113,11 @@ static int diff_print_one_name_only(
git_buf_putc(out, '\n'))
return -1;
- if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR,
- git_buf_cstr(out), git_buf_len(out), pi->payload))
+ pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
+ pi->line.content = git_buf_cstr(out);
+ pi->line.content_len = git_buf_len(out);
+
+ if (pi->print_cb(delta, NULL, &pi->line, pi->payload))
return callback_error();
return 0;
@@ -149,8 +158,11 @@ static int diff_print_one_name_status(
if (git_buf_oom(out))
return -1;
- if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR,
- git_buf_cstr(out), git_buf_len(out), pi->payload))
+ pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
+ pi->line.content = git_buf_cstr(out);
+ pi->line.content_len = git_buf_len(out);
+
+ if (pi->print_cb(delta, NULL, &pi->line, pi->payload))
return callback_error();
return 0;
@@ -192,8 +204,11 @@ static int diff_print_one_raw(
if (git_buf_oom(out))
return -1;
- if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR,
- git_buf_cstr(out), git_buf_len(out), pi->payload))
+ pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
+ pi->line.content = git_buf_cstr(out);
+ pi->line.content_len = git_buf_len(out);
+
+ if (pi->print_cb(delta, NULL, &pi->line, pi->payload))
return callback_error();
return 0;
@@ -302,8 +317,11 @@ static int diff_print_patch_file(
pi->buf, delta, oldpfx, newpfx, pi->oid_strlen) < 0)
return -1;
- if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_FILE_HDR,
- git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload))
+ pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
+ pi->line.content = git_buf_cstr(pi->buf);
+ pi->line.content_len = git_buf_len(pi->buf);
+
+ if (pi->print_cb(delta, NULL, &pi->line, pi->payload))
return callback_error();
if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
@@ -316,8 +334,12 @@ static int diff_print_patch_file(
"Binary files %s%s and %s%s differ\n") < 0)
return -1;
- if (pi->print_cb(delta, NULL, GIT_DIFF_LINE_BINARY,
- git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload))
+ pi->line.origin = GIT_DIFF_LINE_BINARY;
+ pi->line.content = git_buf_cstr(pi->buf);
+ pi->line.content_len = git_buf_len(pi->buf);
+ pi->line.num_lines = 1;
+
+ if (pi->print_cb(delta, NULL, &pi->line, pi->payload))
return callback_error();
return 0;
@@ -325,9 +347,7 @@ static int diff_print_patch_file(
static int diff_print_patch_hunk(
const git_diff_delta *d,
- const git_diff_hunk *r,
- const char *header,
- size_t header_len,
+ const git_diff_hunk *h,
void *data)
{
diff_print_info *pi = data;
@@ -335,12 +355,11 @@ static int diff_print_patch_hunk(
if (S_ISDIR(d->new_file.mode))
return 0;
- git_buf_clear(pi->buf);
- if (git_buf_put(pi->buf, header, header_len) < 0)
- return -1;
+ pi->line.origin = GIT_DIFF_LINE_HUNK_HDR;
+ pi->line.content = h->header;
+ pi->line.content_len = h->header_len;
- if (pi->print_cb(d, r, GIT_DIFF_LINE_HUNK_HDR,
- git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload))
+ if (pi->print_cb(d, h, &pi->line, pi->payload))
return callback_error();
return 0;
@@ -348,10 +367,8 @@ static int diff_print_patch_hunk(
static int diff_print_patch_line(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin, /* GIT_DIFF_LINE value from above */
- const char *content,
- size_t content_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *data)
{
diff_print_info *pi = data;
@@ -359,21 +376,7 @@ static int diff_print_patch_line(
if (S_ISDIR(delta->new_file.mode))
return 0;
- git_buf_clear(pi->buf);
- git_buf_grow(pi->buf, content_len + 2);
-
- if (line_origin == GIT_DIFF_LINE_ADDITION ||
- line_origin == GIT_DIFF_LINE_DELETION ||
- line_origin == GIT_DIFF_LINE_CONTEXT)
- git_buf_putc(pi->buf, line_origin);
-
- git_buf_put(pi->buf, content, content_len);
-
- if (git_buf_oom(pi->buf))
- return -1;
-
- if (pi->print_cb(delta, range, line_origin,
- git_buf_cstr(pi->buf), git_buf_len(pi->buf), pi->payload))
+ if (pi->print_cb(delta, hunk, line, pi->payload))
return callback_error();
return 0;
@@ -452,15 +455,19 @@ int git_patch_print(
static int diff_print_to_buffer_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin,
- const char *content,
- size_t content_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *payload)
{
git_buf *output = payload;
- GIT_UNUSED(delta); GIT_UNUSED(range); GIT_UNUSED(line_origin);
- return git_buf_put(output, content, content_len);
+ GIT_UNUSED(delta); GIT_UNUSED(hunk);
+
+ if (line->origin == GIT_DIFF_LINE_ADDITION ||
+ line->origin == GIT_DIFF_LINE_DELETION ||
+ line->origin == GIT_DIFF_LINE_CONTEXT)
+ git_buf_putc(output, line->origin);
+
+ return git_buf_put(output, line->content, line->content_len);
}
/* print a git_patch to a string buffer */
diff --git a/src/diff_xdiff.c b/src/diff_xdiff.c
index 972039753..a90f8d5d1 100644
--- a/src/diff_xdiff.c
+++ b/src/diff_xdiff.c
@@ -53,36 +53,94 @@ typedef struct {
git_xdiff_output *xo;
git_patch *patch;
git_diff_hunk hunk;
+ size_t old_lineno, new_lineno;
} git_xdiff_info;
+static int diff_update_lines(
+ git_xdiff_info *info,
+ git_diff_line *line,
+ const char *content,
+ size_t content_len)
+{
+ const char *scan = content, *scan_end = content + content_len;
+
+ for (line->num_lines = 0; scan < scan_end; ++scan)
+ if (*scan == '\n')
+ ++line->num_lines;
+
+ line->content = content;
+ line->content_len = content_len;
+
+ /* expect " "/"-"/"+", then data */
+ switch (line->origin) {
+ case GIT_DIFF_LINE_ADDITION:
+ case GIT_DIFF_LINE_DEL_EOFNL:
+ line->old_lineno = -1;
+ line->new_lineno = info->new_lineno;
+ info->new_lineno += line->num_lines;
+ break;
+ case GIT_DIFF_LINE_DELETION:
+ case GIT_DIFF_LINE_ADD_EOFNL:
+ line->old_lineno = info->old_lineno;
+ line->new_lineno = -1;
+ info->old_lineno += line->num_lines;
+ break;
+ case GIT_DIFF_LINE_CONTEXT:
+ case GIT_DIFF_LINE_CONTEXT_EOFNL:
+ line->old_lineno = info->old_lineno;
+ line->new_lineno = info->new_lineno;
+ info->old_lineno += line->num_lines;
+ info->new_lineno += line->num_lines;
+ break;
+ default:
+ giterr_set(GITERR_INVALID, "Unknown diff line origin %02x",
+ (unsigned int)line->origin);
+ return -1;
+ }
+
+ return 0;
+}
+
static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
{
git_xdiff_info *info = priv;
git_patch *patch = info->patch;
const git_diff_delta *delta = git_patch_get_delta(patch);
git_diff_output *output = &info->xo->output;
+ git_diff_line line;
if (len == 1) {
output->error = git_xdiff_parse_hunk(&info->hunk, bufs[0].ptr);
if (output->error < 0)
return output->error;
+ info->hunk.header_len = bufs[0].size;
+ if (info->hunk.header_len >= sizeof(info->hunk.header))
+ info->hunk.header_len = sizeof(info->hunk.header) - 1;
+ memcpy(info->hunk.header, bufs[0].ptr, info->hunk.header_len);
+ info->hunk.header[info->hunk.header_len] = '\0';
+
if (output->hunk_cb != NULL &&
- output->hunk_cb(delta, &info->hunk,
- bufs[0].ptr, bufs[0].size, output->payload))
+ output->hunk_cb(delta, &info->hunk, output->payload))
output->error = GIT_EUSER;
+
+ info->old_lineno = info->hunk.old_start;
+ info->new_lineno = info->hunk.new_start;
}
if (len == 2 || len == 3) {
/* expect " "/"-"/"+", then data */
- char origin =
+ line.origin =
(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_ADDITION :
(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_DELETION :
GIT_DIFF_LINE_CONTEXT;
- if (output->data_cb != NULL &&
- output->data_cb(delta, &info->hunk,
- origin, bufs[1].ptr, bufs[1].size, output->payload))
+ output->error = diff_update_lines(
+ info, &line, bufs[1].ptr, bufs[1].size);
+
+ if (!output->error &&
+ output->data_cb != NULL &&
+ output->data_cb(delta, &info->hunk, &line, output->payload))
output->error = GIT_EUSER;
}
@@ -92,14 +150,17 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
* If we have a '-' and a third buf, then we have removed a line
* with out a newline but added a blank line, so ADD_EOFNL.
*/
- char origin =
+ line.origin =
(*bufs[0].ptr == '+') ? GIT_DIFF_LINE_DEL_EOFNL :
(*bufs[0].ptr == '-') ? GIT_DIFF_LINE_ADD_EOFNL :
GIT_DIFF_LINE_CONTEXT_EOFNL;
- if (output->data_cb != NULL &&
- output->data_cb(delta, &info->hunk,
- origin, bufs[2].ptr, bufs[2].size, output->payload))
+ output->error = diff_update_lines(
+ info, &line, bufs[2].ptr, bufs[2].size);
+
+ if (!output->error &&
+ output->data_cb != NULL &&
+ output->data_cb(delta, &info->hunk, &line, output->payload))
output->error = GIT_EUSER;
}
diff --git a/tests-clar/diff/blob.c b/tests-clar/diff/blob.c
index 898c037b5..b51bc0f38 100644
--- a/tests-clar/diff/blob.c
+++ b/tests-clar/diff/blob.c
@@ -319,8 +319,8 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
git_blob *e = NULL;
git_patch *p;
const git_diff_delta *delta;
- int line;
- char origin;
+ const git_diff_line *line;
+ int l, max_l;
cl_git_pass(git_patch_from_blobs(&p, d, NULL, e, NULL, &opts));
@@ -337,10 +337,10 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
- for (line = 0; line < git_patch_num_lines_in_hunk(p, 0); ++line) {
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, NULL, NULL, NULL, NULL, p, 0, line));
- cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
+ max_l = git_patch_num_lines_in_hunk(p, 0);
+ for (l = 0; l < max_l; ++l) {
+ cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
+ cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
}
git_patch_free(p);
@@ -362,10 +362,10 @@ void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
- for (line = 0; line < git_patch_num_lines_in_hunk(p, 0); ++line) {
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, NULL, NULL, NULL, NULL, p, 0, line));
- cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
+ max_l = git_patch_num_lines_in_hunk(p, 0);
+ for (l = 0; l < max_l; ++l) {
+ cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
+ cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
}
git_patch_free(p);
diff --git a/tests-clar/diff/diff_helpers.c b/tests-clar/diff/diff_helpers.c
index cf768865e..466d0ef54 100644
--- a/tests-clar/diff/diff_helpers.c
+++ b/tests-clar/diff/diff_helpers.c
@@ -95,41 +95,37 @@ int diff_print_file_cb(
int diff_hunk_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- const char *header,
- size_t header_len,
+ const git_diff_hunk *hunk,
void *payload)
{
diff_expects *e = payload;
+ const char *scan = hunk->header, *scan_end = scan + hunk->header_len;
GIT_UNUSED(delta);
/* confirm no NUL bytes in header text */
- while (header_len--) cl_assert('\0' != *header++);
+ while (scan < scan_end)
+ cl_assert('\0' != *scan++);
e->hunks++;
- e->hunk_old_lines += range->old_lines;
- e->hunk_new_lines += range->new_lines;
+ e->hunk_old_lines += hunk->old_lines;
+ e->hunk_new_lines += hunk->new_lines;
return 0;
}
int diff_line_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin,
- const char *content,
- size_t content_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *payload)
{
diff_expects *e = payload;
GIT_UNUSED(delta);
- GIT_UNUSED(range);
- GIT_UNUSED(content);
- GIT_UNUSED(content_len);
+ GIT_UNUSED(hunk);
e->lines++;
- switch (line_origin) {
+ switch (line->origin) {
case GIT_DIFF_LINE_CONTEXT:
case GIT_DIFF_LINE_CONTEXT_EOFNL: /* techically not a line */
e->line_ctxt++;
@@ -186,30 +182,23 @@ int diff_foreach_via_iterator(
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
- const git_diff_hunk *range;
- const char *hdr;
- size_t hdr_len, l, num_l;
+ const git_diff_hunk *hunk;
+ size_t l, num_l;
- cl_git_pass(git_patch_get_hunk(
- &range, &hdr, &hdr_len, &num_l, patch, h));
+ cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
- if (hunk_cb && hunk_cb(delta, range, hdr, hdr_len, data) != 0) {
+ if (hunk_cb && hunk_cb(delta, hunk, data) != 0) {
git_patch_free(patch);
goto abort;
}
for (l = 0; l < num_l; ++l) {
- char origin;
- const char *line;
- size_t line_len;
- int old_lineno, new_lineno;
+ const git_diff_line *line;
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &line, &line_len, &old_lineno, &new_lineno,
- patch, h, l));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
if (line_cb &&
- line_cb(delta, range, origin, line, line_len, data) != 0) {
+ line_cb(delta, hunk, line, data) != 0) {
git_patch_free(patch);
goto abort;
}
@@ -228,18 +217,15 @@ abort:
static int diff_print_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin, /**< GIT_DIFF_LINE_... value from above */
- const char *content,
- size_t content_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *payload)
{
GIT_UNUSED(payload);
GIT_UNUSED(delta);
- GIT_UNUSED(range);
- GIT_UNUSED(line_origin);
- GIT_UNUSED(content_len);
- fputs(content, (FILE *)payload);
+ GIT_UNUSED(hunk);
+ fprintf((FILE *)payload, "%c%.*s",
+ line->origin, (int)line->content_len, line->content);
return 0;
}
diff --git a/tests-clar/diff/diff_helpers.h b/tests-clar/diff/diff_helpers.h
index e3ad61f29..bf21f4b1f 100644
--- a/tests-clar/diff/diff_helpers.h
+++ b/tests-clar/diff/diff_helpers.h
@@ -44,17 +44,13 @@ extern int diff_print_file_cb(
extern int diff_hunk_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- const char *header,
- size_t header_len,
+ const git_diff_hunk *hunk,
void *cb_data);
extern int diff_line_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin,
- const char *content,
- size_t content_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *cb_data);
extern int diff_foreach_via_iterator(
diff --git a/tests-clar/diff/diffiter.c b/tests-clar/diff/diffiter.c
index 1a1e5dfc3..f886e1baa 100644
--- a/tests-clar/diff/diffiter.c
+++ b/tests-clar/diff/diffiter.c
@@ -101,15 +101,10 @@ void test_diff_diffiter__iterate_files_and_hunks(void)
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
- const git_diff_hunk *range;
- const char *header;
- size_t header_len, num_l;
-
- cl_git_pass(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, h));
+ const git_diff_hunk *hunk;
- cl_assert(range);
- cl_assert(header);
+ cl_git_pass(git_patch_get_hunk(&hunk, NULL, patch, h));
+ cl_assert(hunk);
hunk_count++;
}
@@ -229,22 +224,17 @@ void test_diff_diffiter__iterate_all(void)
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
const git_diff_hunk *range;
- const char *header;
- size_t header_len, l, num_l;
+ size_t l, num_l;
- cl_git_pass(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, h));
- cl_assert(range && header);
+ cl_git_pass(git_patch_get_hunk(&range, &num_l, patch, h));
+ cl_assert(range);
exp.hunks++;
for (l = 0; l < num_l; ++l) {
- char origin;
- const char *content;
- size_t content_len;
+ const git_diff_line *line;
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &content, &content_len, NULL, NULL, patch, h, l));
- cl_assert(content);
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
+ cl_assert(line && line->content);
exp.lines++;
}
}
diff --git a/tests-clar/diff/patch.c b/tests-clar/diff/patch.c
index 9c01c3b4e..366e5da58 100644
--- a/tests-clar/diff/patch.c
+++ b/tests-clar/diff/patch.c
@@ -26,40 +26,37 @@ void test_diff_patch__cleanup(void)
static int check_removal_cb(
const git_diff_delta *delta,
- const git_diff_hunk *range,
- char line_origin,
- const char *formatted_output,
- size_t output_len,
+ const git_diff_hunk *hunk,
+ const git_diff_line *line,
void *payload)
{
GIT_UNUSED(payload);
- GIT_UNUSED(output_len);
- switch (line_origin) {
+ switch (line->origin) {
case GIT_DIFF_LINE_FILE_HDR:
- cl_assert_equal_s(EXPECTED_HEADER, formatted_output);
- cl_assert(range == NULL);
+ cl_assert_equal_s(EXPECTED_HEADER, line->content);
+ cl_assert(hunk == NULL);
goto check_delta;
case GIT_DIFF_LINE_HUNK_HDR:
- cl_assert_equal_s(EXPECTED_HUNK, formatted_output);
+ cl_assert_equal_s(EXPECTED_HUNK, line->content);
/* Fall through */
case GIT_DIFF_LINE_CONTEXT:
case GIT_DIFF_LINE_DELETION:
- goto check_range;
+ goto check_hunk;
default:
/* unexpected code path */
return -1;
}
-check_range:
- cl_assert(range != NULL);
- cl_assert_equal_i(1, range->old_start);
- cl_assert_equal_i(2, range->old_lines);
- cl_assert_equal_i(0, range->new_start);
- cl_assert_equal_i(0, range->new_lines);
+check_hunk:
+ cl_assert(hunk != NULL);
+ cl_assert_equal_i(1, hunk->old_start);
+ cl_assert_equal_i(2, hunk->old_lines);
+ cl_assert_equal_i(0, hunk->new_start);
+ cl_assert_equal_i(0, hunk->new_lines);
check_delta:
cl_assert_equal_s("subdir.txt", delta->old_file.path);
@@ -227,11 +224,9 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
git_diff *diff;
git_patch *patch;
const git_diff_delta *delta;
- const git_diff_hunk *range;
- const char *hdr, *text;
- size_t hdrlen, hunklen, textlen;
- char origin;
- int oldno, newno;
+ const git_diff_hunk *hunk;
+ const git_diff_line *line;
+ size_t hunklen;
git_buf old_content = GIT_BUF_INIT, actual = GIT_BUF_INIT;
const char *new_content = "The Song of Seven Cities\n------------------------\n\nI WAS Lord of Cities very sumptuously builded.\nSeven roaring Cities paid me tribute from afar.\nIvory their outposts were--the guardrooms of them gilded,\nAnd garrisoned with Amazons invincible in war.\n\nThis is some new text;\nNot as good as the old text;\nBut here it is.\n\nSo they warred and trafficked only yesterday, my Cities.\nTo-day there is no mark or mound of where my Cities stood.\nFor the River rose at midnight and it washed away my Cities.\nThey are evened with Atlantis and the towns before the Flood.\n\nRain on rain-gorged channels raised the water-levels round them,\nFreshet backed on freshet swelled and swept their world from sight,\nTill the emboldened floods linked arms and, flashing forward, drowned them--\nDrowned my Seven Cities and their peoples in one night!\n\nLow among the alders lie their derelict foundations,\nThe beams wherein they trusted and the plinths whereon they built--\nMy rulers and their treasure and their unborn populations,\nDead, destroyed, aborted, and defiled with mud and silt!\n\nAnother replacement;\nBreaking up the poem;\nGenerating some hunks.\n\nTo the sound of trumpets shall their seed restore my Cities\nWealthy and well-weaponed, that once more may I behold\nAll the world go softly when it walks before my Cities,\nAnd the horses and the chariots fleeing from them as of old!\n\n -- Rudyard Kipling\n";
@@ -263,78 +258,71 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
/* check hunk 0 */
cl_git_pass(
- git_patch_get_hunk(&range, &hdr, &hdrlen, &hunklen, patch, 0));
+ git_patch_get_hunk(&hunk, &hunklen, patch, 0));
cl_assert_equal_i(18, (int)hunklen);
- cl_assert_equal_i(6, (int)range->old_start);
- cl_assert_equal_i(15, (int)range->old_lines);
- cl_assert_equal_i(6, (int)range->new_start);
- cl_assert_equal_i(9, (int)range->new_lines);
+ cl_assert_equal_i(6, (int)hunk->old_start);
+ cl_assert_equal_i(15, (int)hunk->old_lines);
+ cl_assert_equal_i(6, (int)hunk->new_start);
+ cl_assert_equal_i(9, (int)hunk->new_lines);
cl_assert_equal_i(18, (int)git_patch_num_lines_in_hunk(patch, 0));
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 0));
- cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 0));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("Ivory their outposts were--the guardrooms of them gilded,\n", actual.ptr);
- cl_assert_equal_i(6, oldno);
- cl_assert_equal_i(6, newno);
+ cl_assert_equal_i(6, line->old_lineno);
+ cl_assert_equal_i(6, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 3));
- cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3));
+ cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("All the world went softly when it walked before my Cities--\n", actual.ptr);
- cl_assert_equal_i(9, oldno);
- cl_assert_equal_i(-1, newno);
+ cl_assert_equal_i(9, line->old_lineno);
+ cl_assert_equal_i(-1, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 12));
- cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 12));
+ cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("This is some new text;\n", actual.ptr);
- cl_assert_equal_i(-1, oldno);
- cl_assert_equal_i(9, newno);
+ cl_assert_equal_i(-1, line->old_lineno);
+ cl_assert_equal_i(9, line->new_lineno);
/* check hunk 1 */
- cl_git_pass(
- git_patch_get_hunk(&range, &hdr, &hdrlen, &hunklen, patch, 1));
+ cl_git_pass(git_patch_get_hunk(&hunk, &hunklen, patch, 1));
cl_assert_equal_i(18, (int)hunklen);
- cl_assert_equal_i(31, (int)range->old_start);
- cl_assert_equal_i(15, (int)range->old_lines);
- cl_assert_equal_i(25, (int)range->new_start);
- cl_assert_equal_i(9, (int)range->new_lines);
+ cl_assert_equal_i(31, (int)hunk->old_start);
+ cl_assert_equal_i(15, (int)hunk->old_lines);
+ cl_assert_equal_i(25, (int)hunk->new_start);
+ cl_assert_equal_i(9, (int)hunk->new_lines);
cl_assert_equal_i(18, (int)git_patch_num_lines_in_hunk(patch, 1));
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 1, 0));
- cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 0));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("My rulers and their treasure and their unborn populations,\n", actual.ptr);
- cl_assert_equal_i(31, oldno);
- cl_assert_equal_i(25, newno);
+ cl_assert_equal_i(31, line->old_lineno);
+ cl_assert_equal_i(25, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 1, 3));
- cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 3));
+ cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("The Daughters of the Palace whom they cherished in my Cities,\n", actual.ptr);
- cl_assert_equal_i(34, oldno);
- cl_assert_equal_i(-1, newno);
+ cl_assert_equal_i(34, line->old_lineno);
+ cl_assert_equal_i(-1, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 1, 12));
- cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 1, 12));
+ cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("Another replacement;\n", actual.ptr);
- cl_assert_equal_i(-1, oldno);
- cl_assert_equal_i(28, newno);
+ cl_assert_equal_i(-1, line->old_lineno);
+ cl_assert_equal_i(28, line->new_lineno);
git_patch_free(patch);
git_diff_free(diff);
@@ -356,57 +344,51 @@ void test_diff_patch__hunks_have_correct_line_numbers(void)
/* check hunk 0 */
- cl_git_pass(
- git_patch_get_hunk(&range, &hdr, &hdrlen, &hunklen, patch, 0));
+ cl_git_pass(git_patch_get_hunk(&hunk, &hunklen, patch, 0));
cl_assert_equal_i(6, (int)hunklen);
- cl_assert_equal_i(46, (int)range->old_start);
- cl_assert_equal_i(4, (int)range->old_lines);
- cl_assert_equal_i(46, (int)range->new_start);
- cl_assert_equal_i(4, (int)range->new_lines);
+ cl_assert_equal_i(46, (int)hunk->old_start);
+ cl_assert_equal_i(4, (int)hunk->old_lines);
+ cl_assert_equal_i(46, (int)hunk->new_start);
+ cl_assert_equal_i(4, (int)hunk->new_lines);
cl_assert_equal_i(6, (int)git_patch_num_lines_in_hunk(patch, 0));
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 1));
- cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 1));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("And the horses and the chariots fleeing from them as of old!\n", actual.ptr);
- cl_assert_equal_i(47, oldno);
- cl_assert_equal_i(47, newno);
+ cl_assert_equal_i(47, line->old_lineno);
+ cl_assert_equal_i(47, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 2));
- cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 2));
+ cl_assert_equal_i(GIT_DIFF_LINE_CONTEXT, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("\n", actual.ptr);
- cl_assert_equal_i(48, oldno);
- cl_assert_equal_i(48, newno);
+ cl_assert_equal_i(48, line->old_lineno);
+ cl_assert_equal_i(48, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 3));
- cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 3));
+ cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s(" -- Rudyard Kipling\n", actual.ptr);
- cl_assert_equal_i(49, oldno);
- cl_assert_equal_i(-1, newno);
+ cl_assert_equal_i(49, line->old_lineno);
+ cl_assert_equal_i(-1, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 4));
- cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 4));
+ cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s(" -- Rudyard Kipling", actual.ptr);
- cl_assert_equal_i(-1, oldno);
- cl_assert_equal_i(49, newno);
+ cl_assert_equal_i(-1, line->old_lineno);
+ cl_assert_equal_i(49, line->new_lineno);
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &text, &textlen, &oldno, &newno, patch, 0, 5));
- cl_assert_equal_i(GIT_DIFF_LINE_DEL_EOFNL, (int)origin);
- cl_git_pass(git_buf_set(&actual, text, textlen));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 5));
+ cl_assert_equal_i(GIT_DIFF_LINE_DEL_EOFNL, (int)line->origin);
+ cl_git_pass(git_buf_set(&actual, line->content, line->content_len));
cl_assert_equal_s("\n\\ No newline at end of file\n", actual.ptr);
- cl_assert_equal_i(-1, oldno);
- cl_assert_equal_i(49, newno);
+ cl_assert_equal_i(-1, line->old_lineno);
+ cl_assert_equal_i(49, line->new_lineno);
git_patch_free(patch);
git_diff_free(diff);
@@ -465,31 +447,34 @@ static void check_single_patch_stats(
/* walk lines in hunk with basic sanity checks */
for (; hunks > 0; --hunks) {
size_t i, max_i;
- int lastoldno = -1, oldno, lastnewno = -1, newno;
- char origin;
+ const git_diff_line *line;
+ int last_new_lineno = -1, last_old_lineno = -1;
max_i = git_patch_num_lines_in_hunk(patch, hunks - 1);
for (i = 0; i < max_i; ++i) {
int expected = 1;
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, NULL, NULL, &oldno, &newno, patch, hunks - 1, i));
+ cl_git_pass(
+ git_patch_get_line_in_hunk(&line, patch, hunks - 1, i));
- if (origin == GIT_DIFF_LINE_ADD_EOFNL ||
- origin == GIT_DIFF_LINE_DEL_EOFNL ||
- origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
+ if (line->origin == GIT_DIFF_LINE_ADD_EOFNL ||
+ line->origin == GIT_DIFF_LINE_DEL_EOFNL ||
+ line->origin == GIT_DIFF_LINE_CONTEXT_EOFNL)
expected = 0;
- if (oldno >= 0) {
- if (lastoldno >= 0)
- cl_assert_equal_i(expected, oldno - lastoldno);
- lastoldno = oldno;
+ if (line->old_lineno >= 0) {
+ if (last_old_lineno >= 0)
+ cl_assert_equal_i(
+ expected, line->old_lineno - last_old_lineno);
+ last_old_lineno = line->old_lineno;
}
- if (newno >= 0) {
- if (lastnewno >= 0)
- cl_assert_equal_i(expected, newno - lastnewno);
- lastnewno = newno;
+
+ if (line->new_lineno >= 0) {
+ if (last_new_lineno >= 0)
+ cl_assert_equal_i(
+ expected, line->new_lineno - last_new_lineno);
+ last_new_lineno = line->new_lineno;
}
}
}
diff --git a/tests-clar/diff/tree.c b/tests-clar/diff/tree.c
index 8231d3632..ca2daf5fb 100644
--- a/tests-clar/diff/tree.c
+++ b/tests-clar/diff/tree.c
@@ -257,11 +257,10 @@ void test_diff_tree__larger_hunks(void)
{
const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
- size_t d, num_d, h, num_h, l, num_l, header_len, line_len;
+ size_t d, num_d, h, num_h, l, num_l;
git_patch *patch;
- const git_diff_hunk *range;
- const char *header, *line;
- char origin;
+ const git_diff_hunk *hunk;
+ const git_diff_line *line;
g_repo = cl_git_sandbox_init("diff");
@@ -280,21 +279,17 @@ void test_diff_tree__larger_hunks(void)
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
- cl_git_pass(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, h));
+ cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
for (l = 0; l < num_l; ++l) {
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &line, &line_len, NULL, NULL, patch, h, l));
+ cl_git_pass(git_patch_get_line_in_hunk(&line, patch, h, l));
cl_assert(line);
}
- cl_git_fail(git_patch_get_line_in_hunk(
- &origin, &line, &line_len, NULL, NULL, patch, h, num_l));
+ cl_git_fail(git_patch_get_line_in_hunk(&line, patch, h, num_l));
}
- cl_git_fail(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, num_h));
+ cl_git_fail(git_patch_get_hunk(&hunk, &num_l, patch, num_h));
git_patch_free(patch);
}
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index ee63a700d..474891c16 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -673,7 +673,7 @@ void test_diff_workdir__larger_hunks(void)
const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
git_tree *a, *b;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
- size_t i, d, num_d, h, num_h, l, num_l, header_len, line_len;
+ size_t i, d, num_d, h, num_h, l, num_l;
g_repo = cl_git_sandbox_init("diff");
@@ -686,9 +686,8 @@ void test_diff_workdir__larger_hunks(void)
for (i = 0; i <= 2; ++i) {
git_diff *diff = NULL;
git_patch *patch;
- const git_diff_hunk *range;
- const char *header, *line;
- char origin;
+ const git_diff_hunk *hunk;
+ const git_diff_line *line;
/* okay, this is a bit silly, but oh well */
switch (i) {
@@ -712,23 +711,21 @@ void test_diff_workdir__larger_hunks(void)
num_h = git_patch_num_hunks(patch);
for (h = 0; h < num_h; h++) {
- cl_git_pass(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, h));
+ cl_git_pass(git_patch_get_hunk(&hunk, &num_l, patch, h));
for (l = 0; l < num_l; ++l) {
- cl_git_pass(git_patch_get_line_in_hunk(
- &origin, &line, &line_len, NULL, NULL, patch, h, l));
+ cl_git_pass(
+ git_patch_get_line_in_hunk(&line, patch, h, l));
cl_assert(line);
}
/* confirm fail after the last item */
- cl_git_fail(git_patch_get_line_in_hunk(
- &origin, &line, &line_len, NULL, NULL, patch, h, num_l));
+ cl_git_fail(
+ git_patch_get_line_in_hunk(&line, patch, h, num_l));
}
/* confirm fail after the last item */
- cl_git_fail(git_patch_get_hunk(
- &range, &header, &header_len, &num_l, patch, num_h));
+ cl_git_fail(git_patch_get_hunk(&hunk, &num_l, patch, num_h));
git_patch_free(patch);
}