commit - 984ca65b1b715a9fdc86bfff64e90a485d008058
commit + 93f8150ade45bb6185afe5b5ff3110db6403f8b3
blob - 792940d176efeada092e96fee5f42111ef1fb6a7
blob + a563080497cd7254b968b0777b78e9e2a5772e92
--- lib/diff_main.c
+++ lib/diff_main.c
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"
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");
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
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;
}