From 32047af6d6d0013a04956b590a7a520bc16ba2c1 Mon Sep 17 00:00:00 2001 From: Thomas Nilefalk Date: Wed, 1 Jan 2025 13:31:42 +0100 Subject: [PATCH] [editorbuffertable] Complete register/deregister --- src/editorbuffertable.c | 39 ++++++++++++++++++------- src/editorbuffertable.h | 2 +- src/editorbuffertable_tests.c | 54 ++++++++++++++++++++++++++++------- 3 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/editorbuffertable.c b/src/editorbuffertable.c index dc8f43d0..5e866d78 100644 --- a/src/editorbuffertable.c +++ b/src/editorbuffertable.c @@ -107,18 +107,35 @@ EditorBuffer *deregisterEditorBuffer(char *fileName) { if (!editorBufferIsMember(list, &foundIndex, NULL)) return NULL; - EditorBuffer *found_buffer = editorBufferTable.tab[foundIndex]->buffer; - if (strcmp(found_buffer->fileName, fileName) == 0) { - EditorBufferList *list_element = editorBufferTable.tab[foundIndex]; - editorBufferTable.tab[foundIndex] = list_element->next; - free(list_element); + EditorBufferList **elementP = &editorBufferTable.tab[foundIndex]; + while(*elementP != NULL && strcmp((*elementP)->buffer->fileName, fileName) != 0) { + elementP = &(*elementP)->next; + } + + if (*elementP != NULL) { + EditorBuffer *found_buffer = (*elementP)->buffer; + EditorBufferList *element = *elementP; + *elementP = element->next; + free(element); return found_buffer; } else { - /* Assume it is the second in the list */ - EditorBuffer *found_buffer = editorBufferTable.tab[foundIndex]->next->buffer; - EditorBufferList *list_element = editorBufferTable.tab[foundIndex]->next; - editorBufferTable.tab[foundIndex]->next = list_element->next; - free(list_element); - return found_buffer; + return NULL; + } +} + +/** + * @brief Retrievs an editor buffer in the table and returns it, or NULL + * + * @params fileName - the filename in the buffer to find + * + */ +EditorBuffer *getEditorBufferForFile(char *fileName) { + EditorBuffer buffer = {.fileName = fileName}; + EditorBufferList element = {.buffer = &buffer, .next = NULL}; + EditorBufferList *foundElement; + + if (editorBufferIsMember(&element, NULL, &foundElement)) { + return foundElement->buffer; } + return NULL; } diff --git a/src/editorbuffertable.h b/src/editorbuffertable.h index ec6dcbce..3c831503 100644 --- a/src/editorbuffertable.h +++ b/src/editorbuffertable.h @@ -31,6 +31,6 @@ extern void clearEditorBuffer(int index); /* Register and deregister will hide the lists that the hashlist uses */ extern int registerEditorBuffer(EditorBuffer *buffer); extern EditorBuffer *deregisterEditorBuffer(char *fileName); - +extern EditorBuffer *getEditorBufferForFile(char *fileName); #endif diff --git a/src/editorbuffertable_tests.c b/src/editorbuffertable_tests.c index 411a9ac3..6042b116 100644 --- a/src/editorbuffertable_tests.c +++ b/src/editorbuffertable_tests.c @@ -106,10 +106,10 @@ Ensure(EditorBufferTable, can_register_and_deregister_a_single_buffer) { assert_that(editorBufferTable.tab[registered_index], is_null); } -static int createTwoClashingEditorBuffers(char *first_filename, char *second_filename) { +static void givenThreeClashingEditorBuffers(char *first_filename, char *second_filename, char *third_filename) { /* Inject a hashFun that we can control */ injectHashFun(injectedHashFun); - /* ... and let it return the same hash as for the first file name */ + /* ... and let it return the same hash for all file names */ always_expect(injectedHashFun, will_return(hashFun(first_filename))); EditorBuffer *buffer1 = createEditorBufferFor(first_filename); @@ -118,33 +118,65 @@ static int createTwoClashingEditorBuffers(char *first_filename, char *second_fil EditorBuffer *buffer2 = createEditorBufferFor(second_filename); int index2 = registerEditorBuffer(buffer2); - /* Now we have two buffers at the same index, deregister the first one */ + EditorBuffer *buffer3 = createEditorBufferFor(third_filename); + int index3 = registerEditorBuffer(buffer3); + assert_that(index2, is_equal_to(index1)); - return index1; + assert_that(index3, is_equal_to(index2)); } Ensure(EditorBufferTable, can_deregister_first_buffer_with_hash_clash) { char *first_filename = "first_file.c"; char *second_filename = "second_file.c"; + char *third_filename = "third_file.c"; - int index = createTwoClashingEditorBuffers(first_filename, second_filename); + givenThreeClashingEditorBuffers(first_filename, second_filename, third_filename); EditorBuffer *deregistered_buffer = deregisterEditorBuffer(first_filename); assert_that(deregistered_buffer->fileName, is_equal_to_string(first_filename)); - assert_that(editorBufferTable.tab[index]->buffer->fileName, is_equal_to_string(second_filename)); - assert_that(editorBufferTable.tab[index]->next, is_null); + assert_that(getEditorBufferForFile(first_filename), is_null); + + EditorBuffer *buffer2 = getEditorBufferForFile(second_filename); + assert_that(buffer2, is_not_null); + assert_that(buffer2->fileName, is_equal_to_string(second_filename)); + + EditorBuffer *buffer3 = getEditorBufferForFile(third_filename); + assert_that(buffer3, is_not_null); + assert_that(buffer3->fileName, is_equal_to_string(third_filename)); } Ensure(EditorBufferTable, can_deregister_second_buffer_with_hash_clash) { char *first_filename = "first_file.c"; char *second_filename = "second_file.c"; + char *third_filename = "third_file.c"; - int index = createTwoClashingEditorBuffers(first_filename, second_filename); + givenThreeClashingEditorBuffers(first_filename, second_filename, third_filename); EditorBuffer *deregistered_buffer = deregisterEditorBuffer(second_filename); - assert_that(deregistered_buffer->fileName, is_equal_to_string(second_filename)); - assert_that(editorBufferTable.tab[index]->buffer->fileName, is_equal_to_string(first_filename)); - assert_that(editorBufferTable.tab[index]->next, is_null); + + EditorBuffer *buffer1 = getEditorBufferForFile(first_filename); + assert_that(buffer1, is_not_null); + assert_that(buffer1->fileName, is_equal_to_string(first_filename)); + + assert_that(getEditorBufferForFile(second_filename), is_null); + + EditorBuffer *buffer3 = getEditorBufferForFile(third_filename); + assert_that(buffer3, is_not_null); + assert_that(buffer3->fileName, is_equal_to_string(third_filename)); +} + +Ensure(EditorBufferTable, can_deregister_third_buffer_with_hash_clash) { + char *first_filename = "first_file.c"; + char *second_filename = "second_file.c"; + char *third_filename = "third_file.c"; + + givenThreeClashingEditorBuffers(first_filename, second_filename, third_filename); + + EditorBuffer *deregistered_buffer = deregisterEditorBuffer(third_filename); + + assert_that(deregistered_buffer->fileName, is_equal_to_string(third_filename)); + assert_that(getEditorBufferForFile(first_filename), is_not_null); + assert_that(getEditorBufferForFile(second_filename), is_not_null); }