/// dynamic array class /// written by: Harry Irving #include #include #include #include #include typedef enum LineState { UNMODIFIED, MODIFIED, ADDED, REMOVED, } LineState; typedef struct { uint32_t size; // Current number of elements uint32_t capacity; // Total capacity allocated LineState* data; // Array of LineState values } StateArray; StateArray arr_init(int capacity) { StateArray arr; arr.size = capacity; arr.capacity = capacity; arr.data = (LineState*)calloc(capacity, sizeof(LineState)); // Initialize all elements to UNMODIFIED for (int i = 0; i < capacity; i++) { arr.data[i] = UNMODIFIED; } return arr; } void arr_print(StateArray* self) { FILE* log_file = fopen("diff.txt", "w"); if (log_file == NULL) { fprintf(stderr, "Error: Could not open log file\n"); } for (int i = 0; i < self->size; i++) { switch (self->data[i]) { case UNMODIFIED: fwrite("UNMODIFIED\n", sizeof(char), strlen("UNMODIFIED\n"), log_file); break; case MODIFIED: fwrite("MODIFIED\n", sizeof(char), strlen("MODIFIED\n"), log_file); break; case ADDED: fwrite("ADDED\n", sizeof(char), strlen("ADDED\n"), log_file); break; case REMOVED: fwrite("REMOVED\n", sizeof(char), strlen("REMOVED\n"), log_file); break; } } fclose(log_file); } int arr_added_or_removed_before(StateArray* self, int index) { int count = 0; for (int i = 0; i < index; i++) { if (self->data[i] == ADDED || self->data[i] == REMOVED) { if (self->data[i] == REMOVED) { index++; } count++; } } return count; } void arr_set(StateArray* self, int index, LineState state) { int offset = arr_added_or_removed_before(self, index); self->data[index] = state; } LineState arr_remove(StateArray* self, int index) { int offset = arr_added_or_removed_before(self, index); if (index >= self->size) { return -1; } LineState removed = self->data[index]; // Shift remaining elements left for (int i = index; i < self->size - 1; i++) { self->data[i] = self->data[i + 1]; } self->size--; return removed; } int arr_insert(StateArray* self, int index, LineState state) { int offset = arr_added_or_removed_before(self, index); if (index > self->size) { return -1; } self->size++; // Grow array if needed if (self->size > self->capacity) { self->capacity = (self->size) * sizeof(LineState); self->data = (LineState*)realloc(self->data, self->capacity * sizeof(LineState)); } // Shift elements right to make room for (int i = self->size - 1; i > index; i--) { self->data[i] = self->data[i - 1]; } self->data[index] = state; return 0; } LineState arr_get(StateArray* self, int index) { int offset = arr_added_or_removed_before(self, index); return self->data[index]; } int arr_original_offset(StateArray* self, int index) { int offset = 0; for (int i = 0; i < index; i++) { if (self->data[i] == ADDED) { offset--; } } return offset; } int arr_modified_offset(StateArray* self, int index) { int offset = 0; for (int i = 0; i < index; i++) { if (self->data[i] == REMOVED) { offset--; } } return offset; } int arr_dealloc(StateArray* self) { free(self->data); self->data = NULL; self->size = 0; self->capacity = 0; return 0; }