Commit Diff


commit - 93f8150ade45bb6185afe5b5ff3110db6403f8b3
commit + 87c313418265b477d8931182e8e9e0990db4f3ba
blob - 4ce1b320e06779fbf641c890bdb8a0d6dcea3ed9
blob + 0df18491956c216ee363ae7f2e0513b0746ab1fd
--- .gitignore
+++ .gitignore
@@ -6,3 +6,4 @@ diff/diff
 tags
 test/got*.diff
 test/verify.*
+test/results_test
blob - a4745ea9dd19e94f0bc9f34bbf25b3adf9395682
blob + 8a07062d01d7db4493862d75ae6a6f4335fb6ea2
--- lib/diff_internal.h
+++ lib/diff_internal.h
@@ -217,3 +217,7 @@ int diff_output_lines(struct diff_output_info *output_
 		       unsigned int count);
 
 struct diff_output_info *diff_output_info_alloc(void);
+
+void
+diff_data_init_subsection(struct diff_data *d, struct diff_data *parent,
+			  struct diff_atom *from_atom, unsigned int atoms_count);
blob - ad6ffbd9d12fc4f81e7e59ea3b4b7801c0b53887
blob + 092ddce16cbae3745517da6d77fcc1d961cdf83b
--- test/Makefile
+++ test/Makefile
@@ -5,3 +5,20 @@ verify:
 	./verify_all.sh
 clean:
 	-rm verify.*
