#include "tree.h" PathBuffer* new_path_buffer() { PathBuffer* buffer = calloc(1, sizeof(PathBuffer)); if (!buffer) { perror("ERROR: Failed to allocate PathBuffer"); exit(1); } buffer->capacity = 10; buffer->len = 0; buffer->paths = calloc(buffer->capacity, sizeof(char*)); if (!buffer->paths) { perror("ERROR: Failed to allocate paths array"); free(buffer); exit(1); } return buffer; } void add_path(PathBuffer* buffer, char* path) { if (buffer->len >= buffer->capacity) { buffer->capacity *= 2; char** new_paths = realloc(buffer->paths, buffer->capacity * sizeof(char*)); if (!new_paths) { perror("ERROR: PathBuffer realloc failed!"); exit(1); } buffer->paths = new_paths; } char* path_copy = strdup(path); if (!path_copy) { perror("ERROR: strdup failed in add_path!"); exit(1); } buffer->paths[buffer->len++] = path_copy; } void free_path_buffer(PathBuffer* buffer) { if (buffer) { for (size_t i = 0; i < buffer->len; i++) { free(buffer->paths[i]); } free(buffer->paths); free(buffer); } } static int is_dot_or_dotdot(const char* s) { return (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0'))); } static char* join_path(const char* a, const char* b) { size_t la = strlen(a); size_t lb = strlen(b); int need_sep = (la > 0 && a[la - 1] != '/'); char* s = calloc(la + (need_sep ? 1 : 0) + lb + 1, sizeof(char)); if (!s) { perror("ERROR: calloc failed in join_path!"); exit(1); } memcpy(s, a, la); size_t p = la; if (need_sep) s[p++] = '/'; memcpy(s + p, b, lb + 1); return s; } void walk(const char* base, const char* rel, PathBuffer* paths) { char* dir_full = rel[0] ? join_path(base, rel) : strdup(base); if (!dir_full) { perror("ERROR: memory allocation failed in walk!"); exit(1); } DIR* dir = opendir(dir_full); if (!dir) { free(dir_full); return; } struct dirent* de; while ((de = readdir(dir)) != NULL) { if (is_dot_or_dotdot(de->d_name)) continue; char* child_rel = rel[0] ? join_path(rel, de->d_name) : strdup(de->d_name); if (!child_rel) { perror("ERROR: memory allocation failed in walk!"); closedir(dir); free(dir_full); exit(1); } char* child_full = join_path(base, child_rel); struct stat st; if (lstat(child_full, &st) != 0) { free(child_full); free(child_rel); continue; } if (S_ISDIR(st.st_mode)) { walk(base, child_rel, paths); } else { add_path(paths, child_rel); } free(child_rel); free(child_full); } closedir(dir); free(dir_full); }