"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Tom Jones <thj@freebsd.org>
Subject:
diff.git: Fix ed script output
To:
gameoftrees@openbsd.org
Date:
Tue, 30 Aug 2022 14:47:58 +0100

Download raw body.

Thread
Prior to this change ed script output was in the wrong order, i.e. in
the order diff_result provides and changes where missing added or
changed lines. ed edits need to be in reverse order to keep the edited
file in sync 

---
 lib/diff_output_edscript.c | 41 ++++++++++++++++++++++++++++----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/lib/diff_output_edscript.c b/lib/diff_output_edscript.c
index 42d4d5b..3365d90 100644
--- a/lib/diff_output_edscript.c
+++ b/lib/diff_output_edscript.c
@@ -81,19 +81,34 @@ 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);
+		}
+	}
+
+	/* 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);
+			fprintf(dest, ".\n");
+		}
+		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;
 		}
 	}
+
 	if (rc < 0)
 		return errno;
 	if (outinfo) {
@@ -151,7 +166,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;