Skip to content

Instantly share code, notes, and snippets.

@aflaag
Last active April 21, 2023 14:53
Show Gist options
  • Save aflaag/2da22eba4786affc9d685980ba4dd271 to your computer and use it in GitHub Desktop.
Save aflaag/2da22eba4786affc9d685980ba4dd271 to your computer and use it in GitHub Desktop.
#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