Blob


1 --- test019.left.txt
2 +++ test019.right.txt
3 @@ -40,8 +40,23 @@
4 #include "got_lib_object.h"
6 static const struct got_error *
7 -diff_blobs(struct got_diffreg_result **resultp,
8 -struct got_blob_object *blob1, struct got_blob_object *blob2,
9 +add_line_offset(off_t **line_offsets, size_t *nlines, off_t off)
10 +{
11 + off_t *p;
12 +
13 + p = reallocarray(*line_offsets, *nlines + 1, sizeof(off_t));
14 + if (p == NULL)
15 + return got_error_from_errno("reallocarray");
16 + *line_offsets = p;
17 + (*line_offsets)[*nlines] = off;
18 + (*nlines)++;
19 + return NULL;
20 +}
21 +
22 +static const struct got_error *
23 +diff_blobs(off_t **line_offsets, size_t *nlines,
24 + struct got_diffreg_result **resultp, struct got_blob_object *blob1,
25 + struct got_blob_object *blob2,
26 const char *label1, const char *label2, mode_t mode1, mode_t mode2,
27 int diff_context, int ignore_whitespace, FILE *outfile)
28 {
29 @@ -52,7 +67,12 @@
30 char *idstr1 = NULL, *idstr2 = NULL;
31 size_t size1, size2;
32 struct got_diffreg_result *result;
33 + off_t outoff = 0;
34 + int n;
36 + if (line_offsets && *line_offsets && *nlines > 0)
37 + outoff = (*line_offsets)[*nlines - 1];
38 +
39 if (resultp)
40 *resultp = NULL;
42 @@ -116,10 +136,32 @@
43 goto done;
44 }
45 }
46 - fprintf(outfile, "blob - %s%s\n", idstr1,
47 + n = fprintf(outfile, "blob - %s%s\n", idstr1,
48 modestr1 ? modestr1 : "");
49 - fprintf(outfile, "blob + %s%s\n", idstr2,
50 + if (n < 0) {
51 + err = got_error_from_errno("fprintf");
52 + goto done;
53 + }
54 + outoff += n;
55 + if (line_offsets) {
56 + err = add_line_offset(line_offsets, nlines, outoff);
57 + if (err)
58 + goto done;
59 + }
60 +
61 + n = fprintf(outfile, "blob + %s%s\n", idstr2,
62 modestr2 ? modestr2 : "");
63 + if (n < 0) {
64 + err = got_error_from_errno("fprintf");
65 + goto done;
66 + }
67 + outoff += n;
68 + if (line_offsets) {
69 + err = add_line_offset(line_offsets, nlines, outoff);
70 + if (err)
71 + goto done;
72 + }
73 +
74 free(modestr1);
75 free(modestr2);
76 }
77 @@ -129,7 +171,7 @@
78 goto done;
80 if (outfile) {
81 - err = got_diffreg_output(NULL, NULL, result, f1, f2,
82 + err = got_diffreg_output(line_offsets, nlines, result, f1, f2,
83 label1 ? label1 : idstr1,
84 label2 ? label2 : idstr2,
85 GOT_DIFF_OUTPUT_UNIDIFF, diff_context, outfile);
86 @@ -158,21 +200,21 @@
87 struct got_object_id *id2, const char *label1, const char *label2,
88 mode_t mode1, mode_t mode2, struct got_repository *repo)
89 {
90 - const struct got_error *err;
91 struct got_diff_blob_output_unidiff_arg *a = arg;
93 - err = diff_blobs(NULL, blob1, blob2, label1, label2, mode1, mode2,
94 - a->diff_context, a->ignore_whitespace, a->outfile);
95 - return err;
96 + return diff_blobs(&a->line_offsets, &a->nlines, NULL,
97 + blob1, blob2, label1, label2, mode1, mode2, a->diff_context,
98 + a->ignore_whitespace, a->outfile);
99 }
101 const struct got_error *
102 -got_diff_blob(struct got_blob_object *blob1, struct got_blob_object *blob2,
103 +got_diff_blob(off_t **line_offsets, size_t *nlines,
104 + struct got_blob_object *blob1, struct got_blob_object *blob2,
105 const char *label1, const char *label2, int diff_context,
106 int ignore_whitespace, FILE *outfile)
108 - return diff_blobs(NULL, blob1, blob2, label1, label2, 0, 0, diff_context,
109 - ignore_whitespace, outfile);
110 + return diff_blobs(line_offsets, nlines, NULL, blob1, blob2,
111 + label1, label2, 0, 0, diff_context, ignore_whitespace, outfile);
114 static const struct got_error *
115 @@ -259,7 +301,8 @@
117 const struct got_error *err = NULL;
119 - err = diff_blobs(result, blob1, blob2, NULL, NULL, 0, 0, 3, 0, NULL);
120 + err = diff_blobs(NULL, NULL, result, blob1, blob2,
121 + NULL, NULL, 0, 0, 3, 0, NULL);
122 if (err) {
123 got_diffreg_result_free(*result);
124 *result = NULL;
125 @@ -702,7 +745,8 @@
128 const struct got_error *
129 -got_diff_objects_as_blobs(struct got_object_id *id1, struct got_object_id *id2,
130 +got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines,
131 + struct got_object_id *id1, struct got_object_id *id2,
132 const char *label1, const char *label2, int diff_context,
133 int ignore_whitespace, struct got_repository *repo, FILE *outfile)
135 @@ -722,8 +766,8 @@
136 if (err)
137 goto done;
139 - err = got_diff_blob(blob1, blob2, label1, label2, diff_context,
140 - ignore_whitespace, outfile);
141 + err = got_diff_blob(line_offsets, nlines, blob1, blob2,
142 + label1, label2, diff_context, ignore_whitespace, outfile);
143 done:
144 if (blob1)
145 got_object_blob_close(blob1);
146 @@ -733,13 +777,15 @@
149 const struct got_error *
150 -got_diff_objects_as_trees(struct got_object_id *id1, struct got_object_id *id2,
151 +got_diff_objects_as_trees(off_t **line_offsets, size_t *nlines,
152 + struct got_object_id *id1, struct got_object_id *id2,
153 char *label1, char *label2, int diff_context, int ignore_whitespace,
154 struct got_repository *repo, FILE *outfile)
156 const struct got_error *err;
157 struct got_tree_object *tree1 = NULL, *tree2 = NULL;
158 struct got_diff_blob_output_unidiff_arg arg;
159 + int want_lineoffsets = (line_offsets != NULL && *line_offsets != NULL);
161 if (id1 == NULL && id2 == NULL)
162 return got_error(GOT_ERR_NO_OBJ);
163 @@ -757,8 +803,20 @@
164 arg.diff_context = diff_context;
165 arg.ignore_whitespace = ignore_whitespace;
166 arg.outfile = outfile;
167 + if (want_lineoffsets) {
168 + arg.line_offsets = *line_offsets;
169 + arg.nlines = *nlines;
170 + } else {
171 + arg.line_offsets = NULL;
172 + arg.nlines = 0;
173 + }
174 err = got_diff_tree(tree1, tree2, label1, label2, repo,
175 got_diff_blob_output_unidiff, &arg, 1);
177 + if (want_lineoffsets) {
178 + *line_offsets = arg.line_offsets; /* was likely re-allocated */
179 + *nlines = arg.nlines;
180 + }
181 done:
182 if (tree1)
183 got_object_tree_close(tree1);
184 @@ -768,8 +826,9 @@
187 const struct got_error *
188 -got_diff_objects_as_commits(struct got_object_id *id1,
189 - struct got_object_id *id2, int diff_context, int ignore_whitespace,
190 +got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines,
191 + struct got_object_id *id1, struct got_object_id *id2,
192 + int diff_context, int ignore_whitespace,
193 struct got_repository *repo, FILE *outfile)
195 const struct got_error *err;
196 @@ -788,7 +847,7 @@
197 if (err)
198 goto done;
200 - err = got_diff_objects_as_trees(
201 + err = got_diff_objects_as_trees(line_offsets, nlines,
202 commit1 ? got_object_commit_get_tree_id(commit1) : NULL,
203 got_object_commit_get_tree_id(commit2), "", "", diff_context,
204 ignore_whitespace, repo, outfile);