Download raw body.
diff.git: Fix ed script output
Updated to capture the '.' fprintf. I rearranged to update offp in side
the hunk loop.
- Tom
diff --git a/lib/diff_output_edscript.c b/lib/diff_output_edscript.c
index 42d4d5b..87d0e91 100644
--- a/lib/diff_output_edscript.c
+++ b/lib/diff_output_edscript.c
@@ -32,9 +32,9 @@ static int
output_edscript_chunk(struct diff_output_info *outinfo,
FILE *dest, const struct diff_input_info *info,
const struct diff_result *result,
- struct diff_chunk_context *cc)
+ struct diff_chunk_context *cc, off_t *outoff)
{
- off_t outoff = 0, *offp;
+ off_t *offp;
int left_start, left_len, right_start, right_len;
int rc;
@@ -81,17 +81,10 @@ output_edscript_chunk(struct diff_output_info *outinfo,
}
} else {
/* change */
- if (left_len == 1 && right_len == 1) {
- rc = fprintf(dest, "%dc%d\n", left_start, right_start);
- } else if (left_len == 1) {
- rc = fprintf(dest, "%dc%d,%d\n", left_start,
- right_start, cc->right.end);
- } else if (right_len == 1) {
- rc = fprintf(dest, "%d,%dc%d\n", left_start,
- cc->left.end, right_start);
+ if (left_len == 1) {
+ rc = fprintf(dest, "%dc\n", left_start);
} else {
- rc = fprintf(dest, "%d,%dc%d,%d\n", left_start,
- cc->left.end, right_start, cc->right.end);
+ rc = fprintf(dest, "%d,%dc\n", left_start, cc->left.end);
}
}
if (rc < 0)
@@ -100,8 +93,41 @@ output_edscript_chunk(struct diff_output_info *outinfo,
ARRAYLIST_ADD(offp, outinfo->line_offsets);
if (offp == NULL)
return ENOMEM;
- outoff += rc;
- *offp = outoff;
+ *outoff += rc;
+ *offp = *outoff;
+ }
+
+ /* Now write out the new lines in all the joined chunks. */
+ int c_idx;
+ for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) {
+ const struct diff_chunk *c = &result->chunks.head[c_idx];
+ if (c->left_count && !c->right_count)
+ continue;
+ if (c->right_count && !c->left_count) {
+ rc = diff_output_lines(outinfo, dest,
+ c->solved ? "" : "?",
+ c->right_start, c->right_count);
+ if (rc != DIFF_RC_OK)
+ return rc;
+
+ rc = fprintf(dest, ".\n");
+ if (rc != DIFF_RC_OK)
+ return rc;
+ if (outinfo) {
+ ARRAYLIST_ADD(offp, outinfo->line_offsets);
+ if (offp == NULL)
+ return ENOMEM;
+ outoff += rc;
+ *offp = *outoff;
+ }
+ }
+ if (rc)
+ return rc;
+ if (cc->chunk.end == result->chunks.len) {
+ rc = diff_output_trailing_newline_msg(outinfo, dest, c);
+ if (rc != DIFF_RC_OK)
+ return rc;
+ }
}
return DIFF_RC_OK;
@@ -121,6 +147,7 @@ diff_output_edscript(struct diff_output_info **output_info,
bool force_text = (flags & DIFF_FLAG_FORCE_TEXT_DATA);
bool have_binary = (atomizer_flags & DIFF_ATOMIZER_FOUND_BINARY_DATA);
int i, rc;
+ off_t outoff = 0, *offp;
if (!result)
return EINVAL;
@@ -151,7 +178,11 @@ diff_output_edscript(struct diff_output_info **output_info,
return DIFF_RC_OK;
}
- for (i = 0; i < result->chunks.len; i++) {
+ /*
+ * Changes in an ed script are in reverse order, the last change to the
+ * file has to be made first to keep state while making edits.
+ */
+ for (i = result->chunks.len-1; i >= 0 ; i--) {
struct diff_chunk *chunk = &result->chunks.head[i];
enum diff_chunk_type t = diff_chunk_type(chunk);
struct diff_chunk_context next;
@@ -178,13 +209,15 @@ diff_output_edscript(struct diff_output_info **output_info,
continue;
}
- rc = output_edscript_chunk(outinfo, dest, info, result, &cc);
+ rc = output_edscript_chunk(outinfo, dest, info, result, &cc,
+ &outoff);
if (rc != DIFF_RC_OK)
return rc;
cc = next;
}
if (!diff_chunk_context_empty(&cc))
- return output_edscript_chunk(outinfo, dest, info, result, &cc);
+ return output_edscript_chunk(outinfo, dest, info, result, &cc,
+ &outoff);
return DIFF_RC_OK;
}
diff.git: Fix ed script output