refactor(utilities)!: renamed PathBuffer to StringBuffer

This commit is contained in:
lisk77 2025-08-28 03:48:44 +02:00
parent 983c6d4ca4
commit 52e740fab0
2 changed files with 185 additions and 58 deletions

View file

@ -32,45 +32,7 @@ int list_push(List* list, void* item) {
return 1;
}
PathType get_path_type(const char* path) {
struct stat st;
int rc = stat(path, &st);
if (rc != 0) {
return (errno == ENOENT) ? PT_NOEXIST : PT_ERROR;
}
if (S_ISREG(st.st_mode)) return PT_FILE;
if (S_ISDIR(st.st_mode)) return PT_DIR;
return PT_OTHER;
}
PathBuffer* path_buffer_new() {
return list_new(sizeof(char*));
}
void path_buffer_push(PathBuffer* buffer, char* path) {
char* path_copy = strdup(path);
if (!path_copy) {
perror("ERROR: strdup failed in add_path");
return;
}
list_push(buffer, &path_copy);
}
int compare_paths(const void* a, const void* b) {
const char* s1 = *(const char**)a;
const char* s2 = *(const char**)b;
return strcmp(s1,s2);
}
void path_buffer_sort(PathBuffer* buffer) {
if (!buffer || buffer->len <= 1) {
return;
}
qsort(buffer->items, buffer->len, sizeof(char*), compare_paths);
}
void path_buffer_free(PathBuffer* buffer) {
void list_free(List* buffer) {
if (buffer) {
for (size_t i = 0; i < buffer->len; i++) {
free(buffer->items[i]);
@ -80,6 +42,114 @@ void path_buffer_free(PathBuffer* buffer) {
}
}
void* binary_search(const void* key, const void* base, size_t num_elements, size_t element_size, int (*compare)(const void*, const void*)) {
if (!key || !base || !compare || num_elements == 0) {
return NULL;
}
size_t left = 0;
size_t right = num_elements - 1;
while (left <= right) {
size_t mid = left + (right - left) / 2;
const char* mid_element = (const char*)base + (mid * element_size);
int cmp = compare(key, mid_element);
if (cmp == 0) {
return (void*)mid_element;
}
else if (cmp < 0) {
if (mid == 0) break;
right = mid - 1;
}
else {
left = mid + 1;
}
}
return NULL;
}
void* list_binary_search(List* list, const void* key, int (*compare)(const void*, const void*)) {
if (!list || !key || !compare) {
return NULL;
}
return binary_search(key, list->items, list->len, list->item_size, compare);
}
StringBuffer* string_buffer_new() {
return list_new(sizeof(char*));
}
int string_buffer_push(StringBuffer* buffer, char* path) {
char* path_copy = strdup(path);
if (!path_copy) {
perror("ERROR: strdup failed in string_buffer_push!");
return 0;
}
return list_push(buffer, &path_copy);
}
int compare_strings(const void* a, const void* b) {
const char* s1 = *(const char**)a;
const char* s2 = *(const char**)b;
return strcmp(s1,s2);
}
void string_buffer_sort(StringBuffer* buffer) {
if (!buffer || buffer->len <= 1) {
return;
}
qsort(buffer->items, buffer->len, sizeof(char*), compare_strings);
}
char* string_buffer_search(StringBuffer* buffer, char* path) {
if (!buffer || !path) return NULL;
return (char*)list_binary_search(buffer, path, compare_strings);
}
FileInfoBuffer* file_info_buffer_new() {
return list_new(sizeof(FileInfo));
}
int file_info_buffer_push(FileInfoBuffer* buffer, FileInfo info) {
return list_push(buffer, &info);
}
void file_info_buffer_free(List* buffer) {
if (buffer) {
free(buffer->items);
free(buffer);
}
}
int compare_file_info(const void* a, const void* b) {
const FileInfo* info1 = (const FileInfo*)a;
const FileInfo* info2 = (const FileInfo*)b;
return strcmp(info1->name, info2->name);
}
void file_info_buffer_sort(FileInfoBuffer* buffer) {
if (!buffer || buffer->len <= 1) {
return;
}
qsort(buffer->items, buffer->len, sizeof(FileInfo), compare_file_info);
}
FileInfo* file_info_buffer_search(FileInfoBuffer* buffer, const char* filename) {
if (!buffer || !filename) return NULL;
FileInfo search_key = {.mode = 0, .name = (char*)filename};
return (FileInfo*)list_binary_search(buffer, &search_key, compare_file_info);
}
static int is_dot_or_dotdot(const char* s) {
return (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0')));
}
@ -196,7 +266,7 @@ char* find_root(char* relative) {
return NULL;
}
void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_repo_path, char* repo_root_path) {
void walk(char* base, char* base_rel, char* rel, FileInfoBuffer* file_infos, int full_repo_path, char* repo_root_path) {
DIR* dir = opendir(base);
if (!dir) {
return;
@ -235,7 +305,7 @@ void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_rep
exit(1);
}
walk(child_full, base_rel, new_rel, paths, full_repo_path, repo_root_path);
walk(child_full, base_rel, new_rel, file_infos, full_repo_path, repo_root_path);
free(new_rel);
} else {
char* relative_path;
@ -254,12 +324,14 @@ void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_rep
if (!full_repo_path) {
normalize_path(relative_path, base_rel);
path_buffer_push(paths, relative_path);
FileInfo info = (FileInfo){.mode=st.st_mode, .name=strdup(relative_path)};
file_info_buffer_push(file_infos, info);
free(relative_path);
}
else {
char* repo_path = get_repo_path(repo_root_path, relative_path);
path_buffer_push(paths, repo_path);
FileInfo info = (FileInfo){.mode=st.st_mode, .name=strdup(repo_path)};
file_info_buffer_push(file_infos, info);
free(relative_path);
free(repo_path);
}
@ -278,6 +350,18 @@ char* get_repo_path(char* repo_root_path, char* path) {
return real_path;
}
int is_in_repo(char* repo_root_path, char* path) {
size_t root_len = strlen(repo_root_path);
char* path_base = strdup(path);
path_base[root_len] = '\0';
int cmp = strcmp(path_base, repo_root_path);
free(path_base);
return cmp;
}
void visualize_diff(File* old_version, File* new_version, ActionList* actions) {
int* deleted_lines = calloc(old_version->lines, sizeof(int));
int* inserted_lines = calloc(new_version->lines, sizeof(int));
@ -333,9 +417,9 @@ void visualize_diff(File* old_version, File* new_version, ActionList* actions) {
// In this function we assume that base is a prefix of path
// Thus we just need the length of the base to jump ahead in the path
void cut_path(char* base, char* path) {
int cut_path(char* base, char* path) {
size_t base_len = strlen(base);
if (strlen(path) < base_len) perror("ERROR: the provided path is smaller than the base path!");
if (strlen(path) < base_len) return 0;
int add = strlen(path) != base_len ? 1 : 0;
strcpy(path, path+base_len+add);
@ -345,6 +429,8 @@ void cut_path(char* base, char* path) {
snprintf(tmp, sizeof(tmp), "%s/", path);
strcpy(path, tmp);
}
return 1;
}
// In this function we assume that the end of the base and the beginning of the
@ -365,4 +451,34 @@ void combine_path(char* base, char* path) {
strcpy(path, tmp);
}
PathType get_path_type(const char* path) {
struct stat st;
int rc = stat(path, &st);
if (rc != 0) {
return (errno == ENOENT) ? PT_NOEXIST : PT_ERROR;
}
if (S_ISREG(st.st_mode)) return PT_FILE;
if (S_ISDIR(st.st_mode)) return PT_DIR;
return PT_OTHER;
}
char* get_file_content(char* path) {
if (!path) return NULL;
FILE* file = fopen(path, "rb");
if (!file) { perror("ERROR: could not open file in get_file_content!"); return NULL; }
if (fseek(file, 0, SEEK_END) != 0) { fclose(file); return NULL; }
long file_size = ftell(file);
if (file_size < 0) { perror("ERROR: file size is negative in get_file_content!"); fclose(file); return NULL; }
if (fseek(file, 0, SEEK_SET) != 0) { fclose(file); return NULL; }
size_t n = (size_t)file_size;
char* buf = (char*)calloc(n + 1, 1);
if (!buf) { fclose(file); return NULL; }
size_t got = fread(buf, 1, n, file);
fclose(file);
buf[got] = '\0';
return buf;
}