Last active
April 21, 2023 14:53
-
-
Save aflaag/2da22eba4786affc9d685980ba4dd271 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <dirent.h> | |
#include <string.h> | |
#include <stdint.h> | |
typedef struct { | |
char* path; | |
struct Directory** sub_dirs; | |
} Directory; | |
char* string_realloc(char* ptr, int str_len) { | |
char* new_ptr = calloc(str_len + 1, sizeof(char)); | |
if (new_ptr == NULL) { | |
return NULL; | |
} | |
memcpy(new_ptr, ptr, str_len); | |
free(ptr); | |
return new_ptr; | |
} | |
int build_tree_internals(int64_t* path_ptr, int path_acc_len, char* curr_part, int indent) { | |
DIR* dir_ptr = opendir((char*) *path_ptr); | |
struct dirent *dir; | |
for (int i = 0; i < indent; i++) { | |
printf(" "); | |
} | |
if (dir_ptr) { | |
printf("%s/\n", curr_part); | |
while ((dir = readdir(dir_ptr)) != NULL) { | |
char* dir_name = dir->d_name; | |
if (strcmp(dir_name, ".") && strcmp(dir_name, "..")) { | |
int new_part_len = strlen(dir_name); | |
int total_len = path_acc_len + new_part_len; | |
char* path_new = (char*) string_realloc((char*) *path_ptr, total_len + 1); | |
if (path_new == NULL) { | |
closedir(dir_ptr); | |
return -1; | |
} | |
strcat(path_new, "/"); | |
strcat(path_new, dir_name); | |
*path_ptr = (int64_t) path_new; | |
int err = build_tree_internals(path_ptr, total_len + 1, dir_name, indent + 4); | |
char* path_shrinked = string_realloc((char*) *path_ptr, path_acc_len); | |
if (path_shrinked == NULL) { | |
closedir(dir_ptr); | |
free(path_new); | |
return -1; | |
} | |
*path_ptr = (int64_t) path_shrinked; | |
} | |
} | |
} else { // TODO: HANDLE ERRORS!! | |
printf("%s\n", curr_part); | |
} | |
closedir(dir_ptr); | |
return 0; | |
} | |
int build_tree(char* root) { | |
int path_acc_len = strlen(root); | |
char* path_acc = strdup(root); | |
if (path_acc == NULL) { | |
return -1; | |
} | |
int64_t* path_ptr = (int64_t*) calloc(1, sizeof(int)); | |
if (path_ptr == NULL) { | |
free(path_acc); | |
return -1; | |
} | |
*path_ptr = (int64_t) path_acc; | |
int err = build_tree_internals(path_ptr, path_acc_len, root, 0); | |
if (err != 0) { | |
fprintf(stderr, "ERRORS TODO"); | |
free(path_acc); // TODO: is it double free? | |
free(path_ptr); | |
return -1; | |
} | |
free(path_ptr); | |
return 0; | |
} | |
int main(int argc, char* argv[]) { | |
if (argc < 2) { | |
fprintf(stderr, "Missing path.\n"); | |
exit(0); | |
} | |
build_tree(argv[1]); | |
// build_tree("../root/"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment