refactor(tree,utilities)!: moved find_root and walk to the utilities and removed the Tree struct in favor or the FileInfoBuffer
This commit is contained in:
parent
8efadf051c
commit
326a33a3f4
4 changed files with 149 additions and 157 deletions
|
|
@ -15,22 +15,12 @@
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
typedef List PathBuffer;
|
typedef List PathBuffer;
|
||||||
typedef List Tree;
|
|
||||||
typedef List FileInfoBuffer;
|
typedef List FileInfoBuffer;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char* dir;
|
|
||||||
FileInfoBuffer* files;
|
|
||||||
size_t len;
|
|
||||||
size_t capacity;
|
|
||||||
} TreeEntry;
|
|
||||||
|
|
||||||
PathBuffer* path_buffer_new();
|
PathBuffer* path_buffer_new();
|
||||||
void path_buffer_push(PathBuffer*, char*);
|
void path_buffer_push(PathBuffer*, char*);
|
||||||
void path_buffer_sort(PathBuffer*);
|
void path_buffer_sort(PathBuffer*);
|
||||||
void path_buffer_free(PathBuffer*);
|
void path_buffer_free(PathBuffer*);
|
||||||
char* find_root(char*);
|
|
||||||
void walk(char*, char*, char*, PathBuffer*, int, char*);
|
|
||||||
void save_tree(PathBuffer*);
|
void save_tree(PathBuffer*);
|
||||||
|
|
||||||
#endif // TREE_H
|
#endif // TREE_H
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ typedef struct {
|
||||||
List* list_new(size_t);
|
List* list_new(size_t);
|
||||||
int list_push(List*, void*);
|
int list_push(List*, void*);
|
||||||
PathType get_path_type(const char*);
|
PathType get_path_type(const char*);
|
||||||
|
char* find_root(char*);
|
||||||
|
void walk(char*, char*, char*, PathBuffer*, int, char*);
|
||||||
void visualize_diff(File*, File*, ActionList*);
|
void visualize_diff(File*, File*, ActionList*);
|
||||||
void cut_path(char* base, char* path);
|
void cut_path(char* base, char* path);
|
||||||
void combine_path(char* base, char* path);
|
void combine_path(char* base, char* path);
|
||||||
|
|
|
||||||
147
src/tree.c
147
src/tree.c
|
|
@ -60,78 +60,6 @@ static char* join_path(const char* a, const char* b) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A function that returns the system path of the where the closest merk
|
|
||||||
// directory to the current working directory is located up in direction to
|
|
||||||
// the filesystem root
|
|
||||||
// Mutates relative in place to get the correct amount of ../ in relation to
|
|
||||||
// the directory which the software was called in
|
|
||||||
char* find_root(char* relative) {
|
|
||||||
char* current_dir = calloc(PATH_MAX, sizeof(char));
|
|
||||||
if (!current_dir) {
|
|
||||||
perror("ERROR: calloc in find_root failed!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!getcwd(current_dir, PATH_MAX)) {
|
|
||||||
perror("ERROR: getcwd in find_root failed!");
|
|
||||||
free(current_dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* search_dir = strdup(current_dir);
|
|
||||||
if (!search_dir) {
|
|
||||||
perror("ERROR: strdup in find_root failed!");
|
|
||||||
free(current_dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
size_t dir_len = strlen(search_dir);
|
|
||||||
size_t merk_path_len = dir_len + strlen("/.merk") + 1;
|
|
||||||
char* merk_path = calloc(merk_path_len, sizeof(char));
|
|
||||||
if (!merk_path) {
|
|
||||||
perror("ERROR: calloc in find_root failed!");
|
|
||||||
free(current_dir);
|
|
||||||
free(search_dir);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(merk_path, merk_path_len, "%s/.merk", search_dir);
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (stat(merk_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
|
||||||
free(current_dir);
|
|
||||||
free(merk_path);
|
|
||||||
char* result = strdup(search_dir);
|
|
||||||
free(search_dir);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(merk_path);
|
|
||||||
|
|
||||||
if (strcmp(search_dir, "/") == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
char temp[PATH_MAX];
|
|
||||||
snprintf(temp, sizeof(temp), "../%s", relative);
|
|
||||||
strcpy(relative, temp);
|
|
||||||
|
|
||||||
char* parent = strrchr(search_dir, '/');
|
|
||||||
if (parent == search_dir) {
|
|
||||||
search_dir[1] = '\0';
|
|
||||||
} else if (parent) {
|
|
||||||
*parent = '\0';
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(current_dir);
|
|
||||||
free(search_dir);
|
|
||||||
printf("ERROR: you are in no merk repository!\nCreate a new repository with merk init\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void normalize_path(char* path, char* rel) {
|
void normalize_path(char* path, char* rel) {
|
||||||
if (strlen(rel) == 0) return;
|
if (strlen(rel) == 0) return;
|
||||||
|
|
||||||
|
|
@ -153,81 +81,6 @@ void normalize_path(char* path, char* rel) {
|
||||||
strcpy(path, path+latest+(counter > 0 ? 1 : 0));
|
strcpy(path, path+latest+(counter > 0 ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_repo_path, char* repo_root_path) {
|
|
||||||
DIR* dir = opendir(base);
|
|
||||||
if (!dir) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dirent* de;
|
|
||||||
while ((de = readdir(dir)) != NULL) {
|
|
||||||
if (is_dot_or_dotdot(de->d_name)) continue;
|
|
||||||
if (strcmp(de->d_name, ".merk") == 0) continue;
|
|
||||||
|
|
||||||
char* child_full = join_path(base, de->d_name);
|
|
||||||
if (!child_full) {
|
|
||||||
perror("ERROR: memory allocation failed in walk!");
|
|
||||||
closedir(dir);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (lstat(child_full, &st) != 0) {
|
|
||||||
free(child_full);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
|
||||||
char* new_rel;
|
|
||||||
if (rel && rel[0]) {
|
|
||||||
new_rel = join_path(rel, de->d_name);
|
|
||||||
} else {
|
|
||||||
new_rel = strdup(de->d_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!new_rel) {
|
|
||||||
perror("ERROR: memory allocation failed in walk!");
|
|
||||||
free(child_full);
|
|
||||||
closedir(dir);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
walk(child_full, base_rel, new_rel, paths, full_repo_path, repo_root_path);
|
|
||||||
free(new_rel);
|
|
||||||
} else {
|
|
||||||
char* relative_path;
|
|
||||||
if (rel && rel[0]) {
|
|
||||||
relative_path = join_path(rel, de->d_name);
|
|
||||||
} else {
|
|
||||||
relative_path = strdup(de->d_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!relative_path) {
|
|
||||||
perror("ERROR: memory allocation failed in walk!");
|
|
||||||
free(child_full);
|
|
||||||
closedir(dir);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!full_repo_path) {
|
|
||||||
normalize_path(relative_path, base_rel);
|
|
||||||
path_buffer_push(paths, relative_path);
|
|
||||||
free(relative_path);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
char* real_path = realpath(relative_path, NULL);
|
|
||||||
cut_path(repo_root_path, real_path);
|
|
||||||
path_buffer_push(paths, real_path);
|
|
||||||
free(relative_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(child_full);
|
|
||||||
}
|
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void save_tree(PathBuffer* tree) {
|
void save_tree(PathBuffer* tree) {
|
||||||
PathBuffer* files = path_buffer_new();
|
PathBuffer* files = path_buffer_new();
|
||||||
char relative[PATH_MAX] = "";
|
char relative[PATH_MAX] = "";
|
||||||
|
|
|
||||||
147
src/utilities.c
147
src/utilities.c
|
|
@ -43,6 +43,153 @@ PathType get_path_type(const char* path) {
|
||||||
return PT_OTHER;
|
return PT_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A function that returns the system path of the where the closest merk
|
||||||
|
// directory to the current working directory is located up in direction to
|
||||||
|
// the filesystem root
|
||||||
|
// Mutates relative in place to get the correct amount of ../ in relation to
|
||||||
|
// the directory which the software was called in
|
||||||
|
char* find_root(char* relative) {
|
||||||
|
char* current_dir = calloc(PATH_MAX, sizeof(char));
|
||||||
|
if (!current_dir) {
|
||||||
|
perror("ERROR: calloc in find_root failed!");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getcwd(current_dir, PATH_MAX)) {
|
||||||
|
perror("ERROR: getcwd in find_root failed!");
|
||||||
|
free(current_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* search_dir = strdup(current_dir);
|
||||||
|
if (!search_dir) {
|
||||||
|
perror("ERROR: strdup in find_root failed!");
|
||||||
|
free(current_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
size_t dir_len = strlen(search_dir);
|
||||||
|
size_t merk_path_len = dir_len + strlen("/.merk") + 1;
|
||||||
|
char* merk_path = calloc(merk_path_len, sizeof(char));
|
||||||
|
if (!merk_path) {
|
||||||
|
perror("ERROR: calloc in find_root failed!");
|
||||||
|
free(current_dir);
|
||||||
|
free(search_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(merk_path, merk_path_len, "%s/.merk", search_dir);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (stat(merk_path, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||||
|
free(current_dir);
|
||||||
|
free(merk_path);
|
||||||
|
char* result = strdup(search_dir);
|
||||||
|
free(search_dir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(merk_path);
|
||||||
|
|
||||||
|
if (strcmp(search_dir, "/") == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[PATH_MAX];
|
||||||
|
snprintf(temp, sizeof(temp), "../%s", relative);
|
||||||
|
strcpy(relative, temp);
|
||||||
|
|
||||||
|
char* parent = strrchr(search_dir, '/');
|
||||||
|
if (parent == search_dir) {
|
||||||
|
search_dir[1] = '\0';
|
||||||
|
} else if (parent) {
|
||||||
|
*parent = '\0';
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(current_dir);
|
||||||
|
free(search_dir);
|
||||||
|
printf("ERROR: you are in no merk repository!\nCreate a new repository with merk init\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void walk(char* base, char* base_rel, char* rel, PathBuffer* paths, int full_repo_path, char* repo_root_path) {
|
||||||
|
DIR* dir = opendir(base);
|
||||||
|
if (!dir) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent* de;
|
||||||
|
while ((de = readdir(dir)) != NULL) {
|
||||||
|
if (is_dot_or_dotdot(de->d_name)) continue;
|
||||||
|
if (strcmp(de->d_name, ".merk") == 0) continue;
|
||||||
|
|
||||||
|
char* child_full = join_path(base, de->d_name);
|
||||||
|
if (!child_full) {
|
||||||
|
perror("ERROR: memory allocation failed in walk!");
|
||||||
|
closedir(dir);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (lstat(child_full, &st) != 0) {
|
||||||
|
free(child_full);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
char* new_rel;
|
||||||
|
if (rel && rel[0]) {
|
||||||
|
new_rel = join_path(rel, de->d_name);
|
||||||
|
} else {
|
||||||
|
new_rel = strdup(de->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new_rel) {
|
||||||
|
perror("ERROR: memory allocation failed in walk!");
|
||||||
|
free(child_full);
|
||||||
|
closedir(dir);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
walk(child_full, base_rel, new_rel, paths, full_repo_path, repo_root_path);
|
||||||
|
free(new_rel);
|
||||||
|
} else {
|
||||||
|
char* relative_path;
|
||||||
|
if (rel && rel[0]) {
|
||||||
|
relative_path = join_path(rel, de->d_name);
|
||||||
|
} else {
|
||||||
|
relative_path = strdup(de->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!relative_path) {
|
||||||
|
perror("ERROR: memory allocation failed in walk!");
|
||||||
|
free(child_full);
|
||||||
|
closedir(dir);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!full_repo_path) {
|
||||||
|
normalize_path(relative_path, base_rel);
|
||||||
|
path_buffer_push(paths, relative_path);
|
||||||
|
free(relative_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char* real_path = realpath(relative_path, NULL);
|
||||||
|
cut_path(repo_root_path, real_path);
|
||||||
|
path_buffer_push(paths, real_path);
|
||||||
|
free(relative_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(child_full);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
|
||||||
void visualize_diff(File* old_version, File* new_version, ActionList* actions) {
|
void visualize_diff(File* old_version, File* new_version, ActionList* actions) {
|
||||||
int* deleted_lines = calloc(old_version->lines, sizeof(int));
|
int* deleted_lines = calloc(old_version->lines, sizeof(int));
|
||||||
int* inserted_lines = calloc(new_version->lines, sizeof(int));
|
int* inserted_lines = calloc(new_version->lines, sizeof(int));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue