fix number of lines accounted for during blame
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
diff --git a/got/got.c b/got/got.c
index eb5fcb7..81e94d2 100644
--- a/got/got.c
+++ b/got/got.c
@@ -2285,6 +2285,7 @@ cmd_blame(int argc, char *argv[])
char *commit_id_str = NULL;
struct blame_cb_args bca;
int ch, obj_type, i;
+ size_t filesize;
#ifndef PROFILE
if (pledge("stdio rpath wpath cpath flock proc exec sendfd unveil",
@@ -2411,11 +2412,15 @@ cmd_blame(int argc, char *argv[])
error = got_error_from_errno("got_opentemp");
goto done;
}
- error = got_object_blob_dump_to_file(NULL, &bca.nlines,
+ error = got_object_blob_dump_to_file(&filesize, &bca.nlines,
&bca.line_offsets, bca.f, blob);
if (error || bca.nlines == 0)
goto done;
+ /* Don't include \n at EOF in the blame line count. */
+ if (bca.line_offsets[bca.nlines - 1] == filesize)
+ bca.nlines--;
+
bca.lines = calloc(bca.nlines, sizeof(*bca.lines));
if (bca.lines == NULL) {
error = got_error_from_errno("calloc");
diff --git a/lib/blame.c b/lib/blame.c
index a1b4bd5..df12bfb 100644
--- a/lib/blame.c
+++ b/lib/blame.c
@@ -344,9 +344,13 @@ blame_open(struct got_blame **blamep, const char *path,
}
err = got_object_blob_dump_to_file(&blame->filesize, &blame->nlines,
&blame->line_offsets, blame->f, blob);
- if (err)
+ if (err || blame->nlines == 0)
goto done;
+ /* Don't include \n at EOF in the blame line count. */
+ if (blame->line_offsets[blame->nlines - 1] == blame->filesize)
+ blame->nlines--;
+
blame->lines = calloc(blame->nlines, sizeof(*blame->lines));
if (blame->lines == NULL) {
err = got_error_from_errno("calloc");
diff --git a/lib/object.c b/lib/object.c
index 14011f6..a47efb0 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -1164,6 +1164,7 @@ got_object_blob_dump_to_file(size_t *filesize, int *nlines,
if (len == 0)
break;
buf = got_object_blob_get_read_buf(blob);
+ i = hdrlen;
if (line_offsets && nlines) {
if (*line_offsets == NULL) {
/* Have some data but perhaps no '\n'. */
@@ -1172,11 +1173,20 @@ got_object_blob_dump_to_file(size_t *filesize, int *nlines,
*line_offsets = calloc(1, sizeof(**line_offsets));
if (*line_offsets == NULL)
return got_error_from_errno("malloc");
+
+ /* Skip forward over end of first line. */
+ while (i < len) {
+ if (buf[i] == '\n')
+ break;
+ i++;
+ }
}
- /* Scan '\n' offsets in this chunk of data. */
- for (i = hdrlen; i < len; i++) {
- if (buf[i] != '\n')
+ /* Scan '\n' offsets in remaining chunk of data. */
+ while (i < len) {
+ if (buf[i] != '\n') {
+ i++;
continue;
+ }
(*nlines)++;
if (noffsets < *nlines) {
off_t *o = recallocarray(*line_offsets,
@@ -1193,6 +1203,7 @@ got_object_blob_dump_to_file(size_t *filesize, int *nlines,
}
off = total_len + i - hdrlen + 1;
(*line_offsets)[*nlines - 1] = off;
+ i++;
}
}
/* Skip blob object header first time around. */
diff --git a/tog/tog.c b/tog/tog.c
index a4136fe..8019b23 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -3248,9 +3248,13 @@ run_blame(struct tog_blame *blame, struct tog_view *view, int *blame_complete,
}
err = got_object_blob_dump_to_file(&blame->filesize, &blame->nlines,
&blame->line_offsets, blame->f, blob);
- if (err)
+ if (err || blame->nlines == 0)
goto done;
+ /* Don't include \n at EOF in the blame line count. */
+ if (blame->line_offsets[blame->nlines - 1] == blame->filesize)
+ blame->nlines--;
+
blame->lines = calloc(blame->nlines, sizeof(*blame->lines));
if (blame->lines == NULL) {
err = got_error_from_errno("calloc");