78 lines
2.4 KiB
C
78 lines
2.4 KiB
C
#include "action_list.h"
|
|
|
|
// Create a new ActionList
|
|
ActionList* new_list() {
|
|
ActionList* list = calloc(1, sizeof(ActionList));
|
|
list->capacity = 10;
|
|
list->actions = calloc(list->capacity, sizeof(Action));
|
|
list->len = 0;
|
|
return list;
|
|
}
|
|
|
|
// Add an Action to the end of the ActionList
|
|
void add_action(ActionList* list, Action action) {
|
|
if (list->len >= list->capacity) {
|
|
list->capacity *= 2;
|
|
list->actions = realloc(list->actions, list->capacity*sizeof(Action));
|
|
if (list->actions == NULL) {
|
|
perror("Actions list reallocation failed!");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
list->actions[list->len++] = action;
|
|
}
|
|
|
|
// Concatenate two ActionLists. Modifies list1 in place
|
|
void append_list(ActionList* list1, ActionList* list2) {
|
|
size_t available_space = list1->capacity - list1->len;
|
|
if (available_space < list2->len) {
|
|
list1->capacity += list2->capacity;
|
|
list1->actions = realloc(list1->actions, list1->capacity*sizeof(Action));
|
|
if (list1->actions == NULL) {
|
|
perror("Actions list reallaction failed!");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
memcpy(list1->actions + list1->len, list2->actions, list2->len * sizeof *list2->actions);
|
|
list1->len += list2->len;
|
|
}
|
|
|
|
void free_action_list(ActionList* list) {
|
|
if (!list) return;
|
|
|
|
for (size_t i = 0; i < list->len; i++) {
|
|
if (list->actions[i].content) {
|
|
free(list->actions[i].content); // Free content for INSERT actions
|
|
}
|
|
}
|
|
|
|
free(list->actions); // Free the array of actions
|
|
free(list); // Free the ActionList itself
|
|
}
|
|
|
|
int compare_actions(const void* a, const void* b) {
|
|
const Action* action1 = (const Action*)a;
|
|
const Action* action2 = (const Action*)b;
|
|
|
|
if (action1->type != action2->type) {
|
|
return (action1->type == DELETE) ? -1 : 1;
|
|
}
|
|
|
|
if (action1->type == DELETE) {
|
|
if (action1->line_original < action2->line_original) return 1;
|
|
if (action1->line_original > action2->line_original) return -1;
|
|
return 0;
|
|
} else {
|
|
if (action1->line_changed < action2->line_changed) return -1;
|
|
if (action1->line_changed > action2->line_changed) return 1;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void sort_action_list(ActionList* actions) {
|
|
if (!actions || actions->len <= 1) return;
|
|
|
|
qsort(actions->actions, actions->len, sizeof(Action), compare_actions);
|
|
}
|