Commit Diff


commit - 984ca65b1b715a9fdc86bfff64e90a485d008058
commit + 93f8150ade45bb6185afe5b5ff3110db6403f8b3
blob - 792940d176efeada092e96fee5f42111ef1fb6a7
blob + a563080497cd7254b968b0777b78e9e2a5772e92
--- lib/diff_main.c
+++ lib/diff_main.c
@@ -207,75 +207,48 @@ diff_atom_same(bool *same,
 	return 0;
 }
 
-/* Even if a left or right side is empty, diff output may need to know the
- * position in that file.
- * So left_start or right_start must never be NULL -- pass left_count or
- * right_count as zero to indicate staying at that position without consuming
- * any lines. */
-struct diff_chunk *
-diff_state_add_chunk(struct diff_state *state, bool solved,
-		     struct diff_atom *left_start, unsigned int left_count,
-		     struct diff_atom *right_start, unsigned int right_count)
+static struct diff_chunk *
+diff_state_add_solved_chunk(struct diff_state *state,
+			    const struct diff_chunk *chunk)
 {
-	diff_chunk_arraylist_t *result = NULL;
+	diff_chunk_arraylist_t *result;
 	struct diff_chunk *new_chunk;
-	struct diff_chunk chunk = {
-		.solved = solved,
-		.left_start = left_start,
-		.left_count = left_count,
-		.right_start = right_start,
-		.right_count = right_count,
-	};
 	enum diff_chunk_type last_t;
-	enum diff_chunk_type prev_last_t;
 	enum diff_chunk_type new_t;
-
-	debug("Add %s chunk:\n", chunk.solved ? "solved" : "UNSOLVED");
-	debug("L\n");
-	debug_dump_atoms(&state->left, chunk.left_start, chunk.left_count);
-	debug("R\n");
-	debug_dump_atoms(&state->right, chunk.right_start, chunk.right_count);
-
-	if (!solved || state->temp_result.len) {
-		/* Append to temp_result */
-		result = &state->temp_result;
-	} else if (!state->result->chunks.len) {
-		/* Append to final result */
-		result = &state->result->chunks;
-	}
-	if (result) {
-		ARRAYLIST_ADD(new_chunk, *result);
-		if (!new_chunk)
-			return NULL;
-		*new_chunk = chunk;
-		goto chunk_added;
-	}
 
 	/* Append to solved chunks; make sure that adjacent chunks of same type are combined, and that a minus chunk
 	 * never directly follows a plus chunk. */
 	result = &state->result->chunks;
 
-	prev_last_t = result->len > 1 ?
-		diff_chunk_type(&result->head[result->len - 2]) : CHUNK_EMPTY;
 	last_t = diff_chunk_type(&result->head[result->len - 1]);
-	new_t = diff_chunk_type(&chunk);
+	new_t = diff_chunk_type(chunk);
 
+	debug("Add %s chunk:\n", chunk->solved ? "solved" : "UNSOLVED");
+	debug("L\n");
+	debug_dump_atoms(&state->left, chunk->left_start, chunk->left_count);
+	debug("R\n");
+	debug_dump_atoms(&state->right, chunk->right_start, chunk->right_count);
+
 	if (new_t == last_t) {
 		new_chunk = &result->head[result->len - 1];
-		new_chunk->left_count += chunk.left_count;
-		new_chunk->right_count += chunk.right_count;
+		new_chunk->left_count += chunk->left_count;
+		new_chunk->right_count += chunk->right_count;
 		debug("  - added chunk touches previous one of same type, joined:\n");
 		debug("L\n");
 		debug_dump_atoms(&state->left, new_chunk->left_start, new_chunk->left_count);
 		debug("R\n");
 		debug_dump_atoms(&state->right, new_chunk->right_start, new_chunk->right_count);
 	} else if (last_t == CHUNK_PLUS && new_t == CHUNK_MINUS) {
-		/* If a minus-chunk follows a plus-chunk, place it above the plus-chunk.
+		enum diff_chunk_type prev_last_t =
+			result->len > 1 ?
+				diff_chunk_type(&result->head[result->len - 2])
+				: CHUNK_EMPTY;
+		/* If a minus-chunk follows a plus-chunk, place it above the plus-chunk->
 		 * Is the one before that also a minus? combine. */
 		if (prev_last_t == CHUNK_MINUS) {
 			new_chunk = &result->head[result->len - 2];
-			new_chunk->left_count += chunk.left_count;
-			new_chunk->right_count += chunk.right_count;
+			new_chunk->left_count += chunk->left_count;
+			new_chunk->right_count += chunk->right_count;
 
 			debug("  - added minus-chunk follows plus-chunk,"
 			      " put before that plus-chunk and joined"
@@ -288,7 +261,7 @@ diff_state_add_chunk(struct diff_state *state, bool so
 			ARRAYLIST_INSERT(new_chunk, *result, result->len - 1);
 			if (!new_chunk)
 				return NULL;
-			*new_chunk = chunk;
+			*new_chunk = *chunk;
 
 			debug("  - added minus-chunk follows plus-chunk,"
 			      " put before that plus-chunk\n");
@@ -297,12 +270,49 @@ diff_state_add_chunk(struct diff_state *state, bool so
 		ARRAYLIST_ADD(new_chunk, *result);
 		if (!new_chunk)
 			return NULL;
+		*new_chunk = *chunk;
+	}
+	return new_chunk;
+}
+
+/* Even if a left or right side is empty, diff output may need to know the
+ * position in that file.
+ * So left_start or right_start must never be NULL -- pass left_count or
+ * right_count as zero to indicate staying at that position without consuming
+ * any lines. */
+struct diff_chunk *
+diff_state_add_chunk(struct diff_state *state, bool solved,
+		     struct diff_atom *left_start, unsigned int left_count,
+		     struct diff_atom *right_start, unsigned int right_count)
+{
+	diff_chunk_arraylist_t *result = NULL;
+	struct diff_chunk *new_chunk;
+	struct diff_chunk chunk = {
+		.solved = solved,
+		.left_start = left_start,
+		.left_count = left_count,
+		.right_start = right_start,
+		.right_count = right_count,
+	};
+
+	if (!solved || state->temp_result.len) {
+		/* Append to temp_result */
+		debug("append to temp_result\n");
+		result = &state->temp_result;
+	} else if (!state->result->chunks.len) {
+		/* Append to final result */
+		debug("first chunk\n");
+		result = &state->result->chunks;
+	}
+	if (result) {
+		ARRAYLIST_ADD(new_chunk, *result);
+		if (!new_chunk)
+			return NULL;
 		*new_chunk = chunk;
-		goto chunk_added;
+		return new_chunk;
 	}
 
-chunk_added:
-	return new_chunk;
+	return diff_state_add_solved_chunk(state, &chunk);
 }
 
 void
@@ -492,13 +502,7 @@ diff_run_algo(const struct diff_algo_config *algo_conf
 	for (i = 0; i < state->temp_result.len; i++) {
 		struct diff_chunk *c = &state->temp_result.head[i];
 		if (c->solved) {
-			struct diff_chunk *final_c;
-			ARRAYLIST_ADD(final_c, state->result->chunks);
-			if (!final_c) {
-				rc = ENOMEM;
-				goto return_rc;
-			}
-			*final_c = *c;
+			diff_state_add_solved_chunk(state, c);
 			continue;
 		}