+	-rm results_test
+	-$(MAKE) -C ../lib clean
+
+CFLAGS = -fsanitize=address -fsanitize=undefined -g -O3
+CFLAGS += -Wstrict-prototypes -Wunused-variable
+
+SRCS=	results_test.c
+LIB=	../lib/libdiff.a
+
+# Compat sources
+CFLAGS+=       -I$(CURDIR)/../compat/include
+
+results_test: $(SRCS) $(LIB)
+	gcc $(CFLAGS) -I../include -I../lib -o $@ $^
+
+../lib/libdiff.a: ../lib/*.[hc] ../include/*.h
+	$(MAKE) -C ../lib
blob - /dev/null
blob + b15d76376408eb269b5923d31ea25786806b8dc1 (mode 644)
--- /dev/null
+++ test/expect.results_test
@@ -0,0 +1,12 @@
+
+--- test_minus_after_plus()
+[0] same lines L2 R2 @L 0 @R 0
+[1] minus lines L3 R0 @L 4 @R 10
+[2] plus lines L0 R3 @L 4 @R 4
+[3] same lines L2 R2 @L 10 @R 10
+
+--- test_plus_after_plus()
+[0] same lines L2 R2 @L 0 @R 0
+[1] minus lines L3 R0 @L 4 @R 4
+[2] plus lines L0 R3 @L 10 @R 4
+[3] same lines L2 R2 @L 10 @R 10
blob - /dev/null
blob + 4534bde81ad7ca55467131607a967f7f4ae0d4b6 (mode 644)
--- /dev/null
+++ test/results_test.c
@@ -0,0 +1,166 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <arraylist.h>
+#include <diff_main.h>
+
+#include <diff_internal.h>
+#include <diff_debug.h>
+
+void test_minus_after_plus(void)
+{
+	struct diff_result *result = malloc(sizeof(struct diff_result));
+	char *left_data = "a\nb\nc\nd\ne\nm\nn\n";
+	char *right_data = "a\nb\nj\nk\nl\nm\nn\n";
+	int i;
+
+	printf("\n--- %s()\n", __func__);
+
+	*result = (struct diff_result) {
+		.left = (struct diff_data){
+			.data = left_data,
+			.len = strlen(left_data),
+			.root = &result->left,
+		},
+		.right = (struct diff_data){
+			.data = right_data,
+			.len = strlen(right_data),
+			.root = &result->right,
+		},
+	};
+
+	diff_atomize_text_by_line(0, &result->left, &result->right);
+
+	struct diff_state state = {
+		.result = result,
+		.recursion_depth_left = 32,
+	};
+	diff_data_init_subsection(&state.left, &result->left,
+				  result->left.atoms.head,
+				  result->left.atoms.len);
+	diff_data_init_subsection(&state.right, &result->right,
+				  result->right.atoms.head,
+				  result->right.atoms.len);
+
+	/* "same" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[0], 2,
+			     &state.right.atoms.head[0], 2);
+
+	/* "plus" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[2], 0,
+			     &state.right.atoms.head[2], 3);
+
+	/* "minus" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[2], 3,
+			     &state.right.atoms.head[5], 0);
+
+	/* "same" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[5], 2,
+			     &state.right.atoms.head[5], 2);
+
+	for (i = 0; i < result->chunks.len; i++) {
+		struct diff_chunk *c = &result->chunks.head[i];
+		enum diff_chunk_type t = diff_chunk_type(c);
+
+		printf("[%d] %s lines L%d R%d @L %d @R %d\n",
+		      i, (t == CHUNK_MINUS ? "minus" :
+			  (t == CHUNK_PLUS ? "plus" :
+			   (t == CHUNK_SAME ? "same" : "?"))),
+		      c->left_count,
+		      c->right_count,
+		      c->left_start ? c->left_start->pos : -1,
+		      c->right_start ? c->right_start->pos : -1);
+	}
+
+	diff_result_free(result);
+}
+
+void test_plus_after_plus(void)
+{
+	struct diff_result *result = malloc(sizeof(struct diff_result));
+	char *left_data = "a\nb\nc\nd\ne\nm\nn\n";
+	char *right_data = "a\nb\nj\nk\nl\nm\nn\n";
+	struct diff_chunk *c;
+
+	printf("\n--- %s()\n", __func__);
+
+	*result = (struct diff_result) {
+		.left = (struct diff_data){
+			.data = left_data,
+			.len = strlen(left_data),
+			.root = &result->left,
+		},
+		.right = (struct diff_data){
+			.data = right_data,
+			.len = strlen(right_data),
+			.root = &result->right,
+		},
+	};
+
+	diff_atomize_text_by_line(0, &result->left, &result->right);
+
+	struct diff_state state = {
+		.result = result,
+		.recursion_depth_left = 32,
+	};
+	diff_data_init_subsection(&state.left, &result->left,
+				  result->left.atoms.head,
+				  result->left.atoms.len);
+	diff_data_init_subsection(&state.right, &result->right,
+				  result->right.atoms.head,
+				  result->right.atoms.len);
+
+	/* "same" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[0], 2,
+			     &state.right.atoms.head[0], 2);
+
+	/* "minus" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[2], 3,
+			     &state.right.atoms.head[2], 0);
+
+	/* "plus" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[5], 0,
+			     &state.right.atoms.head[2], 1);
+	/* "plus" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[5], 0,
+			     &state.right.atoms.head[3], 2);
+
+	/* "same" section */
+	diff_state_add_chunk(&state, true,
+			     &state.left.atoms.head[5], 2,
+			     &state.right.atoms.head[5], 2);
+
+	ARRAYLIST_FOREACH(c, result->chunks) {
+		enum diff_chunk_type t = diff_chunk_type(c);
+
+		printf("[%d] %s lines L%d R%d @L %d @R %d\n",
+		      ARRAYLIST_IDX(c, result->chunks),
+		      (t == CHUNK_MINUS ? "minus" :
+		       (t == CHUNK_PLUS ? "plus" :
+			(t == CHUNK_SAME ? "same" : "?"))),
+		      c->left_count,
+		      c->right_count,
+		      c->left_start ? c->left_start->pos : -1,
+		      c->right_start ? c->right_start->pos : -1);
+	}
+
+	diff_result_free(result);
+}
+
+int main(void)
+{
+	test_minus_after_plus();
+	test_plus_after_plus();
+	return 0;
+}