From d397434ceda35703b2823f1f4fad47fff90ea87a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 10 May 2020 20:16:59 -0500 Subject: [PATCH] Progress: further work in Featureless Make, implement cleanup operation --- level_3/fake/c/fake.c | 44 ++++++++++++++------- level_3/fake/c/fake.h | 8 +++- level_3/fake/c/private-build.c | 2 +- level_3/fake/c/private-clean.c | 40 +++++++++++++++++++ level_3/fake/c/private-clean.h | 44 +++++++++++++++++++++ level_3/fake/c/private-fake.c | 74 +++++++++++++++++++++++++----------- level_3/fake/c/private-fake.h | 8 ++-- level_3/fake/data/build/dependencies | 1 + level_3/fake/data/build/settings | 2 +- 9 files changed, 179 insertions(+), 44 deletions(-) diff --git a/level_3/fake/c/fake.c b/level_3/fake/c/fake.c index 5dc7961..db67b5a 100644 --- a/level_3/fake/c/fake.c +++ b/level_3/fake/c/fake.c @@ -262,31 +262,49 @@ extern "C" { status = fake_build_operate(*data); if (f_status_is_error(status)) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_clean); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); + if (data->verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_build); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); + } + break; } } else if (operations[i] == fake_operation_clean) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_clean); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + status = fake_clean_operate(*data); + + if (f_status_is_error(status)) { + if (data->verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_clean); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); + } + + break; + } } else if (operations[i] == fake_operation_make) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_make); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + if (data->verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_make); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + } } else if (operations[i] == fake_operation_skeleton) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_skeleton); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + if (data->verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_skeleton); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + } } } // for } else { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify an operation."); + if (data->verbosity != fake_verbosity_quiet) { + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify an operation."); + } + status = f_status_set_error(f_invalid_parameter); } diff --git a/level_3/fake/c/fake.h b/level_3/fake/c/fake.h index f4e35ad..901db04 100644 --- a/level_3/fake/c/fake.h +++ b/level_3/fake/c/fake.h @@ -111,11 +111,12 @@ #include // fll-0 includes -#include -#include #include #include #include +#include +#include +#include // fll-1 includes #include @@ -125,6 +126,7 @@ // fll-2 includes #include +#include #include #include #include @@ -245,6 +247,8 @@ extern "C" { #endif // _di_fake_build_language_ #ifndef _di_fake_defines_ + #define fake_directory_max_recursion 2048 + enum { fake_operation_build = 1, fake_operation_clean, diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 7f92034..6bc3166 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -48,7 +48,7 @@ extern "C" { } if (f_status_is_error(status)) { - fake_print_error_file(data.context, data.verbosity, f_status_set_fine(status), name_function, path.string, "file", f_true); + fake_print_error_file(data.context, data.verbosity, f_status_set_fine(status), name_function, path.string, f_true, f_true); f_macro_string_dynamic_delete_simple(buffer); f_macro_string_dynamic_delete_simple(path); diff --git a/level_3/fake/c/private-clean.c b/level_3/fake/c/private-clean.c index a85ade6..61e17ba 100644 --- a/level_3/fake/c/private-clean.c +++ b/level_3/fake/c/private-clean.c @@ -6,6 +6,46 @@ extern "C" { #endif +#ifndef _di_fake_clean_operate_ + f_return_status fake_clean_operate(const fake_data data) { + f_status status = f_none; + + if (data.verbosity != fake_verbosity_quiet) { + printf("%c", f_string_eol); + fl_color_print(f_standard_output, data.context.important, data.context.reset, "Deleting all files within build directory '"); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "%s", data.path_build.string); + fl_color_print_line(f_standard_output, data.context.important, data.context.reset, "'."); + } + + if (data.verbosity == fake_verbosity_verbose) { + status = f_directory_remove_custom(data.path_build.string, fake_directory_max_recursion, f_true, fake_clean_remove_recursively_verbosely); + } + else { + status = f_directory_remove(data.path_build.string, fake_directory_max_recursion, f_true); + } + + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "f_directory_remove", f_true); + return status; + } + + return f_none; + } +#endif // _di_fake_clean_operate_ + +#if !defined(_di_fake_clean_operate_) + int fake_clean_remove_recursively_verbosely(const char *path, const struct stat *file_stat, int type, struct FTW *entity) { + if (entity->level == 0) return 0; + + int result = remove(path); + + if (result == 0) { + printf("Removed '%s'.%c", path, f_string_eol); + } + + return result; + } +#endif // !defined(_di_fake_clean_operate_) #ifdef __cplusplus } // extern "C" diff --git a/level_3/fake/c/private-clean.h b/level_3/fake/c/private-clean.h index 01e125c..df83f07 100644 --- a/level_3/fake/c/private-clean.h +++ b/level_3/fake/c/private-clean.h @@ -12,6 +12,50 @@ extern "C" { #endif +/** + * Execute the clean operation. + * + * @param data + * The program data. + * + * @return + * f_none on success. + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_clean_operate_ + extern f_return_status fake_clean_operate(const fake_data data) f_gcc_attribute_visibility_internal; +#endif // _di_fake_clean_operate_ + + +/** + * A special function intended to be used directly by nftw(). + * + * This is intended to be used by the specified function as a function pointer and therefore follows the required structure. + * + * This is essentially a wrapper to remove(). + * + * @param path + * The file path. + * @param file_stat + * The file stat. + * @param type + * The file type. + * @param entity + * The FTW entity. + * + * @return + * 0 on success. + * -1 on failure. + * Check errno for details. + * + * @see f_directory_remove() + * @see nftw() + * @see remove() + */ +#if !defined(_di_fake_clean_operate_) + extern int fake_clean_remove_recursively_verbosely(const char *path, const struct stat *file_stat, int type, struct FTW *entity) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fake_clean_operate_) + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/c/private-fake.c b/level_3/fake/c/private-fake.c index b7a4d54..5ad664e 100644 --- a/level_3/fake/c/private-fake.c +++ b/level_3/fake/c/private-fake.c @@ -194,22 +194,16 @@ extern "C" { #endif // _di_fake_print_error_ #ifndef _di_fake_print_error_file_ - f_return_status fake_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string file_name, const f_string file_or_directory, const bool fallback) { + f_return_status fake_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string name, const bool is_file, const bool fallback) { + f_string file_or_directory = 0; - if (status == f_file_not_found) { - if (verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find file '"); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); - fl_color_print_line(f_standard_error, context.error, context.reset, "'."); - } + if (is_file) file_or_directory = "file"; + else file_or_directory = "directory"; - return f_none; - } - - if (status == f_directory_not_found) { + if (status == f_file_not_found) { if (verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find directory '"); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find %s '", file_or_directory); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -218,10 +212,10 @@ extern "C" { if (status == f_invalid_parameter) { if (verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ", function, file_name); + fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ", function, name); fl_color_print(f_standard_error, context.notable, context.reset, "%s", function); fl_color_print(f_standard_error, context.error, context.reset, "() for the %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -231,7 +225,7 @@ extern "C" { if (status == f_invalid_name) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Invalid %s name '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -241,7 +235,7 @@ extern "C" { if (status == f_out_of_memory) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to access %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -251,7 +245,7 @@ extern "C" { if (status == f_number_overflow) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Overflow while trying to access %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -261,7 +255,7 @@ extern "C" { if (status == f_invalid_directory) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Invalid directory while trying to access %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -271,7 +265,7 @@ extern "C" { if (status == f_access_denied) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Access denied while trying to access %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -281,18 +275,52 @@ extern "C" { if (status == f_loop) { if (verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Loop while trying to access %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } return f_none; } + if (is_file) { + } + else { + if (status == f_directory_not_found) { + if (verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find %s '", file_or_directory); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + + return f_none; + } + + if (status == f_no_data) { + if (verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: could not find %s '", file_or_directory); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + + return f_none; + } + + if (status == f_failure) { + if (verbosity != fake_verbosity_quiet) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to read the %s '", file_or_directory); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + + return f_none; + } + } + if (fake_print_error(context, verbosity, status, function, f_false) == f_unknown && fallback && verbosity != fake_verbosity_quiet) { fl_color_print(f_standard_error, context.error, context.reset, "UNKNOWN ERROR: ("); fl_color_print(f_standard_error, context.notable, context.reset, "%d", status); fl_color_print(f_standard_error, context.error, context.reset, ") occurred for %s '", file_or_directory); - fl_color_print(f_standard_error, context.notable, context.reset, "%s", file_name); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); } @@ -573,7 +601,7 @@ extern "C" { if (f_status_is_error(status)) { if (f_status_set_fine(status) != f_directory_not_found || parameters_required[i]) { - fake_print_error_file(data->context, data->verbosity, f_status_set_fine(status), "f_file_stat", parameter_values[i]->string, "directory", f_true); + fake_print_error_file(data->context, data->verbosity, f_status_set_fine(status), "f_file_stat", parameter_values[i]->string, f_false, f_true); return status; } } diff --git a/level_3/fake/c/private-fake.h b/level_3/fake/c/private-fake.h index c88d08b..2e9092e 100644 --- a/level_3/fake/c/private-fake.h +++ b/level_3/fake/c/private-fake.h @@ -59,10 +59,10 @@ extern "C" { * The error status code to report on. * @param function * The function call that returned the error. - * @param file_name + * @param name * The name of the file or directory. - * @param file_or_directory - * A string that should be either 'file' or 'directory' used when printing the message. + * @param is_file + * Set to TRUE if this is a file and FALSE if this is a directory. * @param fallback * Set to f_true to print the fallback error message for unknown errors. * @@ -71,7 +71,7 @@ extern "C" { * f_unknown is returned if the status code has no print message. */ #ifndef _di_fake_print_error_file_ - extern f_return_status fake_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string file_name, const f_string file_or_directory, const bool fallback) f_gcc_attribute_visibility_internal; + extern f_return_status fake_print_error_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string name, const bool is_file, const bool fallback) f_gcc_attribute_visibility_internal; #endif // _di_fake_print_error_file_ /** diff --git a/level_3/fake/data/build/dependencies b/level_3/fake/data/build/dependencies index 7794fe9..c7ca115 100644 --- a/level_3/fake/data/build/dependencies +++ b/level_3/fake/data/build/dependencies @@ -11,6 +11,7 @@ f_print f_utf fl_color fl_console +fl_directory fl_file fl_fss fl_string diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index 55bef6b..1312632 100644 --- a/level_3/fake/data/build/settings +++ b/level_3/fake/data/build/settings @@ -13,7 +13,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_execute -lfll_fss -lfll_program -lfl_utf -lfl_string -lfl_file -lfl_fss -lfl_console -lfl_color -lf_utf -lf_print -lf_file -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_program -lfll_fss -lfll_execute -lfl_utf -lfl_string -lfl_file -lfl_fss -lfl_directory -lfl_console -lfl_color -lf_utf -lf_print -lf_file -lf_conversion -lf_console -lf_memory build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 build_libraries_fll-monolithic -lfll build_sources_library fake.c private-fake.c private-clean.c private-build.c private-make.c private-skeleton.c -- 1.8.3.1