commit - 8da526b59d8479dce1543e22fc5073e639d115c8
commit + 82c78e96f11e4190c3d91f18122df14e30347300
blob - ddfd81fefa159116d100f5e18c9ce0e2eb2914a3
blob + 65551dc9c9ab16277bcd21dddd49e8bd176e6da6
--- got/got.c
+++ got/got.c
arg.force_text_diff = force_text_diff;
arg.diff_algo = GOT_DIFF_ALGORITHM_PATIENCE;
arg.outfile = outfile;
- arg.line_offsets = NULL;
+ arg.lines = NULL;
arg.nlines = 0;
while (path[0] == '/')
path++;
blob - 4243be1c5479449f6d3623e760d1979bd58682b8
blob + bc4bc871ee90bf32c4fd2bd3b2b452f29d5822a0
--- include/got_diff.h
+++ include/got_diff.h
};
/*
+ * List of all line types in a diff (including '{got,tog} log' lines).
+ * XXX GOT_DIFF_LINE_HUNK to GOT_DIFF_LINE_NONE inclusive must map to the
+ * DIFF_LINE_* macro counterparts defined in lib/diff_output.h (i.e., 60-64).
+ */
+enum got_diff_line_type {
+ GOT_DIFF_LINE_LOGMSG,
+ GOT_DIFF_LINE_AUTHOR,
+ GOT_DIFF_LINE_DATE,
+ GOT_DIFF_LINE_CHANGES,
+ GOT_DIFF_LINE_META,
+ GOT_DIFF_LINE_BLOB_MIN,
+ GOT_DIFF_LINE_BLOB_PLUS,
+ GOT_DIFF_LINE_HUNK = 60,
+ GOT_DIFF_LINE_MINUS,
+ GOT_DIFF_LINE_PLUS,
+ GOT_DIFF_LINE_CONTEXT,
+ GOT_DIFF_LINE_NONE
+};
+
+struct got_diff_line {
+ off_t offset;
+ uint8_t type;
+};
+
+/*
* Compute the differences between two blobs and write unified diff text
* to the provided output file. Two open temporary files must be provided
* for internal use; these files can be obtained from got_opentemp() and
* If not NULL, the two initial output arguments will be populated with an
* array of line offsets for, and the number of lines in, the unidiff text.
*/
-const struct got_error *got_diff_blob(off_t **, size_t *,
+const struct got_error *got_diff_blob(struct got_diff_line **, size_t *,
struct got_blob_object *, struct got_blob_object *, FILE *, FILE *,
const char *, const char *, enum got_diff_algorithm, int, int, int,
FILE *);
/*
* The number of lines contained in produced unidiff text output,
- * and an array of byte offsets to each line. May be initialized to
- * zero and NULL to ignore line offsets. If not NULL, then the line
- * offsets array will be populated. Optionally, the array can be
- * pre-populated with line offsets, with nlines > 0 indicating
- * the length of the pre-populated array. This is useful if the
- * output file already contains some lines of text.
- * The array will be grown as needed to accomodate additional line
- * offsets, and the last offset found in a pre-populated array will
- * be added to all subsequent offsets.
+ * and an array of got_diff_lines with byte offset and line type to
+ * each line. May be initialized to zero and NULL to ignore line
+ * metadata. If not NULL, then the array of line offsets and types will
+ * be populated. Optionally, the array can be pre-populated with line
+ * offsets and types, with nlines > 0 indicating the length of the
+ * pre-populated array. This is useful if the output file already
+ * contains some lines of text. The array will be grown as needed to
+ * accomodate additional offsets and types, and the last offset found
+ * in a pre-populated array will be added to all subsequent offsets.
*/
size_t nlines;
- off_t *line_offsets; /* Dispose of with free(3) when done. */
+ struct got_diff_line *lines; /* Dispose of with free(3) when done. */
};
const struct got_error *got_diff_blob_output_unidiff(void *,
struct got_blob_object *, struct got_blob_object *, FILE *, FILE *,
* If not NULL, the two initial output arguments will be populated with an
* array of line offsets for, and the number of lines in, the unidiff text.
*/
-const struct got_error *got_diff_objects_as_blobs(off_t **, size_t *,
- FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- const char *, const char *, enum got_diff_algorithm, int, int, int,
- struct got_repository *, FILE *);
+const struct got_error *got_diff_objects_as_blobs(struct got_diff_line **,
+ size_t *, FILE *, FILE *, int, int, struct got_object_id *,
+ struct got_object_id *, const char *, const char *, enum got_diff_algorithm,
+ int, int, int, struct got_repository *, FILE *);
struct got_pathlist_head;
* If not NULL, the two initial output arguments will be populated with an
* array of line offsets for, and the number of lines in, the unidiff text.
*/
-const struct got_error *got_diff_objects_as_trees(off_t **, size_t *,
- FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- struct got_pathlist_head *, const char *, const char *,
- enum got_diff_algorithm, int, int, int, struct got_repository *, FILE *);
+const struct got_error *got_diff_objects_as_trees(struct got_diff_line **,
+ size_t *, FILE *, FILE *, int, int, struct got_object_id *,
+ struct got_object_id *, struct got_pathlist_head *, const char *,
+ const char *, enum got_diff_algorithm, int, int, int,
+ struct got_repository *, FILE *);
/*
* Diff two objects, assuming both objects are commits.
* If not NULL, the two initial output arguments will be populated with an
* array of line offsets for, and the number of lines in, the unidiff text.
*/
-const struct got_error *got_diff_objects_as_commits(off_t **, size_t *,
- FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- struct got_pathlist_head *, enum got_diff_algorithm, int, int, int,
- struct got_repository *, FILE *);
+const struct got_error *got_diff_objects_as_commits(struct got_diff_line **,
+ size_t *, FILE *, FILE *, int, int, struct got_object_id *,
+ struct got_object_id *, struct got_pathlist_head *, enum got_diff_algorithm,
+ int, int, int, struct got_repository *, FILE *);
#define GOT_DIFF_MAX_CONTEXT 64
blob - 14734de52bef2db3787421c6d6fb25df85a94361
blob + a998453e7e5bc7ff3b9c707e6d83dfc42d959d5d
--- lib/diff.c
+++ lib/diff.c
#include "got_lib_object.h"
static const struct got_error *
-add_line_offset(off_t **line_offsets, size_t *nlines, off_t off)
+add_line_metadata(struct got_diff_line **lines, size_t *nlines,
+ off_t off, uint8_t type)
{
- off_t *p;
+ struct got_diff_line *p;
- p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t));
+ p = reallocarray(*lines, *nlines + 1, sizeof(**lines));
if (p == NULL)
return got_error_from_errno("reallocarray");
- *line_offsets = p;
- (*line_offsets)[*nlines] = off;
+ *lines = p;
+ (*lines)[*nlines].offset = off;
+ (*lines)[*nlines].type = type;
(*nlines)++;
+
return NULL;
}
static const struct got_error *
-diff_blobs(off_t **line_offsets, size_t *nlines,
+diff_blobs(struct got_diff_line **lines, size_t *nlines,
struct got_diffreg_result **resultp, struct got_blob_object *blob1,
struct got_blob_object *blob2, FILE *f1, FILE *f2,
const char *label1, const char *label2, mode_t mode1, mode_t mode2,
off_t outoff = 0;
int n;
- if (line_offsets && *line_offsets && *nlines > 0)
- outoff = (*line_offsets)[*nlines - 1];
- else if (line_offsets) {
- err = add_line_offset(line_offsets, nlines, 0);
+ if (lines && *lines && nlines > 0)
+ outoff = (*lines)[*nlines - 1].offset;
+ else if (lines) {
+ err = add_line_metadata(lines, nlines, 0, GOT_DIFF_LINE_NONE);
if (err)
goto done;
}
if (n < 0)
goto done;
outoff += n;
- if (line_offsets) {
- err = add_line_offset(line_offsets, nlines, outoff);
+ if (lines) {
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_BLOB_MIN);
if (err)
goto done;
}
if (n < 0)
goto done;
outoff += n;
- if (line_offsets) {
- err = add_line_offset(line_offsets, nlines, outoff);
+ if (lines) {
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_BLOB_PLUS);
if (err)
goto done;
}
goto done;
if (outfile) {
- err = got_diffreg_output(line_offsets, nlines, result,
+ err = got_diffreg_output(lines, nlines, result,
blob1 != NULL, blob2 != NULL,
label1 ? label1 : idstr1,
label2 ? label2 : idstr2,
{
struct got_diff_blob_output_unidiff_arg *a = arg;
- return diff_blobs(&a->line_offsets, &a->nlines, NULL,
+ return diff_blobs(&a->lines, &a->nlines, NULL,
blob1, blob2, f1, f2, label1, label2, mode1, mode2, a->diff_context,
a->ignore_whitespace, a->force_text_diff, a->outfile, a->diff_algo);
}
const struct got_error *
-got_diff_blob(off_t **line_offsets, size_t *nlines,
+got_diff_blob(struct got_diff_line **lines, size_t*nlines,
struct got_blob_object *blob1, struct got_blob_object *blob2,
FILE *f1, FILE *f2, const char *label1, const char *label2,
enum got_diff_algorithm diff_algo, int diff_context,
int ignore_whitespace, int force_text_diff, FILE *outfile)
{
- return diff_blobs(line_offsets, nlines, NULL, blob1, blob2, f1, f2,
+ return diff_blobs(lines, nlines, NULL, blob1, blob2, f1, f2,
label1, label2, 0, 0, diff_context, ignore_whitespace,
force_text_diff, outfile, diff_algo);
}
}
const struct got_error *
-got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines,
+got_diff_objects_as_blobs(struct got_diff_line **lines, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
const char *label1, const char *label2,
if (err)
goto done;
}
- err = got_diff_blob(line_offsets, nlines, blob1, blob2, f1, f2,
- label1, label2, diff_algo, diff_context, ignore_whitespace,
- force_text_diff, outfile);
+ err = got_diff_blob(lines, nlines, blob1, blob2, f1, f2, label1, label2,
+ diff_algo, diff_context, ignore_whitespace, force_text_diff,
+ outfile);
done:
if (blob1)
got_object_blob_close(blob1);
}
static const struct got_error *
-show_object_id(off_t **line_offsets, size_t *nlines, const char *obj_typestr,
- int ch, const char *id_str, FILE *outfile)
+show_object_id(struct got_diff_line **lines, size_t *nlines,
+ const char *obj_typestr, int ch, const char *id_str, FILE *outfile)
{
const struct got_error *err;
int n;
off_t outoff = 0;
n = fprintf(outfile, "%s %c %s\n", obj_typestr, ch, id_str);
- if (line_offsets != NULL && *line_offsets != NULL) {
+ if (lines != NULL && *lines != NULL) {
if (*nlines == 0) {
- err = add_line_offset(line_offsets, nlines, 0);
+ err = add_line_metadata(lines, nlines, 0,
+ GOT_DIFF_LINE_META);
if (err)
return err;
} else
- outoff = (*line_offsets)[*nlines - 1];
+ outoff = (*lines)[*nlines - 1].offset;
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_META);
if (err)
return err;
}
}
static const struct got_error *
-diff_objects_as_trees(off_t **line_offsets, size_t *nlines,
+diff_objects_as_trees(struct got_diff_line **lines, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
const struct got_error *err;
struct got_tree_object *tree1 = NULL, *tree2 = NULL;
struct got_diff_blob_output_unidiff_arg arg;
- int want_lineoffsets = (line_offsets != NULL && *line_offsets != NULL);
+ int want_linemeta = (lines != NULL && *lines != NULL);
if (id1 == NULL && id2 == NULL)
return got_error(GOT_ERR_NO_OBJ);
arg.ignore_whitespace = ignore_whitespace;
arg.force_text_diff = force_text_diff;
arg.outfile = outfile;
- if (want_lineoffsets) {
- arg.line_offsets = *line_offsets;
+ if (want_linemeta) {
+ arg.lines = *lines;
arg.nlines = *nlines;
} else {
- arg.line_offsets = NULL;
+ arg.lines = NULL;
arg.nlines = 0;
}
if (paths == NULL || TAILQ_EMPTY(paths)) {
err = diff_paths(tree1, tree2, f1, f2, fd1, fd2, paths, repo,
got_diff_blob_output_unidiff, &arg);
}
- if (want_lineoffsets) {
- *line_offsets = arg.line_offsets; /* was likely re-allocated */
+ if (want_linemeta) {
+ *lines = arg.lines; /* was likely re-allocated */
*nlines = arg.nlines;
}
done:
}
const struct got_error *
-got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines,
+got_diff_objects_as_trees(struct got_diff_line **lines, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
err = got_object_id_str(&idstr, id1);
if (err)
goto done;
- err = show_object_id(line_offsets, nlines, "tree", '-',
- idstr, outfile);
+ err = show_object_id(lines, nlines, "tree", '-', idstr, outfile);
if (err)
goto done;
free(idstr);
idstr = NULL;
} else {
- err = show_object_id(line_offsets, nlines, "tree", '-',
- "/dev/null", outfile);
+ err = show_object_id(lines, nlines, "tree", '-', "/dev/null",
+ outfile);
if (err)
goto done;
}
err = got_object_id_str(&idstr, id2);
if (err)
goto done;
- err = show_object_id(line_offsets, nlines, "tree", '+',
- idstr, outfile);
+ err = show_object_id(lines, nlines, "tree", '+', idstr, outfile);
if (err)
goto done;
free(idstr);
idstr = NULL;
} else {
- err = show_object_id(line_offsets, nlines, "tree", '+',
- "/dev/null", outfile);
+ err = show_object_id(lines, nlines, "tree", '+', "/dev/null",
+ outfile);
if (err)
goto done;
}
- err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
- id1, id2, paths, label1, label2, diff_context, ignore_whitespace,
+ err = diff_objects_as_trees(lines, nlines, f1, f2, fd1, fd2, id1, id2,
+ paths, label1, label2, diff_context, ignore_whitespace,
force_text_diff, repo, outfile, diff_algo);
done:
free(idstr);
}
const struct got_error *
-got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines,
+got_diff_objects_as_commits(struct got_diff_line **lines, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, enum got_diff_algorithm diff_algo,
err = got_object_id_str(&idstr, id1);
if (err)
goto done;
- err = show_object_id(line_offsets, nlines, "commit", '-',
- idstr, outfile);
+ err = show_object_id(lines, nlines, "commit", '-', idstr,
+ outfile);
if (err)
goto done;
free(idstr);
idstr = NULL;
} else {
- err = show_object_id(line_offsets, nlines, "commit", '-',
- "/dev/null", outfile);
+ err = show_object_id(lines, nlines, "commit", '-', "/dev/null",
+ outfile);
if (err)
goto done;
}
err = got_object_id_str(&idstr, id2);
if (err)
goto done;
- err = show_object_id(line_offsets, nlines, "commit", '+',
- idstr, outfile);
+ err = show_object_id(lines, nlines, "commit", '+', idstr, outfile);
if (err)
goto done;
- err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
+ err = diff_objects_as_trees(lines, nlines, f1, f2, fd1, fd2,
commit1 ? got_object_commit_get_tree_id(commit1) : NULL,
got_object_commit_get_tree_id(commit2), paths, "", "",
diff_context, ignore_whitespace, force_text_diff, repo, outfile,
blob - f50562ea7c4eab62df85e0099e0b4de267333c5b
blob + ee175dcf640d5b8d7770236de9c443a5888891dd
--- lib/diffreg.c
+++ lib/diffreg.c
}
const struct got_error *
-got_diffreg_output(off_t **line_offsets, size_t *nlines,
+got_diffreg_output(struct got_diff_line **lines, size_t *nlines,
struct got_diffreg_result *diff_result, int f1_exists, int f2_exists,
const char *path1, const char *path2,
enum got_diff_output_format output_format, int context_lines, FILE *outfile)
switch (output_format) {
case GOT_DIFF_OUTPUT_UNIDIFF:
rc = diff_output_unidiff(
- line_offsets ? &output_info : NULL, outfile, &info,
+ lines ? &output_info : NULL, outfile, &info,
diff_result->result, context_lines);
if (rc != DIFF_RC_OK)
return got_error_set_errno(rc, "diff_output_unidiff");
break;
case GOT_DIFF_OUTPUT_EDSCRIPT:
- rc = diff_output_edscript(line_offsets ? &output_info : NULL,
+ rc = diff_output_edscript(lines ? &output_info : NULL,
outfile, &info, diff_result->result);
if (rc != DIFF_RC_OK)
return got_error_set_errno(rc, "diff_output_edscript");
}
- if (line_offsets && *line_offsets) {
+ if (lines && *lines) {
if (output_info->line_offsets.len > 0) {
- off_t prev_offset = 0, *p, *o;
+ struct got_diff_line *p;
+ off_t prev_offset = 0, *o;
+ uint8_t *o2;
int i, len;
if (*nlines > 0) {
- prev_offset = (*line_offsets)[*nlines - 1];
+ prev_offset = (*lines)[*nlines - 1].offset;
/*
* First line offset is always zero. Skip it
* when appending to a pre-populated array.
*/
o = &output_info->line_offsets.head[1];
+ o2 = &output_info->line_types.head[1];
len = output_info->line_offsets.len - 1;
} else {
o = &output_info->line_offsets.head[0];
+ o2 = &output_info->line_types.head[0];
len = output_info->line_offsets.len;
}
- p = reallocarray(*line_offsets, *nlines + len,
- sizeof(off_t));
+ p = reallocarray(*lines, *nlines + len, sizeof(**lines));
if (p == NULL)
return got_error_from_errno("calloc");
- for (i = 0; i < len; i++)
- p[*nlines + i] = o[i] + prev_offset;
- *line_offsets = p;
+ for (i = 0; i < len; i++) {
+ p[*nlines + i].offset = o[i] + prev_offset;
+ p[*nlines + i].type = o2[i];
+ }
+ *lines = p;
*nlines += len;
}
diff_output_info_free(output_info);
blob - 3ff8d96891722f9a89a5245a2fb9b5e5c8424e83
blob + 43c7096d0a3fe2bb611660d822341235f3223a17
--- lib/got_lib_diff.h
+++ lib/got_lib_diff.h
struct diff_data *, const struct diff_config *, int, int);
const struct got_error *got_diffreg(struct got_diffreg_result **, FILE *,
FILE *, enum got_diff_algorithm, int, int);
-const struct got_error *got_diffreg_output(off_t **, size_t *,
+const struct got_error *got_diffreg_output(struct got_diff_line **, size_t *,
struct got_diffreg_result *, int, int, const char *, const char *,
enum got_diff_output_format, int, FILE *);
const struct got_error *got_diffreg_result_free(struct got_diffreg_result *);
blob - ff238905b35da47efd5533334d11290e37f51345
blob + 7675eb02809eb3f2eb24a7b6e4066ffaefbc42bc
--- tog/tog.1
+++ tog/tog.1
Scroll to the top of the view.
.It Cm End, G
Scroll to the bottom of the view.
+.It Cm \&(
+Navigate to the Nth previous file in the diff (default: 1).
+.It Cm \&)
+Navigate to the Nth next file in the diff (default: 1).
+.It Cm \&{
+Navigate to the Nth previous hunk in the diff (default: 1).
+.It Cm \&}
+Navigate to the Nth next hunk in the diff (default: 1).
.It Cm \&[
Reduce diff context by N lines (default: 1).
.It Cm \&]
blob - fe1a8df50fa4464f8dcf2d9e23e1ba930990a656
blob + bba44ebab024533437e4486a69fe0b9f00188cfb
--- tog/tog.c
+++ tog/tog.c
return default_color_value(envvar);
}
-
struct tog_diff_view_state {
struct got_object_id *id1, *id2;
const char *label1, *label2;
FILE *f, *f1, *f2;
int fd1, fd2;
+ int lineno;
int first_displayed_line;
int last_displayed_line;
int eof;
int force_text_diff;
struct got_repository *repo;
struct tog_colors colors;
+ struct got_diff_line *lines;
size_t nlines;
- off_t *line_offsets;
int matched_line;
int selected_line;
struct tog_diff_view_state *s = &view->state.diff;
regmatch_t *regmatch = &view->regmatch;
const struct got_error *err;
- int lineno, nprinted = 0;
+ int nprinted = 0;
char *line;
size_t linesize = 0;
ssize_t linelen;
off_t line_offset;
attr_t attr;
- lineno = s->first_displayed_line - 1;
- line_offset = s->line_offsets[s->first_displayed_line - 1];
+ s->lineno = s->first_displayed_line - 1;
+ line_offset = s->lines[s->first_displayed_line - 1].offset;
if (fseeko(s->f, line_offset, SEEK_SET) == -1)
return got_error_from_errno("fseek");
if (header) {
int ln = view->gline ? view->gline <= (view->nlines - 3) / 2 ?
1 : view->gline - (view->nlines - 3) / 2 :
- lineno + s->selected_line;
+ s->lineno + s->selected_line;
if (asprintf(&line, "[%d/%d] %s", ln, nlines, header) == -1)
return got_error_from_errno("asprintf");
}
attr = 0;
- if (++lineno < s->first_displayed_line)
+ if (++s->lineno < s->first_displayed_line)
continue;
- if (view->gline && !gotoline(view, &lineno, &nprinted))
+ if (view->gline && !gotoline(view, &s->lineno, &nprinted))
continue;
- if (lineno == view->hiline)
+ if (s->lineno == view->hiline)
attr = A_STANDOUT;
/* Set view->maxx based on full line length. */
free(wline);
wline = NULL;
}
- if (lineno == view->hiline) {
+ if (s->lineno == view->hiline) {
/* highlight full gline length */
while (width++ < view->ncols)
waddch(view->window, ' ');
if (attr)
wattroff(view->window, attr);
if (++nprinted == 1)
- s->first_displayed_line = lineno;
+ s->first_displayed_line = s->lineno;
}
free(line);
if (nprinted >= 1)
}
static const struct got_error *
-add_line_offset(off_t **line_offsets, size_t *nlines, off_t off)
+add_line_metadata(struct got_diff_line **lines, size_t *nlines,
+ off_t off, uint8_t type)
{
- off_t *p;
+ struct got_diff_line *p;
- p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t));
+ p = reallocarray(*lines, *nlines + 1, sizeof(**lines));
if (p == NULL)
return got_error_from_errno("reallocarray");
- *line_offsets = p;
- (*line_offsets)[*nlines] = off;
+ *lines = p;
+ (*lines)[*nlines].offset = off;
+ (*lines)[*nlines].type = type;
(*nlines)++;
+
return NULL;
}
static const struct got_error *
-write_commit_info(off_t **line_offsets, size_t *nlines,
+write_commit_info(struct got_diff_line **lines, size_t *nlines,
struct got_object_id *commit_id, struct got_reflist_head *refs,
struct got_repository *repo, FILE *outfile)
{
goto done;
}
- err = add_line_offset(line_offsets, nlines, 0);
+ err = add_line_metadata(lines, nlines, 0, GOT_DIFF_LINE_NONE);
if (err)
goto done;
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff, GOT_DIFF_LINE_META);
if (err)
goto done;
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff, GOT_DIFF_LINE_AUTHOR);
if (err)
goto done;
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_DATE);
if (err)
goto done;
}
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_AUTHOR);
if (err)
goto done;
}
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_META);
if (err)
goto done;
free(id_str);
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_LOGMSG);
if (err)
goto done;
}
goto done;
}
outoff += n;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff,
+ GOT_DIFF_LINE_CHANGES);
if (err)
goto done;
free((char *)pe->path);
fputc('\n', outfile);
outoff++;
- err = add_line_offset(line_offsets, nlines, outoff);
+ err = add_line_metadata(lines, nlines, outoff, GOT_DIFF_LINE_NONE);
done:
got_pathlist_free(&changed_paths);
free(id_str);
free(refs_str);
got_object_commit_close(commit);
if (err) {
- free(*line_offsets);
- *line_offsets = NULL;
+ free(*lines);
+ *lines = NULL;
*nlines = 0;
}
return err;
FILE *f = NULL;
int obj_type;
- free(s->line_offsets);
- s->line_offsets = malloc(sizeof(off_t));
- if (s->line_offsets == NULL)
+ free(s->lines);
+ s->lines = malloc(sizeof(*s->lines));
+ if (s->lines == NULL)
return got_error_from_errno("malloc");
s->nlines = 0;
switch (obj_type) {
case GOT_OBJ_TYPE_BLOB:
- err = got_diff_objects_as_blobs(&s->line_offsets, &s->nlines,
+ err = got_diff_objects_as_blobs(&s->lines, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2,
s->label1, s->label2, tog_diff_algo, s->diff_context,
s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_TREE:
- err = got_diff_objects_as_trees(&s->line_offsets, &s->nlines,
+ err = got_diff_objects_as_trees(&s->lines, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL, "", "",
tog_diff_algo, s->diff_context, s->ignore_whitespace,
s->force_text_diff, s->repo, s->f);
refs = got_reflist_object_id_map_lookup(tog_refs_idmap, s->id2);
/* Show commit info if we're diffing to a parent/root commit. */
if (s->id1 == NULL) {
- err = write_commit_info(&s->line_offsets, &s->nlines,
- s->id2, refs, s->repo, s->f);
+ err = write_commit_info(&s->lines, &s->nlines, s->id2,
+ refs, s->repo, s->f);
if (err)
goto done;
} else {
parent_ids = got_object_commit_get_parent_ids(commit2);
STAILQ_FOREACH(pid, parent_ids, entry) {
if (got_object_id_cmp(s->id1, &pid->id) == 0) {
- err = write_commit_info(
- &s->line_offsets, &s->nlines,
- s->id2, refs, s->repo, s->f);
+ err = write_commit_info(&s->lines,
+ &s->nlines, s->id2, refs, s->repo,
+ s->f);
if (err)
goto done;
break;
}
got_object_commit_close(commit2);
- err = got_diff_objects_as_commits(&s->line_offsets, &s->nlines,
+ err = got_diff_objects_as_commits(&s->lines, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL,
tog_diff_algo, s->diff_context, s->ignore_whitespace,
s->force_text_diff, s->repo, s->f);
err = got_error(GOT_ERR_OBJ_TYPE);
break;
}
- if (err)
- goto done;
done:
if (s->f && fflush(s->f) != 0 && err == NULL)
err = got_error_from_errno("fflush");
lineno = s->nlines;
}
- offset = s->line_offsets[lineno - 1];
+ offset = s->lines[lineno - 1].offset;
if (fseeko(s->f, offset, SEEK_SET) != 0) {
free(line);
return got_error_from_errno("fseeko");
err = got_error_from_errno("close");
s->fd2 = -1;
free_colors(&s->colors);
- free(s->line_offsets);
- s->line_offsets = NULL;
+ free(s->lines);
+ s->lines = NULL;
s->nlines = 0;
return err;
}
s->matched_line = 0;
diff_view_indicate_progress(view);
return create_diff(s);
+}
+
+static void
+diff_prev_index(struct tog_diff_view_state *s, enum got_diff_line_type type)
+{
+ int start, i;
+
+ i = start = s->first_displayed_line - 1;
+
+ while (s->lines[i].type != type) {
+ if (i == 0)
+ i = s->nlines - 1;
+ if (--i == start)
+ return; /* do nothing, requested type not in file */
+ }
+
+ s->selected_line = 1;
+ s->first_displayed_line = i;
}
+static void
+diff_next_index(struct tog_diff_view_state *s, enum got_diff_line_type type)
+{
+ int start, i;
+
+ i = start = s->first_displayed_line + 1;
+
+ while (s->lines[i].type != type) {
+ if (i == s->nlines - 1)
+ i = 0;
+ if (++i == start)
+ return; /* do nothing, requested type not in file */
+ }
+
+ s->selected_line = 1;
+ s->first_displayed_line = i;
+}
+
static struct got_object_id *get_selected_commit_id(struct tog_blame_line *,
int, int, int);
static struct got_object_id *get_annotation_for_line(struct tog_blame_line *,
ssize_t linelen;
int i, nscroll = view->nlines - 1, up = 0;
+ s->lineno = s->first_displayed_line - 1 + s->selected_line;
+
switch (ch) {
case '0':
view->x = 0;
}
free(line);
break;
+ case '(':
+ diff_prev_index(s, GOT_DIFF_LINE_BLOB_MIN);
+ break;
+ case ')':
+ diff_next_index(s, GOT_DIFF_LINE_BLOB_MIN);
+ break;
+ case '{':
+ diff_prev_index(s, GOT_DIFF_LINE_HUNK);
+ break;
+ case '}':
+ diff_next_index(s, GOT_DIFF_LINE_HUNK);
+ break;
case '[':
if (s->diff_context > 0) {
s->diff_context--;