From 0b83168020717259404c3130f0455026a37001ed Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 17 Nov 2019 19:08:32 -0600 Subject: [PATCH] Update: Document fl_directory_list() and finish implementing it The said function is documented as incomplete and has now been completed. --- level_1/fl_directory/c/directory.c | 76 +++++++++++++++++++++++++------------- level_1/fl_directory/c/directory.h | 18 +++++++-- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/level_1/fl_directory/c/directory.c b/level_1/fl_directory/c/directory.c index 4b26f8e..f6d46d8 100644 --- a/level_1/fl_directory/c/directory.c +++ b/level_1/fl_directory/c/directory.c @@ -5,7 +5,6 @@ extern "C" { #endif #ifndef _di_fl_directory_list_ - // put the names of each file and/or directory inside the names parameter f_return_status fl_directory_list(const f_string directory_path, f_string_dynamics *names) { #ifndef _di_level_1_parameter_checking_ if (names == 0) return f_status_set_error(f_invalid_parameter); @@ -13,49 +12,76 @@ extern "C" { struct dirent **listing = 0; int length = 0; - int counter = 0; + int i = 0; f_string_length size = 0; f_status status = f_none; length = scandir(directory_path, &listing, 0, alphasort); - for (; counter < length; counter++) { - size = strnlen(listing[counter]->d_name, fl_directory_name_max); + for (; i < length; i++) { + size = strnlen(listing[i]->d_name, fl_directory_name_max); - // there is no reason to include "." and ".." in the directory listing - if (strncmp(listing[counter]->d_name, "..", 3) != 0 && strncmp(listing[counter]->d_name, ".", 2) != 0) { - if (names->used >= names->size) { - f_macro_string_dynamics_resize(status, (*names), names->used + fl_directory_default_allocation_step); + // There is no reason to include "." and ".." in the directory listing. + if (strncmp(listing[i]->d_name, "..", 3) == 0 || strncmp(listing[i]->d_name, ".", 2) == 0) { + f_memory_delete((void **) & listing[i], sizeof(char *), 1); + continue; + } - if (f_status_is_error(status)) { - return status; - } - } + if (names->used >= names->size) { + f_macro_string_dynamics_resize(status, (*names), names->size + fl_directory_default_allocation_step); + + if (f_status_is_error(status)) { + f_status status2 = f_none; - f_macro_string_dynamic_resize(status, names->array[names->used], size); - if (f_status_is_error(status)) { - return status; + for (int j = i; j < length; j++) { + f_memory_delete((void **) & listing[i], sizeof(char *), 1); } - memcpy(names->array[names->used].string, listing[counter]->d_name, size); - names->array[names->used].used = size; - names->used++; + f_macro_string_dynamics_delete(status2, (*names)); + f_memory_delete((void **) & listing, sizeof(struct dirent *), 1); + + return status; } + } + + f_macro_string_dynamic_new(status, names->array[names->used], size); + + if (f_status_is_error(status)) { + f_status status2 = f_none; + + for (int j = i; j < length; j++) { + f_memory_delete((void **) & listing[i], sizeof(char *), 1); + } + + f_macro_string_dynamics_delete(status2, (*names)); + f_memory_delete((void **) & listing, sizeof(struct dirent *), 1); + + return status; + } + + memcpy(names->array[names->used].string, listing[i]->d_name, size); + names->array[names->used].used = size; + names->used++; + + f_memory_delete((void **) & listing[i], sizeof(char *), 1); + } // for - // FIXME: the second and third paramater are probably wrong - f_memory_delete((void **) & listing[counter], sizeof(struct dirent), 0); + for (int j = i; j < length; j++) { + f_memory_delete((void **) & listing[i], sizeof(char *), 1); } - // FIXME: the second and third paramater are probably wrong - f_memory_delete((void **) & listing, sizeof(struct dirent *), 0); + f_memory_delete((void **) & listing, sizeof(struct dirent *), 1); if (length == 0) { - // an empty directory return f_no_data; } else if (length == -1) { - if (errno == ENOMEM) return f_status_set_error(f_allocation_error); - else return f_status_set_error(f_failure); + if (errno == ENOMEM) { + return f_status_set_error(f_allocation_error); + } + else { + return f_status_set_error(f_failure); + } } return f_none; diff --git a/level_1/fl_directory/c/directory.h b/level_1/fl_directory/c/directory.h index 11f2b36..dcc0deb 100644 --- a/level_1/fl_directory/c/directory.h +++ b/level_1/fl_directory/c/directory.h @@ -34,10 +34,22 @@ extern "C" { #define fl_directory_name_max 255 #endif // _di_fl_directory_limitations_ +/** + * Print the names of each file and/or directory inside the given directory. + * + * @param directory_path + * Filesystem path to the directory. + * @param names + * Will be populated with the names of each file and/or directory inside the names parameter. + * + * @return + * f_none on success. + * f_no_data if directory is empty (@fixme: unlikely due to '.' and '..' probably always being returned.). + * f_failure (with error bit) if failed to read directory information. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_reallocation_error (with error bit) on memory reallocation error. + */ #ifndef _di_fl_directory_list_ - /** - * put the names of each file and/or directory inside the names parameter. - */ extern f_return_status fl_directory_list(const f_string directory_path, f_string_dynamics *names); #endif // _di_fl_directory_list_ -- 1.8.3.1