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