From: Kevin Day Date: Thu, 13 Feb 2025 03:34:43 +0000 (-0600) Subject: Progress: Continue working on completing the remove program. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=c90ae08803ad9fae50bddd5ad0548afe565a2d5d;p=kevux-tools Progress: Continue working on completing the remove program. Complete the recursion logic. There wasn't much left to do at glance. Additional testing will weed out any remaining incomplete functionality. This should leaves: - The remaining `@todo` notes. - Any remaining advanced matching (if any). - Adding runtime tests. A note about adding unit or runtime tests. I am thinking that I need to mock all of the remove functions. These mocked functions will write a flag bit in something that will designate all of the removed files. This result of marked removals can be matched to the expected removals. This could operate like a combination of a unit test and a runtime test (unit test over the main program, which would be effectively the same as a runtime test in some ways). --- diff --git a/data/build/stand_alone/configs/remove-config.h b/data/build/stand_alone/configs/remove-config.h index 2051ad6..21b270f 100644 --- a/data/build/stand_alone/configs/remove-config.h +++ b/data/build/stand_alone/configs/remove-config.h @@ -380,7 +380,7 @@ #define _di_f_file_operation_get_type_s_ #define _di_f_file_operation_identify_s_ #define _di_f_file_operation_link_s_ -#define _di_f_file_operation_list_s_ +//#define _di_f_file_operation_list_s_ #define _di_f_file_operation_move_s_ #define _di_f_file_operation_open_s_ #define _di_f_file_operation_pipe_s_ diff --git a/sources/c/program/kevux/tools/remove/main/common/print.c b/sources/c/program/kevux/tools/remove/main/common/print.c index 01e496c..f0cda1e 100644 --- a/sources/c/program/kevux/tools/remove/main/common/print.c +++ b/sources/c/program/kevux/tools/remove/main/common/print.c @@ -22,6 +22,7 @@ extern "C" { "fl_conversion_dynamic_partial_to_unsigned_detect", "fl_conversion_dynamic_to_unsigned_detect", "fl_path_clean", + "fl_recurse_do", "fll_program_parameter_process_context", "fll_program_parameter_process_empty", "fll_program_parameter_process_verbosity", diff --git a/sources/c/program/kevux/tools/remove/main/common/print.h b/sources/c/program/kevux/tools/remove/main/common/print.h index 1611454..94b14f8 100644 --- a/sources/c/program/kevux/tools/remove/main/common/print.h +++ b/sources/c/program/kevux/tools/remove/main/common/print.h @@ -55,6 +55,7 @@ extern "C" { kt_remove_f_fl_conversion_dynamic_partial_to_unsigned_detect_e, kt_remove_f_fl_conversion_dynamic_to_unsigned_detect_e, kt_remove_f_fl_path_clean_e, + kt_remove_f_fl_recurse_do_e, kt_remove_f_fll_program_parameter_process_context_e, kt_remove_f_fll_program_parameter_process_empty_e, kt_remove_f_fll_program_parameter_process_verbosity_e, diff --git a/sources/c/program/kevux/tools/remove/main/convert.c b/sources/c/program/kevux/tools/remove/main/convert.c index 07d00bd..b137bdf 100644 --- a/sources/c/program/kevux/tools/remove/main/convert.c +++ b/sources/c/program/kevux/tools/remove/main/convert.c @@ -14,14 +14,14 @@ extern "C" { } { - f_string_static_t strings[] = { + const f_string_static_t strings[] = { kt_remove_now_s, kt_remove_today_s, kt_remove_tomorrow_s, kt_remove_yesterday_s, }; - uint16_t enumerations[] = { + const uint16_t enumerations[] = { kt_remove_flag_date_now_d, kt_remove_flag_date_today_d, kt_remove_flag_date_tomorrow_d, diff --git a/sources/c/program/kevux/tools/remove/main/operate.c b/sources/c/program/kevux/tools/remove/main/operate.c index 6631add..2c86afc 100644 --- a/sources/c/program/kevux/tools/remove/main/operate.c +++ b/sources/c/program/kevux/tools/remove/main/operate.c @@ -66,7 +66,7 @@ extern "C" { if (!recurse || !recurse->state.custom || F_status_set_fine(recurse->state.status) == F_interrupt) return; if (!kt_remove_operate_shall_remove(recurse->state.code) || !(flag & f_directory_recurse_do_flag_action_e)) return; - recurse->state.status = kt_remove_operate_file_remove((kt_remove_main_t *) recurse->state.custom, name, recurse->state.code); + recurse->state.status = kt_remove_operate_file_remove((kt_remove_main_t *) recurse->state.custom, recurse->path, recurse->state.code); } #endif // _di_kt_remove_operate_file_recurse_action_ @@ -77,37 +77,26 @@ extern "C" { kt_remove_main_t * const main = (kt_remove_main_t *) recurse->state.custom; - // @todo print error messages - // Arguments to fl_recurse_do() are invalid (parameter checking). if (flag == f_directory_recurse_do_flag_top_e) { - return; - } - - // The top-level path is an empty string or an error occurred while processing the top-level path. - if (flag == (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e)) { - // @todo note that F_directory_not (with error bit) is returned if the top-level path is not a directory. + kt_remove_print_error_status(&main->program.error, macro_kt_remove_f(fl_recurse_do), recurse->state.status); return; } // The top-level path is an empty string or an error occurred while processing the top-level path. - if (flag == (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_before_e)) { - // @todo note that F_directory_not (with error bit) is returned if the top-level path does not exist. + if (flag == (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e) || flag == (f_directory_recurse_do_flag_top_e | f_directory_recurse_do_flag_path_e | f_directory_recurse_do_flag_before_e)) { + kt_remove_print_error_file_status(&main->program.error, macro_kt_remove_f(fl_recurse_do), name, f_file_operation_stat_s, fll_error_file_type_path_e, recurse->state.status); return; } // An error happened during directory list loading. if (flag == (f_directory_recurse_do_flag_list_e | f_directory_recurse_do_flag_path_e)) { + kt_remove_print_error_file_status(&main->program.error, macro_kt_remove_f(fl_recurse_do), name, f_file_operation_list_s, fll_error_file_type_directory_e, recurse->state.status); + return; } - - //kt_remove_print_error_recursion_max(&main->program.error); - - // recurse->state.code is the top-level operate flag. - - //kt_remove_print_error_operate_file_directory_recurse(&main->program.error, macro_fake_f(fl_directory_do), flag_operate, *recurse->path_top, recurse->path_cache, f_file_operation_delete_s, F_true); } #endif // _di_kt_remove_operate_file_recurse_handle_ diff --git a/sources/c/program/kevux/tools/remove/main/preprocess.c b/sources/c/program/kevux/tools/remove/main/preprocess.c index b0cb627..ed2f7e8 100644 --- a/sources/c/program/kevux/tools/remove/main/preprocess.c +++ b/sources/c/program/kevux/tools/remove/main/preprocess.c @@ -17,7 +17,7 @@ extern "C" { if (kt_remove_signal_check(main)) return 0; - kt_remove_print_simulate_operate_file(&main->program.output, path); + kt_remove_print_simulate_operate_file(&main->program.output, path, flag_operate); main->setting.state.status = f_file_exists(path, main->setting.flag & kt_remove_main_flag_follow_d); @@ -366,7 +366,7 @@ extern "C" { if (!recurse || !recurse->state.custom || F_status_set_fine(recurse->state.status) == F_interrupt) return; if (flag & f_directory_recurse_do_flag_action_e) { - kt_remove_preprocess_file((kt_remove_main_t *) recurse->state.custom, name, recurse->state.code); + kt_remove_preprocess_file((kt_remove_main_t *) recurse->state.custom, recurse->path, recurse->state.code); } } #endif // _di_kt_remove_preprocess_file_recurse_action_ diff --git a/sources/c/program/kevux/tools/remove/main/print/error.c b/sources/c/program/kevux/tools/remove/main/print/error.c index a72a929..1fdc8b4 100644 --- a/sources/c/program/kevux/tools/remove/main/print/error.c +++ b/sources/c/program/kevux/tools/remove/main/print/error.c @@ -32,6 +32,34 @@ extern "C" { } #endif // _di_kt_remove_print_error_file_ +#ifndef _di_kt_remove_print_error_file_status_ + f_status_t kt_remove_print_error_file_status(fl_print_t * const print, const f_string_t function, const f_string_static_t name, const f_string_static_t operation, const uint8_t type, const f_status_t status) { + + if (!print) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + if (F_status_set_fine(status) != F_interrupt) { + fll_error_file_print(print, F_status_set_fine(status), function, F_true, name, operation, type); + } + + return F_okay; + } +#endif // _di_kt_remove_print_error_file_status_ + +#ifndef _di_kt_remove_print_error_status_ + f_status_t kt_remove_print_error_status(fl_print_t * const print, const f_string_t function, const f_status_t status) { + + if (!print) return F_status_set_error(F_output_not); + if (print->verbosity < f_console_verbosity_error_e) return F_output_not; + + if (F_status_set_fine(status) != F_interrupt) { + fll_error_print(print, F_status_set_fine(status), function, F_true); + } + + return F_okay; + } +#endif // _di_kt_remove_print_error_status_ + #ifndef _di_kt_remove_print_error_parameter_missing_value_requires_amount_ f_status_t kt_remove_print_error_parameter_missing_value_requires_amount(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t parameter, const f_number_unsigned_t amount) { diff --git a/sources/c/program/kevux/tools/remove/main/print/error.h b/sources/c/program/kevux/tools/remove/main/print/error.h index 03aa792..5ca8216 100644 --- a/sources/c/program/kevux/tools/remove/main/print/error.h +++ b/sources/c/program/kevux/tools/remove/main/print/error.h @@ -25,6 +25,10 @@ extern "C" { * Must not be NULL. * * This does not alter print.custom.setting.state.status. + * @param function + * (optional) The name of the function where the error happened. + * + * Set to NULL to disable. * * @return * F_okay on success. @@ -48,8 +52,9 @@ extern "C" { * * This does not alter print.custom.setting.state.status. * @param function - * The name of the function where the error happened. - * Set to 0 to disable. + * (optional) The name of the function where the error happened. + * + * Set to NULL to disable. * @param name * The name of the file or directory. * @param operation @@ -70,6 +75,72 @@ extern "C" { #endif // _di_kt_remove_print_error_file_ /** + * Print file related error or warning messages, using status from the parameter. + * + * This is useful for functions where the main.state.status is not being used, such as with fl_directory_do(). + * + * @param print + * The output structure to print to. + * + * Must not be NULL. + * + * This does not alter print.custom.setting.state.status. + * @param function + * (optional) The name of the function where the error happened. + * + * Set to NULL to disable. + * @param name + * The name of the file or directory. + * @param operation + * The operation that fails, such as 'create' or 'access'. + * @param type + * A valid file type code from the fll_error_file_type enum. + * @param status + * The status code to use. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + * + * @see fll_error_file_print() + */ +#ifndef _di_kt_remove_print_error_file_status_ + extern f_status_t kt_remove_print_error_file_status(fl_print_t * const print, const f_string_t function, const f_string_static_t name, const f_string_static_t operation, const uint8_t type, const f_status_t status); +#endif // _di_kt_remove_print_error_file_status_ + +/** + * Print generic error message regarding a function failing in some way, using status from the parameter. + * + * This is useful for functions where the main.state.status is not being used, such as with fl_directory_do(). + * + * @param print + * The output structure to print to. + * + * Must not be NULL. + * + * This does not alter print.custom.setting.state.status. + * @param function + * (optional) The name of the function where the error happened. + * + * Set to NULL to disable. + * @param status + * The status code to use. + * + * @return + * F_okay on success. + * F_output_not on success, but no printing is performed. + * + * F_output_not (with error bit) if setting is NULL. + * + * @see fll_error_print() + */ +#ifndef _di_kt_remove_print_error_status_ + extern f_status_t kt_remove_print_error_status(fl_print_t * const print, const f_string_t function, const f_status_t status); +#endif // _di_kt_remove_print_error_status_ + +/** * Print message about parameter not have the required amount of values associated with this parameter. * * This is only printed when verbosity is not set to quiet. diff --git a/sources/c/program/kevux/tools/remove/main/print/simulate.c b/sources/c/program/kevux/tools/remove/main/print/simulate.c index 108e7d9..9900a9f 100644 --- a/sources/c/program/kevux/tools/remove/main/print/simulate.c +++ b/sources/c/program/kevux/tools/remove/main/print/simulate.c @@ -43,7 +43,7 @@ extern "C" { #endif // _di_kt_remove_print_simulate_operate_boolean_ #ifndef _di_kt_remove_print_simulate_operate_file_ - void kt_remove_print_simulate_operate_file(fl_print_t * const print, const f_string_static_t path) { + void kt_remove_print_simulate_operate_file(fl_print_t * const print, const f_string_static_t path, const uint16_t flag) { if (!print || !print->custom) return; @@ -51,7 +51,17 @@ extern "C" { if (!(main->setting.flag & kt_remove_main_flag_simulate_d)) return; - fll_print_format("%[Remove '%Q'%]:%r", main->program.output.to, main->program.output.set->notable, path, main->program.output.set->notable, f_string_eol_s); + fll_print_format( + "%r%[Remove '%Q'%]:%r", + main->program.output.to, + flag & kt_remove_flag_file_operate_child_d + ? f_string_eol_s + : f_string_empty_s, + main->program.output.set->notable, + path, + main->program.output.set->notable, + f_string_eol_s + ); } #endif // _di_kt_remove_print_simulate_operate_file_ diff --git a/sources/c/program/kevux/tools/remove/main/print/simulate.h b/sources/c/program/kevux/tools/remove/main/print/simulate.h index ad34e0c..99dfa4a 100644 --- a/sources/c/program/kevux/tools/remove/main/print/simulate.h +++ b/sources/c/program/kevux/tools/remove/main/print/simulate.h @@ -72,9 +72,12 @@ extern "C" { * This does not alter print.custom.setting.state.status. * @param path * The path to the file to operate on. + * @param flag + * The file operate flags associated with the file. + * The kt_remove_flag_file_operate_link_d is of specific interest here. */ #ifndef _di_kt_remove_print_simulate_operate_file_ - extern void kt_remove_print_simulate_operate_file(fl_print_t * const print, const f_string_static_t path); + extern void kt_remove_print_simulate_operate_file(fl_print_t * const print, const f_string_static_t path, const uint16_t flag); #endif // _di_kt_remove_print_simulate_operate_file_ /**