From 3befe37125e426d452a1b9b9a1fab97ab221c7f1 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 26 Apr 2025 22:09:42 -0500 Subject: [PATCH] Update: Featureless Make with regard to recent fl_directory_do() changes. The changes to `fl_directory_do()` requires that the Featureless Make be updated. I noticed that the `fake_build_copy()` has the `perserve_offset` parameter (also a typo in the name). This was added in a hackish way in the past as sort of a quick and lazy solution. Break this out into two parameters `preserve` and `offset` to allow for preserving the path with no offset at all. I believe the current function structure is still not ideal but that is a problem for another time. The `fake_do_copy_action()` callback for `fl_directory_do()` is now rewritten. I distantly remember not being happy with the situation of the code and I would have needed to fix the `cache_map` to have a more logical use. There were too many changes going on at the time and I did not want to deal with changing that as well. Well, the problem of that approach finally caught up with me and I have fixed it now. The `cache_map` now has the `key` as the source directory and the path as the `destination` directory. I impulsively decided to use a `uint8_t` to designate the functions. Then I wrapped the code in `F_status_is_error_not()` to allow for calling the error handling later on. This has a downside of a rather ugly ternary blob. Aside from the ternary blob, the rest of the code is rather simpler due to the avoidance of always handling the error and returning. This is not well tested and I need to review the changes made as it should affect how the Featureless Make builds the tree structure. The unit tests do seem to be failing to build. I suspect there is some sort of problem in these changes that need to be further investigated. --- level_3/fake/c/main/build.c | 219 +++++++++++++----------- level_3/fake/c/main/build.h | 18 +- level_3/fake/c/main/common/print.c | 1 + level_3/fake/c/main/common/print.h | 1 + level_3/fake/c/main/fake/do.c | 200 ++++++++++------------ level_3/fake/c/main/fake/do.h | 6 + level_3/fake/c/main/make/operate_process_type.c | 145 ++++++++++------ 7 files changed, 314 insertions(+), 276 deletions(-) diff --git a/level_3/fake/c/main/build.c b/level_3/fake/c/main/build.c index c936a44..f51813a 100644 --- a/level_3/fake/c/main/build.c +++ b/level_3/fake/c/main/build.c @@ -164,7 +164,7 @@ extern "C" { #endif // _di_fake_build_arguments_standard_add_ #ifndef _di_fake_build_copy_ - void fake_build_copy(fake_data_t * const data, const f_mode_t mode, const f_string_static_t label, const f_string_static_t source, const f_string_static_t destination, const f_string_statics_t files, const f_string_static_t file_stage, const f_number_unsigned_t perserve_offset) { + void fake_build_copy(fake_data_t * const data, const f_mode_t mode, const f_string_static_t label, const f_string_static_t source, const f_string_static_t destination, const f_string_statics_t files, const f_string_static_t file_stage, const uint8_t preserve, const f_number_unsigned_t offset) { if (!data || !data->main) return; if (data->main->setting.state.status == F_child) return; @@ -176,6 +176,7 @@ extern "C" { f_string_static_t buffer = f_string_static_t_initialize; f_status_t failed = F_okay; fake_local_t local = macro_fake_local_t_initialize_1(main, &main->cache_map, &failed); + uint8_t func = 0; main->cache_recurse_do.action = &fake_do_copy_action; main->cache_recurse_do.handle = &fake_do_copy_handle; @@ -184,18 +185,25 @@ extern "C" { main->cache_recurse_do.flag = f_directory_recurse_do_flag_before_after_d; main->cache_recurse_do.mode = mode; + // Use cache_recurse_do.path as the top-level destination path for error printing. + // Use cache_recurse_do.path_cache as partial destination (directory creation) or for storing the top path with fl_directory_do(). + // Use cache_map.key as source. + // Use cache_map.value as destination. fake_string_dynamic_reset(&main->cache_recurse_do.path); fake_string_dynamic_reset(&main->cache_recurse_do.path_cache); + fake_string_dynamic_reset(&main->cache_map.key); + fake_string_dynamic_reset(&main->cache_map.value); fake_build_print_message_copying(&main->program.message, label); - fake_string_dynamic_reset(&main->cache_2); - fake_string_dynamic_reset(&main->cache_map.key); + main->setting.state.status = f_string_dynamic_append_nulless(source, &main->cache_map.key); - main->setting.state.status = f_string_dynamic_append_nulless(source, &main->cache_2); + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(destination, &main->cache_map.value); + } if (F_status_is_error_not(main->setting.state.status)) { - main->setting.state.status = f_string_dynamic_append_nulless(destination, &main->cache_map.key); + main->setting.state.status = f_string_dynamic_append_nulless(destination, &main->cache_recurse_do.path); } if (F_status_is_error(main->setting.state.status)) { @@ -209,132 +217,139 @@ extern "C" { if (macro_fake_signal_check(&main->program, &main->setting.state)) break; if (!files.array[i].used) continue; - fake_string_dynamic_reset(&main->cache_map.value); - - main->cache_2.used = source.used; - main->cache_map.key.used = destination.used; + fake_string_dynamic_reset(&main->cache_recurse_do.path_cache); - main->setting.state.status = f_string_dynamic_append_nulless(files.array[i], &main->cache_2); + main->cache_map.key.used = source.used; + main->cache_map.value.used = destination.used; - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless)); + func = 0; + main->setting.state.status = f_memory_array_increase_by(f_path_separator_s.used + files.array[i].used + 1, sizeof(f_char_t), (void **) &main->cache_map.key.string, &main->cache_map.key.used, &main->cache_map.key.size); - break; + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_memory_array_increase_by(f_path_separator_s.used + files.array[i].used + 1, sizeof(f_char_t), (void **) &main->cache_map.value.string, &main->cache_map.value.used, &main->cache_map.value.size); } - main->cache_2.string[main->cache_2.used] = 0; - main->cache_map.key.string[main->cache_map.key.used] = 0; - - main->setting.state.status = f_directory_is(main->cache_2); + if (F_status_is_error_not(main->setting.state.status)) { + func = 1; + main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, &main->cache_map.key); + } - if (main->setting.state.status == F_true) { - main->setting.state.status = f_file_name_base(main->cache_2, &main->cache_map.key); + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, &main->cache_map.value); + } - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_file_name_base)); + if (F_status_is_error_not(main->setting.state.status)) { + func = 2; + main->setting.state.status = f_string_dynamic_append_nulless(files.array[i], &main->cache_map.key); + } - break; + if (F_status_is_error_not(main->setting.state.status)) { + if (preserve) { + func = 3; + main->setting.state.status = f_file_name_base(files.array[i], &main->cache_map.value); } + else { + if (offset) { + buffer.string = files.array[i].string + offset; + buffer.used = files.array[i].used - offset; - main->cache_map.key.string[main->cache_map.key.used] = 0; - - fl_directory_do(main->cache_2, &main->cache_recurse_do); - if (F_status_set_fine(main->setting.state.status) == F_interrupt) break; - - // Always provide a final error message to the copy message. - if (F_status_is_error(main->setting.state.status)) { - - // The final message will be generic failure if a message is already printed, otherwise a more detailed message is printed. - if (F_status_is_error(failed)) { - failed = main->setting.state.status; - main->setting.state.status = F_status_set_error(F_failure); + main->setting.state.status = f_string_dynamic_append_nulless(buffer, &main->cache_map.value); } - - fake_print_error_build_operation_file(&main->program.error, macro_fake_f(fl_directory_do), f_file_operation_copy_s, main->cache_2, main->cache_map.key, f_file_operation_to_s, F_true); - - if (F_status_is_error(failed)) { - main->setting.state.status = failed; + else { + main->setting.state.status = f_string_dynamic_append_nulless(files.array[i], &main->cache_map.value); } - - break; } } - else if (main->setting.state.status == F_false) { - main->setting.state.status = f_string_dynamic_append_nulless(destination, &main->cache_map.value); - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless)); - - break; - } - - if (perserve_offset && perserve_offset < main->cache_2.used) { - buffer.string = main->cache_2.string + perserve_offset; - buffer.used = main->cache_2.used - perserve_offset; - - main->setting.state.status = f_file_name_directory(buffer, &main->cache_map.key); + if (F_status_is_error_not(main->setting.state.status)) { + func = 4; + main->setting.state.status = f_string_dynamic_terminate_after(&main->cache_map.value); + } - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_file_name_directory)); + if (F_status_is_error_not(main->setting.state.status)) { + func = 5; - break; - } + main->cache_map.key.string[main->cache_map.key.used] = 0; + main->cache_map.value.string[main->cache_map.value.used] = 0; - main->setting.state.status = fl_directory_create(main->cache_map.key, F_file_mode_all_rwx_d); + main->setting.state.status = f_directory_is(main->cache_map.key); + } - if (F_status_is_error(main->setting.state.status)) { - fake_print_error_file(&main->program.error, macro_fake_f(fl_directory_create), main->cache_map.key, f_file_operation_create_s, fll_error_file_type_directory_e); + if (main->setting.state.status == F_true) { + func = 2; + main->setting.state.status = f_string_dynamic_append_nulless(main->cache_map.key, &main->cache_recurse_do.path_cache); - break; - } + if (F_status_is_error_not(main->setting.state.status)) { + func = 4; + main->setting.state.status = f_string_dynamic_terminate_after(&main->cache_recurse_do.path_cache); + } - main->setting.state.status = f_string_append_nulless(main->cache_2.string + perserve_offset, main->cache_2.used - perserve_offset, &main->cache_map.value); + if (F_status_is_error_not(main->setting.state.status)) { + fl_directory_do(main->cache_recurse_do.path_cache, &main->cache_recurse_do); + if (F_status_set_fine(main->setting.state.status) == F_interrupt) break; + // Always provide a final error message to the copy message. if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_string_append_nulless)); - break; - } - } - else { - fake_string_dynamic_reset(&main->cache_map.key); + // The final message will be generic failure if a message is already printed, otherwise a more detailed message is printed. + if (F_status_is_error(failed)) { + failed = main->setting.state.status; + main->setting.state.status = F_status_set_error(F_failure); + } - main->setting.state.status = f_file_name_base(main->cache_2, &main->cache_map.value); + fake_print_error_build_operation_file(&main->program.error, macro_fake_f(fl_directory_do), f_file_operation_copy_s, main->cache_map.key, main->cache_map.value, f_file_operation_to_s, F_true); - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_file_name_base)); + if (F_status_is_error(failed)) { + main->setting.state.status = failed; + } break; } } + } + else if (main->setting.state.status == F_false) { + func = 6; + main->setting.state.status = f_file_name_directory(main->cache_map.value, &main->cache_recurse_do.path_cache); - main->cache_map.value.string[main->cache_map.value.used] = 0; - - fake_print_verbose_copying(&main->program.message, main->cache_2, main->cache_map.value); - - main->setting.state.status = f_file_copy(main->cache_2, main->cache_map.value, mode, F_file_default_size_read_d, f_file_stat_flag_reference_e); - - if (F_status_is_error(main->setting.state.status)) { - fake_print_error_build_operation_file(&main->program.error, macro_fake_f(f_file_copy), f_file_operation_copy_s, main->cache_2, main->cache_map.value, f_file_operation_to_s, F_true); - - break; + if (F_status_is_error_not(main->setting.state.status)) { + func = 7; + main->setting.state.status = fl_directory_create(main->cache_recurse_do.path_cache, F_file_mode_all_rwx_d); } - // Restore the destination path in cases where it is changed. - if (!perserve_offset || perserve_offset >= main->cache_2.used) { - fake_string_dynamic_reset(&main->cache_map.key); - - main->setting.state.status = f_string_dynamic_append_nulless(destination, &main->cache_map.key); - - if (F_status_is_error(main->setting.state.status)) { - fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless)); + if (F_status_is_error_not(main->setting.state.status)) { + fake_print_verbose_copying(&main->program.message, main->cache_map.key, main->cache_map.value); - break; - } + func = 8; + main->setting.state.status = f_file_copy(main->cache_map.key, main->cache_map.value, mode, F_file_default_size_read_d, f_file_stat_flag_reference_e); } } - else if (F_status_is_error(main->setting.state.status)) { - fake_print_error_file(&main->program.error, macro_fake_f(f_directory_is), main->cache_2, f_file_operation_create_s, fll_error_file_type_file_e); + + if (F_status_is_error(main->setting.state.status)) { + fake_print_error_build_operation_file( + &main->program.error, + !func + ? macro_fake_f(f_memory_array_increase_by) + : func == 1 + ? macro_fake_f(f_string_dynamic_append_assure) + : func == 2 + ? macro_fake_f(f_string_dynamic_append_nulless) + : func == 3 + ? macro_fake_f(f_file_name_base) + : func == 4 + ? macro_fake_f(f_string_dynamic_terminate_after) + : func == 5 + ? macro_fake_f(f_directory_is) + : func == 6 + ? macro_fake_f(f_file_name_directory) + : func == 7 + ? macro_fake_f(fl_directory_create) + : macro_fake_f(f_file_copy), + f_file_operation_copy_s, + main->cache_map.key, + main->cache_map.value, + f_file_operation_to_s, + F_true + ); break; } @@ -647,9 +662,9 @@ extern "C" { main->program.child = fake_build_execute_process_script(data, &data_build, data_build.setting.process_pre, stage.file_process_pre); - fake_build_copy(data, mode, fake_build_documentation_files_s, data->path_data_documentation, data->path_build_documentation, data_build.setting.build_sources_documentation, stage.file_sources_documentation, 0); + fake_build_copy(data, mode, fake_build_documentation_files_s, data->path_data_documentation, data->path_build_documentation, data_build.setting.build_sources_documentation, stage.file_sources_documentation, F_false, 0); - fake_build_copy(data, mode, fake_build_setting_files_s, data->path_data_settings, data->path_build_settings, data_build.setting.build_sources_setting, stage.file_sources_settings, 0); + fake_build_copy(data, mode, fake_build_setting_files_s, data->path_data_settings, data->path_build_settings, data_build.setting.build_sources_setting, stage.file_sources_settings, F_false, 0); if (data_build.setting.language == fake_build_language_shell_e) { fake_build_object_script(data, &data_build, mode, stage.file_object_script); @@ -669,7 +684,7 @@ extern "C" { } } - fake_build_copy(data, mode, fake_build_scripts_s, main->cache_argument, data->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0); + fake_build_copy(data, mode, fake_build_scripts_s, main->cache_argument, data->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, F_false, 0); } } else { @@ -690,14 +705,14 @@ extern "C" { } } - fake_build_copy(data, mode, fake_build_header_files_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers, stage.file_sources_headers, data_build.setting.preserve_path_headers ? main->cache_argument.used : 0); + fake_build_copy(data, mode, fake_build_header_files_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers, stage.file_sources_headers, data_build.setting.preserve_path_headers, main->cache_argument.used); if (data_build.setting.build_shared) { - fake_build_copy(data, mode, fake_build_header_files_shared_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers_shared, stage.file_sources_headers, data_build.setting.preserve_path_headers ? main->cache_argument.used : 0); + fake_build_copy(data, mode, fake_build_header_files_shared_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers_shared, stage.file_sources_headers, data_build.setting.preserve_path_headers, main->cache_argument.used); } if (data_build.setting.build_static) { - fake_build_copy(data, mode, fake_build_header_files_static_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers_static, stage.file_sources_headers, data_build.setting.preserve_path_headers ? main->cache_argument.used : 0); + fake_build_copy(data, mode, fake_build_header_files_static_s, main->cache_argument, main->cache_1, data_build.setting.build_sources_headers_static, stage.file_sources_headers, data_build.setting.preserve_path_headers, main->cache_argument.used); } } @@ -729,7 +744,7 @@ extern "C" { fake_print_error(&main->program.error, macro_fake_f(f_string_dynamic_append_nulless)); } else { - fake_build_copy(data, mode, fake_build_scripts_s, main->cache_argument, data->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0); + fake_build_copy(data, mode, fake_build_scripts_s, main->cache_argument, data->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, F_false, 0); } } } diff --git a/level_3/fake/c/main/build.h b/level_3/fake/c/main/build.h index 236d5cf..04702da 100644 --- a/level_3/fake/c/main/build.h +++ b/level_3/fake/c/main/build.h @@ -53,7 +53,6 @@ extern "C" { * @param data * The program data. * - * This modifies data.main.cache_2. * This modifies data.main.cache_map. * This modifies data.main.cache_recurse_do. * @@ -87,16 +86,15 @@ extern "C" { * The files to copy from source to destination. * @param file_stage * The specific stage file path. - * @param perserve_offset - * (optional) When a positive number, this represents the amount of characters at the front of each file to ignore. - * Everything after that is preserved, and the directory is created if necessary. - * - * This is always treated as 0 for any file that is a directory type. - * - * Set to 0 to disable. + * @param preserve + * Set to F_true to preserve the path. + * Set to F_False to only use the base name when copying. + * @param offset + * When preserve is F_true, this represents the amount of characters at the front of each path to ignore. + * Everything after the offset is preserved, and directories are created if necessary. * * Example: 'sources/c/level_0/fss.h' with a preseve of 10, would result in the path of 'level_0/fss.h' being preserved. - * Whereas a perserve_offset of 0 would result in a path of 'fss.h' being used (the 'level_0/' directory is not preserved). + * Whereas a preseve is F_false, then the path used would instead be 'fss.h' (the 'sources/c/level_0/' directories are not preserved). * * @see f_directory_is() * @see f_file_copy() @@ -111,7 +109,7 @@ extern "C" { * @see fll_program_print_signal_received() */ #ifndef _di_fake_build_copy_ - extern void fake_build_copy(fake_data_t * const data, const f_mode_t mode, const f_string_static_t label, const f_string_static_t source, const f_string_static_t destination, const f_string_statics_t files, const f_string_static_t file_stage, const f_number_unsigned_t perserve_offset); + extern void fake_build_copy(fake_data_t * const data, const f_mode_t mode, const f_string_static_t label, const f_string_static_t source, const f_string_static_t destination, const f_string_statics_t files, const f_string_static_t file_stage, const uint8_t preserve, const f_number_unsigned_t offset); #endif // _di_fake_build_copy_ /** diff --git a/level_3/fake/c/main/common/print.c b/level_3/fake/c/main/common/print.c index 5b5d3ec..1433840 100644 --- a/level_3/fake/c/main/common/print.c +++ b/level_3/fake/c/main/common/print.c @@ -62,6 +62,7 @@ extern "C" { "f_string_dynamic_partial_append", "f_string_dynamic_partial_append_nulless", "f_string_dynamic_prepend", + "f_string_dynamic_terminate_after", "f_thread_create", "f_utf_is_word_dash_plus", "fl_conversion_dynamic_to_unsigned_detect", diff --git a/level_3/fake/c/main/common/print.h b/level_3/fake/c/main/common/print.h index 413acc0..2633080 100644 --- a/level_3/fake/c/main/common/print.h +++ b/level_3/fake/c/main/common/print.h @@ -95,6 +95,7 @@ extern "C" { fake_f_f_string_dynamic_partial_append_e, fake_f_f_string_dynamic_partial_append_nulless_e, fake_f_f_string_dynamic_prepend_e, + fake_f_f_string_dynamic_terminate_after_e, fake_f_f_thread_create_e, fake_f_f_utf_is_word_dash_plus_e, fake_f_fl_conversion_dynamic_to_unsigned_detect_e, diff --git a/level_3/fake/c/main/fake/do.c b/level_3/fake/c/main/fake/do.c index d7b4808..c95dc9a 100644 --- a/level_3/fake/c/main/fake/do.c +++ b/level_3/fake/c/main/fake/do.c @@ -26,146 +26,120 @@ extern "C" { } f_string_map_t * const map = (f_string_map_t *) local->custom_1; + uint8_t func = 0; - if (!recurse->depth && (flag & f_directory_recurse_do_flag_before_d)) { - if (recurse->state.code & fake_state_code_clone_d) { - fake_print_verbose_cloning(&local->main->program.message, *recurse->path_top, map->key); - - recurse->state.status = f_file_clone(*recurse->path_top, map->key, F_file_default_size_write_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e)); - } - else { - fake_print_verbose_copying(&local->main->program.message, *recurse->path_top, map->key); - - recurse->state.status = f_file_copy(*recurse->path_top, map->key, recurse->mode, F_file_default_size_write_d, f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e); - } - - if (F_status_is_error(recurse->state.status)) { - local->main->setting.state.status = recurse->state.status; - - fake_print_error_file(&local->main->program.error, (recurse->state.code & fake_state_code_clone_d) ? macro_fake_f(f_file_clone) : macro_fake_f(f_file_copy), *recurse->path_top, (recurse->state.code & fake_state_code_clone_d) ? f_file_operation_clone_s : f_file_operation_copy_s, fll_error_file_type_directory_e); - - // Save the error status for when the error message is printed. - *((f_status_t *) local->custom_2) = recurse->state.status; - } - else { - fake_string_dynamic_reset(&recurse->path_cache); + // Append the directory path on start. + // If the path is a directory, then make sure to copy/clone the directory first before the action. + if (flag & f_directory_recurse_do_flag_before_d) { - // Pre-populate the destination into the path cache. - recurse->state.status = f_string_dynamic_append_nulless(map->key, &recurse->path_cache); + // Append the name to the path everytime, except for the top-path because that is already part of the path. + if (recurse->depth) { + func = 0; + recurse->state.status = f_memory_array_increase_by(f_path_separator_s.used + name.used + 1, sizeof(f_char_t), (void **) &map->key.string, &map->key.used, &map->key.size); if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = F_okay; - - // Do not allow trailing path separators in the string's length calculation, except root directory '/'. - for (; recurse->path_cache.used; --recurse->path_cache.used) { - if (recurse->path_cache.string[recurse->path_cache.used - 1] != f_path_separator_s.string[0]) break; - } // for - - recurse->path_cache.string[recurse->path_cache.used] = 0; + recurse->state.status = f_memory_array_increase_by(f_path_separator_s.used + name.used + 1, sizeof(f_char_t), (void **) &map->value.string, &map->value.used, &map->value.size); } - } - - return; - } - if (flag & f_directory_recurse_do_flag_before_d) { - if ((flag & f_directory_recurse_do_flag_directory_d) && (flag & f_directory_recurse_do_flag_action_d)) { - - // Push the directory name on the path stack (the destination path is expected to be pre-populated). - recurse->state.status = f_memory_array_increase_by(f_path_separator_s.used + name.used + 1, sizeof(f_char_t), (void **) &recurse->path_cache.string, &recurse->path_cache.used, &recurse->path_cache.size); + if (F_status_is_error_not(recurse->state.status)) { + func = 1; + recurse->state.status = f_string_dynamic_append_nulless(f_path_separator_s, &map->key); + } if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = f_string_dynamic_append_assure(f_path_separator_s, &recurse->path_cache); + recurse->state.status = f_string_dynamic_append_nulless(f_path_separator_s, &map->value); } if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = f_string_dynamic_append_nulless(name, &recurse->path_cache); + recurse->state.status = f_string_dynamic_append_nulless(name, &map->key); } - // Guaranetee NULL terminated string. - recurse->path_cache.string[recurse->path_cache.used] = 0; + if (F_status_is_error_not(recurse->state.status)) { + recurse->state.status = f_string_dynamic_append_nulless(name, &map->value); + } + } - if (F_status_is_error(recurse->state.status)) return; + if (F_status_is_error_not(recurse->state.status)) { + map->key.string[map->key.used] = 0; + map->value.string[map->value.used] = 0; if (recurse->state.code & fake_state_code_clone_d) { - fake_print_verbose_cloning(&local->main->program.message, recurse->path, recurse->path_cache); - - recurse->state.status = f_file_clone(recurse->path, recurse->path_cache, F_file_default_size_write_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e)); + fake_print_verbose_cloning(&local->main->program.message, map->key, map->value); + + func = 2; + recurse->state.status = f_file_clone( + map->key, + map->value, + F_file_default_size_write_d, + f_file_stat_flag_group_e | f_file_stat_flag_owner_e | ( + recurse->flag & f_directory_recurse_do_flag_dereference_d + ? 0 + : f_file_stat_flag_reference_e + ) + ); } else { - fake_print_verbose_copying(&local->main->program.message, recurse->path, recurse->path_cache); - - recurse->state.status = f_file_copy(recurse->path, recurse->path_cache, recurse->mode, F_file_default_size_write_d, f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e); + fake_print_verbose_copying(&local->main->program.message, map->key, map->value); + + func = 3; + recurse->state.status = f_file_copy( + map->key, + map->value, + recurse->mode, + F_file_default_size_write_d, + recurse->flag & f_directory_recurse_do_flag_dereference_d + ? 0 + : f_file_stat_flag_reference_e + ); } + } - if (F_status_is_error(recurse->state.status)) { - local->main->setting.state.status = recurse->state.status; + if (F_status_is_error(recurse->state.status)) { + local->main->setting.state.status = recurse->state.status; - fake_print_error_file(&local->main->program.error, (recurse->state.code & fake_state_code_clone_d) ? macro_fake_f(f_file_clone) : macro_fake_f(f_file_copy), recurse->path, (recurse->state.code & fake_state_code_clone_d) ? f_file_operation_clone_s : f_file_operation_copy_s, fll_error_file_type_directory_e); + fake_print_error_file( + &local->main->program.error, + !func + ? macro_fake_f(f_memory_array_increase_by) + : func == 1 + ? macro_fake_f(f_string_dynamic_append_nulless) + : func == 2 + ? macro_fake_f(f_file_clone) + : macro_fake_f(f_file_copy), + map->key, + recurse->state.code & fake_state_code_clone_d + ? f_file_operation_clone_s + : f_file_operation_copy_s, + fll_error_file_type_directory_e + ); - // Save the error status for when the error message is printed. - *((f_status_t *) local->custom_2) = recurse->state.status; - } + // Save the error status for when the error message is printed. + *((f_status_t *) local->custom_2) = recurse->state.status; } return; } + else if (flag & f_directory_recurse_do_flag_after_d) { - if (!recurse->depth && (flag & f_directory_recurse_do_flag_after_d)) { - if ((flag & f_directory_recurse_do_flag_directory_d) && (flag & f_directory_recurse_do_flag_action_d)) { + // Pop the current path off of the path stack. + if (recurse->depth) { + if (map->key.size && map->key.size >= f_path_separator_s.used + name.used) { + map->key.used -= f_path_separator_s.used + name.used; - // Pop the current path off of the path stack. - if (F_status_is_error_not(recurse->state.status)) { - recurse->path_cache.used -= f_path_separator_s.used + name.used; + // Guaranetee NULL terminated string. + map->key.string[map->key.used] = 0; } - // Guaranetee NULL terminated string. - recurse->path_cache.string[recurse->path_cache.used] = 0; + if (map->value.size && map->value.size >= f_path_separator_s.used + name.used) { + map->value.used -= f_path_separator_s.used + name.used; + + // Guaranetee NULL terminated string. + map->value.string[map->value.used] = 0; + } } return; } - - fake_string_dynamic_reset(&map->value); - - recurse->state.status = f_memory_array_increase_by(recurse->path_cache.used + f_path_separator_s.used + name.used + 1, sizeof(f_char_t), (void **) &map->value.string, &map->value.used, &map->value.size); - - if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = f_string_dynamic_append_nulless(recurse->path_cache, &map->value); - } - - if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = f_string_dynamic_append_assure(f_path_separator_s, &map->value); - } - - if (F_status_is_error_not(recurse->state.status)) { - recurse->state.status = f_string_dynamic_append_nulless(name, &map->value); - } - - // Guaranetee NULL terminated string. - map->value.string[map->value.used] = 0; - - if (F_status_is_error(recurse->state.status)) return; - - if (recurse->state.code & fake_state_code_clone_d) { - fake_print_verbose_cloning(&local->main->program.message, recurse->path, map->value); - - recurse->state.status = f_file_clone(recurse->path, map->value, F_file_default_size_write_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e)); - } - else { - fake_print_verbose_copying(&local->main->program.message, recurse->path, map->value); - - recurse->state.status = f_file_copy(recurse->path, map->value, recurse->mode, F_file_default_size_write_d, f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e); - } - - if (F_status_is_error(recurse->state.status)) { - local->main->setting.state.status = recurse->state.status; - - fake_print_error_file(&local->main->program.error, (recurse->state.code & fake_state_code_clone_d) ? macro_fake_f(f_file_clone) : macro_fake_f(f_file_copy), map->value, f_file_operation_create_s, (flag & f_directory_recurse_do_flag_directory_d) ? fll_error_file_type_directory_e : fll_error_file_type_file_e); - - // Save the error status for when the error message is printed. - *((f_status_t *) local->custom_2) = recurse->state.status; - } } #endif // _di_fake_do_copy_action_ @@ -181,7 +155,19 @@ extern "C" { if (F_status_is_error_not(*((f_status_t *) local->custom_2))) { local->main->setting.state.status = recurse->state.status; - fake_print_error_build_operation_file(&local->main->program.error, macro_fake_f(fl_directory_do), (recurse->state.code & fake_state_code_clone_d) ? f_file_operation_clone_s : f_file_operation_copy_s, *recurse->path_top, recurse->path_cache, f_file_operation_to_s, F_true); + fake_print_error_build_operation_file( + &local->main->program.error, + macro_fake_f(fl_directory_do), + recurse->state.code & fake_state_code_clone_d + ? f_file_operation_clone_s + : f_file_operation_copy_s, + recurse->path_top + ? *recurse->path_top + : f_string_empty_s, + recurse->path, + f_file_operation_to_s, + F_true + ); *((f_status_t *) local->custom_2) = recurse->state.status; } diff --git a/level_3/fake/c/main/fake/do.h b/level_3/fake/c/main/fake/do.h index 2ee1806..6e687b3 100644 --- a/level_3/fake/c/main/fake/do.h +++ b/level_3/fake/c/main/fake/do.h @@ -21,6 +21,12 @@ extern "C" { * * This can also be used for a clone or a move operation when the appropriate flags or set. * + * This expects and potentially alters the following: + * - main.cache_recurse_do.path: The top-level destination path to use when printing errors. + * - main.cache_recurse_do.path_cache: A cache to use for special cases. + * - recurse.state.custom: A pointer to fake_local_t. + * - recurse.state.custom.custom_1: A pointer to f_string_map_t where the custom_1.key is the specific source path and custom_1.value is the destination path during before, action, and after operations. + * * @param recurse * The recuse structure. * diff --git a/level_3/fake/c/main/make/operate_process_type.c b/level_3/fake/c/main/make/operate_process_type.c index 4673845..862e334 100644 --- a/level_3/fake/c/main/make/operate_process_type.c +++ b/level_3/fake/c/main/make/operate_process_type.c @@ -209,7 +209,7 @@ extern "C" { fake_main_t * const main = data_make->main; - const f_number_unsigned_t total = main->cache_arguments.used - 1; + const f_number_unsigned_t total = main->cache_arguments.used ? main->cache_arguments.used - 1 : 0; f_status_t failed = F_okay; fake_local_t local = macro_fake_local_t_initialize_1(main, &main->cache_map, &failed); @@ -226,14 +226,21 @@ extern "C" { macro_f_mode_t_set_default_umask(main->cache_recurse_do.mode, main->program.umask); } + // Use cache_recurse_do.path as the top-level destination path for error printing. + // Use cache_recurse_do.path_cache as partial destination (directory creation) or for storing the top path with fl_directory_do(). + // Use cache_map.key as source. + // Use cache_map.value as destination. fake_string_dynamic_reset(&main->cache_recurse_do.path); fake_string_dynamic_reset(&main->cache_recurse_do.path_cache); + fake_string_dynamic_reset(&main->cache_map.key); + fake_string_dynamic_reset(&main->cache_map.value); - bool existing = F_true; - f_number_unsigned_t i = 0; - const f_string_t *function = 0; - const f_string_static_t *operation = 0; + uint8_t func = 0; + uint8_t existing = F_true; uint8_t type = fll_error_file_type_path_e; + f_number_unsigned_t i = 0; + + f_string_static_t operation = f_string_static_t_initialize; // The first argument may designate not to dereference links. if (f_compare_dynamic(fake_make_operation_argument_no_dereference_s, main->cache_arguments.array[i]) == F_equal_to) { @@ -246,93 +253,117 @@ extern "C" { main->setting.state.status = f_directory_is(main->cache_arguments.array[1]); if (F_status_is_error(main->setting.state.status)) { - function = ¯o_fake_f(f_directory_is); - operation = &f_file_operation_identify_s; + operation = f_file_operation_identify_s; } else if (main->setting.state.status == F_false || main->setting.state.status == F_file_found_not || main->setting.state.status == F_data_not) { existing = F_false; } } - if (F_status_is_error_not(main->setting.state.status)) { - for (; i < total; ++i) { - - fake_string_dynamic_reset(&main->cache_map.key); + for (; F_status_is_error_not(main->setting.state.status) && i < total; ++i) { - main->setting.state.status = f_string_dynamic_append_nulless(main->cache_arguments.array[total], &main->cache_map.key); + fake_string_dynamic_reset(&main->cache_recurse_do.path); + fake_string_dynamic_reset(&main->cache_map.key); + fake_string_dynamic_reset(&main->cache_map.value); - if (F_status_is_error(main->setting.state.status)) { - function = ¯o_fake_f(f_string_dynamic_append_nulless); - operation = &f_file_operation_process_s; + func = 0; + operation = f_file_operation_process_s; + main->setting.state.status = f_memory_array_increase_by(main->cache_arguments.array[i].used + 1, sizeof(f_char_t), (void **) &main->cache_map.key.string, &main->cache_map.key.used, &main->cache_map.key.size); - break; - } + if (F_status_is_error_not(main->setting.state.status)) { + func = 1; + main->setting.state.status = f_string_dynamic_append_nulless(main->cache_arguments.array[i], &main->cache_map.key); + } - if (existing) { - main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, &main->cache_map.key); + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->cache_arguments.array[total], &main->cache_map.value); + } - if (F_status_is_error(main->setting.state.status)) { - function = ¯o_fake_f(f_string_dynamic_append_assure); - operation = &f_file_operation_process_s; + if (F_status_is_error_not(main->setting.state.status)) { + main->setting.state.status = f_string_dynamic_append_nulless(main->cache_arguments.array[total], &main->cache_recurse_do.path); + } - break; - } + if (F_status_is_error_not(main->setting.state.status) && existing) { + func = 2; + main->setting.state.status = f_string_dynamic_append_assure(f_path_separator_s, &main->cache_map.value); + } - main->setting.state.status = f_file_name_base(main->cache_arguments.array[i], &main->cache_map.key); + if (F_status_is_error_not(main->setting.state.status) && existing) { + func = 3; + main->setting.state.status = f_string_dynamic_terminate_after(&main->cache_map.key); + } - if (F_status_is_error(main->setting.state.status)) { - function = ¯o_fake_f(f_file_name_base); - operation = &f_file_operation_process_s; + if (F_status_is_error_not(main->setting.state.status) && existing) { + func = 4; + main->setting.state.status = f_file_name_base(main->cache_arguments.array[i], &main->cache_map.value); + } - break; - } - } + if (F_status_is_error_not(main->setting.state.status)) { + func = 5; + operation = f_file_operation_identify_s; + type = fll_error_file_type_directory_e; main->setting.state.status = f_directory_is(main->cache_arguments.array[i]); if (main->setting.state.status == F_true) { + func = 6; + operation = clone ? f_file_operation_clone_s : f_file_operation_copy_s; + fl_directory_do(main->cache_arguments.array[i], &main->cache_recurse_do); if (F_status_is_error(main->cache_recurse_do.state.status)) { main->setting.state.status = main->cache_recurse_do.state.status; - - function = ¯o_fake_f(fl_directory_do); - operation = clone ? &f_file_operation_clone_s : &f_file_operation_copy_s; - type = fll_error_file_type_directory_e; - - break; } } else if (main->setting.state.status == F_false) { + type = fll_error_file_type_file_e; + if (clone) { - main->setting.state.status = f_file_clone(main->cache_arguments.array[i], main->cache_map.key, F_file_default_size_write_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e)); + func = 7; + operation = f_file_operation_clone_s; + + main->setting.state.status = f_file_clone(main->cache_arguments.array[i], main->cache_map.value, F_file_default_size_write_d, f_file_stat_flag_group_e | f_file_stat_flag_owner_e | (f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e)); } else { - main->setting.state.status = f_file_copy(main->cache_arguments.array[i], main->cache_map.key, main->cache_recurse_do.mode, F_file_default_size_write_d, f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e); - } - - if (F_status_is_error(main->setting.state.status)) { - function = clone ? ¯o_fake_f(f_file_clone) : ¯o_fake_f(f_file_copy); - operation = clone ? &f_file_operation_clone_s : &f_file_operation_copy_s; - type = fll_error_file_type_file_e; + func = 8; + operation = f_file_operation_copy_s; - break; + main->setting.state.status = f_file_copy(main->cache_arguments.array[i], main->cache_map.value, main->cache_recurse_do.mode, F_file_default_size_write_d, f_directory_recurse_do_flag_dereference_d ? 0 : f_file_stat_flag_reference_e); } - fake_make_print_verbose_operate_copy(&main->program.message, clone, main->cache_arguments.array[i], main->cache_map.key); - } - else if (F_status_is_error(main->setting.state.status)) { - function = ¯o_fake_f(f_directory_is); - operation = &f_file_operation_identify_s; - type = fll_error_file_type_directory_e; - - break; + if (F_status_is_error_not(main->cache_recurse_do.state.status)) { + fake_make_print_verbose_operate_copy(&main->program.message, clone, main->cache_arguments.array[i], main->cache_map.value); + } } - } // for - } + } + } // for if (F_status_is_error(main->setting.state.status)) { - fake_print_error_file(&main->program.error, *function, main->cache_arguments.array[1], *operation, type); + fake_print_error_file( + &main->program.error, + !func + ? macro_fake_f(f_memory_array_increase_by) + : func == 1 + ? macro_fake_f(f_string_dynamic_append_nulless) + : func == 2 + ? macro_fake_f(f_string_dynamic_append_assure) + : func == 3 + ? macro_fake_f(f_string_dynamic_terminate_after) + : func == 4 + ? macro_fake_f(f_file_name_base) + : func == 5 + ? macro_fake_f(f_directory_is) + : func == 6 + ? macro_fake_f(fl_directory_do) + : func == 7 + ? macro_fake_f(f_file_clone) + : macro_fake_f(f_file_copy), + main->cache_arguments.used + ? main->cache_arguments.array[1] + : f_string_empty_s, + operation, + type + ); main->setting.state.status = F_status_set_error(F_failure); } -- 1.8.3.1