xref: /freebsd/contrib/libdiff/test/expect019.diff (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
1--- test019.left.txt
2+++ test019.right.txt
3@@ -40,8 +40,23 @@
4 #include "got_lib_object.h"
5
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;
35
36+	if (line_offsets && *line_offsets && *nlines > 0)
37+		outoff = (*line_offsets)[*nlines - 1];
38+
39 	if (resultp)
40 		*resultp = NULL;
41
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;
79
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;
92
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 }
100
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)
107 {
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);
112 }
113
114 static const struct got_error *
115@@ -259,7 +301,8 @@
116 {
117 	const struct got_error *err = NULL;
118
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 @@
126 }
127
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)
134 {
135@@ -722,8 +766,8 @@
136 		if (err)
137 			goto done;
138 	}
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 @@
147 }
148
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)
155 {
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);
160
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);
176+
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 @@
185 }
186
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)
194 {
195 	const struct got_error *err;
196@@ -788,7 +847,7 @@
197 	if (err)
198 		goto done;
199
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);
205