diff --git a/21st_century_c/process_dir.c b/21st_century_c/process_dir.c new file mode 100644 index 0000000..8132eb5 --- /dev/null +++ b/21st_century_c/process_dir.c @@ -0,0 +1,53 @@ +#include "process_dir.h" +#include +#include +#include + + +int process_dir_r(filestruct level) { + if (!level.fullname) { + if (level.name) { + level.fullname = level.name; + } else { + level.fullname = "."; + } + } + int errct = 0; + + DIR *current = opendir(level.fullname); + if (!current) { + return 1; + } + + struct dirent *entry; + while ((entry = readdir(current))) { + + if (entry->d_name[0] == '.') { + continue; + } + + filestruct next_level = level; + next_level.name = entry->d_name; + (void) asprintf(&next_level.fullname, "%s/%s", level.fullname, entry->d_name); + if (next_level.fullname == NULL) { + return 1; + } + + if (entry->d_type == DT_DIR) { + next_level.depth++; + if (level.directory_action) { + level.directory_action(next_level); + } + errct += process_dir_r(next_level); + } else if (entry->d_type == DT_REG && level.file_action) { + level.file_action(next_level); + errct += next_level.error; + } + + if (next_level.fullname) { + free(next_level.fullname); + } + } + closedir(current); + return errct; +} diff --git a/21st_century_c/process_dir.h b/21st_century_c/process_dir.h new file mode 100644 index 0000000..2dec565 --- /dev/null +++ b/21st_century_c/process_dir.h @@ -0,0 +1,17 @@ +struct filestruct; +typedef void (*level_fn)(struct filestruct path); + + +typedef struct filestruct +{ + char *name, *fullname; + level_fn directory_action, file_action; + int depth, error; + void *data; +} filestruct; + + + +#define process_dir(...) process_dir_r((filestruct){__VA_ARGS__}) + +int process_dir_r(filestruct level); diff --git a/21st_century_c/show_tree.c b/21st_century_c/show_tree.c new file mode 100644 index 0000000..230e714 --- /dev/null +++ b/21st_century_c/show_tree.c @@ -0,0 +1,29 @@ +#include +#include "process_dir.h" + + +void print_dir(filestruct in) { + for (size_t i = 0; i < in.depth-1; ++i) { + printf(" "); + } + printf("├ %s\n", in.name); + for (size_t i = 0; i < in.depth-1; ++i) { + printf(" "); + } + printf("└───┐\n"); +} + + +void print_file(filestruct in) { + for (size_t i = 0; i < in.depth; ++i) { + printf(" "); + } + printf("│ %s\n", in.name); +} + + +int main (int argc, char **argv) { + char *start = (argc > 1) ? argv[1] : "."; + printf("Tree for %s:\n", start ? start : "the current directory"); + process_dir(.name=start, .file_action=print_file, .directory_action=print_dir); +}