From: Kevin Day Date: Sat, 18 Dec 2021 17:58:56 +0000 (-0600) Subject: Cleanup: Explode sources into separate files. X-Git-Tag: 0.5.7~26 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=03e3f7fd9ff8f0666c31c7472e486f987a2f048b;p=fll Cleanup: Explode sources into separate files. After analyzing the complexity of some of the sources, I found that these should be broken out. --- diff --git a/level_3/fake/c/fake.c b/level_3/fake/c/fake.c index 311dd1b..b94958d 100644 --- a/level_3/fake/c/fake.c +++ b/level_3/fake/c/fake.c @@ -1,9 +1,11 @@ #include "fake.h" #include "private-common.h" #include "private-fake.h" +#include "private-fake-path_generate.h" #include "private-build.h" #include "private-clean.h" #include "private-make.h" +#include "private-make-operate.h" #include "private-print.h" #include "private-skeleton.h" diff --git a/level_3/fake/c/private-build-library.c b/level_3/fake/c/private-build-library.c new file mode 100644 index 0000000..e488eff --- /dev/null +++ b/level_3/fake/c/private-build-library.c @@ -0,0 +1,642 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-library.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_build_library_script_ + int fake_build_library_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + + fake_build_touch(main, file_stage, status); + + return 0; + } +#endif // _di_fake_build_library_script_ + +#ifndef _di_fake_build_library_shared_ + int fake_build_library_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + if (!data_build.setting.build_sources_library.used) return 0; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Compiling shared library.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_string_dynamics_t arguments = f_string_dynamics_t_initialize; + + { + const f_string_static_t *path_sources = &main->path_sources; + + if (data_build.setting.path_standard) { + path_sources = &main->path_sources_c; + + if (data_build.setting.build_language == fake_build_language_type_cpp) { + path_sources = &main->path_sources_cpp; + } + } + else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { + path_sources = &data_build.setting.path_sources; + } + + f_array_length_t i = 0; + f_array_length_t j = 0; + f_array_length_t source_length = 0; + + const f_string_dynamics_t *sources[2] = { + &data_build.setting.build_sources_library, + &data_build.setting.build_sources_library_shared, + }; + + for (; i < 2; ++i) { + + for (j = 0; j < sources[i]->used; ++j) { + + if (!sources[i]->array[j].used) continue; + + source_length = path_sources->used + sources[i]->array[j].used; + + char source[source_length + 1]; + + memcpy(source, path_sources->string, path_sources->used); + memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); + source[source_length] = 0; + + *status = fll_execute_arguments_add(source, source_length, &arguments); + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + macro_f_string_dynamics_t_delete_simple(arguments); + return 0; + } + } + + const f_array_length_t parameter_file_name_length = fake_build_parameter_library_name_prefix_s_length + data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_shared_s_length; + const f_array_length_t parameter_file_name_major_length = data_build.setting.version_major.used ? parameter_file_name_length + data_build.setting.version_major_prefix.used + data_build.setting.version_major.used : 0; + const f_array_length_t parameter_file_name_minor_length = data_build.setting.version_minor.used ? parameter_file_name_major_length + data_build.setting.version_minor_prefix.used + data_build.setting.version_minor.used : 0; + const f_array_length_t parameter_file_name_micro_length = data_build.setting.version_micro.used ? parameter_file_name_minor_length + data_build.setting.version_micro_prefix.used + data_build.setting.version_micro.used : 0; + const f_array_length_t parameter_file_name_nano_length = data_build.setting.version_nano.used ? parameter_file_name_micro_length + data_build.setting.version_nano_prefix.used + data_build.setting.version_nano.used : 0; + + char parameter_file_name[parameter_file_name_length + 1]; + char parameter_file_name_major[parameter_file_name_major_length + 1]; + char parameter_file_name_minor[parameter_file_name_minor_length + 1]; + char parameter_file_name_micro[parameter_file_name_micro_length + 1]; + char parameter_file_name_nano[parameter_file_name_nano_length + 1]; + + parameter_file_name[parameter_file_name_length] = 0; + parameter_file_name_major[parameter_file_name_major_length] = 0; + parameter_file_name_minor[parameter_file_name_minor_length] = 0; + parameter_file_name_micro[parameter_file_name_micro_length] = 0; + parameter_file_name_nano[parameter_file_name_nano_length] = 0; + + memcpy(parameter_file_name, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + + if (parameter_file_name_major_length) { + memcpy(parameter_file_name_major, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + + if (parameter_file_name_minor_length) { + memcpy(parameter_file_name_minor, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + } + } + } + } + + f_array_length_t count = fake_build_parameter_library_name_prefix_s_length; + + memcpy(parameter_file_name + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + + if (parameter_file_name_major_length) { + memcpy(parameter_file_name_major + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + + if (parameter_file_name_minor_length) { + memcpy(parameter_file_name_minor + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + } + } + } + } + + count += data_build.setting.project_name.used; + + memcpy(parameter_file_name + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + + if (parameter_file_name_major_length) { + memcpy(parameter_file_name_major + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + + if (parameter_file_name_minor_length) { + memcpy(parameter_file_name_minor + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + } + } + } + } + + if (parameter_file_name_major_length) { + count += fake_build_parameter_library_name_suffix_shared_s_length; + + if (data_build.setting.version_major_prefix.used) { + memcpy(parameter_file_name_major + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); + + if (parameter_file_name_minor_length) { + memcpy(parameter_file_name_minor + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); + } + } + } + + count += data_build.setting.version_major_prefix.used; + } + + memcpy(parameter_file_name_major + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + + if (parameter_file_name_minor_length) { + memcpy(parameter_file_name_minor + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + } + } + } + + if (parameter_file_name_minor_length) { + count += data_build.setting.version_major.used; + + if (data_build.setting.version_minor_prefix.used) { + memcpy(parameter_file_name_minor + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); + } + } + + count += data_build.setting.version_minor_prefix.used; + } + + memcpy(parameter_file_name_minor + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); + + if (parameter_file_name_micro_length) { + memcpy(parameter_file_name_micro + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); + } + } + + if (parameter_file_name_micro_length) { + count += data_build.setting.version_minor.used; + + if (data_build.setting.version_micro_prefix.used) { + memcpy(parameter_file_name_micro + count, data_build.setting.version_micro_prefix.string, data_build.setting.version_micro_prefix.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_micro_prefix.string, data_build.setting.version_micro_prefix.used); + } + + count += data_build.setting.version_micro_prefix.used; + } + + memcpy(parameter_file_name_micro + count, data_build.setting.version_micro.string, data_build.setting.version_micro.used); + + if (parameter_file_name_nano_length) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_micro.string, data_build.setting.version_micro.used); + + count += data_build.setting.version_micro.used; + + if (data_build.setting.version_nano_prefix.used) { + memcpy(parameter_file_name_nano + count, data_build.setting.version_nano_prefix.string, data_build.setting.version_nano_prefix.used); + count += data_build.setting.version_nano_prefix.used; + } + + memcpy(parameter_file_name_nano + count, data_build.setting.version_nano.string, data_build.setting.version_nano.used); + } + } + } + } + + { + f_array_length_t parameter_linker_length = fake_build_parameter_library_shared_prefix_s_length; + f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used; + + if (data_build.setting.version_file == fake_build_version_type_major) { + parameter_file_path_length += parameter_file_name_major_length; + } + else if (data_build.setting.version_file == fake_build_version_type_minor) { + parameter_file_path_length += parameter_file_name_minor_length; + } + else if (data_build.setting.version_file == fake_build_version_type_micro) { + parameter_file_path_length += parameter_file_name_micro_length; + } + else if (data_build.setting.version_file == fake_build_version_type_nano) { + parameter_file_path_length += parameter_file_name_nano_length; + } + + if (data_build.setting.version_target == fake_build_version_type_major) { + parameter_linker_length += parameter_file_name_major_length; + } + else if (data_build.setting.version_target == fake_build_version_type_minor) { + parameter_linker_length += parameter_file_name_minor_length; + } + else if (data_build.setting.version_target == fake_build_version_type_micro) { + parameter_linker_length += parameter_file_name_micro_length; + } + else if (data_build.setting.version_target == fake_build_version_type_nano) { + parameter_linker_length += parameter_file_name_nano_length; + } + + char parameter_linker[parameter_linker_length + 1]; + char parameter_file_path[parameter_file_path_length + 1]; + + memcpy(parameter_linker, fake_build_parameter_library_shared_prefix_s, fake_build_parameter_library_shared_prefix_s_length); + memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); + + if (data_build.setting.version_file == fake_build_version_type_major) { + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_major, parameter_file_name_major_length); + } + else if (data_build.setting.version_file == fake_build_version_type_minor) { + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_minor, parameter_file_name_minor_length); + } + else if (data_build.setting.version_file == fake_build_version_type_micro) { + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_micro, parameter_file_name_micro_length); + } + else if (data_build.setting.version_file == fake_build_version_type_nano) { + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_nano, parameter_file_name_nano_length); + } + + if (data_build.setting.version_target == fake_build_version_type_major) { + memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_major, parameter_file_name_major_length); + } + else if (data_build.setting.version_target == fake_build_version_type_minor) { + memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_minor, parameter_file_name_minor_length); + } + else if (data_build.setting.version_target == fake_build_version_type_micro) { + memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_micro, parameter_file_name_micro_length); + } + else if (data_build.setting.version_target == fake_build_version_type_nano) { + memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_nano, parameter_file_name_nano_length); + } + + parameter_linker[parameter_linker_length] = 0; + parameter_file_path[parameter_file_path_length] = 0; + + const f_string_t values[] = { + fake_build_parameter_library_shared_s, + parameter_linker, + fake_build_parameter_library_output_s, + parameter_file_path, + }; + + const f_array_length_t lengths[] = { + fake_build_parameter_library_shared_s_length, + parameter_linker_length, + fake_build_parameter_library_output_s_length, + parameter_file_path_length, + }; + + for (uint8_t i = 0; i < 4; ++i) { + + if (!lengths[i]) continue; + + *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); + if (F_status_is_error(*status)) break; + } // for + + fake_build_arguments_standard_add(main, data_build, F_true, F_true, &arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + macro_f_string_dynamics_t_delete_simple(arguments); + + return 0; + } + } + + { + const int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); + + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error(*status)) return 0; + if (*status == F_child) return result; + } + + if (parameter_file_name_major_length) { + f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_length; + + char parameter_file_path[parameter_file_path_length + 1]; + + memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name, parameter_file_name_length); + + parameter_file_path[parameter_file_path_length] = 0; + + *status = f_file_link(parameter_file_name_major, parameter_file_path); + + if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_major, f_string_eol_s[0]); + } + else if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found) { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); + + return 0; + } + + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_major, "link", fll_error_file_type_file); + + return 0; + } + } + + if (data_build.setting.version_file != fake_build_version_type_major && parameter_file_name_major_length) { + + f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_major_length; + + char parameter_file_path[parameter_file_path_length + 1]; + + memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_major, parameter_file_name_major_length); + + parameter_file_path[parameter_file_path_length] = 0; + + *status = f_file_link(parameter_file_name_minor, parameter_file_path); + + if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_minor, f_string_eol_s[0]); + } + else if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found) { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); + + return 0; + } + + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_minor, "link", fll_error_file_type_file); + + return 0; + } + + if (data_build.setting.version_file != fake_build_version_type_minor && parameter_file_name_minor_length) { + + f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_minor_length; + + char parameter_file_path[parameter_file_path_length + 1]; + + memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_minor, parameter_file_name_minor_length); + + parameter_file_path[parameter_file_path_length] = 0; + + *status = f_file_link(parameter_file_name_micro, parameter_file_path); + + if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_micro, f_string_eol_s[0]); + } + else if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found) { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); + + return 0; + } + + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_micro, "link", fll_error_file_type_file); + + return 0; + } + + if (data_build.setting.version_file != fake_build_version_type_micro && parameter_file_name_micro_length) { + + f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_micro_length; + + char parameter_file_path[parameter_file_path_length + 1]; + + memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); + memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_micro, parameter_file_name_micro_length); + + parameter_file_path[parameter_file_path_length] = 0; + + *status = f_file_link(parameter_file_name_nano, parameter_file_path); + + if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_nano, f_string_eol_s[0]); + } + else if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found) { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); + + return 0; + } + + fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_nano, "link", fll_error_file_type_file); + + return 0; + } + } + } + } + + fake_build_touch(main, file_stage, status); + + return 0; + } +#endif // _di_fake_build_library_shared_ + +#ifndef _di_fake_build_library_static_ + int fake_build_library_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + if (!data_build.setting.build_sources_library.used) return 0; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Compiling static library.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_string_dynamic_t file_name = f_string_dynamic_t_initialize; + f_string_dynamic_t source_path = f_string_dynamic_t_initialize; + f_string_dynamics_t arguments = f_string_dynamics_t_initialize; + + f_array_length_t i = 0; + + for (; i < data_build.setting.build_indexer_arguments.used; ++i) { + + if (!data_build.setting.build_indexer_arguments.array[i].used) continue; + + *status = fll_execute_arguments_add(data_build.setting.build_indexer_arguments.array[i].string, data_build.setting.build_indexer_arguments.array[i].used, &arguments); + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_error_not(*status)) { + f_array_length_t destination_length = main->path_build_libraries_static.used + fake_build_parameter_library_name_prefix_s_length; + destination_length += data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_static_s_length; + + char destination[destination_length + 1]; + + destination_length = 0; + + memcpy(destination, main->path_build_libraries_static.string, main->path_build_libraries_static.used); + destination_length += main->path_build_libraries_static.used; + + memcpy(destination + destination_length, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + destination_length += fake_build_parameter_library_name_prefix_s_length; + + memcpy(destination + destination_length, data_build.setting.project_name.string, data_build.setting.project_name.used); + destination_length += data_build.setting.project_name.used; + + memcpy(destination + destination_length, fake_build_parameter_library_name_suffix_static_s, fake_build_parameter_library_name_suffix_static_s_length); + destination_length += fake_build_parameter_library_name_suffix_static_s_length; + + destination[destination_length] = 0; + + *status = fll_execute_arguments_add(destination, destination_length, &arguments); + } + + if (F_status_is_error_not(*status)) { + f_array_length_t source_length = 0; + f_array_length_t j = 0; + + const f_string_dynamics_t *sources[2] = { + &data_build.setting.build_sources_library, + &data_build.setting.build_sources_library_static, + }; + + for (i = 0; i < 2; ++i) { + + for (j = 0; j < sources[i]->used; ++j) { + + source_path.used = 0; + + *status = fake_build_get_file_name_without_extension(main, sources[i]->array[j], &file_name); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fake_build_get_file_name_without_extension", F_true); + + break; + } + + *status = f_file_name_directory(sources[i]->array[j].string, sources[i]->array[j].used, &source_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_directory", F_true); + + break; + } + + if (source_path.used) { + *status = f_string_dynamic_prepend(main->path_build_objects, &source_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_prepend", F_true); + + break; + } + + *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, &source_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); + + break; + } + + *status = f_string_dynamic_terminate_after(&source_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + + break; + } + + source_length = source_path.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; + } + else { + source_length = main->path_build_objects.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; + } + + char source[source_length + 1]; + + if (source_path.used) { + memcpy(source, source_path.string, source_path.used); + memcpy(source + source_path.used, file_name.string, file_name.used); + memcpy(source + source_path.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); + } + else { + memcpy(source, main->path_build_objects.string, main->path_build_objects.used); + memcpy(source + main->path_build_objects.used, file_name.string, file_name.used); + memcpy(source + main->path_build_objects.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); + } + + source[source_length] = 0; + + *status = fll_execute_arguments_add(source, source_length, &arguments); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + break; + } + } // for + } // for + } + + int result = main->child; + + if (F_status_is_error_not(*status)) { + result = fake_execute(main, data_build.environment, data_build.setting.build_indexer, arguments, status); + } + + macro_f_string_dynamic_t_delete_simple(file_name); + macro_f_string_dynamic_t_delete_simple(source_path); + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error_not(*status) && *status != F_child) { + fake_build_touch(main, file_stage, status); + } + + return result; + } +#endif // _di_fake_build_library_static_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-build-library.h b/level_3/fake/c/private-build-library.h new file mode 100644 index 0000000..8e7a093 --- /dev/null +++ b/level_3/fake/c/private-build-library.h @@ -0,0 +1,91 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_build_library_h +#define _PRIVATE_build_library_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Build the script libraries. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_library_script_ + extern int fake_build_library_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_library_script_ + +/** + * Build the shared libraries. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_library_shared_ + extern int fake_build_library_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_library_shared_ + +/** + * Build the static libraries. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_library_static_ + extern int fake_build_library_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_library_static_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_build_library_h diff --git a/level_3/fake/c/private-build-load.c b/level_3/fake/c/private-build-load.c new file mode 100644 index 0000000..be8c731 --- /dev/null +++ b/level_3/fake/c/private-build-load.c @@ -0,0 +1,1557 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-load.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_build_load_environment_ + void fake_build_load_environment(fake_main_t * const main, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + // Reset the environment. + for (f_array_length_t i = 0; i < environment->used; ++i) { + environment->array[i].name.used = 0; + environment->array[i].value.used = 0; + } // for + + environment->used = 0; + + { + // Add the guaranteed environment variables. + const f_string_t variables_name[] = { + f_path_environment_s, + f_path_present_working_s + }; + + const f_array_length_t variables_length[] = { + F_path_environment_s_length, + F_path_present_working_s_length + }; + + for (uint8_t i = 0; i < 2; ++i) { + + *status = fl_environment_load_name(variables_name[i], variables_length[i], environment); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_environment_load_name", F_true); + break; + } + } // for + + if (F_status_is_error(*status)) { + return; + } + } + + if (environment->used + data_build.setting.environment.used > environment->size) { + if (environment->used + data_build.setting.environment.used > f_environment_max_length) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe values for the setting '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_environment_s, main->error.notable); + fl_print_format("%[' of setting file '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_environment_s, main->error.notable); + fl_print_format("%[' is too large.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + flockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_array_too_large); + + return; + } + } + + *status = fl_environment_load_names(data_build.setting.environment, environment); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_environment_load_names", F_true); + } + } +#endif // _di_fake_build_load_environment_ + +#ifndef _di_fake_build_load_setting_ + void fake_build_load_setting(fake_main_t * const main, const f_string_static_t setting_file, fake_build_setting_t *setting, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + return; + } + + char path_file[main->path_data_build.used + setting_file.used + 1]; + + { + f_string_dynamic_t buffer = f_string_dynamic_t_initialize; + + f_fss_objects_t objects = f_fss_objects_t_initialize; + f_fss_contents_t contents = f_fss_contents_t_initialize; + + if (setting_file.used) { + memcpy(path_file, main->path_data_build.string, main->path_data_build.used); + memcpy(path_file + main->path_data_build.used, setting_file.string, setting_file.used); + + path_file[main->path_data_build.used + setting_file.used] = 0; + + *status = fake_file_buffer(main, path_file, &buffer); + } + else { + *status = fake_file_buffer(main, main->file_data_build_settings.string, &buffer); + } + + if (F_status_is_error_not(*status)) { + f_string_range_t range = macro_f_string_range_t_initialize(buffer.used); + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + + { + f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); + + *status = fll_fss_extended_read(buffer, state, &range, &objects, &contents, 0, 0, &delimits, 0); + } + + if (F_status_is_error(*status)) { + fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_settings.string, range, F_true); + } + else { + *status = fl_fss_apply_delimit(delimits, &buffer); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); + } + else { + fake_build_load_setting_process(main, F_true, setting_file.used ? path_file : main->file_data_build_settings.string, buffer, objects, contents, setting, status); + } + } + + macro_f_fss_delimits_t_delete_simple(delimits); + } + + macro_f_string_dynamic_t_delete_simple(buffer); + macro_f_fss_objects_t_delete_simple(objects); + macro_f_fss_contents_t_delete_simple(contents); + } + + // Error when required settings are not specified. + if (F_status_is_error_not(*status)) { + bool failed = F_false; + + f_string_static_t * const settings[] = { + &setting->project_name, + }; + + f_string_t names[] = { + fake_build_setting_name_project_name_s, + }; + + for (uint8_t i = 0; i < 1; ++i) { + + if (!settings[i]->used) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, names[i], main->error.notable); + fl_print_format("%[' is required but is not specified in the settings file '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting_file.used ? path_file : main->file_data_build_settings.string, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + + failed = F_true; + } + } // for + + if (failed) { + *status = F_status_set_error(F_failure); + + return; + } + } + + fake_build_load_setting_defaults(main, setting, status); + } +#endif // _di_fake_build_load_setting_ + +#ifndef _di_fake_build_load_setting_process_ + void fake_build_load_setting_process(fake_main_t * const main, const bool checks, const f_string_t path_file, const f_string_static_t buffer, const f_fss_objects_t objects, const f_fss_contents_t contents, fake_build_setting_t *setting, f_status_t *status) { + + if (F_status_is_error(*status) && buffer.used) return; + + if (fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + return; + } + + bool error_printed = F_false; + + f_string_dynamics_t build_compiler = f_string_dynamics_t_initialize; + f_string_dynamics_t build_indexer = f_string_dynamics_t_initialize; + f_string_dynamics_t build_language = f_string_dynamics_t_initialize; + f_string_dynamics_t build_script = f_string_dynamics_t_initialize; + f_string_dynamics_t build_shared = f_string_dynamics_t_initialize; + f_string_dynamics_t build_static = f_string_dynamics_t_initialize; + f_string_dynamics_t path_headers = f_string_dynamics_t_initialize; + f_string_dynamics_t path_headers_preserve = f_string_dynamics_t_initialize; + f_string_dynamics_t path_language = f_string_dynamics_t_initialize; + f_string_dynamics_t path_library_script = f_string_dynamics_t_initialize; + f_string_dynamics_t path_library_shared = f_string_dynamics_t_initialize; + f_string_dynamics_t path_library_static = f_string_dynamics_t_initialize; + f_string_dynamics_t path_program_script = f_string_dynamics_t_initialize; + f_string_dynamics_t path_program_shared = f_string_dynamics_t_initialize; + f_string_dynamics_t path_program_static = f_string_dynamics_t_initialize; + f_string_dynamics_t path_sources = f_string_dynamics_t_initialize; + f_string_dynamics_t path_standard = f_string_dynamics_t_initialize; + f_string_dynamics_t process_post = f_string_dynamics_t_initialize; + f_string_dynamics_t process_pre = f_string_dynamics_t_initialize; + f_string_dynamics_t project_name = f_string_dynamics_t_initialize; + f_string_dynamics_t search_exclusive = f_string_dynamics_t_initialize; + f_string_dynamics_t search_shared = f_string_dynamics_t_initialize; + f_string_dynamics_t search_static = f_string_dynamics_t_initialize; + f_string_dynamics_t version_file = f_string_dynamics_t_initialize; + f_string_dynamics_t version_major = f_string_dynamics_t_initialize; + f_string_dynamics_t version_major_prefix = f_string_dynamics_t_initialize; + f_string_dynamics_t version_micro = f_string_dynamics_t_initialize; + f_string_dynamics_t version_micro_prefix = f_string_dynamics_t_initialize; + f_string_dynamics_t version_minor = f_string_dynamics_t_initialize; + f_string_dynamics_t version_minor_prefix = f_string_dynamics_t_initialize; + f_string_dynamics_t version_nano = f_string_dynamics_t_initialize; + f_string_dynamics_t version_nano_prefix = f_string_dynamics_t_initialize; + f_string_dynamics_t version_target = f_string_dynamics_t_initialize; + + const f_string_t settings_name[] = { + fake_build_setting_name_build_compiler_s, + fake_build_setting_name_build_indexer_s, + fake_build_setting_name_build_indexer_arguments_s, + fake_build_setting_name_build_language_s, + fake_build_setting_name_build_libraries_s, + fake_build_setting_name_build_libraries_shared_s, + fake_build_setting_name_build_libraries_static_s, + fake_build_setting_name_build_script_s, + fake_build_setting_name_build_shared_s, + fake_build_setting_name_build_sources_headers_s, + fake_build_setting_name_build_sources_headers_shared_s, + fake_build_setting_name_build_sources_headers_static_s, + fake_build_setting_name_build_sources_library_s, + fake_build_setting_name_build_sources_library_shared_s, + fake_build_setting_name_build_sources_library_static_s, + fake_build_setting_name_build_sources_program_s, + fake_build_setting_name_build_sources_program_shared_s, + fake_build_setting_name_build_sources_program_static_s, + fake_build_setting_name_build_sources_script_s, + fake_build_setting_name_build_sources_settings_s, + fake_build_setting_name_build_static_s, + fake_build_setting_name_defines_s, + fake_build_setting_name_defines_library_s, + fake_build_setting_name_defines_library_shared_s, + fake_build_setting_name_defines_library_static_s, + fake_build_setting_name_defines_program_s, + fake_build_setting_name_defines_program_shared_s, + fake_build_setting_name_defines_program_static_s, + fake_build_setting_name_defines_shared_s, + fake_build_setting_name_defines_static_s, + fake_build_setting_name_environment_s, + fake_build_setting_name_flags_s, + fake_build_setting_name_flags_library_s, + fake_build_setting_name_flags_library_shared_s, + fake_build_setting_name_flags_library_static_s, + fake_build_setting_name_flags_program_s, + fake_build_setting_name_flags_program_shared_s, + fake_build_setting_name_flags_program_static_s, + fake_build_setting_name_flags_shared_s, + fake_build_setting_name_flags_static_s, + fake_build_setting_name_modes_s, + fake_build_setting_name_modes_default_s, + fake_build_setting_name_path_headers_s, + fake_build_setting_name_path_headers_preserve_s, + fake_build_setting_name_path_language_s, + fake_build_setting_name_path_library_script_s, + fake_build_setting_name_path_library_shared_s, + fake_build_setting_name_path_library_static_s, + fake_build_setting_name_path_program_script_s, + fake_build_setting_name_path_program_shared_s, + fake_build_setting_name_path_program_static_s, + fake_build_setting_name_path_sources_s, + fake_build_setting_name_path_standard_s, + fake_build_setting_name_process_post_s, + fake_build_setting_name_process_pre_s, + fake_build_setting_name_project_name_s, + fake_build_setting_name_search_exclusive_s, + fake_build_setting_name_search_shared_s, + fake_build_setting_name_search_static_s, + fake_build_setting_name_version_file_s, + fake_build_setting_name_version_major_s, + fake_build_setting_name_version_major_prefix_s, + fake_build_setting_name_version_micro_s, + fake_build_setting_name_version_micro_prefix_s, + fake_build_setting_name_version_minor_s, + fake_build_setting_name_version_minor_prefix_s, + fake_build_setting_name_version_nano_s, + fake_build_setting_name_version_nano_prefix_s, + fake_build_setting_name_version_target_s, + }; + + const f_array_length_t settings_length[] = { + fake_build_setting_name_build_compiler_s_length, + fake_build_setting_name_build_indexer_s_length, + fake_build_setting_name_build_indexer_arguments_s_length, + fake_build_setting_name_build_language_s_length, + fake_build_setting_name_build_libraries_s_length, + fake_build_setting_name_build_libraries_shared_s_length, + fake_build_setting_name_build_libraries_static_s_length, + fake_build_setting_name_build_script_s_length, + fake_build_setting_name_build_shared_s_length, + fake_build_setting_name_build_sources_headers_s_length, + fake_build_setting_name_build_sources_headers_shared_s_length, + fake_build_setting_name_build_sources_headers_static_s_length, + fake_build_setting_name_build_sources_library_s_length, + fake_build_setting_name_build_sources_library_shared_s_length, + fake_build_setting_name_build_sources_library_static_s_length, + fake_build_setting_name_build_sources_program_s_length, + fake_build_setting_name_build_sources_program_shared_s_length, + fake_build_setting_name_build_sources_program_static_s_length, + fake_build_setting_name_build_sources_script_s_length, + fake_build_setting_name_build_sources_settings_s_length, + fake_build_setting_name_build_static_s_length, + fake_build_setting_name_defines_s_length, + fake_build_setting_name_defines_library_s_length, + fake_build_setting_name_defines_library_shared_s_length, + fake_build_setting_name_defines_library_static_s_length, + fake_build_setting_name_defines_program_s_length, + fake_build_setting_name_defines_program_shared_s_length, + fake_build_setting_name_defines_program_static_s_length, + fake_build_setting_name_defines_shared_s_length, + fake_build_setting_name_defines_static_s_length, + fake_build_setting_name_environment_length_s, + fake_build_setting_name_flags_s_length, + fake_build_setting_name_flags_library_s_length, + fake_build_setting_name_flags_library_shared_s_length, + fake_build_setting_name_flags_library_static_s_length, + fake_build_setting_name_flags_program_s_length, + fake_build_setting_name_flags_program_shared_s_length, + fake_build_setting_name_flags_program_static_s_length, + fake_build_setting_name_flags_shared_s_length, + fake_build_setting_name_flags_static_s_length, + fake_build_setting_name_modes_s_length, + fake_build_setting_name_modes_default_s_length, + fake_build_setting_name_path_headers_s_length, + fake_build_setting_name_path_headers_preserve_s_length, + fake_build_setting_name_path_language_s_length, + fake_build_setting_name_path_library_script_s_length, + fake_build_setting_name_path_library_shared_s_length, + fake_build_setting_name_path_library_static_s_length, + fake_build_setting_name_path_program_script_s_length, + fake_build_setting_name_path_program_shared_s_length, + fake_build_setting_name_path_program_static_s_length, + fake_build_setting_name_path_sources_s_length, + fake_build_setting_name_path_standard_s_length, + fake_build_setting_name_process_post_s_length, + fake_build_setting_name_process_pre_s_length, + fake_build_setting_name_project_name_s_length, + fake_build_setting_name_search_exclusive_s_length, + fake_build_setting_name_search_shared_s_length, + fake_build_setting_name_search_static_s_length, + fake_build_setting_name_version_file_s_length, + fake_build_setting_name_version_major_s_length, + fake_build_setting_name_version_major_prefix_s_length, + fake_build_setting_name_version_micro_s_length, + fake_build_setting_name_version_micro_prefix_s_length, + fake_build_setting_name_version_minor_s_length, + fake_build_setting_name_version_minor_prefix_s_length, + fake_build_setting_name_version_nano_s_length, + fake_build_setting_name_version_nano_prefix_s_length, + fake_build_setting_name_version_target_s_length, + }; + + f_string_dynamics_t *settings_value[] = { + &build_compiler, + &build_indexer, + &setting->build_indexer_arguments, + &build_language, + &setting->build_libraries, + &setting->build_libraries_shared, + &setting->build_libraries_static, + &build_script, + &build_shared, + &setting->build_sources_headers, + &setting->build_sources_headers_shared, + &setting->build_sources_headers_static, + &setting->build_sources_library, + &setting->build_sources_library_shared, + &setting->build_sources_library_static, + &setting->build_sources_program, + &setting->build_sources_program_shared, + &setting->build_sources_program_static, + &setting->build_sources_script, + &setting->build_sources_setting, + &build_static, + &setting->defines, + &setting->defines_library, + &setting->defines_library_shared, + &setting->defines_library_static, + &setting->defines_program, + &setting->defines_program_shared, + &setting->defines_program_static, + &setting->defines_shared, + &setting->defines_static, + &setting->environment, + &setting->flags, + &setting->flags_library, + &setting->flags_library_shared, + &setting->flags_library_static, + &setting->flags_program, + &setting->flags_program_shared, + &setting->flags_program_static, + &setting->flags_shared, + &setting->flags_static, + &setting->modes, + &setting->modes_default, + &path_headers, + &path_headers_preserve, + &path_language, + &path_library_script, + &path_library_shared, + &path_library_static, + &path_program_script, + &path_program_shared, + &path_program_static, + &path_sources, + &path_standard, + &process_post, + &process_pre, + &project_name, + &search_exclusive, + &search_shared, + &search_static, + &version_file, + &version_major, + &version_major_prefix, + &version_micro, + &version_micro_prefix, + &version_minor, + &version_minor_prefix, + &version_nano, + &version_nano_prefix, + &version_target, + }; + + bool settings_matches[] = { + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + F_false, + }; + + f_string_t function = "fll_fss_snatch_apart"; + + *status = fll_fss_snatch_apart(buffer, objects, contents, settings_name, settings_length, fake_build_setting_total_d, settings_value, settings_matches, 0); + + if (*status == F_none) { + const int total_build_libraries = setting->build_libraries.used; + + f_string_dynamic_t settings_mode_name_dynamic[fake_build_setting_total_d]; + f_string_t settings_mode_names[fake_build_setting_total_d]; + f_array_length_t setting_mode_lengths[fake_build_setting_total_d]; + + const f_string_dynamics_t *modes = &setting->modes_default; + bool found = F_false; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + // if any mode is specified, the entire defaults is replaced. + if (main->mode.used) { + modes = &main->mode; + } + + for (; i < modes->used; ++i) { + + found = F_false; + + for (j = 0; j < setting->modes.used; ++j) { + + if (fl_string_dynamic_compare_trim(modes->array[i], setting->modes.array[j]) == F_equal_to) { + found = F_true; + break; + } + } // for + + if (found == F_false) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe specified mode '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, modes->array[i], main->error.notable); + fl_print_format("%[' is not a valid mode, according to '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, path_file, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + error_printed = F_true; + *status = F_status_set_error(F_parameter); + break; + } + + memset(&settings_mode_name_dynamic, 0, sizeof(f_string_dynamic_t) * fake_build_setting_total_d); + memset(&settings_mode_names, 0, sizeof(f_string_t) * fake_build_setting_total_d); + memset(&setting_mode_lengths, 0, sizeof(f_array_length_t) * fake_build_setting_total_d); + + for (j = 0; j < fake_build_setting_total_d; ++j) { + + setting_mode_lengths[j] = settings_length[j] + 1 + modes->array[i].used; + + macro_f_string_dynamic_t_resize(*status, settings_mode_name_dynamic[j], setting_mode_lengths[j]); + + if (F_status_is_error(*status)) { + function = "macro_f_string_dynamic_t_resize"; + + break; + } + + memcpy(settings_mode_name_dynamic[j].string, settings_name[j], settings_length[j]); + memcpy(settings_mode_name_dynamic[j].string + settings_length[j] + 1, modes->array[i].string, modes->array[i].used); + settings_mode_name_dynamic[j].string[settings_length[j]] = '-'; + + settings_mode_names[j] = settings_mode_name_dynamic[j].string; + } // for + + if (*status == F_none) { + *status = fll_fss_snatch_apart(buffer, objects, contents, settings_mode_names, setting_mode_lengths, fake_build_setting_total_d, settings_value, 0, 0); + + if (F_status_is_error(*status)) { + function = "fll_fss_snatch_apart"; + } + } + + for (j = 0; j < fake_build_setting_total_d; ++j) { + macro_f_string_dynamic_t_delete_simple(settings_mode_name_dynamic[j]); + } // for + + if (F_status_is_error(*status)) break; + } // for + + // "build_libraries" is appended after all modes to help assist with static linker file issues (@todo there should likely be more options to have a postfix linker parameter that can be added here instead, such as "build_libraries_last"). + if (total_build_libraries) { + f_string_dynamic_t temporary[total_build_libraries]; + + for (i = 0; i < total_build_libraries; ++i) { + + temporary[i].string = setting->build_libraries.array[i].string; + temporary[i].used = setting->build_libraries.array[i].used; + temporary[i].size = setting->build_libraries.array[i].size; + } // for + + for (i = 0, j = total_build_libraries; j < setting->build_libraries.used; ++i, ++j) { + + setting->build_libraries.array[i].string = setting->build_libraries.array[j].string; + setting->build_libraries.array[i].used = setting->build_libraries.array[j].used; + setting->build_libraries.array[i].size = setting->build_libraries.array[j].size; + } // for + + for (i = setting->build_libraries.used - total_build_libraries, j = 0; j < total_build_libraries; ++i, ++j) { + + setting->build_libraries.array[i].string = temporary[j].string; + setting->build_libraries.array[i].used = temporary[j].used; + setting->build_libraries.array[i].size = temporary[j].size; + } // for + } + } + + if (F_status_is_error(*status)) { + if (*status == F_status_set_error(F_string_too_large)) { + if (main->error.verbosity != f_console_verbosity_quiet) { + funlockfile(main->error.to.stream); + + fl_print_format("%c%[%SA setting in the file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, path_file, main->error.notable); + fl_print_format("%[' is too long.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + } + else if (!error_printed) { + fll_error_print(main->error, F_status_set_fine(*status), function, F_true); + } + } + else { + const f_string_t settings_single_name[] = { + fake_build_setting_name_build_compiler_s, + fake_build_setting_name_build_indexer_s, + fake_build_setting_name_build_language_s, + fake_build_setting_name_build_script_s, + fake_build_setting_name_build_shared_s, + fake_build_setting_name_build_static_s, + fake_build_setting_name_path_headers_s, + fake_build_setting_name_path_headers_preserve_s, + fake_build_setting_name_path_language_s, + fake_build_setting_name_path_library_script_s, + fake_build_setting_name_path_library_shared_s, + fake_build_setting_name_path_library_static_s, + fake_build_setting_name_path_program_script_s, + fake_build_setting_name_path_program_shared_s, + fake_build_setting_name_path_program_static_s, + fake_build_setting_name_path_sources_s, + fake_build_setting_name_path_standard_s, + fake_build_setting_name_process_post_s, + fake_build_setting_name_process_pre_s, + fake_build_setting_name_project_name_s, + fake_build_setting_name_search_exclusive_s, + fake_build_setting_name_search_shared_s, + fake_build_setting_name_search_static_s, + fake_build_setting_name_version_file_s, + fake_build_setting_name_version_major_s, + fake_build_setting_name_version_major_prefix_s, + fake_build_setting_name_version_micro_s, + fake_build_setting_name_version_micro_prefix_s, + fake_build_setting_name_version_minor_s, + fake_build_setting_name_version_minor_prefix_s, + fake_build_setting_name_version_nano_s, + fake_build_setting_name_version_nano_prefix_s, + fake_build_setting_name_version_target_s, + }; + + const f_string_statics_t *settings_single_source[] = { + &build_compiler, + &build_indexer, + &build_language, + &build_script, + &build_shared, + &build_static, + &path_headers, + &path_headers_preserve, + &path_language, + &path_library_script, + &path_library_shared, + &path_library_static, + &path_program_script, + &path_program_shared, + &path_program_static, + &path_sources, + &path_standard, + &process_post, + &process_pre, + &project_name, + &search_exclusive, + &search_shared, + &search_static, + &version_file, + &version_major, + &version_major_prefix, + &version_micro, + &version_micro_prefix, + &version_minor, + &version_minor_prefix, + &version_nano, + &version_nano_prefix, + &version_target, + }; + + bool * const settings_single_bool[] = { + 0, // build_compiler + 0, // build_indexer + 0, // build_language + &setting->build_script, // build_script + &setting->build_shared, // build_shared + &setting->build_static, // build_static + 0, // path_headers + &setting->path_headers_preserve, // path_headers_preserve + 0, // path_language + 0, // path_library_script + 0, // path_library_shared + 0, // path_library_static + 0, // path_program_script + 0, // path_program_shared + 0, // path_program_static + 0, // path_sources + &setting->path_standard, // path_standard + 0, // process_post + 0, // process_pre + 0, // project_name + &setting->search_exclusive, // search_exclusive + &setting->search_shared, // search_shared + &setting->search_static, // search_static + }; + + f_string_dynamic_t * const settings_single_destination[] = { + &setting->build_compiler, // build_compiler + &setting->build_indexer, // build_indexer + 0, // build_language + 0, // build_script + 0, // build_shared + 0, // build_static + &setting->path_headers, // path_headers + 0, // path_headers_preserve + &setting->path_language, // path_language + &setting->path_library_script, // path_library_script + &setting->path_library_shared, // path_library_shared + &setting->path_library_static, // path_library_static + &setting->path_program_script, // path_program_script + &setting->path_program_shared, // path_program_shared + &setting->path_program_static, // path_program_static + &setting->path_sources, // path_sources + 0, // path_standard + &setting->process_post, // process_post + &setting->process_pre, // process_pre + &setting->project_name, // project_name + 0, // search_exclusive + 0, // search_shared + 0, // search_static + 0, // version_file + &setting->version_major, // version_major + &setting->version_major_prefix, // version_major_prefix + &setting->version_micro, // version_micro + &setting->version_micro_prefix, // version_micro_prefix + &setting->version_minor, // version_minor + &setting->version_minor_prefix, // version_minor_prefix + &setting->version_nano, // version_nano + &setting->version_nano_prefix, // version_nano_prefix + }; + + uint8_t * const settings_single_language[] = { + 0, // build_compiler + 0, // build_indexer + &setting->build_language, // build_language + }; + + uint8_t * const settings_single_version[] = { + 0, // build_compiler + 0, // build_indexer + 0, // build_language + 0, // build_script + 0, // build_shared + 0, // build_static + 0, // path_headers + 0, // path_headers_preserve + 0, // path_language + 0, // path_library_script + 0, // path_library_shared + 0, // path_library_static + 0, // path_program_script + 0, // path_program_shared + 0, // path_program_static + 0, // path_sources + 0, // path_standard + 0, // process_post + 0, // process_pre + 0, // project_name + 0, // search_exclusive + 0, // search_shared + 0, // search_static + &setting->version_file, // version_file + 0, // version_major + 0, // version_major_prefix + 0, // version_micro + 0, // version_micro_prefix + 0, // version_minor + 0, // version_minor_prefix + 0, // version_nano + 0, // version_nano_prefix + &setting->version_target, // version_target + }; + + const uint8_t settings_single_version_default[] = { + 0, // build_compiler + 0, // build_indexer + 0, // build_language + 0, // build_script + 0, // build_shared + 0, // build_static + 0, // path_headers + 0, // path_headers_preserve + 0, // path_language + 0, // path_library_script + 0, // path_library_shared + 0, // path_library_static + 0, // path_program_script + 0, // path_program_shared + 0, // path_program_static + 0, // path_sources + 0, // path_standard + 0, // process_post + 0, // process_pre + 0, // project_name + 0, // search_exclusive + 0, // search_shared + 0, // search_static + fake_build_version_type_micro, // version_file + 0, // version_major + 0, // version_major_prefix + 0, // version_micro + 0, // version_micro_prefix + 0, // version_minor + 0, // version_minor_prefix + 0, // version_nano + 0, // version_nano_prefix + fake_build_version_type_major, // version_target + }; + + const char *settings_single_version_default_name[] = { + 0, // build_compiler + 0, // build_indexer + 0, // build_language + 0, // build_script + 0, // build_shared + 0, // build_static + 0, // path_headers + 0, // path_headers_preserve + 0, // path_language + 0, // path_library_script + 0, // path_library_shared + 0, // path_library_static + 0, // path_program_script + 0, // path_program_shared + 0, // path_program_static + 0, // path_sources + 0, // path_standard + 0, // process_post + 0, // process_pre + 0, // project_name + 0, // search_exclusive + 0, // search_shared + 0, // search_static + fake_build_version_micro_s, // version_file + 0, // version_major + 0, // version_major_prefix + 0, // version_micro + 0, // version_micro_prefix + 0, // version_minor + 0, // version_minor_prefix + 0, // version_nano + 0, // version_nano_prefix + fake_build_version_major_s, // version_target + }; + + // 1 = "yes" or "no", 2 = path/, 3 = literal, 4 = "bash", "c", or "c++", 5 = "major", "minor", "micro", or "nano". + const uint8_t settings_single_type[] = { + 3, // build_compiler + 3, // build_indexer + 4, // build_language + 1, // build_script + 1, // build_shared + 1, // build_static + 2, // path_headers + 1, // path_headers_preserve + 2, // path_language + 2, // path_library_script + 2, // path_library_shared + 2, // path_library_static + 2, // path_program_script + 2, // path_program_shared + 2, // path_program_static + 2, // path_sources + 1, // path_standard + 3, // process_post + 3, // process_pre + 3, // project_name + 1, // search_exclusive + 1, // search_shared + 1, // search_static + 5, // version_file + 3, // version_major + 3, // version_major_prefix + 3, // version_micro + 3, // version_micro_prefix + 3, // version_minor + 3, // version_minor_prefix + 3, // version_nano + 3, // version_nano_prefix + 5, // version_target + }; + + for (f_array_length_t i = 0; i < 33; ++i) { + + if (!settings_single_source[i]->used) continue; + + if (settings_single_source[i]->used > 1) { + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' may only have a single property, only using the first: '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, settings_single_source[i]->array[0], main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + + if (settings_single_type[i] == 1) { + if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_common_setting_bool_yes_s, settings_single_source[i]->array[0].used, fake_common_setting_bool_yes_s_length) == F_equal_to) { + *settings_single_bool[i] = F_true; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_common_setting_bool_no_s, settings_single_source[i]->array[0].used, fake_common_setting_bool_no_s_length) == F_equal_to) { + *settings_single_bool[i] = F_false; + } + else { + *settings_single_bool[i] = F_true; + + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' may be either '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_yes_s, main->warning.notable); + fl_print_format("%[' or '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_no_s, main->warning.notable); + fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_yes_s, main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + } + else if (settings_single_type[i] == 4) { + if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_bash_s, settings_single_source[i]->array[0].used, fake_build_language_bash_s_length) == F_equal_to) { + *settings_single_language[i] = fake_build_language_type_bash; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_c_s, settings_single_source[i]->array[0].used, fake_build_language_c_s_length) == F_equal_to) { + *settings_single_language[i] = fake_build_language_type_c; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_cpp_s, settings_single_source[i]->array[0].used, fake_build_language_cpp_s_length) == F_equal_to) { + *settings_single_language[i] = fake_build_language_type_cpp; + } + else { + *settings_single_language[i] = fake_build_language_type_c; + + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' may only be one of '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_bash_s, main->warning.notable); + fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_c_s, main->warning.notable); + fl_print_format("%[', or '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_cpp_s, main->warning.notable); + fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_c_s, main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + } + else if (settings_single_type[i] == 5) { + if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_major_s, settings_single_source[i]->array[0].used, fake_build_version_major_s_length) == F_equal_to) { + *settings_single_version[i] = fake_build_version_type_major; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_minor_s, settings_single_source[i]->array[0].used, fake_build_version_minor_s_length) == F_equal_to) { + *settings_single_version[i] = fake_build_version_type_minor; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_micro_s, settings_single_source[i]->array[0].used, fake_build_version_micro_s_length) == F_equal_to) { + *settings_single_version[i] = fake_build_version_type_micro; + } + else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_nano_s, settings_single_source[i]->array[0].used, fake_build_version_nano_s_length) == F_equal_to) { + *settings_single_version[i] = fake_build_version_type_nano; + } + else { + *settings_single_version[i] = settings_single_version_default[i]; + + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' may only be one of '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_major_s, main->warning.notable); + fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_minor_s, main->warning.notable); + fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_micro_s, main->warning.notable); + fl_print_format("%[', or '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_nano_s, main->warning.notable); + fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, settings_single_version_default_name[i], main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + } + else { + + // Replace any potential existing value. + settings_single_destination[i]->used = 0; + + *status = f_string_dynamic_append_nulless(settings_single_source[i]->array[0], settings_single_destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + + break; + } + + if (settings_single_type[i] == 2) { + *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, settings_single_destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); + + break; + } + } + + *status = f_string_dynamic_terminate_after(settings_single_destination[i]); + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + + break; + } + } + } // for + + if (F_status_is_error_not(*status)) { + if (checks && !setting->version_file) { + setting->version_file = fake_build_version_type_micro; + + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, fake_build_setting_name_version_file_s, main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' is required, defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_micro_s, main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + + if (checks && !setting->version_target) { + setting->version_target = fake_build_version_type_major; + + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, fake_build_setting_name_version_target_s, main->warning.notable); + fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); + fl_print_format("%[' is required, defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_major_s, main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + } + + // Provide these defaults only if the Object is not defined (this allows for empty Content to exist if the Object is defined). + // In the case of the version prefixes, if the associated version is empty, then instead clear the associated version prefix. + if (F_status_is_error_not(*status)) { + f_string_dynamic_t *prefix[] = { + &setting->version_major_prefix, + &setting->version_minor_prefix, + &setting->version_micro_prefix, + &setting->version_nano_prefix, + }; + + f_string_dynamic_t *version[] = { + &setting->version_major, + &setting->version_minor, + &setting->version_micro, + &setting->version_nano, + }; + + bool has_prefix_object[] = { + settings_matches[61], // version_major_prefix + settings_matches[63], // version_minor_prefix + settings_matches[65], // version_micro_prefix + settings_matches[67], // version_nano_prefix + }; + + const char *name_target[] = { + fake_build_version_major_s, + fake_build_version_minor_s, + fake_build_version_micro_s, + fake_build_version_nano_s, + }; + + const char *name_object[] = { + fake_build_setting_name_version_major_s, + fake_build_setting_name_version_minor_s, + fake_build_setting_name_version_micro_s, + fake_build_setting_name_version_nano_s, + }; + + const char *setting_name[] = { + fake_build_setting_name_version_file_s, + fake_build_setting_name_version_target_s, + }; + + const uint8_t setting_target[] = { + setting->version_file, + setting->version_target, + }; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < 4; ++i) { + + if (version[i]->used) { + if (!has_prefix_object[i]) { + prefix[i]->used = 0; + + *status = f_string_append(fake_build_setting_default_version_prefix_s, fake_build_setting_default_version_prefix_s_length, prefix[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + break; + } + } + } + else if (checks) { + prefix[i]->used = 0; + + for (j = 0; j < 2; ++j) { + + if (setting_target[j] && i + 1 <= setting_target[j]) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SWhen the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting_name[j], main->error.notable); + fl_print_format("%[' is set to '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, name_target[setting_target[j] - 1], main->error.notable); + fl_print_format("%[' then the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, name_object[i], main->error.notable); + fl_print_format("%[' Object must have Content.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_failure); + break; + } + } // for + + if (F_status_is_error(*status)) break; + } + } // for + } + } + + macro_f_string_dynamics_t_delete_simple(build_compiler); + macro_f_string_dynamics_t_delete_simple(build_indexer); + macro_f_string_dynamics_t_delete_simple(build_language); + macro_f_string_dynamics_t_delete_simple(build_script); + macro_f_string_dynamics_t_delete_simple(build_shared); + macro_f_string_dynamics_t_delete_simple(build_static); + macro_f_string_dynamics_t_delete_simple(path_headers); + macro_f_string_dynamics_t_delete_simple(path_headers_preserve); + macro_f_string_dynamics_t_delete_simple(path_language); + macro_f_string_dynamics_t_delete_simple(path_library_script); + macro_f_string_dynamics_t_delete_simple(path_library_shared); + macro_f_string_dynamics_t_delete_simple(path_library_static); + macro_f_string_dynamics_t_delete_simple(path_program_script); + macro_f_string_dynamics_t_delete_simple(path_program_shared); + macro_f_string_dynamics_t_delete_simple(path_program_static); + macro_f_string_dynamics_t_delete_simple(path_sources); + macro_f_string_dynamics_t_delete_simple(path_standard); + macro_f_string_dynamics_t_delete_simple(process_post); + macro_f_string_dynamics_t_delete_simple(process_pre); + macro_f_string_dynamics_t_delete_simple(project_name); + macro_f_string_dynamics_t_delete_simple(search_exclusive); + macro_f_string_dynamics_t_delete_simple(search_shared); + macro_f_string_dynamics_t_delete_simple(search_static); + macro_f_string_dynamics_t_delete_simple(version_file); + macro_f_string_dynamics_t_delete_simple(version_major); + macro_f_string_dynamics_t_delete_simple(version_major_prefix); + macro_f_string_dynamics_t_delete_simple(version_micro); + macro_f_string_dynamics_t_delete_simple(version_micro_prefix); + macro_f_string_dynamics_t_delete_simple(version_minor); + macro_f_string_dynamics_t_delete_simple(version_minor_prefix); + macro_f_string_dynamics_t_delete_simple(version_nano); + macro_f_string_dynamics_t_delete_simple(version_nano_prefix); + macro_f_string_dynamics_t_delete_simple(version_target); + } +#endif // _di_fake_build_load_setting_process_ + +#ifndef _di_fake_build_load_setting_defaults_ + void fake_build_load_setting_defaults(fake_main_t * const main, fake_build_setting_t *setting, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + return; + } + + { + const f_string_t sources[] = { + fake_build_setting_default_version_s, + fake_build_setting_default_version_s, + fake_build_setting_default_version_s, + }; + + const f_array_length_t lengths[] = { + fake_build_setting_default_version_s_length, + fake_build_setting_default_version_s_length, + fake_build_setting_default_version_s_length, + }; + + f_string_dynamic_t * const destinations[] = { + &setting->version_major, + &setting->version_minor, + &setting->version_micro, + }; + + for (uint8_t i = 0; i < 3; ++i) { + + if (destinations[i]->used) continue; + + *status = f_string_append_assure(sources[i], lengths[i], destinations[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); + break; + } + + *status = f_string_dynamic_terminate_after(destinations[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + break; + } + } // for + } + + if (F_status_is_error(*status)) return; + + // Override setting file when any of these are specified in the command line. + if (main->parameters[fake_parameter_shared_disabled].result == f_console_result_found) { + if (main->parameters[fake_parameter_shared_enabled].result == f_console_result_found) { + if (main->parameters[fake_parameter_shared_enabled].location > main->parameters[fake_parameter_shared_disabled].location) { + setting->build_shared = F_true; + setting->search_shared = F_true; + } + else { + setting->build_shared = F_false; + setting->search_shared = F_false; + } + + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe parameters '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_shared_disabled_s, main->error.notable); + fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_shared_enabled_s, main->error.notable); + fl_print_format("%[' contradict, defaulting to '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_shared ? fake_long_shared_enabled_s : fake_long_shared_disabled_s, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + } + else { + setting->build_shared = F_false; + setting->search_shared = F_false; + } + } + else if (main->parameters[fake_parameter_shared_enabled].result == f_console_result_found) { + setting->build_shared = F_true; + setting->search_shared = F_true; + } + + if (main->parameters[fake_parameter_static_disabled].result == f_console_result_found) { + if (main->parameters[fake_parameter_static_enabled].result == f_console_result_found) { + if (main->parameters[fake_parameter_static_enabled].location > main->parameters[fake_parameter_static_disabled].location) { + setting->build_static = F_true; + setting->search_static = F_true; + } + else { + setting->build_static = F_false; + setting->search_static = F_false; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe parameters '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_static_disabled_s, main->error.notable); + fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_static_enabled_s, main->error.notable); + fl_print_format("%[' contradict, defaulting to '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_static ? fake_long_static_enabled_s : fake_long_static_disabled_s, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + } + else { + setting->build_static = F_false; + setting->search_static = F_false; + } + } + else if (main->parameters[fake_parameter_static_enabled].result == f_console_result_found) { + setting->build_static = F_true; + setting->search_static = F_true; + } + + if (setting->build_language == fake_build_language_type_c || setting->build_language == fake_build_language_type_cpp) { + if (setting->build_shared == F_false && setting->build_static == F_false) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe build settings '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_build_shared_s, main->error.notable); + fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_build_static_s, main->error.notable); + fl_print_format("%[' cannot both be false when using the language '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_language == fake_build_language_type_c ? fake_build_language_c_s : fake_build_language_cpp_s, main->error.notable); + fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } +#endif // _di_fake_build_load_setting_defaults_ + +#ifndef _di_fake_build_load_stage_ + void fake_build_load_stage(fake_main_t * const main, const f_string_static_t settings_file, fake_build_stage_t *stage, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + return; + } + + const f_string_t names[] = { + fake_build_stage_libraries_script_s, + fake_build_stage_libraries_shared_s, + fake_build_stage_libraries_static_s, + fake_build_stage_objects_static_s, + fake_build_stage_process_post_s, + fake_build_stage_process_pre_s, + fake_build_stage_programs_script_s, + fake_build_stage_programs_shared_s, + fake_build_stage_programs_static_s, + fake_build_stage_skeleton_s, + fake_build_stage_sources_headers_s, + fake_build_stage_sources_script_s, + fake_build_stage_sources_settings_s, + }; + + const f_array_length_t lengths[] = { + fake_build_stage_libraries_script_s_length, + fake_build_stage_libraries_shared_s_length, + fake_build_stage_libraries_static_s_length, + fake_build_stage_objects_static_s_length, + fake_build_stage_process_post_s_length, + fake_build_stage_process_pre_s_length, + fake_build_stage_programs_script_s_length, + fake_build_stage_programs_shared_s_length, + fake_build_stage_programs_static_s_length, + fake_build_stage_skeleton_s_length, + fake_build_stage_sources_headers_s_length, + fake_build_stage_sources_script_s_length, + fake_build_stage_sources_settings_s_length, + }; + + f_string_dynamic_t * const values[] = { + &stage->file_libraries_script, + &stage->file_libraries_shared, + &stage->file_libraries_static, + &stage->file_objects_static, + &stage->file_process_post, + &stage->file_process_pre, + &stage->file_programs_script, + &stage->file_programs_shared, + &stage->file_programs_static, + &stage->file_skeleton, + &stage->file_sources_headers, + &stage->file_sources_script, + &stage->file_sources_settings, + }; + + *status = F_none; + + f_string_dynamic_t settings_file_base = f_string_dynamic_t_initialize; + + if (settings_file.used) { + *status = f_file_name_base(settings_file.string, settings_file.used, &settings_file_base); + } + else { + *status = f_file_name_base(main->file_data_build_settings.string, main->file_data_build_settings.used, &settings_file_base); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_base", F_true); + + return; + } + + for (uint8_t i = 0; i < fake_build_stage_total_d; ++i) { + + *status = f_string_dynamic_append_nulless(main->path_build_stage, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + + break; + } + + if (main->process.used) { + *status = f_string_append(main->process.string, main->process.used, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + + *status = f_string_append(fake_build_stage_separate_s, fake_build_stage_separate_s_length, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + } + + *status = f_string_append_nulless(names[i], lengths[i], values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + + break; + } + + *status = f_string_append(fake_build_stage_separate_s, fake_build_stage_separate_s_length, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + + *status = f_string_dynamic_append(settings_file_base, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + break; + } + + *status = f_string_append(fake_build_stage_built_s, fake_build_stage_built_s_length, values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + + *status = f_string_dynamic_terminate_after(values[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + + break; + } + } // for + + macro_f_string_dynamic_t_delete_simple(settings_file_base); + } +#endif // _di_fake_build_load_stage_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-build-load.h b/level_3/fake/c/private-build-load.h new file mode 100644 index 0000000..35bfcf9 --- /dev/null +++ b/level_3/fake/c/private-build-load.h @@ -0,0 +1,139 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_build_load_h +#define _PRIVATE_build_load_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Find the build setting file, load it, validate it, and process it. + * + * @param main + * The main program data. + * @param setting_file + * The name of the settings file to use. + * If setting_file.used is 0, then the default or program parameter supplied file is used. + * @param setting + * All build related setting data from the build setting file are loaded into this. + * These setting will have any specified mode property applied. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_load_setting_ + extern void fake_build_load_setting(fake_main_t * const main, const f_string_static_t setting_file, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_load_setting_ + +/** + * Assign build setting defaults. + * + * @param main + * The main program data. + * @param path_file + * The path to the buffer. + * @param buffer + * The loaded file data. + * @param setting + * All build related setting data from the build setting file are loaded into this. + * These setting will have any specified mode property applied. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_load_setting_defaults_ + extern void fake_build_load_setting_defaults(fake_main_t * const main, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_load_setting_defaults_ + +/** + * Load and process the setting buffer. + * + * @param main + * The main program data. + * @param checks + * If TRUE, perform certain "required" sanity checks. + * If FALSE, do not perform certain "required" sanity checks (intended for a fakefile rather than a build settings file). + * @param path_file + * The path to the buffer. + * @param buffer + * The loaded file data. + * @param objects + * The object mapping. + * @param contents + * The content mapping. + * @param setting + * All build related setting data from the build setting file are loaded into this. + * These setting will have any specified mode property applied. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_load_setting_process_ + extern void fake_build_load_setting_process(fake_main_t * const main, const bool checks, const f_string_t path_file, const f_string_static_t buffer, const f_fss_objects_t objects, const f_fss_contents_t contents, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_load_setting_process_ + +/** + * Load the environment used when executing commands. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param environment + * The environment data. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_load_environment_ + extern void fake_build_load_environment(fake_main_t * const main, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_load_environment_ + +/** + * Load the stage file paths. + * + * @param main + * The main program data. + * @param settings_file + * The path to the settings file. + * @param stage + * All stage file paths. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_load_stage_ + extern void fake_build_load_stage(fake_main_t * const main, const f_string_static_t settings_file, fake_build_stage_t *stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_load_stage_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_build_load_h diff --git a/level_3/fake/c/private-build-objects.c b/level_3/fake/c/private-build-objects.c new file mode 100644 index 0000000..9e643eb --- /dev/null +++ b/level_3/fake/c/private-build-objects.c @@ -0,0 +1,232 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-objects.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_build_objects_static_ + int fake_build_objects_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + if (!data_build.setting.build_sources_library.used) return 0; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Compiling static objects.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_string_dynamic_t file_name = f_string_dynamic_t_initialize; + f_string_dynamic_t destination_path = f_string_dynamic_t_initialize; + f_string_dynamics_t arguments = f_string_dynamics_t_initialize; + f_array_length_t source_length = 0; + f_array_length_t destination_length = 0; + + const f_string_static_t *path_sources = &main->path_sources; + + int result = main->child; + + if (data_build.setting.path_standard) { + path_sources = &main->path_sources_c; + + if (data_build.setting.build_language == fake_build_language_type_cpp) { + path_sources = &main->path_sources_cpp; + } + } + else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { + path_sources = &data_build.setting.path_sources; + } + + const f_string_dynamics_t *sources[2] = { + &data_build.setting.build_sources_library, + &data_build.setting.build_sources_library_static, + }; + + f_array_length_t i = 0; + f_array_length_t j = 0; + uint8_t k = 0; + + for (i = 0; i < 2; ++i) { + + for (j = 0; j < sources[i]->used; ++j) { + + file_name.used = 0; + destination_path.used = 0; + + source_length = path_sources->used + sources[i]->array[j].used; + + char source[source_length + 1]; + + memcpy(source, path_sources->string, path_sources->used); + memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); + source[source_length] = 0; + + *status = fake_build_get_file_name_without_extension(main, sources[i]->array[j], &file_name); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fake_build_get_file_name_without_extension", F_true); + + break; + } + + *status = f_file_name_directory(sources[i]->array[j].string, sources[i]->array[j].used, &destination_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_directory", F_true); + + break; + } + + if (destination_path.used) { + *status = f_string_dynamic_prepend(main->path_build_objects, &destination_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_prepend", F_true); + + break; + } + + *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, &destination_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); + break; + } + + *status = f_string_dynamic_terminate_after(&destination_path); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + + break; + } + + *status = f_directory_exists(destination_path.string); + + if (*status == F_false) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe path '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, destination_path, main->error.notable); + fl_print_format("%[' exists but is not a directory.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_failure); + + break; + } + else if (*status == F_file_found_not) { + *status = f_directory_create(destination_path.string, mode.directory); + + if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found_not) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe path '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, destination_path, main->error.notable); + fl_print_format("%[' could not be created, a parent directory does not exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + else { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_create", F_true, destination_path.string, "create", fll_error_file_type_directory); + } + + break; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Directory '%Q' created.%c", main->output.to.stream, destination_path, f_string_eol_s[0]); + } + } + else if (F_status_is_error(*status)) { + fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_exists", F_true, destination_path.string, "create", fll_error_file_type_directory); + + break; + } + + destination_length = destination_path.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; + } + else { + destination_length = main->path_build_objects.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; + } + + char destination[destination_length + 1]; + + if (destination_path.used) { + memcpy(destination, destination_path.string, destination_path.used); + memcpy(destination + destination_path.used, file_name.string, file_name.used); + memcpy(destination + destination_path.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); + } + else { + memcpy(destination, main->path_build_objects.string, main->path_build_objects.used); + memcpy(destination + main->path_build_objects.used, file_name.string, file_name.used); + memcpy(destination + main->path_build_objects.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); + } + + destination[destination_length] = 0; + + const f_string_t values[] = { + source, + fake_build_parameter_object_compile_s, + fake_build_parameter_object_static_s, + fake_build_parameter_object_output_s, + destination, + }; + + const f_array_length_t lengths[] = { + source_length, + fake_build_parameter_object_compile_s_length, + fake_build_parameter_object_static_s_length, + fake_build_parameter_object_output_s_length, + destination_length, + }; + + for (uint8_t k = 0; k < 5; ++k) { + + if (!lengths[k]) continue; + + *status = fll_execute_arguments_add(values[k], lengths[k], &arguments); + if (F_status_is_error(*status)) break; + } // for + + fake_build_arguments_standard_add(main, data_build, F_false, F_true, &arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + break; + } + + result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); + + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error(*status) || *status == F_child) break; + } // for + + if (F_status_is_error(*status) || *status == F_child) break; + } // for + + macro_f_string_dynamic_t_delete_simple(file_name); + macro_f_string_dynamic_t_delete_simple(destination_path); + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error_not(*status) && *status != F_child) { + fake_build_touch(main, file_stage, status); + } + + return result; + } +#endif // _di_fake_build_objects_static_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-build-objects.h b/level_3/fake/c/private-build-objects.h new file mode 100644 index 0000000..4857b11 --- /dev/null +++ b/level_3/fake/c/private-build-objects.h @@ -0,0 +1,43 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_build_objects_h +#define _PRIVATE_build_objects_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Build the static objects. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_objects_static_ + extern int fake_build_objects_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_objects_static_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_build_objects_h diff --git a/level_3/fake/c/private-build-program.c b/level_3/fake/c/private-build-program.c new file mode 100644 index 0000000..aea1158 --- /dev/null +++ b/level_3/fake/c/private-build-program.c @@ -0,0 +1,278 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-program.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_build_program_script_ + int fake_build_program_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + + fake_build_touch(main, file_stage, status); + + return 0; + } +#endif // _di_fake_build_program_script_ + +#ifndef _di_fake_build_program_shared_ + int fake_build_program_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + if (!data_build.setting.build_sources_program.used) return 0; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Compiling shared program.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_string_dynamics_t arguments = f_string_dynamics_t_initialize; + + { + const f_string_static_t *path_sources = &main->path_sources; + + if (data_build.setting.path_standard) { + path_sources = &main->path_sources_c; + + if (data_build.setting.build_language == fake_build_language_type_cpp) { + path_sources = &main->path_sources_cpp; + } + } + else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { + path_sources = &data_build.setting.path_sources; + } + + f_array_length_t source_length = 0; + + const f_string_dynamics_t *sources[2] = { + &data_build.setting.build_sources_program, + &data_build.setting.build_sources_program_shared, + }; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < 2; ++i) { + + for (j = 0; j < sources[i]->used; ++j) { + + source_length = path_sources->used + sources[i]->array[j].used; + + char source[source_length + 1]; + + memcpy(source, path_sources->string, path_sources->used); + memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); + source[source_length] = 0; + + *status = fll_execute_arguments_add(source, source_length, &arguments); + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_error(*status)) break; + } // for + } + + if (F_status_is_error_not(*status)) { + f_array_length_t parameter_file_name_path_length = main->path_build_programs_shared.used + data_build.setting.project_name.used; + + char parameter_file_name_path[parameter_file_name_path_length + 1]; + + memcpy(parameter_file_name_path, main->path_build_programs_shared.string, main->path_build_programs_shared.used); + memcpy(parameter_file_name_path + main->path_build_programs_shared.used, data_build.setting.project_name.string, data_build.setting.project_name.used); + parameter_file_name_path[parameter_file_name_path_length] = 0; + + const f_string_t values[] = { + fake_build_parameter_library_output_s, + parameter_file_name_path, + }; + + const f_array_length_t lengths[] = { + fake_build_parameter_library_output_s_length, + parameter_file_name_path_length, + }; + + for (uint8_t i = 0; i < 2; ++i) { + + if (!lengths[i]) continue; + + *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); + if (F_status_is_error(*status)) break; + } // for + } + + // if project-specific library sources exist, then the -lproject_name needs to be added to the arguments. + if (F_status_is_error_not(*status) && data_build.setting.build_sources_library.used) { + f_array_length_t link_project_library_length = fake_build_parameter_library_link_file_s_length + data_build.setting.project_name.used; + + char link_project_library[link_project_library_length + 1]; + + memcpy(link_project_library, fake_build_parameter_library_link_file_s, fake_build_parameter_library_link_file_s_length); + memcpy(link_project_library + fake_build_parameter_library_link_file_s_length, data_build.setting.project_name.string, data_build.setting.project_name.used); + link_project_library[link_project_library_length] = 0; + + *status = fll_execute_arguments_add(link_project_library, link_project_library_length, &arguments); + } + + fake_build_arguments_standard_add(main, data_build, F_true, F_false, &arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + macro_f_string_dynamics_t_delete_simple(arguments); + return 0; + } + + int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); + + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error_not(*status) && *status != F_child) { + fake_build_touch(main, file_stage, status); + } + + return result; + } +#endif // _di_fake_build_program_shared_ + +#ifndef _di_fake_build_program_static_ + int fake_build_program_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; + if (!data_build.setting.build_sources_program.used) return 0; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Compiling static program.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_string_dynamics_t arguments = f_string_dynamics_t_initialize; + + { + const f_string_static_t *path_sources = &main->path_sources; + + if (data_build.setting.path_standard) { + path_sources = &main->path_sources_c; + + if (data_build.setting.build_language == fake_build_language_type_cpp) { + path_sources = &main->path_sources_cpp; + } + } + else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { + path_sources = &data_build.setting.path_sources; + } + + f_array_length_t source_length = 0; + + const f_string_dynamics_t *sources[2] = { + &data_build.setting.build_sources_program, + &data_build.setting.build_sources_program_static, + }; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < 2; ++i) { + + for (j = 0; j < sources[i]->used; ++j) { + + if (!sources[i]->array[j].used) continue; + + source_length = path_sources->used + sources[i]->array[j].used; + + char source[source_length + 1]; + + memcpy(source, path_sources->string, path_sources->used); + memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); + source[source_length] = 0; + + *status = fll_execute_arguments_add(source, source_length, &arguments); + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_error(*status)) break; + } // for + } + + if (F_status_is_error_not(*status)) { + f_array_length_t source_library_length = main->path_build_libraries_static.used + fake_build_parameter_library_name_prefix_s_length + data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_static_s_length; + + char source_library[source_library_length + 1]; + + source_library_length = 0; + + // only include the library if there are sources that would result in it being built. + if (data_build.setting.build_sources_library.used) { + memcpy(source_library, main->path_build_libraries_static.string, main->path_build_libraries_static.used); + source_library_length += main->path_build_libraries_static.used; + + memcpy(source_library + source_library_length, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + source_library_length += fake_build_parameter_library_name_prefix_s_length; + + memcpy(source_library + source_library_length, data_build.setting.project_name.string, data_build.setting.project_name.used); + source_library_length += data_build.setting.project_name.used; + + memcpy(source_library + source_library_length, fake_build_parameter_library_name_suffix_static_s, fake_build_parameter_library_name_suffix_static_s_length); + source_library_length += fake_build_parameter_library_name_suffix_static_s_length; + } + + source_library[source_library_length] = 0; + + f_array_length_t parameter_file_name_path_length = main->path_build_programs_static.used + data_build.setting.project_name.used; + + char parameter_file_name_path[parameter_file_name_path_length + 1]; + + memcpy(parameter_file_name_path, main->path_build_programs_static.string, main->path_build_programs_static.used); + memcpy(parameter_file_name_path + main->path_build_programs_static.used, data_build.setting.project_name.string, data_build.setting.project_name.used); + parameter_file_name_path[parameter_file_name_path_length] = 0; + + const f_string_t values[] = { + source_library, + fake_build_parameter_library_static_s, + fake_build_parameter_library_output_s, + parameter_file_name_path, + }; + + const f_array_length_t lengths[] = { + source_library_length, + fake_build_parameter_library_static_s_length, + fake_build_parameter_library_output_s_length, + parameter_file_name_path_length, + }; + + for (uint8_t i = 0; i < 4; ++i) { + + if (!lengths[i]) continue; + + *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); + if (F_status_is_error(*status)) break; + } // for + } + + fake_build_arguments_standard_add(main, data_build, F_false, F_false, &arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + + macro_f_string_dynamics_t_delete_simple(arguments); + return 0; + } + + int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); + + macro_f_string_dynamics_t_delete_simple(arguments); + + if (F_status_is_error_not(*status) && *status != F_child) { + fake_build_touch(main, file_stage, status); + } + + return result; + } +#endif // _di_fake_build_program_static_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-build-program.h b/level_3/fake/c/private-build-program.h new file mode 100644 index 0000000..39e02e1 --- /dev/null +++ b/level_3/fake/c/private-build-program.h @@ -0,0 +1,91 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_build_program_h +#define _PRIVATE_build_program_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Build the script programs. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_program_script_ + extern int fake_build_program_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_program_script_ + +/** + * Build the shared programs. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_program_shared_ + extern int fake_build_program_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_program_shared_ + +/** + * Build the static programs. + * + * @param main + * The main program data. + * @param data_build + * All build related data. + * @param mode + * The file mode. + * @param file_stage + * The specific stage file path. + * @param status + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_build_program_static_ + extern int fake_build_program_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_program_static_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_build_program_h diff --git a/level_3/fake/c/private-build-skeleton.c b/level_3/fake/c/private-build-skeleton.c new file mode 100644 index 0000000..caf5815 --- /dev/null +++ b/level_3/fake/c/private-build-skeleton.c @@ -0,0 +1,116 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-skeleton.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_build_skeleton_ + void fake_build_skeleton(fake_main_t * const main, const fake_build_data_t data_build, const mode_t mode, const f_string_static_t file_stage, f_status_t *status) { + + if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return; + + f_string_static_t path_headers = f_string_static_t_initialize; + f_array_length_t directory_headers_length = main->path_build_includes.used + data_build.setting.path_headers.used; + + char directory_headers[directory_headers_length + 1]; + + if (data_build.setting.path_headers.used) { + memcpy(directory_headers, main->path_build_includes.string, main->path_build_includes.used); + memcpy(directory_headers + main->path_build_includes.used, data_build.setting.path_headers.string, data_build.setting.path_headers.used); + + directory_headers[directory_headers_length] = 0; + + path_headers.string = directory_headers; + path_headers.used = directory_headers_length; + path_headers.size = directory_headers_length + 1; + } + else { + directory_headers[0] = 0; + + path_headers.string = directory_headers; + path_headers.used = 0; + path_headers.size = directory_headers_length + 1; + } + + const f_string_static_t *directorys[] = { + &main->path_build, + &main->path_build_documents, + &main->path_build_includes, + &main->path_build_libraries, + &main->path_build_libraries_script, + &main->path_build_libraries_shared, + &main->path_build_libraries_static, + &main->path_build_objects, + &main->path_build_programs, + &main->path_build_programs_script, + &main->path_build_programs_shared, + &main->path_build_programs_static, + &main->path_build_settings, + &main->path_build_stage, + &path_headers, + }; + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Creating base build directories.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + for (uint8_t i = 0; i < 15; ++i) { + + if (!directorys[i]->used) continue; + + // @todo implement this in a common function and use across project for creating parent directories. + for (f_array_length_t j = 0; j < directorys[i]->used; ++j) { + + if (directorys[i]->string[j] != f_path_separator_s[0]) continue; + + directorys[i]->string[j] = 0; + + *status = f_directory_exists(directorys[i]->string); + + if (F_status_is_error(*status) || *status == F_false) { + directorys[i]->string[j] = f_path_separator_s[0]; + + break; + } + + if (*status == F_file_found_not) { + *status = f_directory_create(directorys[i]->string, mode); + } + + directorys[i]->string[j] = f_path_separator_s[0]; + + if (F_status_is_error(*status)) break; + } // for + + if (F_status_is_fine(*status)) { + *status = f_directory_create(directorys[i]->string, mode); + } + + if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found) { + *status = F_none; + continue; + } + + fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_create", F_true, directorys[i]->string, "create", fll_error_file_type_directory); + return; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Created directory '%Q'.%c", main->output.to.stream, directorys[i], f_string_eol_s[0]); + } + } // for + + fake_build_touch(main, file_stage, status); + } +#endif // _di_fake_build_skeleton_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-build-skeleton.h b/level_3/fake/c/private-build-skeleton.h new file mode 100644 index 0000000..5a64a3d --- /dev/null +++ b/level_3/fake/c/private-build-skeleton.h @@ -0,0 +1,42 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_build_skeleton_h +#define _PRIVATE_build_skeleton_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Create all of the base directories inside the build directory. + * + * @param main + * The main program data. + * @param data_build + * The build data. + * @param mode + * The directory mode. + * @param file_stage + * The specific stage file path. + * @param status + * The return status. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_build_skeleton_ + extern void fake_build_skeleton(fake_main_t * const main, const fake_build_data_t data_build, const mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_build_skeleton_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_build_skeleton_h diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 095ce1f..c3e7bd6 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -2,6 +2,11 @@ #include "private-common.h" #include "private-fake.h" #include "private-build.h" +#include "private-build-library.h" +#include "private-build-load.h" +#include "private-build-objects.h" +#include "private-build-program.h" +#include "private-build-skeleton.h" #include "private-make.h" #include "private-print.h" @@ -491,107 +496,6 @@ extern "C" { } #endif // _di_fake_build_copy_ -#ifndef _di_fake_build_skeleton_ - void fake_build_skeleton(fake_main_t * const main, const fake_build_data_t data_build, const mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return; - - f_string_static_t path_headers = f_string_static_t_initialize; - f_array_length_t directory_headers_length = main->path_build_includes.used + data_build.setting.path_headers.used; - - char directory_headers[directory_headers_length + 1]; - - if (data_build.setting.path_headers.used) { - memcpy(directory_headers, main->path_build_includes.string, main->path_build_includes.used); - memcpy(directory_headers + main->path_build_includes.used, data_build.setting.path_headers.string, data_build.setting.path_headers.used); - - directory_headers[directory_headers_length] = 0; - - path_headers.string = directory_headers; - path_headers.used = directory_headers_length; - path_headers.size = directory_headers_length + 1; - } - else { - directory_headers[0] = 0; - - path_headers.string = directory_headers; - path_headers.used = 0; - path_headers.size = directory_headers_length + 1; - } - - const f_string_static_t *directorys[] = { - &main->path_build, - &main->path_build_documents, - &main->path_build_includes, - &main->path_build_libraries, - &main->path_build_libraries_script, - &main->path_build_libraries_shared, - &main->path_build_libraries_static, - &main->path_build_objects, - &main->path_build_programs, - &main->path_build_programs_script, - &main->path_build_programs_shared, - &main->path_build_programs_static, - &main->path_build_settings, - &main->path_build_stage, - &path_headers, - }; - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Creating base build directories.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - for (uint8_t i = 0; i < 15; ++i) { - - if (!directorys[i]->used) continue; - - // @todo implement this in a common function and use across project for creating parent directories. - for (f_array_length_t j = 0; j < directorys[i]->used; ++j) { - - if (directorys[i]->string[j] != f_path_separator_s[0]) continue; - - directorys[i]->string[j] = 0; - - *status = f_directory_exists(directorys[i]->string); - - if (F_status_is_error(*status) || *status == F_false) { - directorys[i]->string[j] = f_path_separator_s[0]; - - break; - } - - if (*status == F_file_found_not) { - *status = f_directory_create(directorys[i]->string, mode); - } - - directorys[i]->string[j] = f_path_separator_s[0]; - - if (F_status_is_error(*status)) break; - } // for - - if (F_status_is_fine(*status)) { - *status = f_directory_create(directorys[i]->string, mode); - } - - if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found) { - *status = F_none; - continue; - } - - fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_create", F_true, directorys[i]->string, "create", fll_error_file_type_directory); - return; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Created directory '%Q'.%c", main->output.to.stream, directorys[i], f_string_eol_s[0]); - } - } // for - - fake_build_touch(main, file_stage, status); - } -#endif // _di_fake_build_skeleton_ - #ifndef _di_fake_build_execute_process_script_ int fake_build_execute_process_script(fake_main_t * const main, const fake_build_data_t data_build, const f_string_static_t process_script, const f_string_static_t file_stage, f_status_t *status) { @@ -856,2760 +760,127 @@ extern "C" { } #endif // _di_fake_build_get_file_name_without_extension_ -#ifndef _di_fake_build_libraries_script_ - int fake_build_libraries_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - - // @todo needs to perform some sort of regex replace on the library scripts. - - fake_build_touch(main, file_stage, status); - - return 0; - } -#endif // _di_fake_build_libraries_script_ - -#ifndef _di_fake_build_library_shared_ - int fake_build_library_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - if (!data_build.setting.build_sources_library.used) return 0; +#ifndef _di_fake_build_operate_ + f_status_t fake_build_operate(const f_string_static_t setting_file, fake_main_t *main) { - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Compiling shared library.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + if (fake_signal_received(main)) { + return F_status_set_error(F_interrupt); } - f_string_dynamics_t arguments = f_string_dynamics_t_initialize; - - { - const f_string_static_t *path_sources = &main->path_sources; - - if (data_build.setting.path_standard) { - path_sources = &main->path_sources_c; - - if (data_build.setting.build_language == fake_build_language_type_cpp) { - path_sources = &main->path_sources_cpp; - } - } - else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { - path_sources = &data_build.setting.path_sources; - } - - f_array_length_t i = 0; - f_array_length_t j = 0; - f_array_length_t source_length = 0; - - const f_string_dynamics_t *sources[2] = { - &data_build.setting.build_sources_library, - &data_build.setting.build_sources_library_shared, - }; - - for (; i < 2; ++i) { - - for (j = 0; j < sources[i]->used; ++j) { - - if (!sources[i]->array[j].used) continue; - - source_length = path_sources->used + sources[i]->array[j].used; + f_status_t status = F_none; + f_mode_t mode = f_mode_t_initialize; - char source[source_length + 1]; + fake_build_data_t data_build = fake_build_data_t_initialize; + fake_build_stage_t stage = fake_build_stage_t_initialize; - memcpy(source, path_sources->string, path_sources->used); - memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); - source[source_length] = 0; + macro_f_mode_t_set_default_umask(mode, main->umask); - *status = fll_execute_arguments_add(source, source_length, &arguments); - if (F_status_is_error(*status)) break; - } // for + fake_build_load_setting(main, setting_file, &data_build.setting, &status); - if (F_status_is_error(*status)) break; - } // for + if (F_status_is_fine(status)) { + if (main->output.verbosity != f_console_verbosity_quiet) { + flockfile(main->output.to.stream); - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); + fl_print_format("%c%[Building project%] ", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important); + fl_print_format("%[%Q%]", main->output.to.stream, main->context.set.notable, data_build.setting.project_name, main->context.set.notable); + fl_print_format("%[.%]%c", main->output.to.stream, main->context.set.important, main->context.set.important, f_string_eol_s[0]); - macro_f_string_dynamics_t_delete_simple(arguments); - return 0; + funlockfile(main->output.to.stream); } } - const f_array_length_t parameter_file_name_length = fake_build_parameter_library_name_prefix_s_length + data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_shared_s_length; - const f_array_length_t parameter_file_name_major_length = data_build.setting.version_major.used ? parameter_file_name_length + data_build.setting.version_major_prefix.used + data_build.setting.version_major.used : 0; - const f_array_length_t parameter_file_name_minor_length = data_build.setting.version_minor.used ? parameter_file_name_major_length + data_build.setting.version_minor_prefix.used + data_build.setting.version_minor.used : 0; - const f_array_length_t parameter_file_name_micro_length = data_build.setting.version_micro.used ? parameter_file_name_minor_length + data_build.setting.version_micro_prefix.used + data_build.setting.version_micro.used : 0; - const f_array_length_t parameter_file_name_nano_length = data_build.setting.version_nano.used ? parameter_file_name_micro_length + data_build.setting.version_nano_prefix.used + data_build.setting.version_nano.used : 0; - - char parameter_file_name[parameter_file_name_length + 1]; - char parameter_file_name_major[parameter_file_name_major_length + 1]; - char parameter_file_name_minor[parameter_file_name_minor_length + 1]; - char parameter_file_name_micro[parameter_file_name_micro_length + 1]; - char parameter_file_name_nano[parameter_file_name_nano_length + 1]; - - parameter_file_name[parameter_file_name_length] = 0; - parameter_file_name_major[parameter_file_name_major_length] = 0; - parameter_file_name_minor[parameter_file_name_minor_length] = 0; - parameter_file_name_micro[parameter_file_name_micro_length] = 0; - parameter_file_name_nano[parameter_file_name_nano_length] = 0; - - memcpy(parameter_file_name, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - - if (parameter_file_name_major_length) { - memcpy(parameter_file_name_major, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - - if (parameter_file_name_minor_length) { - memcpy(parameter_file_name_minor, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); + fake_build_load_stage(main, setting_file, &stage, &status); - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - } - } - } - } + fake_build_load_environment(main, data_build, &data_build.environment, &status); - f_array_length_t count = fake_build_parameter_library_name_prefix_s_length; + fake_build_skeleton(main, data_build, mode.directory, stage.file_skeleton, &status); - memcpy(parameter_file_name + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + main->child = fake_build_execute_process_script(main, data_build, data_build.setting.process_pre, stage.file_process_pre, &status); - if (parameter_file_name_major_length) { - memcpy(parameter_file_name_major + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + fake_build_copy(main, mode, "setting files", main->path_data_settings, main->path_build_settings, data_build.setting.build_sources_setting, stage.file_sources_settings, 0, &status); - if (parameter_file_name_minor_length) { - memcpy(parameter_file_name_minor + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + if (data_build.setting.build_language == fake_build_language_type_bash) { + fake_build_library_script(main, data_build, mode, stage.file_libraries_script, &status); - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, data_build.setting.project_name.string, data_build.setting.project_name.used); + fake_build_program_script(main, data_build, mode, stage.file_programs_script, &status); - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.project_name.string, data_build.setting.project_name.used); - } - } + if (data_build.setting.build_script) { + fake_build_copy(main, mode, "scripts", main->path_sources_script, main->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0, &status); } } + else { + if (data_build.setting.build_sources_headers.used) { + const f_string_static_t *path_sources = &main->path_sources; - count += data_build.setting.project_name.used; - - memcpy(parameter_file_name + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); - - if (parameter_file_name_major_length) { - memcpy(parameter_file_name_major + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); - - if (parameter_file_name_minor_length) { - memcpy(parameter_file_name_minor + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); - - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + if (data_build.setting.path_standard) { + path_sources = &main->path_sources_c; - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, fake_build_parameter_library_name_suffix_shared_s, fake_build_parameter_library_name_suffix_shared_s_length); + if (data_build.setting.build_language == fake_build_language_type_cpp) { + path_sources = &main->path_sources_cpp; } } - } - } - - if (parameter_file_name_major_length) { - count += fake_build_parameter_library_name_suffix_shared_s_length; - - if (data_build.setting.version_major_prefix.used) { - memcpy(parameter_file_name_major + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); - - if (parameter_file_name_minor_length) { - memcpy(parameter_file_name_minor + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); - - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); - - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_major_prefix.string, data_build.setting.version_major_prefix.used); - } - } + else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { + path_sources = &data_build.setting.path_sources; } - count += data_build.setting.version_major_prefix.used; - } + const f_array_length_t path_sources_base_length = path_sources->used; - memcpy(parameter_file_name_major + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + f_string_static_t path_headers = f_string_static_t_initialize; + f_array_length_t directory_headers_length = main->path_build_includes.used + data_build.setting.path_headers.used; - if (parameter_file_name_minor_length) { - memcpy(parameter_file_name_minor + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + char directory_headers[directory_headers_length + 1]; - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, data_build.setting.version_major.string, data_build.setting.version_major.used); + memcpy(directory_headers, main->path_build_includes.string, main->path_build_includes.used); - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_major.string, data_build.setting.version_major.used); - } + if (data_build.setting.path_headers.used) { + memcpy(directory_headers + main->path_build_includes.used, data_build.setting.path_headers.string, data_build.setting.path_headers.used); } - } - - if (parameter_file_name_minor_length) { - count += data_build.setting.version_major.used; - - if (data_build.setting.version_minor_prefix.used) { - memcpy(parameter_file_name_minor + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); - - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_minor_prefix.string, data_build.setting.version_minor_prefix.used); - } - } - - count += data_build.setting.version_minor_prefix.used; - } + directory_headers[directory_headers_length] = 0; - memcpy(parameter_file_name_minor + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); + path_headers.string = directory_headers; + path_headers.used = directory_headers_length; + path_headers.size = directory_headers_length + 1; - if (parameter_file_name_micro_length) { - memcpy(parameter_file_name_micro + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); + fake_build_copy(main, mode, "header files", *path_sources, path_headers, data_build.setting.build_sources_headers, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_minor.string, data_build.setting.version_minor.used); - } + if (data_build.setting.build_shared) { + fake_build_copy(main, mode, "shared header files", *path_sources, path_headers, data_build.setting.build_sources_headers_shared, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); } - if (parameter_file_name_micro_length) { - count += data_build.setting.version_minor.used; - - if (data_build.setting.version_micro_prefix.used) { - memcpy(parameter_file_name_micro + count, data_build.setting.version_micro_prefix.string, data_build.setting.version_micro_prefix.used); - - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_micro_prefix.string, data_build.setting.version_micro_prefix.used); - } - - count += data_build.setting.version_micro_prefix.used; - } - - memcpy(parameter_file_name_micro + count, data_build.setting.version_micro.string, data_build.setting.version_micro.used); - - if (parameter_file_name_nano_length) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_micro.string, data_build.setting.version_micro.used); - - count += data_build.setting.version_micro.used; - - if (data_build.setting.version_nano_prefix.used) { - memcpy(parameter_file_name_nano + count, data_build.setting.version_nano_prefix.string, data_build.setting.version_nano_prefix.used); - count += data_build.setting.version_nano_prefix.used; - } - - memcpy(parameter_file_name_nano + count, data_build.setting.version_nano.string, data_build.setting.version_nano.used); - } + if (data_build.setting.build_static) { + fake_build_copy(main, mode, "static header files", *path_sources, path_headers, data_build.setting.build_sources_headers_static, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); } } - } - - { - f_array_length_t parameter_linker_length = fake_build_parameter_library_shared_prefix_s_length; - f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used; - - if (data_build.setting.version_file == fake_build_version_type_major) { - parameter_file_path_length += parameter_file_name_major_length; - } - else if (data_build.setting.version_file == fake_build_version_type_minor) { - parameter_file_path_length += parameter_file_name_minor_length; - } - else if (data_build.setting.version_file == fake_build_version_type_micro) { - parameter_file_path_length += parameter_file_name_micro_length; - } - else if (data_build.setting.version_file == fake_build_version_type_nano) { - parameter_file_path_length += parameter_file_name_nano_length; - } - - if (data_build.setting.version_target == fake_build_version_type_major) { - parameter_linker_length += parameter_file_name_major_length; - } - else if (data_build.setting.version_target == fake_build_version_type_minor) { - parameter_linker_length += parameter_file_name_minor_length; - } - else if (data_build.setting.version_target == fake_build_version_type_micro) { - parameter_linker_length += parameter_file_name_micro_length; - } - else if (data_build.setting.version_target == fake_build_version_type_nano) { - parameter_linker_length += parameter_file_name_nano_length; - } - - char parameter_linker[parameter_linker_length + 1]; - char parameter_file_path[parameter_file_path_length + 1]; - - memcpy(parameter_linker, fake_build_parameter_library_shared_prefix_s, fake_build_parameter_library_shared_prefix_s_length); - memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); - - if (data_build.setting.version_file == fake_build_version_type_major) { - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_major, parameter_file_name_major_length); - } - else if (data_build.setting.version_file == fake_build_version_type_minor) { - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_minor, parameter_file_name_minor_length); - } - else if (data_build.setting.version_file == fake_build_version_type_micro) { - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_micro, parameter_file_name_micro_length); - } - else if (data_build.setting.version_file == fake_build_version_type_nano) { - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_nano, parameter_file_name_nano_length); - } - - if (data_build.setting.version_target == fake_build_version_type_major) { - memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_major, parameter_file_name_major_length); - } - else if (data_build.setting.version_target == fake_build_version_type_minor) { - memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_minor, parameter_file_name_minor_length); - } - else if (data_build.setting.version_target == fake_build_version_type_micro) { - memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_micro, parameter_file_name_micro_length); - } - else if (data_build.setting.version_target == fake_build_version_type_nano) { - memcpy(parameter_linker + fake_build_parameter_library_shared_prefix_s_length, parameter_file_name_nano, parameter_file_name_nano_length); - } - - parameter_linker[parameter_linker_length] = 0; - parameter_file_path[parameter_file_path_length] = 0; - - const f_string_t values[] = { - fake_build_parameter_library_shared_s, - parameter_linker, - fake_build_parameter_library_output_s, - parameter_file_path, - }; - - const f_array_length_t lengths[] = { - fake_build_parameter_library_shared_s_length, - parameter_linker_length, - fake_build_parameter_library_output_s_length, - parameter_file_path_length, - }; - - for (uint8_t i = 0; i < 4; ++i) { - - if (!lengths[i]) continue; - - *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); - if (F_status_is_error(*status)) break; - } // for - - fake_build_arguments_standard_add(main, data_build, F_true, F_true, &arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); - - macro_f_string_dynamics_t_delete_simple(arguments); - - return 0; - } - } - - { - const int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error(*status)) { - return 0; - } + if (data_build.setting.build_shared) { + main->child = fake_build_library_shared(main, data_build, mode, stage.file_libraries_shared, &status); - if (*status == F_child) { - return result; + main->child = fake_build_program_shared(main, data_build, mode, stage.file_programs_shared, &status); } - } - - if (parameter_file_name_major_length) { - f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_length; - - char parameter_file_path[parameter_file_path_length + 1]; - - memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name, parameter_file_name_length); - parameter_file_path[parameter_file_path_length] = 0; + if (data_build.setting.build_static) { + main->child = fake_build_objects_static(main, data_build, mode, stage.file_objects_static, &status); - *status = f_file_link(parameter_file_name_major, parameter_file_path); + main->child = fake_build_library_static(main, data_build, mode, stage.file_libraries_static, &status); - if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_major, f_string_eol_s[0]); + main->child = fake_build_program_static(main, data_build, mode, stage.file_programs_static, &status); } - else if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found) { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); - - return 0; - } - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_major, "link", fll_error_file_type_file); - - return 0; + if (data_build.setting.build_script) { + fake_build_copy(main, mode, "scripts", main->path_sources_script, main->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0, &status); } } - if (data_build.setting.version_file != fake_build_version_type_major && parameter_file_name_major_length) { - - f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_major_length; - - char parameter_file_path[parameter_file_path_length + 1]; - - memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_major, parameter_file_name_major_length); - - parameter_file_path[parameter_file_path_length] = 0; - - *status = f_file_link(parameter_file_name_minor, parameter_file_path); - - if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_minor, f_string_eol_s[0]); - } - else if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found) { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); - - return 0; - } + fake_build_execute_process_script(main, data_build, data_build.setting.process_post, stage.file_process_post, &status); - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_minor, "link", fll_error_file_type_file); - - return 0; - } - - if (data_build.setting.version_file != fake_build_version_type_minor && parameter_file_name_minor_length) { - - f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_minor_length; - - char parameter_file_path[parameter_file_path_length + 1]; - - memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_minor, parameter_file_name_minor_length); - - parameter_file_path[parameter_file_path_length] = 0; - - *status = f_file_link(parameter_file_name_micro, parameter_file_path); - - if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_micro, f_string_eol_s[0]); - } - else if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found) { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); - - return 0; - } - - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_micro, "link", fll_error_file_type_file); - - return 0; - } - - if (data_build.setting.version_file != fake_build_version_type_micro && parameter_file_name_micro_length) { - - f_array_length_t parameter_file_path_length = main->path_build_libraries_shared.used + parameter_file_name_micro_length; - - char parameter_file_path[parameter_file_path_length + 1]; - - memcpy(parameter_file_path, main->path_build_libraries_shared.string, main->path_build_libraries_shared.used); - memcpy(parameter_file_path + main->path_build_libraries_shared.used, parameter_file_name_micro, parameter_file_name_micro_length); - - parameter_file_path[parameter_file_path_length] = 0; - - *status = f_file_link(parameter_file_name_nano, parameter_file_path); - - if (F_status_is_error_not(*status) && main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Linked file '%S' to '%S'.%c", main->output.to.stream, parameter_file_path, parameter_file_name_nano, f_string_eol_s[0]); - } - else if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found) { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_path, "link", fll_error_file_type_file); - - return 0; - } - - fll_error_file_print(main->error, F_status_set_fine(*status), "f_file_link", F_true, parameter_file_name_nano, "link", fll_error_file_type_file); - - return 0; - } - } - } - } - - fake_build_touch(main, file_stage, status); - - return 0; - } -#endif // _di_fake_build_library_shared_ - -#ifndef _di_fake_build_library_static_ - int fake_build_library_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - if (!data_build.setting.build_sources_library.used) return 0; - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Compiling static library.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - f_string_dynamic_t file_name = f_string_dynamic_t_initialize; - f_string_dynamic_t source_path = f_string_dynamic_t_initialize; - f_string_dynamics_t arguments = f_string_dynamics_t_initialize; - - f_array_length_t i = 0; - - for (; i < data_build.setting.build_indexer_arguments.used; ++i) { - - if (!data_build.setting.build_indexer_arguments.array[i].used) continue; - - *status = fll_execute_arguments_add(data_build.setting.build_indexer_arguments.array[i].string, data_build.setting.build_indexer_arguments.array[i].used, &arguments); - if (F_status_is_error(*status)) break; - } // for - - if (F_status_is_error_not(*status)) { - f_array_length_t destination_length = main->path_build_libraries_static.used + fake_build_parameter_library_name_prefix_s_length; - destination_length += data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_static_s_length; - - char destination[destination_length + 1]; - - destination_length = 0; - - memcpy(destination, main->path_build_libraries_static.string, main->path_build_libraries_static.used); - destination_length += main->path_build_libraries_static.used; - - memcpy(destination + destination_length, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - destination_length += fake_build_parameter_library_name_prefix_s_length; - - memcpy(destination + destination_length, data_build.setting.project_name.string, data_build.setting.project_name.used); - destination_length += data_build.setting.project_name.used; - - memcpy(destination + destination_length, fake_build_parameter_library_name_suffix_static_s, fake_build_parameter_library_name_suffix_static_s_length); - destination_length += fake_build_parameter_library_name_suffix_static_s_length; - - destination[destination_length] = 0; - - *status = fll_execute_arguments_add(destination, destination_length, &arguments); - } - - if (F_status_is_error_not(*status)) { - f_array_length_t source_length = 0; - f_array_length_t j = 0; - - const f_string_dynamics_t *sources[2] = { - &data_build.setting.build_sources_library, - &data_build.setting.build_sources_library_static, - }; - - for (i = 0; i < 2; ++i) { - - for (j = 0; j < sources[i]->used; ++j) { - - source_path.used = 0; - - *status = fake_build_get_file_name_without_extension(main, sources[i]->array[j], &file_name); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fake_build_get_file_name_without_extension", F_true); - break; - } - - *status = f_file_name_directory(sources[i]->array[j].string, sources[i]->array[j].used, &source_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_directory", F_true); - break; - } - - if (source_path.used) { - *status = f_string_dynamic_prepend(main->path_build_objects, &source_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_prepend", F_true); - break; - } - - *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, &source_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(&source_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - - source_length = source_path.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; - } - else { - source_length = main->path_build_objects.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; - } - - char source[source_length + 1]; - - if (source_path.used) { - memcpy(source, source_path.string, source_path.used); - memcpy(source + source_path.used, file_name.string, file_name.used); - memcpy(source + source_path.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); - } - else { - memcpy(source, main->path_build_objects.string, main->path_build_objects.used); - memcpy(source + main->path_build_objects.used, file_name.string, file_name.used); - memcpy(source + main->path_build_objects.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); - } - - source[source_length] = 0; - - *status = fll_execute_arguments_add(source, source_length, &arguments); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); - break; - } - } // for - } // for - } - - int result = main->child; - - if (F_status_is_error_not(*status)) { - result = fake_execute(main, data_build.environment, data_build.setting.build_indexer, arguments, status); - } - - macro_f_string_dynamic_t_delete_simple(file_name); - macro_f_string_dynamic_t_delete_simple(source_path); - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error_not(*status) && *status != F_child) { - fake_build_touch(main, file_stage, status); - } - - return result; - } -#endif // _di_fake_build_library_static_ - -#ifndef _di_fake_build_load_environment_ - void fake_build_load_environment(fake_main_t * const main, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - // reset the environment. - for (f_array_length_t i = 0; i < environment->used; ++i) { - environment->array[i].name.used = 0; - environment->array[i].value.used = 0; - } // for - - environment->used = 0; - - { - // add the guaranteed environment variables. - const f_string_t variables_name[] = { - f_path_environment_s, - f_path_present_working_s - }; - - const f_array_length_t variables_length[] = { - F_path_environment_s_length, - F_path_present_working_s_length - }; - - for (uint8_t i = 0; i < 2; ++i) { - - *status = fl_environment_load_name(variables_name[i], variables_length[i], environment); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_environment_load_name", F_true); - break; - } - } // for - - if (F_status_is_error(*status)) { - return; - } - } - - if (environment->used + data_build.setting.environment.used > environment->size) { - if (environment->used + data_build.setting.environment.used > f_environment_max_length) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe values for the setting '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_environment_s, main->error.notable); - fl_print_format("%[' of setting file '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_environment_s, main->error.notable); - fl_print_format("%[' is too large.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - flockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_array_too_large); - return; - } - } - - *status = fl_environment_load_names(data_build.setting.environment, environment); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_environment_load_names", F_true); - } - } -#endif // _di_fake_build_load_environment_ - -#ifndef _di_fake_build_load_setting_ - void fake_build_load_setting(fake_main_t * const main, const f_string_static_t setting_file, fake_build_setting_t *setting, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - return; - } - - char path_file[main->path_data_build.used + setting_file.used + 1]; - - { - f_string_dynamic_t buffer = f_string_dynamic_t_initialize; - - f_fss_objects_t objects = f_fss_objects_t_initialize; - f_fss_contents_t contents = f_fss_contents_t_initialize; - - if (setting_file.used) { - memcpy(path_file, main->path_data_build.string, main->path_data_build.used); - memcpy(path_file + main->path_data_build.used, setting_file.string, setting_file.used); - - path_file[main->path_data_build.used + setting_file.used] = 0; - - *status = fake_file_buffer(main, path_file, &buffer); - } - else { - *status = fake_file_buffer(main, main->file_data_build_settings.string, &buffer); - } - - if (F_status_is_error_not(*status)) { - f_string_range_t range = macro_f_string_range_t_initialize(buffer.used); - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; - - { - f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); - - *status = fll_fss_extended_read(buffer, state, &range, &objects, &contents, 0, 0, &delimits, 0); - } - - if (F_status_is_error(*status)) { - fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_settings.string, range, F_true); - } - else { - *status = fl_fss_apply_delimit(delimits, &buffer); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); - } - else { - fake_build_load_setting_process(main, F_true, setting_file.used ? path_file : main->file_data_build_settings.string, buffer, objects, contents, setting, status); - } - } - - macro_f_fss_delimits_t_delete_simple(delimits); - } - - macro_f_string_dynamic_t_delete_simple(buffer); - macro_f_fss_objects_t_delete_simple(objects); - macro_f_fss_contents_t_delete_simple(contents); - } - - // Error when required settings are not specified. - if (F_status_is_error_not(*status)) { - bool failed = F_false; - - f_string_static_t * const settings[] = { - &setting->project_name, - }; - - f_string_t names[] = { - fake_build_setting_name_project_name_s, - }; - - for (uint8_t i = 0; i < 1; ++i) { - - if (!settings[i]->used) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, names[i], main->error.notable); - fl_print_format("%[' is required but is not specified in the settings file '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting_file.used ? path_file : main->file_data_build_settings.string, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - - failed = F_true; - } - } // for - - if (failed) { - *status = F_status_set_error(F_failure); - - return; - } - } - - fake_build_load_setting_defaults(main, setting, status); - } -#endif // _di_fake_build_load_setting_ - -#ifndef _di_fake_build_load_setting_process_ - void fake_build_load_setting_process(fake_main_t * const main, const bool checks, const f_string_t path_file, const f_string_static_t buffer, const f_fss_objects_t objects, const f_fss_contents_t contents, fake_build_setting_t *setting, f_status_t *status) { - - if (F_status_is_error(*status) && buffer.used) return; - - if (fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - return; - } - - bool error_printed = F_false; - - f_string_dynamics_t build_compiler = f_string_dynamics_t_initialize; - f_string_dynamics_t build_indexer = f_string_dynamics_t_initialize; - f_string_dynamics_t build_language = f_string_dynamics_t_initialize; - f_string_dynamics_t build_script = f_string_dynamics_t_initialize; - f_string_dynamics_t build_shared = f_string_dynamics_t_initialize; - f_string_dynamics_t build_static = f_string_dynamics_t_initialize; - f_string_dynamics_t path_headers = f_string_dynamics_t_initialize; - f_string_dynamics_t path_headers_preserve = f_string_dynamics_t_initialize; - f_string_dynamics_t path_language = f_string_dynamics_t_initialize; - f_string_dynamics_t path_library_script = f_string_dynamics_t_initialize; - f_string_dynamics_t path_library_shared = f_string_dynamics_t_initialize; - f_string_dynamics_t path_library_static = f_string_dynamics_t_initialize; - f_string_dynamics_t path_program_script = f_string_dynamics_t_initialize; - f_string_dynamics_t path_program_shared = f_string_dynamics_t_initialize; - f_string_dynamics_t path_program_static = f_string_dynamics_t_initialize; - f_string_dynamics_t path_sources = f_string_dynamics_t_initialize; - f_string_dynamics_t path_standard = f_string_dynamics_t_initialize; - f_string_dynamics_t process_post = f_string_dynamics_t_initialize; - f_string_dynamics_t process_pre = f_string_dynamics_t_initialize; - f_string_dynamics_t project_name = f_string_dynamics_t_initialize; - f_string_dynamics_t search_exclusive = f_string_dynamics_t_initialize; - f_string_dynamics_t search_shared = f_string_dynamics_t_initialize; - f_string_dynamics_t search_static = f_string_dynamics_t_initialize; - f_string_dynamics_t version_file = f_string_dynamics_t_initialize; - f_string_dynamics_t version_major = f_string_dynamics_t_initialize; - f_string_dynamics_t version_major_prefix = f_string_dynamics_t_initialize; - f_string_dynamics_t version_micro = f_string_dynamics_t_initialize; - f_string_dynamics_t version_micro_prefix = f_string_dynamics_t_initialize; - f_string_dynamics_t version_minor = f_string_dynamics_t_initialize; - f_string_dynamics_t version_minor_prefix = f_string_dynamics_t_initialize; - f_string_dynamics_t version_nano = f_string_dynamics_t_initialize; - f_string_dynamics_t version_nano_prefix = f_string_dynamics_t_initialize; - f_string_dynamics_t version_target = f_string_dynamics_t_initialize; - - const f_string_t settings_name[] = { - fake_build_setting_name_build_compiler_s, - fake_build_setting_name_build_indexer_s, - fake_build_setting_name_build_indexer_arguments_s, - fake_build_setting_name_build_language_s, - fake_build_setting_name_build_libraries_s, - fake_build_setting_name_build_libraries_shared_s, - fake_build_setting_name_build_libraries_static_s, - fake_build_setting_name_build_script_s, - fake_build_setting_name_build_shared_s, - fake_build_setting_name_build_sources_headers_s, - fake_build_setting_name_build_sources_headers_shared_s, - fake_build_setting_name_build_sources_headers_static_s, - fake_build_setting_name_build_sources_library_s, - fake_build_setting_name_build_sources_library_shared_s, - fake_build_setting_name_build_sources_library_static_s, - fake_build_setting_name_build_sources_program_s, - fake_build_setting_name_build_sources_program_shared_s, - fake_build_setting_name_build_sources_program_static_s, - fake_build_setting_name_build_sources_script_s, - fake_build_setting_name_build_sources_settings_s, - fake_build_setting_name_build_static_s, - fake_build_setting_name_defines_s, - fake_build_setting_name_defines_library_s, - fake_build_setting_name_defines_library_shared_s, - fake_build_setting_name_defines_library_static_s, - fake_build_setting_name_defines_program_s, - fake_build_setting_name_defines_program_shared_s, - fake_build_setting_name_defines_program_static_s, - fake_build_setting_name_defines_shared_s, - fake_build_setting_name_defines_static_s, - fake_build_setting_name_environment_s, - fake_build_setting_name_flags_s, - fake_build_setting_name_flags_library_s, - fake_build_setting_name_flags_library_shared_s, - fake_build_setting_name_flags_library_static_s, - fake_build_setting_name_flags_program_s, - fake_build_setting_name_flags_program_shared_s, - fake_build_setting_name_flags_program_static_s, - fake_build_setting_name_flags_shared_s, - fake_build_setting_name_flags_static_s, - fake_build_setting_name_modes_s, - fake_build_setting_name_modes_default_s, - fake_build_setting_name_path_headers_s, - fake_build_setting_name_path_headers_preserve_s, - fake_build_setting_name_path_language_s, - fake_build_setting_name_path_library_script_s, - fake_build_setting_name_path_library_shared_s, - fake_build_setting_name_path_library_static_s, - fake_build_setting_name_path_program_script_s, - fake_build_setting_name_path_program_shared_s, - fake_build_setting_name_path_program_static_s, - fake_build_setting_name_path_sources_s, - fake_build_setting_name_path_standard_s, - fake_build_setting_name_process_post_s, - fake_build_setting_name_process_pre_s, - fake_build_setting_name_project_name_s, - fake_build_setting_name_search_exclusive_s, - fake_build_setting_name_search_shared_s, - fake_build_setting_name_search_static_s, - fake_build_setting_name_version_file_s, - fake_build_setting_name_version_major_s, - fake_build_setting_name_version_major_prefix_s, - fake_build_setting_name_version_micro_s, - fake_build_setting_name_version_micro_prefix_s, - fake_build_setting_name_version_minor_s, - fake_build_setting_name_version_minor_prefix_s, - fake_build_setting_name_version_nano_s, - fake_build_setting_name_version_nano_prefix_s, - fake_build_setting_name_version_target_s, - }; - - const f_array_length_t settings_length[] = { - fake_build_setting_name_build_compiler_s_length, - fake_build_setting_name_build_indexer_s_length, - fake_build_setting_name_build_indexer_arguments_s_length, - fake_build_setting_name_build_language_s_length, - fake_build_setting_name_build_libraries_s_length, - fake_build_setting_name_build_libraries_shared_s_length, - fake_build_setting_name_build_libraries_static_s_length, - fake_build_setting_name_build_script_s_length, - fake_build_setting_name_build_shared_s_length, - fake_build_setting_name_build_sources_headers_s_length, - fake_build_setting_name_build_sources_headers_shared_s_length, - fake_build_setting_name_build_sources_headers_static_s_length, - fake_build_setting_name_build_sources_library_s_length, - fake_build_setting_name_build_sources_library_shared_s_length, - fake_build_setting_name_build_sources_library_static_s_length, - fake_build_setting_name_build_sources_program_s_length, - fake_build_setting_name_build_sources_program_shared_s_length, - fake_build_setting_name_build_sources_program_static_s_length, - fake_build_setting_name_build_sources_script_s_length, - fake_build_setting_name_build_sources_settings_s_length, - fake_build_setting_name_build_static_s_length, - fake_build_setting_name_defines_s_length, - fake_build_setting_name_defines_library_s_length, - fake_build_setting_name_defines_library_shared_s_length, - fake_build_setting_name_defines_library_static_s_length, - fake_build_setting_name_defines_program_s_length, - fake_build_setting_name_defines_program_shared_s_length, - fake_build_setting_name_defines_program_static_s_length, - fake_build_setting_name_defines_shared_s_length, - fake_build_setting_name_defines_static_s_length, - fake_build_setting_name_environment_length_s, - fake_build_setting_name_flags_s_length, - fake_build_setting_name_flags_library_s_length, - fake_build_setting_name_flags_library_shared_s_length, - fake_build_setting_name_flags_library_static_s_length, - fake_build_setting_name_flags_program_s_length, - fake_build_setting_name_flags_program_shared_s_length, - fake_build_setting_name_flags_program_static_s_length, - fake_build_setting_name_flags_shared_s_length, - fake_build_setting_name_flags_static_s_length, - fake_build_setting_name_modes_s_length, - fake_build_setting_name_modes_default_s_length, - fake_build_setting_name_path_headers_s_length, - fake_build_setting_name_path_headers_preserve_s_length, - fake_build_setting_name_path_language_s_length, - fake_build_setting_name_path_library_script_s_length, - fake_build_setting_name_path_library_shared_s_length, - fake_build_setting_name_path_library_static_s_length, - fake_build_setting_name_path_program_script_s_length, - fake_build_setting_name_path_program_shared_s_length, - fake_build_setting_name_path_program_static_s_length, - fake_build_setting_name_path_sources_s_length, - fake_build_setting_name_path_standard_s_length, - fake_build_setting_name_process_post_s_length, - fake_build_setting_name_process_pre_s_length, - fake_build_setting_name_project_name_s_length, - fake_build_setting_name_search_exclusive_s_length, - fake_build_setting_name_search_shared_s_length, - fake_build_setting_name_search_static_s_length, - fake_build_setting_name_version_file_s_length, - fake_build_setting_name_version_major_s_length, - fake_build_setting_name_version_major_prefix_s_length, - fake_build_setting_name_version_micro_s_length, - fake_build_setting_name_version_micro_prefix_s_length, - fake_build_setting_name_version_minor_s_length, - fake_build_setting_name_version_minor_prefix_s_length, - fake_build_setting_name_version_nano_s_length, - fake_build_setting_name_version_nano_prefix_s_length, - fake_build_setting_name_version_target_s_length, - }; - - f_string_dynamics_t *settings_value[] = { - &build_compiler, - &build_indexer, - &setting->build_indexer_arguments, - &build_language, - &setting->build_libraries, - &setting->build_libraries_shared, - &setting->build_libraries_static, - &build_script, - &build_shared, - &setting->build_sources_headers, - &setting->build_sources_headers_shared, - &setting->build_sources_headers_static, - &setting->build_sources_library, - &setting->build_sources_library_shared, - &setting->build_sources_library_static, - &setting->build_sources_program, - &setting->build_sources_program_shared, - &setting->build_sources_program_static, - &setting->build_sources_script, - &setting->build_sources_setting, - &build_static, - &setting->defines, - &setting->defines_library, - &setting->defines_library_shared, - &setting->defines_library_static, - &setting->defines_program, - &setting->defines_program_shared, - &setting->defines_program_static, - &setting->defines_shared, - &setting->defines_static, - &setting->environment, - &setting->flags, - &setting->flags_library, - &setting->flags_library_shared, - &setting->flags_library_static, - &setting->flags_program, - &setting->flags_program_shared, - &setting->flags_program_static, - &setting->flags_shared, - &setting->flags_static, - &setting->modes, - &setting->modes_default, - &path_headers, - &path_headers_preserve, - &path_language, - &path_library_script, - &path_library_shared, - &path_library_static, - &path_program_script, - &path_program_shared, - &path_program_static, - &path_sources, - &path_standard, - &process_post, - &process_pre, - &project_name, - &search_exclusive, - &search_shared, - &search_static, - &version_file, - &version_major, - &version_major_prefix, - &version_micro, - &version_micro_prefix, - &version_minor, - &version_minor_prefix, - &version_nano, - &version_nano_prefix, - &version_target, - }; - - bool settings_matches[] = { - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - F_false, - }; - - f_string_t function = "fll_fss_snatch_apart"; - - *status = fll_fss_snatch_apart(buffer, objects, contents, settings_name, settings_length, fake_build_setting_total_d, settings_value, settings_matches, 0); - - if (*status == F_none) { - const int total_build_libraries = setting->build_libraries.used; - - f_string_dynamic_t settings_mode_name_dynamic[fake_build_setting_total_d]; - f_string_t settings_mode_names[fake_build_setting_total_d]; - f_array_length_t setting_mode_lengths[fake_build_setting_total_d]; - - const f_string_dynamics_t *modes = &setting->modes_default; - bool found = F_false; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - // if any mode is specified, the entire defaults is replaced. - if (main->mode.used) { - modes = &main->mode; - } - - for (; i < modes->used; ++i) { - - found = F_false; - - for (j = 0; j < setting->modes.used; ++j) { - - if (fl_string_dynamic_compare_trim(modes->array[i], setting->modes.array[j]) == F_equal_to) { - found = F_true; - break; - } - } // for - - if (found == F_false) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe specified mode '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, modes->array[i], main->error.notable); - fl_print_format("%[' is not a valid mode, according to '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, path_file, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - error_printed = F_true; - *status = F_status_set_error(F_parameter); - break; - } - - memset(&settings_mode_name_dynamic, 0, sizeof(f_string_dynamic_t) * fake_build_setting_total_d); - memset(&settings_mode_names, 0, sizeof(f_string_t) * fake_build_setting_total_d); - memset(&setting_mode_lengths, 0, sizeof(f_array_length_t) * fake_build_setting_total_d); - - for (j = 0; j < fake_build_setting_total_d; ++j) { - - setting_mode_lengths[j] = settings_length[j] + 1 + modes->array[i].used; - - macro_f_string_dynamic_t_resize(*status, settings_mode_name_dynamic[j], setting_mode_lengths[j]); - - if (F_status_is_error(*status)) { - function = "macro_f_string_dynamic_t_resize"; - break; - } - - memcpy(settings_mode_name_dynamic[j].string, settings_name[j], settings_length[j]); - memcpy(settings_mode_name_dynamic[j].string + settings_length[j] + 1, modes->array[i].string, modes->array[i].used); - settings_mode_name_dynamic[j].string[settings_length[j]] = '-'; - - settings_mode_names[j] = settings_mode_name_dynamic[j].string; - } // for - - if (*status == F_none) { - *status = fll_fss_snatch_apart(buffer, objects, contents, settings_mode_names, setting_mode_lengths, fake_build_setting_total_d, settings_value, 0, 0); - - if (F_status_is_error(*status)) { - function = "fll_fss_snatch_apart"; - } - } - - for (j = 0; j < fake_build_setting_total_d; ++j) { - macro_f_string_dynamic_t_delete_simple(settings_mode_name_dynamic[j]); - } // for - - if (F_status_is_error(*status)) break; - } // for - - // "build_libraries" is appended after all modes to help assist with static linker file issues (@todo there should likely be more options to have a postfix linker parameter that can be added here instead, such as "build_libraries_last"). - if (total_build_libraries) { - f_string_dynamic_t temporary[total_build_libraries]; - - for (i = 0; i < total_build_libraries; ++i) { - - temporary[i].string = setting->build_libraries.array[i].string; - temporary[i].used = setting->build_libraries.array[i].used; - temporary[i].size = setting->build_libraries.array[i].size; - } // for - - for (i = 0, j = total_build_libraries; j < setting->build_libraries.used; ++i, ++j) { - - setting->build_libraries.array[i].string = setting->build_libraries.array[j].string; - setting->build_libraries.array[i].used = setting->build_libraries.array[j].used; - setting->build_libraries.array[i].size = setting->build_libraries.array[j].size; - } // for - - for (i = setting->build_libraries.used - total_build_libraries, j = 0; j < total_build_libraries; ++i, ++j) { - - setting->build_libraries.array[i].string = temporary[j].string; - setting->build_libraries.array[i].used = temporary[j].used; - setting->build_libraries.array[i].size = temporary[j].size; - } // for - } - } - - if (F_status_is_error(*status)) { - if (*status == F_status_set_error(F_string_too_large)) { - if (main->error.verbosity != f_console_verbosity_quiet) { - funlockfile(main->error.to.stream); - - fl_print_format("%c%[%SA setting in the file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, path_file, main->error.notable); - fl_print_format("%[' is too long.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - } - else if (!error_printed) { - fll_error_print(main->error, F_status_set_fine(*status), function, F_true); - } - } - else { - const f_string_t settings_single_name[] = { - fake_build_setting_name_build_compiler_s, - fake_build_setting_name_build_indexer_s, - fake_build_setting_name_build_language_s, - fake_build_setting_name_build_script_s, - fake_build_setting_name_build_shared_s, - fake_build_setting_name_build_static_s, - fake_build_setting_name_path_headers_s, - fake_build_setting_name_path_headers_preserve_s, - fake_build_setting_name_path_language_s, - fake_build_setting_name_path_library_script_s, - fake_build_setting_name_path_library_shared_s, - fake_build_setting_name_path_library_static_s, - fake_build_setting_name_path_program_script_s, - fake_build_setting_name_path_program_shared_s, - fake_build_setting_name_path_program_static_s, - fake_build_setting_name_path_sources_s, - fake_build_setting_name_path_standard_s, - fake_build_setting_name_process_post_s, - fake_build_setting_name_process_pre_s, - fake_build_setting_name_project_name_s, - fake_build_setting_name_search_exclusive_s, - fake_build_setting_name_search_shared_s, - fake_build_setting_name_search_static_s, - fake_build_setting_name_version_file_s, - fake_build_setting_name_version_major_s, - fake_build_setting_name_version_major_prefix_s, - fake_build_setting_name_version_micro_s, - fake_build_setting_name_version_micro_prefix_s, - fake_build_setting_name_version_minor_s, - fake_build_setting_name_version_minor_prefix_s, - fake_build_setting_name_version_nano_s, - fake_build_setting_name_version_nano_prefix_s, - fake_build_setting_name_version_target_s, - }; - - const f_string_statics_t *settings_single_source[] = { - &build_compiler, - &build_indexer, - &build_language, - &build_script, - &build_shared, - &build_static, - &path_headers, - &path_headers_preserve, - &path_language, - &path_library_script, - &path_library_shared, - &path_library_static, - &path_program_script, - &path_program_shared, - &path_program_static, - &path_sources, - &path_standard, - &process_post, - &process_pre, - &project_name, - &search_exclusive, - &search_shared, - &search_static, - &version_file, - &version_major, - &version_major_prefix, - &version_micro, - &version_micro_prefix, - &version_minor, - &version_minor_prefix, - &version_nano, - &version_nano_prefix, - &version_target, - }; - - bool * const settings_single_bool[] = { - 0, // build_compiler - 0, // build_indexer - 0, // build_language - &setting->build_script, // build_script - &setting->build_shared, // build_shared - &setting->build_static, // build_static - 0, // path_headers - &setting->path_headers_preserve, // path_headers_preserve - 0, // path_language - 0, // path_library_script - 0, // path_library_shared - 0, // path_library_static - 0, // path_program_script - 0, // path_program_shared - 0, // path_program_static - 0, // path_sources - &setting->path_standard, // path_standard - 0, // process_post - 0, // process_pre - 0, // project_name - &setting->search_exclusive, // search_exclusive - &setting->search_shared, // search_shared - &setting->search_static, // search_static - }; - - f_string_dynamic_t * const settings_single_destination[] = { - &setting->build_compiler, // build_compiler - &setting->build_indexer, // build_indexer - 0, // build_language - 0, // build_script - 0, // build_shared - 0, // build_static - &setting->path_headers, // path_headers - 0, // path_headers_preserve - &setting->path_language, // path_language - &setting->path_library_script, // path_library_script - &setting->path_library_shared, // path_library_shared - &setting->path_library_static, // path_library_static - &setting->path_program_script, // path_program_script - &setting->path_program_shared, // path_program_shared - &setting->path_program_static, // path_program_static - &setting->path_sources, // path_sources - 0, // path_standard - &setting->process_post, // process_post - &setting->process_pre, // process_pre - &setting->project_name, // project_name - 0, // search_exclusive - 0, // search_shared - 0, // search_static - 0, // version_file - &setting->version_major, // version_major - &setting->version_major_prefix, // version_major_prefix - &setting->version_micro, // version_micro - &setting->version_micro_prefix, // version_micro_prefix - &setting->version_minor, // version_minor - &setting->version_minor_prefix, // version_minor_prefix - &setting->version_nano, // version_nano - &setting->version_nano_prefix, // version_nano_prefix - }; - - uint8_t * const settings_single_language[] = { - 0, // build_compiler - 0, // build_indexer - &setting->build_language, // build_language - }; - - uint8_t * const settings_single_version[] = { - 0, // build_compiler - 0, // build_indexer - 0, // build_language - 0, // build_script - 0, // build_shared - 0, // build_static - 0, // path_headers - 0, // path_headers_preserve - 0, // path_language - 0, // path_library_script - 0, // path_library_shared - 0, // path_library_static - 0, // path_program_script - 0, // path_program_shared - 0, // path_program_static - 0, // path_sources - 0, // path_standard - 0, // process_post - 0, // process_pre - 0, // project_name - 0, // search_exclusive - 0, // search_shared - 0, // search_static - &setting->version_file, // version_file - 0, // version_major - 0, // version_major_prefix - 0, // version_micro - 0, // version_micro_prefix - 0, // version_minor - 0, // version_minor_prefix - 0, // version_nano - 0, // version_nano_prefix - &setting->version_target, // version_target - }; - - const uint8_t settings_single_version_default[] = { - 0, // build_compiler - 0, // build_indexer - 0, // build_language - 0, // build_script - 0, // build_shared - 0, // build_static - 0, // path_headers - 0, // path_headers_preserve - 0, // path_language - 0, // path_library_script - 0, // path_library_shared - 0, // path_library_static - 0, // path_program_script - 0, // path_program_shared - 0, // path_program_static - 0, // path_sources - 0, // path_standard - 0, // process_post - 0, // process_pre - 0, // project_name - 0, // search_exclusive - 0, // search_shared - 0, // search_static - fake_build_version_type_micro, // version_file - 0, // version_major - 0, // version_major_prefix - 0, // version_micro - 0, // version_micro_prefix - 0, // version_minor - 0, // version_minor_prefix - 0, // version_nano - 0, // version_nano_prefix - fake_build_version_type_major, // version_target - }; - - const char *settings_single_version_default_name[] = { - 0, // build_compiler - 0, // build_indexer - 0, // build_language - 0, // build_script - 0, // build_shared - 0, // build_static - 0, // path_headers - 0, // path_headers_preserve - 0, // path_language - 0, // path_library_script - 0, // path_library_shared - 0, // path_library_static - 0, // path_program_script - 0, // path_program_shared - 0, // path_program_static - 0, // path_sources - 0, // path_standard - 0, // process_post - 0, // process_pre - 0, // project_name - 0, // search_exclusive - 0, // search_shared - 0, // search_static - fake_build_version_micro_s, // version_file - 0, // version_major - 0, // version_major_prefix - 0, // version_micro - 0, // version_micro_prefix - 0, // version_minor - 0, // version_minor_prefix - 0, // version_nano - 0, // version_nano_prefix - fake_build_version_major_s, // version_target - }; - - // 1 = "yes" or "no", 2 = path/, 3 = literal, 4 = "bash", "c", or "c++", 5 = "major", "minor", "micro", or "nano". - const uint8_t settings_single_type[] = { - 3, // build_compiler - 3, // build_indexer - 4, // build_language - 1, // build_script - 1, // build_shared - 1, // build_static - 2, // path_headers - 1, // path_headers_preserve - 2, // path_language - 2, // path_library_script - 2, // path_library_shared - 2, // path_library_static - 2, // path_program_script - 2, // path_program_shared - 2, // path_program_static - 2, // path_sources - 1, // path_standard - 3, // process_post - 3, // process_pre - 3, // project_name - 1, // search_exclusive - 1, // search_shared - 1, // search_static - 5, // version_file - 3, // version_major - 3, // version_major_prefix - 3, // version_micro - 3, // version_micro_prefix - 3, // version_minor - 3, // version_minor_prefix - 3, // version_nano - 3, // version_nano_prefix - 5, // version_target - }; - - for (f_array_length_t i = 0; i < 33; ++i) { - - if (!settings_single_source[i]->used) continue; - - if (settings_single_source[i]->used > 1) { - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' may only have a single property, only using the first: '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, settings_single_source[i]->array[0], main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - - if (settings_single_type[i] == 1) { - if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_common_setting_bool_yes_s, settings_single_source[i]->array[0].used, fake_common_setting_bool_yes_s_length) == F_equal_to) { - *settings_single_bool[i] = F_true; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_common_setting_bool_no_s, settings_single_source[i]->array[0].used, fake_common_setting_bool_no_s_length) == F_equal_to) { - *settings_single_bool[i] = F_false; - } - else { - *settings_single_bool[i] = F_true; - - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' may be either '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_yes_s, main->warning.notable); - fl_print_format("%[' or '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_no_s, main->warning.notable); - fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_common_setting_bool_yes_s, main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - } - else if (settings_single_type[i] == 4) { - if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_bash_s, settings_single_source[i]->array[0].used, fake_build_language_bash_s_length) == F_equal_to) { - *settings_single_language[i] = fake_build_language_type_bash; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_c_s, settings_single_source[i]->array[0].used, fake_build_language_c_s_length) == F_equal_to) { - *settings_single_language[i] = fake_build_language_type_c; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_language_cpp_s, settings_single_source[i]->array[0].used, fake_build_language_cpp_s_length) == F_equal_to) { - *settings_single_language[i] = fake_build_language_type_cpp; - } - else { - *settings_single_language[i] = fake_build_language_type_c; - - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' may only be one of '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_bash_s, main->warning.notable); - fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_c_s, main->warning.notable); - fl_print_format("%[', or '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_cpp_s, main->warning.notable); - fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_language_c_s, main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - } - else if (settings_single_type[i] == 5) { - if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_major_s, settings_single_source[i]->array[0].used, fake_build_version_major_s_length) == F_equal_to) { - *settings_single_version[i] = fake_build_version_type_major; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_minor_s, settings_single_source[i]->array[0].used, fake_build_version_minor_s_length) == F_equal_to) { - *settings_single_version[i] = fake_build_version_type_minor; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_micro_s, settings_single_source[i]->array[0].used, fake_build_version_micro_s_length) == F_equal_to) { - *settings_single_version[i] = fake_build_version_type_micro; - } - else if (fl_string_compare_trim(settings_single_source[i]->array[0].string, fake_build_version_nano_s, settings_single_source[i]->array[0].used, fake_build_version_nano_s_length) == F_equal_to) { - *settings_single_version[i] = fake_build_version_type_nano; - } - else { - *settings_single_version[i] = settings_single_version_default[i]; - - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, settings_single_name[i], main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' may only be one of '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_major_s, main->warning.notable); - fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_minor_s, main->warning.notable); - fl_print_format("%[', '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_micro_s, main->warning.notable); - fl_print_format("%[', or '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_nano_s, main->warning.notable); - fl_print_format("%[', defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, settings_single_version_default_name[i], main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - } - else { - - // Replace any potential existing value. - settings_single_destination[i]->used = 0; - - *status = f_string_dynamic_append_nulless(settings_single_source[i]->array[0], settings_single_destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - - break; - } - - if (settings_single_type[i] == 2) { - *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, settings_single_destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); - - break; - } - } - - *status = f_string_dynamic_terminate_after(settings_single_destination[i]); - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - - break; - } - } - } // for - - if (F_status_is_error_not(*status)) { - if (checks && !setting->version_file) { - setting->version_file = fake_build_version_type_micro; - - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, fake_build_setting_name_version_file_s, main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' is required, defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_micro_s, main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - - if (checks && !setting->version_target) { - setting->version_target = fake_build_version_type_major; - - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe setting '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, fake_build_setting_name_version_target_s, main->warning.notable); - fl_print_format("%[' in the file '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%S%]", main->warning.to.stream, main->warning.notable, path_file, main->warning.notable); - fl_print_format("%[' is required, defaulting to '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%s%]", main->warning.to.stream, main->warning.notable, fake_build_version_major_s, main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - } - - // Provide these defaults only if the Object is not defined (this allows for empty Content to exist if the Object is defined). - // In the case of the version prefixes, if the associated version is empty, then instead clear the associated version prefix. - if (F_status_is_error_not(*status)) { - f_string_dynamic_t *prefix[] = { - &setting->version_major_prefix, - &setting->version_minor_prefix, - &setting->version_micro_prefix, - &setting->version_nano_prefix, - }; - - f_string_dynamic_t *version[] = { - &setting->version_major, - &setting->version_minor, - &setting->version_micro, - &setting->version_nano, - }; - - bool has_prefix_object[] = { - settings_matches[61], // version_major_prefix - settings_matches[63], // version_minor_prefix - settings_matches[65], // version_micro_prefix - settings_matches[67], // version_nano_prefix - }; - - const char *name_target[] = { - fake_build_version_major_s, - fake_build_version_minor_s, - fake_build_version_micro_s, - fake_build_version_nano_s, - }; - - const char *name_object[] = { - fake_build_setting_name_version_major_s, - fake_build_setting_name_version_minor_s, - fake_build_setting_name_version_micro_s, - fake_build_setting_name_version_nano_s, - }; - - const char *setting_name[] = { - fake_build_setting_name_version_file_s, - fake_build_setting_name_version_target_s, - }; - - const uint8_t setting_target[] = { - setting->version_file, - setting->version_target, - }; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < 4; ++i) { - - if (version[i]->used) { - if (!has_prefix_object[i]) { - prefix[i]->used = 0; - - *status = f_string_append(fake_build_setting_default_version_prefix_s, fake_build_setting_default_version_prefix_s_length, prefix[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - } - } - else if (checks) { - prefix[i]->used = 0; - - for (j = 0; j < 2; ++j) { - - if (setting_target[j] && i + 1 <= setting_target[j]) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SWhen the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting_name[j], main->error.notable); - fl_print_format("%[' is set to '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, name_target[setting_target[j] - 1], main->error.notable); - fl_print_format("%[' then the '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, name_object[i], main->error.notable); - fl_print_format("%[' Object must have Content.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_failure); - break; - } - } // for - - if (F_status_is_error(*status)) break; - } - } // for - } - } - - macro_f_string_dynamics_t_delete_simple(build_compiler); - macro_f_string_dynamics_t_delete_simple(build_indexer); - macro_f_string_dynamics_t_delete_simple(build_language); - macro_f_string_dynamics_t_delete_simple(build_script); - macro_f_string_dynamics_t_delete_simple(build_shared); - macro_f_string_dynamics_t_delete_simple(build_static); - macro_f_string_dynamics_t_delete_simple(path_headers); - macro_f_string_dynamics_t_delete_simple(path_headers_preserve); - macro_f_string_dynamics_t_delete_simple(path_language); - macro_f_string_dynamics_t_delete_simple(path_library_script); - macro_f_string_dynamics_t_delete_simple(path_library_shared); - macro_f_string_dynamics_t_delete_simple(path_library_static); - macro_f_string_dynamics_t_delete_simple(path_program_script); - macro_f_string_dynamics_t_delete_simple(path_program_shared); - macro_f_string_dynamics_t_delete_simple(path_program_static); - macro_f_string_dynamics_t_delete_simple(path_sources); - macro_f_string_dynamics_t_delete_simple(path_standard); - macro_f_string_dynamics_t_delete_simple(process_post); - macro_f_string_dynamics_t_delete_simple(process_pre); - macro_f_string_dynamics_t_delete_simple(project_name); - macro_f_string_dynamics_t_delete_simple(search_exclusive); - macro_f_string_dynamics_t_delete_simple(search_shared); - macro_f_string_dynamics_t_delete_simple(search_static); - macro_f_string_dynamics_t_delete_simple(version_file); - macro_f_string_dynamics_t_delete_simple(version_major); - macro_f_string_dynamics_t_delete_simple(version_major_prefix); - macro_f_string_dynamics_t_delete_simple(version_micro); - macro_f_string_dynamics_t_delete_simple(version_micro_prefix); - macro_f_string_dynamics_t_delete_simple(version_minor); - macro_f_string_dynamics_t_delete_simple(version_minor_prefix); - macro_f_string_dynamics_t_delete_simple(version_nano); - macro_f_string_dynamics_t_delete_simple(version_nano_prefix); - macro_f_string_dynamics_t_delete_simple(version_target); - } -#endif // _di_fake_build_load_setting_process_ - -#ifndef _di_fake_build_load_setting_defaults_ - void fake_build_load_setting_defaults(fake_main_t * const main, fake_build_setting_t *setting, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - return; - } - - { - const f_string_t sources[] = { - fake_build_setting_default_version_s, - fake_build_setting_default_version_s, - fake_build_setting_default_version_s, - }; - - const f_array_length_t lengths[] = { - fake_build_setting_default_version_s_length, - fake_build_setting_default_version_s_length, - fake_build_setting_default_version_s_length, - }; - - f_string_dynamic_t * const destinations[] = { - &setting->version_major, - &setting->version_minor, - &setting->version_micro, - }; - - for (uint8_t i = 0; i < 3; ++i) { - - if (destinations[i]->used) continue; - - *status = f_string_append_assure(sources[i], lengths[i], destinations[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(destinations[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - } // for - } - - if (F_status_is_error(*status)) return; - - // Override setting file when any of these are specified in the command line. - if (main->parameters[fake_parameter_shared_disabled].result == f_console_result_found) { - if (main->parameters[fake_parameter_shared_enabled].result == f_console_result_found) { - if (main->parameters[fake_parameter_shared_enabled].location > main->parameters[fake_parameter_shared_disabled].location) { - setting->build_shared = F_true; - setting->search_shared = F_true; - } - else { - setting->build_shared = F_false; - setting->search_shared = F_false; - } - - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe parameters '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_shared_disabled_s, main->error.notable); - fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_shared_enabled_s, main->error.notable); - fl_print_format("%[' contradict, defaulting to '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_shared ? fake_long_shared_enabled_s : fake_long_shared_disabled_s, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - } - else { - setting->build_shared = F_false; - setting->search_shared = F_false; - } - } - else if (main->parameters[fake_parameter_shared_enabled].result == f_console_result_found) { - setting->build_shared = F_true; - setting->search_shared = F_true; - } - - if (main->parameters[fake_parameter_static_disabled].result == f_console_result_found) { - if (main->parameters[fake_parameter_static_enabled].result == f_console_result_found) { - if (main->parameters[fake_parameter_static_enabled].location > main->parameters[fake_parameter_static_disabled].location) { - setting->build_static = F_true; - setting->search_static = F_true; - } - else { - setting->build_static = F_false; - setting->search_static = F_false; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe parameters '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_static_disabled_s, main->error.notable); - fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fake_long_static_enabled_s, main->error.notable); - fl_print_format("%[' contradict, defaulting to '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_static ? fake_long_static_enabled_s : fake_long_static_disabled_s, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - } - else { - setting->build_static = F_false; - setting->search_static = F_false; - } - } - else if (main->parameters[fake_parameter_static_enabled].result == f_console_result_found) { - setting->build_static = F_true; - setting->search_static = F_true; - } - - if (setting->build_language == fake_build_language_type_c || setting->build_language == fake_build_language_type_cpp) { - if (setting->build_shared == F_false && setting->build_static == F_false) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe build settings '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_build_shared_s, main->error.notable); - fl_print_format("%[' and '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_build_setting_name_build_static_s, main->error.notable); - fl_print_format("%[' cannot both be false when using the language '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, setting->build_language == fake_build_language_type_c ? fake_build_language_c_s : fake_build_language_cpp_s, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } -#endif // _di_fake_build_load_setting_defaults_ - -#ifndef _di_fake_build_load_stage_ - void fake_build_load_stage(fake_main_t * const main, const f_string_static_t settings_file, fake_build_stage_t *stage, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - return; - } - - const f_string_t names[] = { - fake_build_stage_libraries_script_s, - fake_build_stage_libraries_shared_s, - fake_build_stage_libraries_static_s, - fake_build_stage_objects_static_s, - fake_build_stage_process_post_s, - fake_build_stage_process_pre_s, - fake_build_stage_programs_script_s, - fake_build_stage_programs_shared_s, - fake_build_stage_programs_static_s, - fake_build_stage_skeleton_s, - fake_build_stage_sources_headers_s, - fake_build_stage_sources_script_s, - fake_build_stage_sources_settings_s, - }; - - const f_array_length_t lengths[] = { - fake_build_stage_libraries_script_s_length, - fake_build_stage_libraries_shared_s_length, - fake_build_stage_libraries_static_s_length, - fake_build_stage_objects_static_s_length, - fake_build_stage_process_post_s_length, - fake_build_stage_process_pre_s_length, - fake_build_stage_programs_script_s_length, - fake_build_stage_programs_shared_s_length, - fake_build_stage_programs_static_s_length, - fake_build_stage_skeleton_s_length, - fake_build_stage_sources_headers_s_length, - fake_build_stage_sources_script_s_length, - fake_build_stage_sources_settings_s_length, - }; - - f_string_dynamic_t * const values[] = { - &stage->file_libraries_script, - &stage->file_libraries_shared, - &stage->file_libraries_static, - &stage->file_objects_static, - &stage->file_process_post, - &stage->file_process_pre, - &stage->file_programs_script, - &stage->file_programs_shared, - &stage->file_programs_static, - &stage->file_skeleton, - &stage->file_sources_headers, - &stage->file_sources_script, - &stage->file_sources_settings, - }; - - *status = F_none; - - f_string_dynamic_t settings_file_base = f_string_dynamic_t_initialize; - - if (settings_file.used) { - *status = f_file_name_base(settings_file.string, settings_file.used, &settings_file_base); - } - else { - *status = f_file_name_base(main->file_data_build_settings.string, main->file_data_build_settings.used, &settings_file_base); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_base", F_true); - - return; - } - - for (uint8_t i = 0; i < fake_build_stage_total_d; ++i) { - - *status = f_string_dynamic_append_nulless(main->path_build_stage, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - break; - } - - if (main->process.used) { - *status = f_string_append(main->process.string, main->process.used, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - - *status = f_string_append(fake_build_stage_separate_s, fake_build_stage_separate_s_length, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - } - - *status = f_string_append_nulless(names[i], lengths[i], values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - break; - } - - *status = f_string_append(fake_build_stage_separate_s, fake_build_stage_separate_s_length, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - - *status = f_string_dynamic_append(settings_file_base, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - break; - } - - *status = f_string_append(fake_build_stage_built_s, fake_build_stage_built_s_length, values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(values[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - } // for - - macro_f_string_dynamic_t_delete_simple(settings_file_base); - } -#endif // _di_fake_build_load_stage_ - -#ifndef _di_fake_build_objects_static_ - int fake_build_objects_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - if (!data_build.setting.build_sources_library.used) return 0; - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Compiling static objects.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - f_string_dynamic_t file_name = f_string_dynamic_t_initialize; - f_string_dynamic_t destination_path = f_string_dynamic_t_initialize; - f_string_dynamics_t arguments = f_string_dynamics_t_initialize; - f_array_length_t source_length = 0; - f_array_length_t destination_length = 0; - - const f_string_static_t *path_sources = &main->path_sources; - - int result = main->child; - - if (data_build.setting.path_standard) { - path_sources = &main->path_sources_c; - - if (data_build.setting.build_language == fake_build_language_type_cpp) { - path_sources = &main->path_sources_cpp; - } - } - else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { - path_sources = &data_build.setting.path_sources; - } - - const f_string_dynamics_t *sources[2] = { - &data_build.setting.build_sources_library, - &data_build.setting.build_sources_library_static, - }; - - f_array_length_t i = 0; - f_array_length_t j = 0; - uint8_t k = 0; - - for (i = 0; i < 2; ++i) { - - for (j = 0; j < sources[i]->used; ++j) { - - file_name.used = 0; - destination_path.used = 0; - - source_length = path_sources->used + sources[i]->array[j].used; - - char source[source_length + 1]; - - memcpy(source, path_sources->string, path_sources->used); - memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); - source[source_length] = 0; - - *status = fake_build_get_file_name_without_extension(main, sources[i]->array[j], &file_name); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fake_build_get_file_name_without_extension", F_true); - break; - } - - *status = f_file_name_directory(sources[i]->array[j].string, sources[i]->array[j].used, &destination_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_file_name_directory", F_true); - break; - } - - if (destination_path.used) { - *status = f_string_dynamic_prepend(main->path_build_objects, &destination_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_prepend", F_true); - break; - } - - *status = f_string_append_assure(f_path_separator_s, F_path_separator_s_length, &destination_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append_assure", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(&destination_path); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - - *status = f_directory_exists(destination_path.string); - - if (*status == F_false) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe path '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, destination_path, main->error.notable); - fl_print_format("%[' exists but is not a directory.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_failure); - break; - } - else if (*status == F_file_found_not) { - *status = f_directory_create(destination_path.string, mode.directory); - - if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found_not) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe path '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, destination_path, main->error.notable); - fl_print_format("%[' could not be created, a parent directory does not exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - else { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_create", F_true, destination_path.string, "create", fll_error_file_type_directory); - } - - break; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Directory '%Q' created.%c", main->output.to.stream, destination_path, f_string_eol_s[0]); - } - } - else if (F_status_is_error(*status)) { - fll_error_file_print(main->error, F_status_set_fine(*status), "f_directory_exists", F_true, destination_path.string, "create", fll_error_file_type_directory); - break; - } - - destination_length = destination_path.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; - } - else { - destination_length = main->path_build_objects.used + file_name.used + fake_build_parameter_object_name_suffix_s_length; - } - - char destination[destination_length + 1]; - - if (destination_path.used) { - memcpy(destination, destination_path.string, destination_path.used); - memcpy(destination + destination_path.used, file_name.string, file_name.used); - memcpy(destination + destination_path.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); - } - else { - memcpy(destination, main->path_build_objects.string, main->path_build_objects.used); - memcpy(destination + main->path_build_objects.used, file_name.string, file_name.used); - memcpy(destination + main->path_build_objects.used + file_name.used, fake_build_parameter_object_name_suffix_s, fake_build_parameter_object_name_suffix_s_length); - } - - destination[destination_length] = 0; - - const f_string_t values[] = { - source, - fake_build_parameter_object_compile_s, - fake_build_parameter_object_static_s, - fake_build_parameter_object_output_s, - destination, - }; - - const f_array_length_t lengths[] = { - source_length, - fake_build_parameter_object_compile_s_length, - fake_build_parameter_object_static_s_length, - fake_build_parameter_object_output_s_length, - destination_length, - }; - - for (uint8_t k = 0; k < 5; ++k) { - - if (!lengths[k]) continue; - - *status = fll_execute_arguments_add(values[k], lengths[k], &arguments); - if (F_status_is_error(*status)) break; - } // for - - fake_build_arguments_standard_add(main, data_build, F_false, F_true, &arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); - break; - } - - result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); - - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error(*status) || *status == F_child) break; - } // for - - if (F_status_is_error(*status) || *status == F_child) break; - } // for - - macro_f_string_dynamic_t_delete_simple(file_name); - macro_f_string_dynamic_t_delete_simple(destination_path); - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error_not(*status) && *status != F_child) { - fake_build_touch(main, file_stage, status); - } - - return result; - } -#endif // _di_fake_build_objects_static_ - -#ifndef _di_fake_build_operate_ - f_status_t fake_build_operate(const f_string_static_t setting_file, fake_main_t *main) { - - if (fake_signal_received(main)) { - return F_status_set_error(F_interrupt); - } - - f_status_t status = F_none; - f_mode_t mode = f_mode_t_initialize; - - fake_build_data_t data_build = fake_build_data_t_initialize; - fake_build_stage_t stage = fake_build_stage_t_initialize; - - macro_f_mode_t_set_default_umask(mode, main->umask); - - fake_build_load_setting(main, setting_file, &data_build.setting, &status); - - if (F_status_is_fine(status)) { - if (main->output.verbosity != f_console_verbosity_quiet) { - flockfile(main->output.to.stream); - - fl_print_format("%c%[Building project%] ", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important); - fl_print_format("%[%Q%]", main->output.to.stream, main->context.set.notable, data_build.setting.project_name, main->context.set.notable); - fl_print_format("%[.%]%c", main->output.to.stream, main->context.set.important, main->context.set.important, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - } - - fake_build_load_stage(main, setting_file, &stage, &status); - - fake_build_load_environment(main, data_build, &data_build.environment, &status); - - fake_build_skeleton(main, data_build, mode.directory, stage.file_skeleton, &status); - - main->child = fake_build_execute_process_script(main, data_build, data_build.setting.process_pre, stage.file_process_pre, &status); - - fake_build_copy(main, mode, "setting files", main->path_data_settings, main->path_build_settings, data_build.setting.build_sources_setting, stage.file_sources_settings, 0, &status); - - if (data_build.setting.build_language == fake_build_language_type_bash) { - fake_build_libraries_script(main, data_build, mode, stage.file_libraries_script, &status); - - fake_build_programs_script(main, data_build, mode, stage.file_programs_script, &status); - - if (data_build.setting.build_script) { - fake_build_copy(main, mode, "scripts", main->path_sources_script, main->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0, &status); - } - } - else { - if (data_build.setting.build_sources_headers.used) { - const f_string_static_t *path_sources = &main->path_sources; - - if (data_build.setting.path_standard) { - path_sources = &main->path_sources_c; - - if (data_build.setting.build_language == fake_build_language_type_cpp) { - path_sources = &main->path_sources_cpp; - } - } - else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { - path_sources = &data_build.setting.path_sources; - } - - const f_array_length_t path_sources_base_length = path_sources->used; - - f_string_static_t path_headers = f_string_static_t_initialize; - f_array_length_t directory_headers_length = main->path_build_includes.used + data_build.setting.path_headers.used; - - char directory_headers[directory_headers_length + 1]; - - memcpy(directory_headers, main->path_build_includes.string, main->path_build_includes.used); - - if (data_build.setting.path_headers.used) { - memcpy(directory_headers + main->path_build_includes.used, data_build.setting.path_headers.string, data_build.setting.path_headers.used); - } - - directory_headers[directory_headers_length] = 0; - - path_headers.string = directory_headers; - path_headers.used = directory_headers_length; - path_headers.size = directory_headers_length + 1; - - fake_build_copy(main, mode, "header files", *path_sources, path_headers, data_build.setting.build_sources_headers, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); - - if (data_build.setting.build_shared) { - fake_build_copy(main, mode, "shared header files", *path_sources, path_headers, data_build.setting.build_sources_headers_shared, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); - } - - if (data_build.setting.build_static) { - fake_build_copy(main, mode, "static header files", *path_sources, path_headers, data_build.setting.build_sources_headers_static, stage.file_sources_headers, data_build.setting.path_headers_preserve ? path_sources_base_length : 0, &status); - } - } - - if (data_build.setting.build_shared) { - main->child = fake_build_library_shared(main, data_build, mode, stage.file_libraries_shared, &status); - - main->child = fake_build_program_shared(main, data_build, mode, stage.file_programs_shared, &status); - } - - if (data_build.setting.build_static) { - main->child = fake_build_objects_static(main, data_build, mode, stage.file_objects_static, &status); - - main->child = fake_build_library_static(main, data_build, mode, stage.file_libraries_static, &status); - - main->child = fake_build_program_static(main, data_build, mode, stage.file_programs_static, &status); - } - - if (data_build.setting.build_script) { - fake_build_copy(main, mode, "scripts", main->path_sources_script, main->path_build_programs_script, data_build.setting.build_sources_script, stage.file_sources_script, 0, &status); - } - } - - fake_build_execute_process_script(main, data_build, data_build.setting.process_post, stage.file_process_post, &status); - - macro_fake_build_main_delete_simple(data_build); - macro_fake_build_stage_t_delete_simple(stage); + macro_fake_build_main_delete_simple(data_build); + macro_fake_build_stage_t_delete_simple(stage); return status; } #endif // _di_fake_build_operate_ -#ifndef _di_fake_build_programs_script_ - int fake_build_programs_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - - // @todo needs to perform some sort of regex replace on the program scripts. - - fake_build_touch(main, file_stage, status); - - return 0; - } -#endif // _di_fake_build_programs_script_ - -#ifndef _di_fake_build_program_shared_ - int fake_build_program_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - if (!data_build.setting.build_sources_program.used) return 0; - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Compiling shared program.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - f_string_dynamics_t arguments = f_string_dynamics_t_initialize; - - { - const f_string_static_t *path_sources = &main->path_sources; - - if (data_build.setting.path_standard) { - path_sources = &main->path_sources_c; - - if (data_build.setting.build_language == fake_build_language_type_cpp) { - path_sources = &main->path_sources_cpp; - } - } - else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { - path_sources = &data_build.setting.path_sources; - } - - f_array_length_t source_length = 0; - - const f_string_dynamics_t *sources[2] = { - &data_build.setting.build_sources_program, - &data_build.setting.build_sources_program_shared, - }; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < 2; ++i) { - - for (j = 0; j < sources[i]->used; ++j) { - - source_length = path_sources->used + sources[i]->array[j].used; - - char source[source_length + 1]; - - memcpy(source, path_sources->string, path_sources->used); - memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); - source[source_length] = 0; - - *status = fll_execute_arguments_add(source, source_length, &arguments); - if (F_status_is_error(*status)) break; - } // for - - if (F_status_is_error(*status)) break; - } // for - } - - if (F_status_is_error_not(*status)) { - f_array_length_t parameter_file_name_path_length = main->path_build_programs_shared.used + data_build.setting.project_name.used; - - char parameter_file_name_path[parameter_file_name_path_length + 1]; - - memcpy(parameter_file_name_path, main->path_build_programs_shared.string, main->path_build_programs_shared.used); - memcpy(parameter_file_name_path + main->path_build_programs_shared.used, data_build.setting.project_name.string, data_build.setting.project_name.used); - parameter_file_name_path[parameter_file_name_path_length] = 0; - - const f_string_t values[] = { - fake_build_parameter_library_output_s, - parameter_file_name_path, - }; - - const f_array_length_t lengths[] = { - fake_build_parameter_library_output_s_length, - parameter_file_name_path_length, - }; - - for (uint8_t i = 0; i < 2; ++i) { - - if (!lengths[i]) continue; - - *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); - if (F_status_is_error(*status)) break; - } // for - } - - // if project-specific library sources exist, then the -lproject_name needs to be added to the arguments. - if (F_status_is_error_not(*status) && data_build.setting.build_sources_library.used) { - f_array_length_t link_project_library_length = fake_build_parameter_library_link_file_s_length + data_build.setting.project_name.used; - - char link_project_library[link_project_library_length + 1]; - - memcpy(link_project_library, fake_build_parameter_library_link_file_s, fake_build_parameter_library_link_file_s_length); - memcpy(link_project_library + fake_build_parameter_library_link_file_s_length, data_build.setting.project_name.string, data_build.setting.project_name.used); - link_project_library[link_project_library_length] = 0; - - *status = fll_execute_arguments_add(link_project_library, link_project_library_length, &arguments); - } - - fake_build_arguments_standard_add(main, data_build, F_true, F_false, &arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); - - macro_f_string_dynamics_t_delete_simple(arguments); - return 0; - } - - int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); - - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error_not(*status) && *status != F_child) { - fake_build_touch(main, file_stage, status); - } - - return result; - } -#endif // _di_fake_build_program_shared_ - -#ifndef _di_fake_build_program_static_ - int fake_build_program_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) { - - if (F_status_is_error(*status) || f_file_exists(file_stage.string) == F_true || *status == F_child) return main->child; - if (!data_build.setting.build_sources_program.used) return 0; - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Compiling static program.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - f_string_dynamics_t arguments = f_string_dynamics_t_initialize; - - { - const f_string_static_t *path_sources = &main->path_sources; - - if (data_build.setting.path_standard) { - path_sources = &main->path_sources_c; - - if (data_build.setting.build_language == fake_build_language_type_cpp) { - path_sources = &main->path_sources_cpp; - } - } - else if (main->parameters[fake_parameter_path_sources].result != f_console_result_additional) { - path_sources = &data_build.setting.path_sources; - } - - f_array_length_t source_length = 0; - - const f_string_dynamics_t *sources[2] = { - &data_build.setting.build_sources_program, - &data_build.setting.build_sources_program_static, - }; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < 2; ++i) { - - for (j = 0; j < sources[i]->used; ++j) { - - if (!sources[i]->array[j].used) continue; - - source_length = path_sources->used + sources[i]->array[j].used; - - char source[source_length + 1]; - - memcpy(source, path_sources->string, path_sources->used); - memcpy(source + path_sources->used, sources[i]->array[j].string, sources[i]->array[j].used); - source[source_length] = 0; - - *status = fll_execute_arguments_add(source, source_length, &arguments); - if (F_status_is_error(*status)) break; - } // for - - if (F_status_is_error(*status)) break; - } // for - } - - if (F_status_is_error_not(*status)) { - f_array_length_t source_library_length = main->path_build_libraries_static.used + fake_build_parameter_library_name_prefix_s_length + data_build.setting.project_name.used + fake_build_parameter_library_name_suffix_static_s_length; - - char source_library[source_library_length + 1]; - - source_library_length = 0; - - // only include the library if there are sources that would result in it being built. - if (data_build.setting.build_sources_library.used) { - memcpy(source_library, main->path_build_libraries_static.string, main->path_build_libraries_static.used); - source_library_length += main->path_build_libraries_static.used; - - memcpy(source_library + source_library_length, fake_build_parameter_library_name_prefix_s, fake_build_parameter_library_name_prefix_s_length); - source_library_length += fake_build_parameter_library_name_prefix_s_length; - - memcpy(source_library + source_library_length, data_build.setting.project_name.string, data_build.setting.project_name.used); - source_library_length += data_build.setting.project_name.used; - - memcpy(source_library + source_library_length, fake_build_parameter_library_name_suffix_static_s, fake_build_parameter_library_name_suffix_static_s_length); - source_library_length += fake_build_parameter_library_name_suffix_static_s_length; - } - - source_library[source_library_length] = 0; - - f_array_length_t parameter_file_name_path_length = main->path_build_programs_static.used + data_build.setting.project_name.used; - - char parameter_file_name_path[parameter_file_name_path_length + 1]; - - memcpy(parameter_file_name_path, main->path_build_programs_static.string, main->path_build_programs_static.used); - memcpy(parameter_file_name_path + main->path_build_programs_static.used, data_build.setting.project_name.string, data_build.setting.project_name.used); - parameter_file_name_path[parameter_file_name_path_length] = 0; - - const f_string_t values[] = { - source_library, - fake_build_parameter_library_static_s, - fake_build_parameter_library_output_s, - parameter_file_name_path, - }; - - const f_array_length_t lengths[] = { - source_library_length, - fake_build_parameter_library_static_s_length, - fake_build_parameter_library_output_s_length, - parameter_file_name_path_length, - }; - - for (uint8_t i = 0; i < 4; ++i) { - - if (!lengths[i]) continue; - - *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); - if (F_status_is_error(*status)) break; - } // for - } - - fake_build_arguments_standard_add(main, data_build, F_false, F_false, &arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_execute_arguments_add", F_true); - - macro_f_string_dynamics_t_delete_simple(arguments); - return 0; - } - - int result = fake_execute(main, data_build.environment, data_build.setting.build_compiler, arguments, status); - - macro_f_string_dynamics_t_delete_simple(arguments); - - if (F_status_is_error_not(*status) && *status != F_child) { - fake_build_touch(main, file_stage, status); - } - - return result; - } -#endif // _di_fake_build_program_static_ - #ifndef _di_fake_build_touch_ void fake_build_touch(fake_main_t * const main, const f_string_dynamic_t file, f_status_t *status) { diff --git a/level_3/fake/c/private-build.h b/level_3/fake/c/private-build.h index de980d1..19cd74d 100644 --- a/level_3/fake/c/private-build.h +++ b/level_3/fake/c/private-build.h @@ -75,29 +75,6 @@ extern "C" { #endif // _di_fake_build_copy_ /** - * Create all of the base directories inside the build directory. - * - * @param main - * The main program data. - * @param data_build - * The build data. - * @param mode - * The directory mode. - * @param file_stage - * The specific stage file path. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_skeleton_ - extern void fake_build_skeleton(fake_main_t * const main, const fake_build_data_t data_build, const mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_skeleton_ - -/** * Execute the Pre-Process or Post-pocess build script. * * @param main @@ -142,222 +119,6 @@ extern "C" { #endif // _di_fake_build_get_file_name_without_extension_ /** - * Build the script libraries. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_libraries_script_ - extern int fake_build_libraries_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_libraries_script_ - -/** - * Build the shared libraries. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_library_shared_ - extern int fake_build_library_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_library_shared_ - -/** - * Build the static libraries. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_library_static_ - extern int fake_build_library_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_library_static_ - -/** - * Find the build setting file, load it, validate it, and process it. - * - * @param main - * The main program data. - * @param setting_file - * The name of the settings file to use. - * If setting_file.used is 0, then the default or program parameter supplied file is used. - * @param setting - * All build related setting data from the build setting file are loaded into this. - * These setting will have any specified mode property applied. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_load_setting_ - extern void fake_build_load_setting(fake_main_t * const main, const f_string_static_t setting_file, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_load_setting_ - -/** - * Assign build setting defaults. - * - * @param main - * The main program data. - * @param path_file - * The path to the buffer. - * @param buffer - * The loaded file data. - * @param setting - * All build related setting data from the build setting file are loaded into this. - * These setting will have any specified mode property applied. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_load_setting_defaults_ - extern void fake_build_load_setting_defaults(fake_main_t * const main, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_load_setting_defaults_ - -/** - * Load and process the setting buffer. - * - * @param main - * The main program data. - * @param checks - * If TRUE, perform certain "required" sanity checks. - * If FALSE, do not perform certain "required" sanity checks (intended for a fakefile rather than a build settings file). - * @param path_file - * The path to the buffer. - * @param buffer - * The loaded file data. - * @param objects - * The object mapping. - * @param contents - * The content mapping. - * @param setting - * All build related setting data from the build setting file are loaded into this. - * These setting will have any specified mode property applied. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_load_setting_process_ - extern void fake_build_load_setting_process(fake_main_t * const main, const bool checks, const f_string_t path_file, const f_string_static_t buffer, const f_fss_objects_t objects, const f_fss_contents_t contents, fake_build_setting_t *setting, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_load_setting_process_ - -/** - * Load the environment used when executing commands. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param environment - * The environment data. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_load_environment_ - extern void fake_build_load_environment(fake_main_t * const main, const fake_build_data_t data_build, f_string_maps_t *environment, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_load_environment_ - -/** - * Load the stage file paths. - * - * @param main - * The main program data. - * @param settings_file - * The path to the settings file. - * @param stage - * All stage file paths. - * @param status - * The return status. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_build_load_stage_ - extern void fake_build_load_stage(fake_main_t * const main, const f_string_static_t settings_file, fake_build_stage_t *stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_load_stage_ - -/** - * Build the static objects. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_objects_static_ - extern int fake_build_objects_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_objects_static_ - -/** * Execute the build operation. * * @param setting_file @@ -376,78 +137,6 @@ extern "C" { #endif // _di_fake_build_operate_ /** - * Build the script programs. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_programs_script_ - extern int fake_build_programs_script(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_programs_script_ - -/** - * Build the shared programs. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_program_shared_ - extern int fake_build_program_shared(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_program_shared_ - -/** - * Build the static programs. - * - * @param main - * The main program data. - * @param data_build - * All build related data. - * @param mode - * The file mode. - * @param file_stage - * The specific stage file path. - * @param status - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_build_program_static_ - extern int fake_build_program_static(fake_main_t * const main, const fake_build_data_t data_build, const f_mode_t mode, const f_string_static_t file_stage, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_build_program_static_ - -/** * Touch the given build stage file, but only if there are no current errors in status. * * @param main diff --git a/level_3/fake/c/private-fake-path_generate.c b/level_3/fake/c/private-fake-path_generate.c new file mode 100644 index 0000000..309eacf --- /dev/null +++ b/level_3/fake/c/private-fake-path_generate.c @@ -0,0 +1,465 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-fake-path_generate.h" +#include "private-build.h" +#include "private-make.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_path_generate_ + f_status_t fake_path_generate(fake_main_t *main) { + + f_status_t status = F_none; + uint8_t i = 0; + + { + const f_string_dynamic_t *parameters_source[] = { + &main->path_build, + &main->path_data, + &main->path_sources, + }; + + const uint8_t parameters_length[] = { + 7, + 2, + 4, + }; + + f_string_dynamic_t *parameters_value_0[] = { + &main->path_build_documents, + &main->path_build_includes, + &main->path_build_libraries, + &main->path_build_objects, + &main->path_build_programs, + &main->path_build_settings, + &main->path_build_stage, + }; + + f_string_dynamic_t *parameters_value_1[] = { + &main->path_data_build, + &main->path_data_settings, + }; + + f_string_dynamic_t *parameters_value_2[] = { + &main->path_sources_bash, + &main->path_sources_c, + &main->path_sources_cpp, + &main->path_sources_script, + }; + + f_string_dynamic_t **const parameters_value[] = { + parameters_value_0, + parameters_value_1, + parameters_value_2, + }; + + for (i = 0; i < 3; ++i) { + + status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); + + return status; + } + } // for + } + + { + const f_string_t parameters_source[] = { + fake_path_part_documents_s, + fake_path_part_includes_s, + fake_path_part_libraries_s, + fake_path_part_objects_s, + fake_path_part_programs_s, + fake_path_part_settings_s, + fake_path_part_stage_s, + fake_path_part_build_s, + fake_path_part_settings_s, + fake_path_part_documents_s, + fake_path_part_licenses_s, + fake_path_part_bash_s, + fake_path_part_c_s, + fake_path_part_cpp_s, + fake_path_part_script_s, + }; + + const f_array_length_t parameters_length[] = { + fake_path_part_documents_s_length, + fake_path_part_includes_s_length, + fake_path_part_libraries_s_length, + fake_path_part_objects_s_length, + fake_path_part_programs_s_length, + fake_path_part_settings_s_length, + fake_path_part_stage_s_length, + fake_path_part_build_s_length, + fake_path_part_settings_s_length, + fake_path_part_documents_s_length, + fake_path_part_licenses_s_length, + fake_path_part_bash_s_length, + fake_path_part_c_s_length, + fake_path_part_cpp_s_length, + fake_path_part_script_s_length, + }; + + f_string_dynamic_t * const parameters_value[] = { + &main->path_build_documents, + &main->path_build_includes, + &main->path_build_libraries, + &main->path_build_objects, + &main->path_build_programs, + &main->path_build_settings, + &main->path_build_stage, + &main->path_data_build, + &main->path_data_settings, + &main->path_documents, + &main->path_licenses, + &main->path_sources_bash, + &main->path_sources_c, + &main->path_sources_cpp, + &main->path_sources_script, + }; + + for (i = 0; i < 15; ++i) { + + status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); + + return status; + } + } // for + } + + { + const f_string_dynamic_t *parameters_source[] = { + &main->path_build_libraries, + &main->path_build_programs, + &main->path_data_build, + &main->path_documents, + }; + + const uint8_t parameters_length[] = { + 3, + 3, + 4, + 1, + }; + + f_string_dynamic_t *parameters_value_0[] = { + &main->path_build_libraries_script, + &main->path_build_libraries_shared, + &main->path_build_libraries_static, + }; + + f_string_dynamic_t *parameters_value_1[] = { + &main->path_build_programs_script, + &main->path_build_programs_shared, + &main->path_build_programs_static, + }; + + f_string_dynamic_t *parameters_value_2[] = { + &main->file_data_build_defines, + &main->file_data_build_dependencies, + &main->file_data_build_fakefile, + &main->file_data_build_settings, + }; + + f_string_dynamic_t *parameters_value_3[] = { + &main->file_documents_readme, + }; + + f_string_dynamic_t **const parameters_value[] = { + parameters_value_0, + parameters_value_1, + parameters_value_2, + parameters_value_3, + }; + + for (i = 0; i < 4; ++i) { + + status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); + + return status; + } + } // for + } + + // When custom fakefile or settings are used and they are paths to a file, remove the default path. + if (f_path_is(main->fakefile.string, main->fakefile.used)) { + main->file_data_build_fakefile.used = 0; + } + + if (f_path_is(main->settings.string, main->settings.used)) { + main->file_data_build_settings.used = 0; + } + + { + const f_string_t parameters_source[] = { + fake_path_part_script_s, + fake_path_part_shared_s, + fake_path_part_static_s, + fake_path_part_script_s, + fake_path_part_shared_s, + fake_path_part_static_s, + fake_file_defines_s, + fake_file_dependencies_s, + main->fakefile.string, + main->settings.string, + fake_file_readme_s, + }; + + const f_array_length_t parameters_length[] = { + fake_path_part_script_s_length, + fake_path_part_shared_s_length, + fake_path_part_static_s_length, + fake_path_part_script_s_length, + fake_path_part_shared_s_length, + fake_path_part_static_s_length, + fake_file_defines_s_length, + fake_file_dependencies_s_length, + main->fakefile.used, + main->settings.used, + fake_file_readme_s_length, + }; + + f_string_dynamic_t * const parameters_value[] = { + &main->path_build_libraries_script, + &main->path_build_libraries_shared, + &main->path_build_libraries_static, + &main->path_build_programs_script, + &main->path_build_programs_shared, + &main->path_build_programs_static, + &main->file_data_build_defines, + &main->file_data_build_dependencies, + &main->file_data_build_fakefile, + &main->file_data_build_settings, + &main->file_documents_readme, + }; + + for (i = 0; i < 11; ++i) { + + status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); + + return status; + } + } // for + } + + if (main->path_work.used) { + { + f_string_dynamic_t * const parameters_value[] = { + &main->path_work_includes, + &main->path_work_libraries, + &main->path_work_programs, + }; + + for (i = 0; i < 3; ++i) { + + status = f_string_dynamic_append_nulless(main->path_work, parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true); + + return status; + } + } // for + } + + { + const f_string_t parameters_source[] = { + fake_path_part_includes_s, + fake_path_part_libraries_s, + fake_path_part_programs_s, + }; + + const f_array_length_t parameters_length[] = { + fake_path_part_includes_s_length, + fake_path_part_libraries_s_length, + fake_path_part_programs_s_length, + }; + + f_string_dynamic_t * const parameters_value[] = { + &main->path_work_includes, + &main->path_work_libraries, + &main->path_work_programs, + }; + + for (i = 0; i < 3; ++i) { + + status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); + + return status; + } + } // for + } + + { + const f_string_dynamic_t *parameters_source[] = { + &main->path_work_libraries, + &main->path_work_programs, + }; + + const uint8_t parameters_length[] = { + 3, + 3, + }; + + f_string_dynamic_t *parameters_value_0[] = { + &main->path_work_libraries_script, + &main->path_work_libraries_shared, + &main->path_work_libraries_static, + }; + + f_string_dynamic_t *parameters_value_1[] = { + &main->path_work_programs_script, + &main->path_work_programs_shared, + &main->path_work_programs_static, + }; + + f_string_dynamic_t **const parameters_value[] = { + parameters_value_0, + parameters_value_1, + }; + + for (i = 0; i < 2; ++i) { + + status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); + + return status; + } + } // for + } + + { + const f_string_t parameters_source[] = { + fake_path_part_script_s, + fake_path_part_shared_s, + fake_path_part_static_s, + fake_path_part_script_s, + fake_path_part_shared_s, + fake_path_part_static_s, + }; + + const f_array_length_t parameters_length[] = { + fake_path_part_script_s_length, + fake_path_part_shared_s_length, + fake_path_part_static_s_length, + fake_path_part_script_s_length, + fake_path_part_shared_s_length, + fake_path_part_static_s_length, + }; + + f_string_dynamic_t * const parameters_value[] = { + &main->path_work_libraries_script, + &main->path_work_libraries_shared, + &main->path_work_libraries_static, + &main->path_work_programs_script, + &main->path_work_programs_shared, + &main->path_work_programs_static, + }; + + for (i = 0; i < 6; ++i) { + + status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); + + return status; + } + } // for + } + } + + { + f_string_dynamic_t * const parameters_value[] = { + &main->path_build_documents, + &main->path_build_includes, + &main->path_build_libraries, + &main->path_build_libraries_script, + &main->path_build_libraries_shared, + &main->path_build_libraries_static, + &main->path_build_objects, + &main->path_build_programs, + &main->path_build_programs_script, + &main->path_build_programs_shared, + &main->path_build_programs_static, + &main->path_build_settings, + &main->path_build_stage, + &main->path_data_build, + &main->path_data_settings, + &main->path_licenses, + &main->path_sources_bash, + &main->path_sources_c, + &main->path_sources_cpp, + &main->path_sources_script, + &main->path_work_includes, + &main->path_work_libraries, + &main->path_work_libraries_script, + &main->path_work_libraries_shared, + &main->path_work_libraries_static, + &main->path_work_programs, + &main->path_work_programs_script, + &main->path_work_programs_shared, + &main->path_work_programs_static, + &main->file_data_build_defines, + &main->file_data_build_dependencies, + &main->file_data_build_fakefile, + &main->file_data_build_settings, + &main->file_documents_readme, + }; + + for (i = 0; i < 34; ++i) { + + if (!parameters_value[i]->used) continue; + + status = f_string_dynamic_terminate_after(parameters_value[i]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); + + return status; + } + } // for + } + + return F_none; + } +#endif // _di_fake_path_generate_ + +#ifndef _di_fake_path_generate_string_dynamic_ + f_status_t fake_path_generate_string_dynamic(fake_main_t *main, const f_string_dynamic_t source, f_string_dynamic_t *destination[], const uint8_t length) { + + f_status_t status = F_none; + + for (uint8_t i = 0; i < length; ++i) { + + status = f_string_dynamic_append_nulless(source, destination[i]); + if (F_status_is_error(status)) return status; + } // for + + return F_none; + } +#endif // _di_fake_path_generate_string_dynamic_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-fake-path_generate.h b/level_3/fake/c/private-fake-path_generate.h new file mode 100644 index 0000000..9962728 --- /dev/null +++ b/level_3/fake/c/private-fake-path_generate.h @@ -0,0 +1,55 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_fake_path_generate_h +#define _PRIVATE_fake_path_generate_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Generate all appropriate paths based on runtime information. + * + * @param main + * The main program data. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_path_generate_ + extern f_status_t fake_path_generate(fake_main_t *main) F_attribute_visibility_internal_d; +#endif // _di_fake_path_generate_ + +/** + * Generate all appropriate paths based on runtime information from dynamic strings. + * + * @param main + * The main program data. + * @param source + * The string to copy from. + * @param destination + * An array of pointers to the strings to append onto. + * @param length + * The size of the values. + * + * @return + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_path_generate_string_dynamic_ + extern f_status_t fake_path_generate_string_dynamic(fake_main_t *main, const f_string_dynamic_t source, f_string_dynamic_t *destination[], const uint8_t size) F_attribute_visibility_internal_d; +#endif // _di_fake_path_generate_string_dynamic_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_fake_path_generate_h diff --git a/level_3/fake/c/private-fake.c b/level_3/fake/c/private-fake.c index e505fca..c2986ee 100644 --- a/level_3/fake/c/private-fake.c +++ b/level_3/fake/c/private-fake.c @@ -1,6 +1,7 @@ #include "fake.h" #include "private-common.h" #include "private-fake.h" +#include "private-fake-path_generate.h" #include "private-build.h" #include "private-make.h" #include "private-print.h" @@ -150,456 +151,6 @@ extern "C" { } #endif // _di_fake_file_buffer_ -#ifndef _di_fake_path_generate_ - f_status_t fake_path_generate(fake_main_t *main) { - - f_status_t status = F_none; - uint8_t i = 0; - - { - const f_string_dynamic_t *parameters_source[] = { - &main->path_build, - &main->path_data, - &main->path_sources, - }; - - const uint8_t parameters_length[] = { - 7, - 2, - 4, - }; - - f_string_dynamic_t *parameters_value_0[] = { - &main->path_build_documents, - &main->path_build_includes, - &main->path_build_libraries, - &main->path_build_objects, - &main->path_build_programs, - &main->path_build_settings, - &main->path_build_stage, - }; - - f_string_dynamic_t *parameters_value_1[] = { - &main->path_data_build, - &main->path_data_settings, - }; - - f_string_dynamic_t *parameters_value_2[] = { - &main->path_sources_bash, - &main->path_sources_c, - &main->path_sources_cpp, - &main->path_sources_script, - }; - - f_string_dynamic_t **const parameters_value[] = { - parameters_value_0, - parameters_value_1, - parameters_value_2, - }; - - for (i = 0; i < 3; ++i) { - - status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); - - return status; - } - } // for - } - - { - const f_string_t parameters_source[] = { - fake_path_part_documents_s, - fake_path_part_includes_s, - fake_path_part_libraries_s, - fake_path_part_objects_s, - fake_path_part_programs_s, - fake_path_part_settings_s, - fake_path_part_stage_s, - fake_path_part_build_s, - fake_path_part_settings_s, - fake_path_part_documents_s, - fake_path_part_licenses_s, - fake_path_part_bash_s, - fake_path_part_c_s, - fake_path_part_cpp_s, - fake_path_part_script_s, - }; - - const f_array_length_t parameters_length[] = { - fake_path_part_documents_s_length, - fake_path_part_includes_s_length, - fake_path_part_libraries_s_length, - fake_path_part_objects_s_length, - fake_path_part_programs_s_length, - fake_path_part_settings_s_length, - fake_path_part_stage_s_length, - fake_path_part_build_s_length, - fake_path_part_settings_s_length, - fake_path_part_documents_s_length, - fake_path_part_licenses_s_length, - fake_path_part_bash_s_length, - fake_path_part_c_s_length, - fake_path_part_cpp_s_length, - fake_path_part_script_s_length, - }; - - f_string_dynamic_t * const parameters_value[] = { - &main->path_build_documents, - &main->path_build_includes, - &main->path_build_libraries, - &main->path_build_objects, - &main->path_build_programs, - &main->path_build_settings, - &main->path_build_stage, - &main->path_data_build, - &main->path_data_settings, - &main->path_documents, - &main->path_licenses, - &main->path_sources_bash, - &main->path_sources_c, - &main->path_sources_cpp, - &main->path_sources_script, - }; - - for (i = 0; i < 15; ++i) { - - status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - - return status; - } - } // for - } - - { - const f_string_dynamic_t *parameters_source[] = { - &main->path_build_libraries, - &main->path_build_programs, - &main->path_data_build, - &main->path_documents, - }; - - const uint8_t parameters_length[] = { - 3, - 3, - 4, - 1, - }; - - f_string_dynamic_t *parameters_value_0[] = { - &main->path_build_libraries_script, - &main->path_build_libraries_shared, - &main->path_build_libraries_static, - }; - - f_string_dynamic_t *parameters_value_1[] = { - &main->path_build_programs_script, - &main->path_build_programs_shared, - &main->path_build_programs_static, - }; - - f_string_dynamic_t *parameters_value_2[] = { - &main->file_data_build_defines, - &main->file_data_build_dependencies, - &main->file_data_build_fakefile, - &main->file_data_build_settings, - }; - - f_string_dynamic_t *parameters_value_3[] = { - &main->file_documents_readme, - }; - - f_string_dynamic_t **const parameters_value[] = { - parameters_value_0, - parameters_value_1, - parameters_value_2, - parameters_value_3, - }; - - for (i = 0; i < 4; ++i) { - - status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); - - return status; - } - } // for - } - - // When custom fakefile or settings are used and they are paths to a file, remove the default path. - if (f_path_is(main->fakefile.string, main->fakefile.used)) { - main->file_data_build_fakefile.used = 0; - } - - if (f_path_is(main->settings.string, main->settings.used)) { - main->file_data_build_settings.used = 0; - } - - { - const f_string_t parameters_source[] = { - fake_path_part_script_s, - fake_path_part_shared_s, - fake_path_part_static_s, - fake_path_part_script_s, - fake_path_part_shared_s, - fake_path_part_static_s, - fake_file_defines_s, - fake_file_dependencies_s, - main->fakefile.string, - main->settings.string, - fake_file_readme_s, - }; - - const f_array_length_t parameters_length[] = { - fake_path_part_script_s_length, - fake_path_part_shared_s_length, - fake_path_part_static_s_length, - fake_path_part_script_s_length, - fake_path_part_shared_s_length, - fake_path_part_static_s_length, - fake_file_defines_s_length, - fake_file_dependencies_s_length, - main->fakefile.used, - main->settings.used, - fake_file_readme_s_length, - }; - - f_string_dynamic_t * const parameters_value[] = { - &main->path_build_libraries_script, - &main->path_build_libraries_shared, - &main->path_build_libraries_static, - &main->path_build_programs_script, - &main->path_build_programs_shared, - &main->path_build_programs_static, - &main->file_data_build_defines, - &main->file_data_build_dependencies, - &main->file_data_build_fakefile, - &main->file_data_build_settings, - &main->file_documents_readme, - }; - - for (i = 0; i < 11; ++i) { - - status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - - return status; - } - } // for - } - - if (main->path_work.used) { - { - f_string_dynamic_t * const parameters_value[] = { - &main->path_work_includes, - &main->path_work_libraries, - &main->path_work_programs, - }; - - for (i = 0; i < 3; ++i) { - - status = f_string_dynamic_append_nulless(main->path_work, parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true); - - return status; - } - } // for - } - - { - const f_string_t parameters_source[] = { - fake_path_part_includes_s, - fake_path_part_libraries_s, - fake_path_part_programs_s, - }; - - const f_array_length_t parameters_length[] = { - fake_path_part_includes_s_length, - fake_path_part_libraries_s_length, - fake_path_part_programs_s_length, - }; - - f_string_dynamic_t * const parameters_value[] = { - &main->path_work_includes, - &main->path_work_libraries, - &main->path_work_programs, - }; - - for (i = 0; i < 3; ++i) { - - status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - - return status; - } - } // for - } - - { - const f_string_dynamic_t *parameters_source[] = { - &main->path_work_libraries, - &main->path_work_programs, - }; - - const uint8_t parameters_length[] = { - 3, - 3, - }; - - f_string_dynamic_t *parameters_value_0[] = { - &main->path_work_libraries_script, - &main->path_work_libraries_shared, - &main->path_work_libraries_static, - }; - - f_string_dynamic_t *parameters_value_1[] = { - &main->path_work_programs_script, - &main->path_work_programs_shared, - &main->path_work_programs_static, - }; - - f_string_dynamic_t **const parameters_value[] = { - parameters_value_0, - parameters_value_1, - }; - - for (i = 0; i < 2; ++i) { - - status = fake_path_generate_string_dynamic(main, *parameters_source[i], parameters_value[i], parameters_length[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "fake_path_generate_string_dynamic", F_true); - - return status; - } - } // for - } - - { - const f_string_t parameters_source[] = { - fake_path_part_script_s, - fake_path_part_shared_s, - fake_path_part_static_s, - fake_path_part_script_s, - fake_path_part_shared_s, - fake_path_part_static_s, - }; - - const f_array_length_t parameters_length[] = { - fake_path_part_script_s_length, - fake_path_part_shared_s_length, - fake_path_part_static_s_length, - fake_path_part_script_s_length, - fake_path_part_shared_s_length, - fake_path_part_static_s_length, - }; - - f_string_dynamic_t * const parameters_value[] = { - &main->path_work_libraries_script, - &main->path_work_libraries_shared, - &main->path_work_libraries_static, - &main->path_work_programs_script, - &main->path_work_programs_shared, - &main->path_work_programs_static, - }; - - for (i = 0; i < 6; ++i) { - - status = f_string_append_nulless(parameters_source[i], parameters_length[i], parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - - return status; - } - } // for - } - } - - { - f_string_dynamic_t * const parameters_value[] = { - &main->path_build_documents, - &main->path_build_includes, - &main->path_build_libraries, - &main->path_build_libraries_script, - &main->path_build_libraries_shared, - &main->path_build_libraries_static, - &main->path_build_objects, - &main->path_build_programs, - &main->path_build_programs_script, - &main->path_build_programs_shared, - &main->path_build_programs_static, - &main->path_build_settings, - &main->path_build_stage, - &main->path_data_build, - &main->path_data_settings, - &main->path_licenses, - &main->path_sources_bash, - &main->path_sources_c, - &main->path_sources_cpp, - &main->path_sources_script, - &main->path_work_includes, - &main->path_work_libraries, - &main->path_work_libraries_script, - &main->path_work_libraries_shared, - &main->path_work_libraries_static, - &main->path_work_programs, - &main->path_work_programs_script, - &main->path_work_programs_shared, - &main->path_work_programs_static, - &main->file_data_build_defines, - &main->file_data_build_dependencies, - &main->file_data_build_fakefile, - &main->file_data_build_settings, - &main->file_documents_readme, - }; - - for (i = 0; i < 34; ++i) { - - if (!parameters_value[i]->used) continue; - - status = f_string_dynamic_terminate_after(parameters_value[i]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - return status; - } - } // for - } - - return F_none; - } -#endif // _di_fake_path_generate_ - -#ifndef _di_fake_path_generate_string_dynamic_ - f_status_t fake_path_generate_string_dynamic(fake_main_t *main, const f_string_dynamic_t source, f_string_dynamic_t *destination[], const uint8_t length) { - - f_status_t status = F_none; - - for (uint8_t i = 0; i < length; ++i) { - - status = f_string_dynamic_append_nulless(source, destination[i]); - if (F_status_is_error(status)) return status; - } // for - - return F_none; - } -#endif // _di_fake_path_generate_string_dynamic_ - #ifndef _di_fake_process_console_parameters_ f_status_t fake_process_console_parameters(const f_console_arguments_t *arguments, fake_main_t *main) { diff --git a/level_3/fake/c/private-fake.h b/level_3/fake/c/private-fake.h index 6e41ef7..2ef5091 100644 --- a/level_3/fake/c/private-fake.h +++ b/level_3/fake/c/private-fake.h @@ -60,42 +60,6 @@ extern "C" { #endif // _di_fake_file_buffer_ /** - * Generate all appropriate paths based on runtime information. - * - * @param main - * The main program data. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_path_generate_ - extern f_status_t fake_path_generate(fake_main_t *main) F_attribute_visibility_internal_d; -#endif // _di_fake_path_generate_ - -/** - * Generate all appropriate paths based on runtime information from dynamic strings. - * - * @param main - * The main program data. - * @param source - * The string to copy from. - * @param destination - * An array of pointers to the strings to append onto. - * @param length - * The size of the values. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_path_generate_string_dynamic_ - extern f_status_t fake_path_generate_string_dynamic(fake_main_t *main, const f_string_dynamic_t source, f_string_dynamic_t *destination[], const uint8_t size) F_attribute_visibility_internal_d; -#endif // _di_fake_path_generate_string_dynamic_ - -/** * Validate console arguments and print any relating error messages. * * @param arguments diff --git a/level_3/fake/c/private-make-load_fakefile.c b/level_3/fake/c/private-make-load_fakefile.c new file mode 100644 index 0000000..2cc4833 --- /dev/null +++ b/level_3/fake/c/private-make-load_fakefile.c @@ -0,0 +1,635 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-build-load.h" +#include "private-clean.h" +#include "private-make.h" +#include "private-make-load_fakefile.h" +#include "private-make-operate.h" +#include "private-print.h" +#include "private-skeleton.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_make_load_fakefile_ + void fake_make_load_fakefile(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + return; + } + + data_make->fakefile.used = 0; + + *status = fake_file_buffer(main, main->file_data_build_fakefile.string, &data_make->buffer); + if (F_status_is_error(*status)) return; + + if (!data_make->buffer.used) { + if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe fakefile '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, main->file_data_build_fakefile, main->warning.notable); + fl_print_format("%[' is empty.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + + return; + } + + f_fss_objects_t list_objects = f_fss_objects_t_initialize; + f_fss_contents_t list_contents = f_fss_contents_t_initialize; + + { + f_string_range_t range = macro_f_string_range_t_initialize(data_make->buffer.used); + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_fss_comments_t comments = f_fss_comments_t_initialize; + + { + f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); + + *status = fll_fss_basic_list_read(data_make->buffer, state, &range, &list_objects, &list_contents, &delimits, 0, &comments); + } + + if (F_status_is_error(*status)) { + fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_basic_list_read", main->file_data_build_fakefile.string, range, F_true); + } + else { + *status = fl_fss_apply_delimit(delimits, &data_make->buffer); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); + } + } + + macro_f_fss_delimits_t_delete_simple(delimits); + macro_f_fss_comments_t_delete_simple(comments); + + if (F_status_is_error(*status)) { + macro_f_fss_objects_t_delete_simple(list_objects); + macro_f_fss_contents_t_delete_simple(list_contents); + + return; + } + } + + { + bool missing_main = F_true; + bool missing_settings = F_true; + + f_fss_set_t settings = f_fss_set_t_initialize; + + f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); + + const f_string_static_t name_settings = macro_f_string_static_t_initialize(fake_make_section_settings_s, fake_make_section_settings_s_length); + const f_string_static_t name_main = macro_f_string_static_t_initialize(fake_make_section_main_s, fake_make_section_main_s_length); + + const f_string_range_t name_settings_range = macro_f_string_range_t_initialize(fake_make_section_settings_s_length); + const f_string_range_t name_main_range = macro_f_string_range_t_initialize(fake_make_section_main_s_length); + + if (list_objects.used > data_make->fakefile.size) { + macro_f_fss_nameds_t_resize((*status), data_make->fakefile, list_objects.used); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "macro_f_fss_nameds_t_resize", F_true); + + macro_f_fss_set_t_delete_simple(settings); + macro_f_fss_objects_t_delete_simple(list_objects); + macro_f_fss_contents_t_delete_simple(list_contents); + + return; + } + + { + f_string_range_t content_range = f_string_range_t_initialize; + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + + for (f_array_length_t i = 0; i < list_objects.used; ++i) { + + if (!(i % fake_signal_check_short_d) && fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + break; + } + + if (fl_string_dynamic_partial_compare(name_settings, data_make->buffer, name_settings_range, list_objects.array[i]) == F_equal_to) { + if (!missing_settings) { + fake_print_warning_settings_object_multiple(main, main->file_data_build_fakefile.string, "list", name_settings.string); + + continue; + } + + delimits.used = 0; + content_range = list_contents.array[i].array[0]; + + *status = fll_fss_extended_read(data_make->buffer, state, &content_range, &settings.objects, &settings.contents, 0, 0, &delimits, 0); + + if (F_status_is_error(*status)) { + fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_fakefile.string, content_range, F_true); + + break; + } + + *status = fl_fss_apply_delimit(delimits, &data_make->buffer); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); + + break; + } + + missing_settings = F_false; + + continue; + } + else if (fl_string_dynamic_partial_compare(name_main, data_make->buffer, name_main_range, list_objects.array[i]) == F_equal_to) { + if (!missing_main) { + fake_print_warning_settings_object_multiple(main, main->file_data_build_fakefile.string, "list", name_main.string); + + continue; + } + + missing_main = F_false; + data_make->main = data_make->fakefile.used; + } + + data_make->fakefile.array[data_make->fakefile.used].name = list_objects.array[i]; + + delimits.used = 0; + content_range = list_contents.array[i].array[0]; + + *status = fll_fss_extended_read(data_make->buffer, state, &content_range, &data_make->fakefile.array[data_make->fakefile.used].objects, &data_make->fakefile.array[data_make->fakefile.used].contents, 0, &data_make->fakefile.array[data_make->fakefile.used].quotess, &delimits, 0); + + if (F_status_is_error(*status)) { + fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_fakefile.string, content_range, F_true); + + break; + } + + *status = fl_fss_apply_delimit(delimits, &data_make->buffer); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); + + break; + } + + ++data_make->fakefile.used; + } // for + + macro_f_fss_delimits_t_delete_simple(delimits); + } + + macro_f_fss_objects_t_delete_simple(list_objects); + macro_f_fss_contents_t_delete_simple(list_contents); + + if (F_status_is_error(*status)) { + macro_f_fss_set_t_delete_simple(settings); + + return; + } + + if (missing_main) { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SThe fakefile '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, main->file_data_build_fakefile, main->error.notable); + fl_print_format("%[' is missing the required '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_make_section_main_s, main->error.notable); + fl_print_format("%[' object.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_failure); + + macro_f_fss_set_t_delete_simple(settings); + + return; + } + + // Always have the parameter variable "return" map at index 0 and be pre-initialized. + { + f_string_t function_name = "macro_f_string_map_multis_t_resize"; + + macro_f_string_map_multis_t_resize(*status, data_make->setting_make.parameter, F_memory_default_allocation_small_d); + + if (F_status_is_error_not(*status)) { + data_make->setting_make.parameter.used = 1; + + function_name = "f_string_append"; + *status = f_string_append(fake_make_setting_return_s, fake_make_setting_return_s_length, &data_make->setting_make.parameter.array[0].name); + } + + if (F_status_is_error_not(*status)) { + function_name = "f_string_dynamic_terminate_after"; + *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].name); + } + + if (F_status_is_error_not(*status)) { + function_name = "f_string_dynamics_resize"; + *status = f_string_dynamics_resize(1, &data_make->setting_make.parameter.array[0].value); + } + + if (F_status_is_error_not(*status)) { + function_name = "f_string_dynamic_terminate_after"; + *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), function_name, F_true); + + macro_f_fss_set_t_delete_simple(settings); + + return; + } + } + + f_string_range_t *range_compiler = 0; + f_string_range_t *range_indexer = 0; + + data_make->setting_make.parameter.array[0].value.used = 1; + data_make->setting_make.load_build = F_true; + data_make->setting_make.fail = fake_make_operation_fail_type_exit; + + if (settings.objects.used) { + bool unmatched_fail = F_true; + bool unmatched_load = F_true; + + for (f_array_length_t i = 0; i < settings.objects.used; ++i) { + + if (fl_string_dynamic_partial_compare_string(fake_make_setting_compiler_s, data_make->buffer, fake_make_setting_compiler_s_length, settings.objects.array[i]) == F_equal_to) { + if (range_compiler) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_compiler_s); + } + else { + if (settings.contents.array[i].used) { + range_compiler = &settings.contents.array[i].array[0]; + + if (settings.contents.array[i].used > 1) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_compiler_s); + } + } + else { + fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); + } + } + } + else if (fl_string_dynamic_partial_compare_string(fake_make_setting_environment_s, data_make->buffer, fake_make_setting_environment_s_length, settings.objects.array[i]) == F_equal_to) { + f_string_dynamic_t name_define = f_string_dynamic_t_initialize; + + f_array_length_t j = 0; + f_array_length_t k = 0; + + for (; j < settings.contents.array[i].used; ++j) { + + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, settings.contents.array[i].array[j], &name_define); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); + break; + } + + *status = f_string_dynamic_terminate_after(&name_define); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + break; + } + + // The environment settings are stored in the build settings rathe than the make settings. + if (fake_make_operate_validate_define_name(name_define) == F_true) { + for (k = 0; k < data_make->setting_build.environment.used; ++k) { + if (fl_string_dynamic_compare(name_define, data_make->setting_build.environment.array[k]) == F_equal_to) { + break; + } + } // for + + if (k == data_make->setting_build.environment.used) { + *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, &data_make->setting_build.environment); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); + break; + } + + // Include the terminating NULL when copying. + ++name_define.used; + + *status = f_string_dynamic_append(name_define, &data_make->setting_build.environment.array[data_make->setting_build.environment.used]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + break; + } + + // Ensure that the terminating NULL is after the end of the string used size. + --data_make->setting_build.environment.array[data_make->setting_build.environment.used++].used; + } + else if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe environment name '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, name_define, main->warning.notable); + fl_print_format("%[' is already added.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + else if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe environment name '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, name_define, main->warning.notable); + fl_print_format("%[' is invalid, ignoring.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + + name_define.used = 0; + } // for + + if (F_status_is_error(*status)) { + macro_f_string_dynamic_t_delete_simple(name_define); + + break; + } + + *status = F_none; + macro_f_string_dynamic_t_delete_simple(name_define); + } + else if (fl_string_dynamic_partial_compare_string(fake_make_setting_fail_s, data_make->buffer, fake_make_setting_fail_s_length, settings.objects.array[i]) == F_equal_to) { + if (unmatched_fail) { + if (settings.contents.array[i].used) { + if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_exit_s, data_make->buffer, fake_make_operation_argument_exit_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_exit; + } + else if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_warn_s, data_make->buffer, fake_make_operation_argument_warn_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_warn; + } + else if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_ignore_s, data_make->buffer, fake_make_operation_argument_ignore_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_ignore; + } + else { + fake_print_warning_settings_content_invalid(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], settings.contents.array[i].array[0], fake_make_section_settings_s); + } + + if (settings.contents.array[i].used > 1) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_fail_s); + } + + unmatched_fail = F_false; + } + else { + fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); + } + } + else { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_fail_s); + } + } + else if (fl_string_dynamic_partial_compare_string(fake_make_setting_indexer_s, data_make->buffer, fake_make_setting_indexer_s_length, settings.objects.array[i]) == F_equal_to) { + if (range_indexer) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_indexer_s); + } + else { + if (settings.contents.array[i].used) { + range_indexer = &settings.contents.array[i].array[0]; + + if (settings.contents.array[i].used > 1) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_indexer_s); + } + } + else { + fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); + } + } + } + else if (fl_string_dynamic_partial_compare_string(fake_make_setting_load_build_s, data_make->buffer, fake_make_setting_load_build_s_length, settings.objects.array[i]) == F_equal_to) { + if (unmatched_load) { + if (settings.contents.array[i].used) { + if (fl_string_dynamic_partial_compare_string(fake_common_setting_bool_yes_s, data_make->buffer, fake_common_setting_bool_yes_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + data_make->setting_make.load_build = F_true; + } + else if (fl_string_dynamic_partial_compare_string(fake_common_setting_bool_no_s, data_make->buffer, fake_common_setting_bool_no_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + data_make->setting_make.load_build = F_false; + } + else { + fake_print_warning_settings_content_invalid(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], settings.contents.array[i].array[0], fake_make_section_settings_s); + } + + unmatched_load = F_false; + + if (settings.contents.array[i].used > 1) { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_load_build_s); + } + } + else { + fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); + } + } + else { + fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_load_build_s); + } + } + else if (fl_string_dynamic_partial_compare_string(fake_make_setting_parameter_s, data_make->buffer, fake_make_setting_parameter_s_length, settings.objects.array[i]) == F_equal_to) { + if (settings.contents.array[i].used) { + if (fl_string_dynamic_partial_compare_string(fake_make_setting_return_s, data_make->buffer, fake_make_setting_return_s_length, settings.contents.array[i].array[0]) == F_equal_to) { + if (settings.contents.array[i].used > 1) { + f_string_t function_name = 0; + + // Each define replaces the previous define. + data_make->setting_make.parameter.array[0].value.array[0].used = 0; + + for (f_array_length_t j = 1; j < settings.contents.array[i].used; ++j) { + + function_name = "f_string_dynamic_partial_append_nulless"; + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, settings.contents.array[i].array[j], &data_make->setting_make.parameter.array[0].value.array[0]); + + if (F_status_is_error_not(*status)) { + function_name = "f_string_dynamic_terminate_after"; + *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); + } + + if (F_status_is_error_not(*status) && j + 1 < settings.contents.array[i].used) { + function_name = "f_string_append_assure"; + *status = f_string_append_assure(f_string_space_s, 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), function_name, F_true); + + break; + } + } // for + + if (F_status_is_error(*status)) break; + } + } + } + else { + fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); + } + } + } // for + + if (F_status_is_error(*status)) { + macro_f_fss_set_t_delete_simple(settings); + + return; + } + } + + if (F_status_is_error_not(*status) && data_make->setting_make.load_build) { + f_string_static_t stub = f_string_static_t_initialize; + + fake_build_load_setting(main, stub, &data_make->setting_build, status); + + if (F_status_is_error(*status) && *status != F_status_set_error(F_interrupt)) { + fll_error_print(main->error, F_status_set_fine(*status), "fake_build_load_setting", F_true); + } + } + + if (F_status_is_error(*status)) { + macro_f_fss_set_t_delete_simple(settings); + + return; + } + + // If either compiler or indexer is specified, each will replace any existing build_compiler or build_indexer, respectively. + if (range_compiler) { + data_make->setting_build.build_compiler.used = 0; + + *status = f_string_dynamic_partial_append(data_make->buffer, *range_compiler, &data_make->setting_build.build_compiler); + } + + if (F_status_is_error_not(*status) && range_indexer) { + data_make->setting_build.build_indexer.used = 0; + + *status = f_string_dynamic_partial_append(data_make->buffer, *range_indexer, &data_make->setting_build.build_indexer); + } + + if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) != F_interrupt) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_partial_append", F_true); + } + + macro_f_fss_set_t_delete_simple(settings); + + return; + } + + f_string_map_multis_t define = f_string_map_multis_t_initialize; + + // Load the fakefile "settings" as if they are build "settings". + fake_build_load_setting_process(main, F_false, main->file_data_build_fakefile.string, data_make->buffer, settings.objects, settings.contents, &data_make->setting_build, status); + + if (F_status_is_error_not(*status) && settings.objects.used) { + const f_string_t settings_name[] = { + fake_make_setting_define_s, + fake_make_setting_parameter_s, + }; + + const f_array_length_t settings_length[] = { + fake_make_setting_define_s_length, + fake_make_setting_parameter_s_length, + }; + + f_string_map_multis_t *settings_value[] = { + &define, + &data_make->setting_make.parameter, + }; + + *status = fll_fss_snatch_map_apart(data_make->buffer, settings.objects, settings.contents, settings_name, settings_length, 2, settings_value, 0, 0); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "fll_fss_snatch_map_apart", F_true); + + macro_f_string_map_multis_t_delete_simple(define); + macro_f_fss_set_t_delete_simple(settings); + + return; + } + } + + if (define.used) { + f_status_t status_validate = F_none; + f_string_dynamic_t combined = f_string_dynamic_t_initialize; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + for (; i < define.used; ++i) { + + status_validate = fake_make_operate_validate_define_name(define.array[i].name); + + if (status_validate) { + combined.used = 0; + + for (j = 0; j < define.array[i].value.used; ++j) { + + *status = f_string_dynamic_mash(f_string_space_s, 1, define.array[i].value.array[j], &combined); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_mash_nulless", F_true); + + break; + } + } // for + + if (F_status_is_error(*status)) break; + + *status = f_string_dynamic_terminate_after(&combined); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + break; + } + + *status = f_environment_set(define.array[i].name.string, combined.string, F_true); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_environment_set", F_true); + + break; + } + } + else { + if (main->error.verbosity != f_console_verbosity_quiet) { + flockfile(main->error.to.stream); + + fl_print_format("%c%[%SInvalid characters in the define setting name '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, define.array[i].name, main->error.notable); + fl_print_format("%[', only alpha-numeric ASCII characters and underscore (without a leading digit) are allowed.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); + } + + *status = F_status_set_error(F_failure); + + break; + } + } // for + + macro_f_string_dynamic_t_delete_simple(combined); + } + + macro_f_string_map_multis_t_delete_simple(define); + macro_f_fss_set_t_delete_simple(settings); + } + } +#endif // _di_fake_make_load_fakefile_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-make-load_fakefile.h b/level_3/fake/c/private-make-load_fakefile.h new file mode 100644 index 0000000..cec8f52 --- /dev/null +++ b/level_3/fake/c/private-make-load_fakefile.h @@ -0,0 +1,43 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_make_load_fakefile_h +#define _PRIVATE_make_load_fakefile_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Find the fake file, load it, validate it, and process it. + * + * This will process any additional files as necessary, such as the build settings file. + * + * @param main + * The main program data. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param status + * The return status. + * + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * + * Status codes (with error bit) are returned on any problem. + * + * @see fake_build_load_setting() + */ +#ifndef _di_fake_make_load_fakefile_ + extern void fake_make_load_fakefile(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_load_fakefile_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_make_load_fakefile_h diff --git a/level_3/fake/c/private-make-load_parameters.c b/level_3/fake/c/private-make-load_parameters.c new file mode 100644 index 0000000..8c5e03d --- /dev/null +++ b/level_3/fake/c/private-make-load_parameters.c @@ -0,0 +1,420 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-clean.h" +#include "private-make.h" +#include "private-make-load_parameters.h" +#include "private-print.h" +#include "private-skeleton.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_make_load_parameters_ + void fake_make_load_parameters(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (main->context.mode != F_color_mode_none_d) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter.color); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter_option.color); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + if (main->context.mode == F_color_mode_no_color_d) { + if (main->parameters[fake_parameter_no_color].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + else if (main->parameters[fake_parameter_no_color].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_no_color_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + } + else if (main->context.mode == F_color_mode_dark_d) { + if (main->parameters[fake_parameter_dark].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + else if (main->parameters[fake_parameter_dark].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_dark_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + } + else { + if (main->parameters[fake_parameter_light].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + else if (main->parameters[fake_parameter_light].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_light_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); + } + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + return; + } + + *status = f_string_dynamic_append(data_make->parameter.color.array[data_make->parameter.color.used], &data_make->parameter_option.color.array[data_make->parameter_option.color.used]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++data_make->parameter.color.used; + ++data_make->parameter_option.color.used; + } + + if (main->error.verbosity != f_console_verbosity_normal) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter.verbosity); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter_option.verbosity); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + if (main->error.verbosity == f_console_verbosity_quiet) { + if (main->parameters[fake_parameter_verbosity_quiet].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + else if (main->parameters[fake_parameter_verbosity_quiet].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_quiet_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + if (main->parameters[fake_parameter_verbosity_verbose].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + else if (main->parameters[fake_parameter_verbosity_verbose].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_verbose_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + } + else { + if (main->parameters[fake_parameter_verbosity_debug].type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + else if (main->parameters[fake_parameter_verbosity_debug].type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(f_console_standard_short_debug_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); + } + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + return; + } + + *status = f_string_dynamic_append(data_make->parameter.verbosity.array[data_make->parameter.verbosity.used], &data_make->parameter_option.verbosity.array[data_make->parameter_option.verbosity.used]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++data_make->parameter.verbosity.used; + ++data_make->parameter_option.verbosity.used; + } + + { + const f_string_t parameter[] = { + fake_short_define_s, + fake_short_mode_s, + }; + + const f_console_parameter_t *console[] = { + &main->parameters[fake_parameter_define], + &main->parameters[fake_parameter_mode], + }; + + const f_string_dynamics_t *source[] = { + &main->define, + &main->mode, + }; + + f_string_dynamics_t * const destination[] = { + &data_make->parameter.define, + &data_make->parameter.mode, + }; + + f_string_dynamics_t * const destination_option[] = { + &data_make->parameter_option.define, + &data_make->parameter_option.mode, + }; + + f_string_dynamics_t * const destination_value[] = { + &data_make->parameter_value.define, + &data_make->parameter_value.mode, + }; + + uint8_t i = 0; + f_array_length_t j = 0; + + for (; i < 2; ++i) { + + if (console[i]->result == f_console_result_none) { + continue; + } + + for (j = 0; j < source[i]->used; ++j) { + + if (destination[i]->used + 2 > destination[i]->size) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + } + + *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_option[i]); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_value[i]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); + + return; + } + + if (console[i]->type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &destination[i]->array[destination[i]->used]); + } + else if (console[i]->type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &destination[i]->array[destination[i]->used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(parameter[i], 1, &destination[i]->array[destination[i]->used]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + return; + } + + *status = f_string_dynamic_append(destination[i]->array[destination[i]->used], &destination_option[i]->array[destination_option[i]->used]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++destination[i]->used; + ++destination_option[i]->used; + + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + *status = f_string_dynamic_append(source[i]->array[j], &destination[i]->array[destination[i]->used]); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamic_append(source[i]->array[j], &destination_value[i]->array[destination_value[i]->used]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++destination[i]->used; + ++destination_value[i]->used; + } // for + } // for + } + + { + const f_string_t parameter[] = { + fake_short_fakefile_s, + fake_short_path_build_s, + fake_short_path_data_s, + fake_short_path_sources_s, + fake_short_path_work_s, + fake_short_process_s, + fake_short_settings_s, + }; + + const f_console_parameter_t *console[] = { + &main->parameters[fake_parameter_fakefile], + &main->parameters[fake_parameter_path_build], + &main->parameters[fake_parameter_path_data], + &main->parameters[fake_parameter_path_sources], + &main->parameters[fake_parameter_path_work], + &main->parameters[fake_parameter_process], + &main->parameters[fake_parameter_settings], + }; + + const f_string_dynamic_t *source[] = { + &main->fakefile, + &main->path_build, + &main->path_data, + &main->path_sources, + &main->path_work, + &main->process, + &main->settings, + }; + + f_string_dynamics_t * const destination[] = { + &data_make->parameter.fakefile, + &data_make->parameter.build, + &data_make->parameter.data, + &data_make->parameter.sources, + &data_make->parameter.work, + &data_make->parameter.process, + &data_make->parameter.settings, + }; + + f_string_dynamics_t * const destination_option[] = { + &data_make->parameter_option.fakefile, + &data_make->parameter_option.build, + &data_make->parameter_option.data, + &data_make->parameter_option.sources, + &data_make->parameter_option.work, + &data_make->parameter_option.process, + &data_make->parameter_option.settings, + }; + + f_string_dynamics_t * const destination_value[] = { + &data_make->parameter_value.fakefile, + &data_make->parameter_value.build, + &data_make->parameter_value.data, + &data_make->parameter_value.sources, + &data_make->parameter_value.work, + &data_make->parameter_value.process, + &data_make->parameter_value.settings, + }; + + for (uint8_t i = 0; i < 7; ++i) { + + if (console[i]->result == f_console_result_none) { + continue; + } + + if (destination[i]->used + 2 > destination[i]->size) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + } + + *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_option[i]); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_value[i]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); + + return; + } + + if (console[i]->type == f_console_type_normal) { + *status = f_string_append(f_console_symbol_short_enable_s, 1, &destination[i]->array[destination[i]->used]); + } + else if (console[i]->type == f_console_type_inverse) { + *status = f_string_append(f_console_symbol_short_disable_s, 1, &destination[i]->array[destination[i]->used]); + } + + if (F_status_is_error_not(*status)) { + *status = f_string_append(parameter[i], 1, &destination[i]->array[destination[i]->used]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); + + return; + } + + *status = f_string_dynamic_append(destination[i]->array[destination[i]->used], &destination_option[i]->array[destination_option[i]->used]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++destination[i]->used; + ++destination_option[i]->used; + + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + *status = f_string_dynamic_append(*source[i], &destination[i]->array[destination[i]->used]); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamic_append(*source[i], &destination_value[i]->array[destination_value[i]->used]); + } + + if (F_status_is_error(*status)) { + fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + return; + } + + ++destination[i]->used; + ++destination_value[i]->used; + } // for + } + } +#endif // _di_fake_make_load_parameters_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-make-load_parameters.h b/level_3/fake/c/private-make-load_parameters.h new file mode 100644 index 0000000..cb8f6a1 --- /dev/null +++ b/level_3/fake/c/private-make-load_parameters.h @@ -0,0 +1,39 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_make_load_parameters_h +#define _PRIVATE_make_load_parameters_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Load the environment variables into a structure more readily available for using in parameter expansion. + * + * @param main + * The main program data. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param status + * The return status. + * + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_load_parameters_ + extern void fake_make_load_parameters(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_load_parameters_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_make_load_parameters_h diff --git a/level_3/fake/c/private-make-operate.c b/level_3/fake/c/private-make-operate.c new file mode 100644 index 0000000..66dff31 --- /dev/null +++ b/level_3/fake/c/private-make-operate.c @@ -0,0 +1,4358 @@ +#include "fake.h" +#include "private-common.h" +#include "private-fake.h" +#include "private-build.h" +#include "private-clean.h" +#include "private-make.h" +#include "private-make-load_parameters.h" +#include "private-make-load_fakefile.h" +#include "private-make-operate.h" +#include "private-print.h" +#include "private-skeleton.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_make_operate_ + f_status_t fake_make_operate(fake_main_t * const main) { + + if (fake_signal_received(main)) { + return F_status_set_error(F_interrupt); + } + + if (main->output.verbosity != f_console_verbosity_quiet) { + fll_print_format("%c%[Making project.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); + } + + f_status_t status = F_none; + f_mode_t mode = f_mode_t_initialize; + + f_array_lengths_t section_stack = f_array_lengths_t_initialize; + fake_make_data_t data_make = fake_make_data_t_initialize; + + status = f_string_dynamics_increase(F_memory_default_allocation_small_d, &data_make.path.stack); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); + + return status; + } + + status = f_path_current(F_true, &data_make.path.stack.array[0]); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_path_current", F_true); + + macro_fake_make_data_t_delete_simple(data_make); + + return status; + } + + status = f_directory_open(data_make.path.stack.array[0].string, F_false, &data_make.path.top.id); + + if (F_status_is_error(status)) { + fll_error_print(main->error, F_status_set_fine(status), "f_directory_open", F_true); + + macro_fake_make_data_t_delete_simple(data_make); + + return status; + } + + data_make.path.stack.used = 1; + + macro_f_mode_t_set_default_umask(mode, main->umask); + + fake_make_load_parameters(main, &data_make, &status); + + fake_make_load_fakefile(main, &data_make, &status); + + if (F_status_is_error(status)) { + macro_fake_make_data_t_delete_simple(data_make); + + return status; + } + + if (data_make.setting_make.fail == fake_make_operation_fail_type_exit) { + data_make.error.prefix = fl_print_error_s; + data_make.error.suffix = 0; + data_make.error.context = main->context.set.error; + data_make.error.notable = main->context.set.notable; + data_make.error.to.stream = F_type_error_d; + data_make.error.to.id = F_type_descriptor_error_d; + data_make.error.set = &main->context.set; + } + else if (data_make.setting_make.fail == fake_make_operation_fail_type_warn) { + data_make.error.prefix = fl_print_warning_s; + data_make.error.suffix = 0; + data_make.error.context = main->context.set.warning; + data_make.error.notable = main->context.set.notable; + data_make.error.to.stream = F_type_warning_d; + data_make.error.to.id = F_type_descriptor_warning_d; + data_make.error.set = &main->context.set; + } + else { + data_make.error.to.stream = 0; + data_make.error.prefix = 0; + data_make.error.suffix = 0; + data_make.error.to.id = -1; + data_make.error.set = &main->context.set; + } + + { + const int result = fake_make_operate_section(main, data_make.main, &data_make, §ion_stack, &status); + + if (status == F_child) { + main->child = result; + } + } + + if (data_make.path.current.stream) { + f_file_stream_close(F_true, &data_make.path.current); + } + + { + f_status_t status_path = f_path_change_at(data_make.path.top.id); + + if (F_status_is_error(status_path) && main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SFailed change back to orignal path '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, data_make.path.stack.array[0], main->warning.notable); + fl_print_format("%[', status code =%] ", main->warning.to.stream, main->warning.context, main->warning.context); + fl_print_format("%[%ui%]", main->warning.to.stream, main->warning.notable, F_status_set_fine(status_path), main->warning.notable); + fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + } + + f_file_stream_close(F_true, &data_make.path.top); + + macro_f_array_lengths_t_delete_simple(section_stack) + macro_fake_make_data_t_delete_simple(data_make) + + return status; + } +#endif // _di_fake_make_operate_ + +#ifndef _di_fake_make_operate_expand_ + void fake_make_operate_expand(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_fss_content_t content, const f_fss_quotes_t quotes, fake_make_data_t *data_make, f_string_dynamics_t *arguments, f_status_t *status) { + + if (F_status_is_error(*status)) return; + if (!content.used) return; + + // Pre-allocate the known arguments size. + *status = f_string_dynamics_increase_by(content.used, arguments); + + if (F_status_is_error(*status) || *status == F_string_too_large) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + const f_string_static_t vocabulary_define = macro_f_string_static_t_initialize(F_iki_vocabulary_0002_define_s, F_iki_vocabulary_0002_define_s_length); + const f_string_static_t vocabulary_parameter = macro_f_string_static_t_initialize(F_iki_vocabulary_0002_parameter_s, F_iki_vocabulary_0002_parameter_s_length); + + const f_string_range_t range_define = macro_f_string_range_t_initialize(F_iki_vocabulary_0002_define_s_length); + const f_string_range_t range_parameter = macro_f_string_range_t_initialize(F_iki_vocabulary_0002_parameter_s_length); + + f_iki_variable_t iki_variable = f_iki_variable_t_initialize; + f_iki_vocabulary_t iki_vocabulary = f_iki_vocabulary_t_initialize; + f_iki_content_t iki_content = f_iki_content_t_initialize; + f_iki_delimits_t iki_delimits = f_iki_delimits_t_initialize; + + f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_iki, 0, (void *) &main, 0); + + f_string_range_t range = f_string_range_t_initialize; + f_string_map_multis_t *parameter = &data_make->setting_make.parameter; + + bool unmatched = F_true; + bool parameter_is = F_false; + bool define_is = F_false; + + f_array_length_t i = 0; + f_array_length_t j = 0; + f_array_length_t k = 0; + f_array_length_t l = 0; + + f_array_length_t used_arguments = 0; + f_array_length_t previous = 0; + + const f_string_t reserved_name[] = { + fake_make_parameter_variable_build_s, + fake_make_parameter_variable_color_s, + fake_make_parameter_variable_data_s, + fake_make_parameter_variable_define_s, + fake_make_parameter_variable_fakefile_s, + fake_make_parameter_variable_mode_s, + fake_make_parameter_variable_process_s, + fake_make_parameter_variable_settings_s, + fake_make_parameter_variable_sources_s, + fake_make_parameter_variable_verbosity_s, + fake_make_parameter_variable_work_s, + fake_make_parameter_variable_option_build_s, + fake_make_parameter_variable_option_color_s, + fake_make_parameter_variable_option_data_s, + fake_make_parameter_variable_option_define_s, + fake_make_parameter_variable_option_fakefile_s, + fake_make_parameter_variable_option_mode_s, + fake_make_parameter_variable_option_process_s, + fake_make_parameter_variable_option_settings_s, + fake_make_parameter_variable_option_sources_s, + fake_make_parameter_variable_option_verbosity_s, + fake_make_parameter_variable_option_work_s, + fake_make_parameter_variable_value_build_s, + fake_make_parameter_variable_value_color_s, + fake_make_parameter_variable_value_data_s, + fake_make_parameter_variable_value_define_s, + fake_make_parameter_variable_value_fakefile_s, + fake_make_parameter_variable_value_mode_s, + fake_make_parameter_variable_value_process_s, + fake_make_parameter_variable_value_settings_s, + fake_make_parameter_variable_value_sources_s, + fake_make_parameter_variable_value_verbosity_s, + fake_make_parameter_variable_value_work_s, + }; + + const f_array_length_t reserved_length[] = { + fake_make_parameter_variable_build_s_length, + fake_make_parameter_variable_color_s_length, + fake_make_parameter_variable_data_s_length, + fake_make_parameter_variable_define_s_length, + fake_make_parameter_variable_fakefile_s_length, + fake_make_parameter_variable_mode_s_length, + fake_make_parameter_variable_process_s_length, + fake_make_parameter_variable_settings_s_length, + fake_make_parameter_variable_sources_s_length, + fake_make_parameter_variable_verbosity_s_length, + fake_make_parameter_variable_work_s_length, + fake_make_parameter_variable_build_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_color_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_data_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_define_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_fakefile_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_mode_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_process_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_settings_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_sources_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_verbosity_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_work_s_length + fake_make_parameter_iki_option_s_length, + fake_make_parameter_variable_build_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_color_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_data_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_define_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_fakefile_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_mode_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_process_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_settings_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_sources_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_verbosity_s_length + fake_make_parameter_iki_value_s_length, + fake_make_parameter_variable_work_s_length + fake_make_parameter_iki_value_s_length, + }; + + f_string_dynamics_t * const reserved_value[] = { + &data_make->parameter.build, + &data_make->parameter.color, + &data_make->parameter.data, + &data_make->parameter.define, + &data_make->parameter.fakefile, + &data_make->parameter.mode, + &data_make->parameter.process, + &data_make->parameter.settings, + &data_make->parameter.sources, + &data_make->parameter.verbosity, + &data_make->parameter.work, + &data_make->parameter_option.build, + &data_make->parameter_option.color, + &data_make->parameter_option.data, + &data_make->parameter_option.define, + &data_make->parameter_option.fakefile, + &data_make->parameter_option.mode, + &data_make->parameter_option.process, + &data_make->parameter_option.settings, + &data_make->parameter_option.sources, + &data_make->parameter_option.verbosity, + &data_make->parameter_option.work, + &data_make->parameter_value.build, + &data_make->parameter_value.color, + &data_make->parameter_value.data, + &data_make->parameter_value.define, + &data_make->parameter_value.fakefile, + &data_make->parameter_value.mode, + &data_make->parameter_value.process, + &data_make->parameter_value.settings, + &data_make->parameter_value.sources, + &data_make->parameter_value.verbosity, + &data_make->parameter_value.work, + }; + + for (; i < content.used; ++i) { + + if (content.array[i].start > content.array[i].stop) continue; + + range = content.array[i]; + + used_arguments = arguments->used; + + *status = fl_iki_read(state, &data_make->buffer, &range, &iki_variable, &iki_vocabulary, &iki_content, &iki_delimits); + + if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) != F_interrupt) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fl_iki_read", F_true); + } + + break; + } + + for (k = 0; k < iki_delimits.used; ++k) { + data_make->buffer.string[iki_delimits.array[k]] = f_iki_syntax_placeholder_s[0]; + } // for + + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + break; + } + + if (iki_variable.used) { + if (iki_variable.array[0].start > 0 && content.array[i].start < iki_variable.array[0].start) { + range.start = content.array[i].start; + range.stop = iki_variable.array[0].start - 1; + + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); + + break; + } + } + + for (j = 0, previous = iki_variable.array[0].start; j < iki_variable.used; ++j) { + + parameter_is = F_false; + define_is = F_false; + + if (previous + 1 < iki_variable.array[j].start) { + range.start = previous + 1; + range.stop = iki_variable.array[j].start - 1; + + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); + + break; + } + } + + *status = fl_string_dynamic_partial_compare(vocabulary_define, data_make->buffer, range_define, iki_vocabulary.array[j]); + + if (*status == F_equal_to) { + define_is = F_true; + } + else if (*status == F_equal_to_not) { + *status = fl_string_dynamic_partial_compare(vocabulary_parameter, data_make->buffer, range_parameter, iki_vocabulary.array[j]); + + if (*status == F_equal_to) { + parameter_is = F_true; + } + } + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fl_string_dynamic_partial_compare", F_true); + + break; + } + + if (parameter_is) { + unmatched = F_true; + + // Check against reserved parameter names and if matches use them instead. + if (fl_string_dynamic_partial_compare_string(fake_make_parameter_variable_return_s, data_make->buffer, fake_make_parameter_variable_return_s_length, iki_content.array[j]) == F_equal_to) { + if (data_make->setting_make.parameter.array[0].value.array[0].used) { + *status = f_string_dynamic_append(data_make->setting_make.parameter.array[0].value.array[0], &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + break; + } + } + else { + *status = f_string_append("0", 1, &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + } + + ++arguments->used; + unmatched = F_false; + } + else { + for (k = 0; k < 33; ++k) { + + if (fl_string_dynamic_partial_compare_string(reserved_name[k], data_make->buffer, reserved_length[k], iki_content.array[j]) == F_equal_to) { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + + return; + } + + for (l = 0; l < reserved_value[k]->used; ++l) { + + if (l > 0) { + *status = f_string_append(f_string_space_s, 1, &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); + + break; + } + } + + *status = f_string_dynamic_append(reserved_value[k]->array[l], &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + break; + } + } // for + + if (F_status_is_error_not(*status)) { + unmatched = F_false; + ++arguments->used; + } + else { + break; + } + } + } // for + } + + if (unmatched && parameter->used) { + for (k = 0; k < parameter->used; ++k) { + + // Check against iki variable list. + *status = fl_string_dynamic_partial_compare_dynamic(parameter->array[k].name, data_make->buffer, iki_content.array[j]); + + if (*status == F_equal_to) { + unmatched = F_false; + + if (parameter->array[k].value.used) { + if (quotes.array[i]) { + for (l = 0; l < parameter->array[k].value.used; ++l) { + + if (l > 0) { + *status = f_string_append(f_string_space_s, 1, &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); + break; + } + } + + *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + break; + } + } // for + } + else { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); + break; + } + + for (l = 0; l < parameter->array[k].value.used; ++l) { + + *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + break; + } + + *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); + break; + } + + ++arguments->used; + } // for + } + } + + break; + } + else if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fl_string_dynamic_compare", F_true); + break; + } + } // for + } + + if (F_status_is_error(*status)) break; + + if (unmatched) { + *status = fake_make_operate_expand_build(main, quotes.array[i], iki_content.array[j], data_make, arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_operate_expand_build", F_true); + break; + } + } + } + else if (define_is && data_make->setting_make.load_build) { + *status = fake_make_operate_expand_environment(main, quotes.array[i], iki_content.array[j], data_make, arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_operate_expand_environment", F_true); + break; + } + } + + previous = iki_variable.array[j].stop; + } // for + + if (F_status_is_error(*status)) break; + + if (iki_variable.array[iki_variable.used - 1].stop < content.array[i].stop) { + range.start = iki_variable.array[iki_variable.used - 1].stop + 1; + range.stop = content.array[i].stop; + + // If arguments->used was not incremented, then use the value, otherwise arguments->used is past the value to append to, so subtract 1. + if (used_arguments == arguments->used) { + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); + } + else { + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used - 1]); + + if (F_status_is_error_not(*status)) { + *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used - 1]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); + break; + } + } + } + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); + break; + } + } + } + else { + *status = f_string_dynamic_partial_append_nulless(data_make->buffer, content.array[i], &arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append_nulless", F_true); + break; + } + } + + // If iki variable did not match (results in empty string) or iki variable is inside quotes, then increment. + if (used_arguments == arguments->used) { + *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); + break; + } + + ++arguments->used; + } + + macro_f_iki_variable_t_delete_simple(iki_variable); + macro_f_iki_vocabulary_t_delete_simple(iki_vocabulary); + macro_f_iki_content_t_delete_simple(iki_content); + macro_f_iki_delimits_t_delete_simple(iki_delimits); + } // for + + macro_f_iki_variable_t_delete_simple(iki_variable); + macro_f_iki_vocabulary_t_delete_simple(iki_vocabulary); + macro_f_iki_content_t_delete_simple(iki_content); + macro_f_iki_delimits_t_delete_simple(iki_delimits); + } +#endif // _di_fake_make_operate_expand_ + +#ifndef _di_fake_make_operate_expand_build_ + f_status_t fake_make_operate_expand_build(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) { + + f_status_t status = F_none; + f_string_dynamic_t value = f_string_dynamic_t_initialize; + + bool unmatched = F_true; + + { + const f_string_t uint8_name[] = { + fake_build_setting_name_build_language_s, + fake_build_setting_name_version_file_s, + fake_build_setting_name_version_target_s, + }; + + const f_array_length_t uint8_length[] = { + fake_build_setting_name_build_language_s_length, + fake_build_setting_name_version_file_s_length, + fake_build_setting_name_version_target_s_length, + }; + + const uint8_t uint8_value[] = { + data_make->setting_build.build_language, + data_make->setting_build.version_file, + data_make->setting_build.version_target, + }; + + for (uint8_t i = 0; i < 3; ++i) { + + status = fl_string_dynamic_partial_compare_string(uint8_name[i], data_make->buffer, uint8_length[i], range_name); + + if (status == F_equal_to) { + unmatched = F_false; + + status = f_conversion_number_unsigned_to_string(uint8_value[i], f_conversion_data_base_10_s, &value); + break; + } + } // for + } + + if (unmatched) { + const f_string_t bool_name[] = { + fake_build_setting_name_build_script_s, + fake_build_setting_name_build_shared_s, + fake_build_setting_name_build_static_s, + fake_build_setting_name_path_standard_s, + fake_build_setting_name_search_exclusive_s, + fake_build_setting_name_search_shared_s, + fake_build_setting_name_search_static_s, + }; + + const f_array_length_t bool_length[] = { + fake_build_setting_name_build_script_s_length, + fake_build_setting_name_build_shared_s_length, + fake_build_setting_name_build_static_s_length, + fake_build_setting_name_path_standard_s_length, + fake_build_setting_name_search_exclusive_s_length, + fake_build_setting_name_search_shared_s_length, + fake_build_setting_name_search_static_s_length, + }; + + const bool bool_value[] = { + data_make->setting_build.build_script, + data_make->setting_build.build_shared, + data_make->setting_build.build_static, + data_make->setting_build.path_standard, + data_make->setting_build.search_exclusive, + data_make->setting_build.search_shared, + data_make->setting_build.search_static, + }; + + for (uint8_t i = 0; i < 7; ++i) { + + status = fl_string_dynamic_partial_compare_string(bool_name[i], data_make->buffer, bool_length[i], range_name); + + if (status == F_equal_to) { + unmatched = F_false; + + if (bool_value[i]) { + status = f_string_append(fake_common_setting_bool_yes_s, fake_common_setting_bool_yes_s_length, &value); + } + else { + status = f_string_append(fake_common_setting_bool_no_s, fake_common_setting_bool_no_s_length, &value); + } + + break; + } + } // for + } + + if (unmatched) { + const f_string_t dynamic_name[] = { + fake_build_setting_name_build_compiler_s, + fake_build_setting_name_build_indexer_s, + fake_build_setting_name_path_headers_s, + fake_build_setting_name_path_language_s, + fake_build_setting_name_path_library_script_s, + fake_build_setting_name_path_library_shared_s, + fake_build_setting_name_path_library_static_s, + fake_build_setting_name_path_program_script_s, + fake_build_setting_name_path_program_shared_s, + fake_build_setting_name_path_program_static_s, + fake_build_setting_name_path_sources_s, + fake_build_setting_name_process_post_s, + fake_build_setting_name_process_pre_s, + fake_build_setting_name_project_name_s, + fake_build_setting_name_version_major_s, + fake_build_setting_name_version_micro_s, + fake_build_setting_name_version_minor_s, + }; + + const f_array_length_t dynamic_length[] = { + fake_build_setting_name_build_compiler_s_length, + fake_build_setting_name_build_indexer_s_length, + fake_build_setting_name_path_headers_s_length, + fake_build_setting_name_path_language_s_length, + fake_build_setting_name_path_library_script_s_length, + fake_build_setting_name_path_library_shared_s_length, + fake_build_setting_name_path_library_static_s_length, + fake_build_setting_name_path_program_script_s_length, + fake_build_setting_name_path_program_shared_s_length, + fake_build_setting_name_path_program_static_s_length, + fake_build_setting_name_path_sources_s_length, + fake_build_setting_name_process_post_s_length, + fake_build_setting_name_process_pre_s_length, + fake_build_setting_name_project_name_s_length, + fake_build_setting_name_version_major_s_length, + fake_build_setting_name_version_micro_s_length, + fake_build_setting_name_version_minor_s_length, + }; + + const f_string_dynamic_t dynamic_value[] = { + data_make->setting_build.build_compiler, + data_make->setting_build.build_indexer, + data_make->setting_build.path_headers, + data_make->setting_build.path_language, + data_make->setting_build.path_library_script, + data_make->setting_build.path_library_shared, + data_make->setting_build.path_library_static, + data_make->setting_build.path_program_script, + data_make->setting_build.path_program_shared, + data_make->setting_build.path_program_static, + data_make->setting_build.path_sources, + data_make->setting_build.process_post, + data_make->setting_build.process_pre, + data_make->setting_build.project_name, + data_make->setting_build.version_major, + data_make->setting_build.version_micro, + data_make->setting_build.version_minor, + }; + + for (uint8_t i = 0; i < 17; ++i) { + + status = fl_string_dynamic_partial_compare_string(dynamic_name[i], data_make->buffer, dynamic_length[i], range_name); + + if (status == F_equal_to) { + unmatched = F_false; + + status = f_string_dynamic_append(dynamic_value[i], &value); + break; + } + } // for + } + + if (unmatched) { + const f_string_t dynamics_name[] = { + fake_build_setting_name_build_libraries_s, + fake_build_setting_name_build_libraries_shared_s, + fake_build_setting_name_build_libraries_static_s, + fake_build_setting_name_build_sources_headers_s, + fake_build_setting_name_build_sources_headers_shared_s, + fake_build_setting_name_build_sources_headers_static_s, + fake_build_setting_name_build_sources_library_s, + fake_build_setting_name_build_sources_library_shared_s, + fake_build_setting_name_build_sources_library_static_s, + fake_build_setting_name_build_sources_program_s, + fake_build_setting_name_build_sources_program_shared_s, + fake_build_setting_name_build_sources_program_static_s, + fake_build_setting_name_build_sources_settings_s, + fake_build_setting_name_build_sources_script_s, + fake_build_setting_name_defines_s, + fake_build_setting_name_defines_library_s, + fake_build_setting_name_defines_library_shared_s, + fake_build_setting_name_defines_library_static_s, + fake_build_setting_name_defines_program_s, + fake_build_setting_name_defines_program_shared_s, + fake_build_setting_name_defines_program_static_s, + fake_build_setting_name_defines_shared_s, + fake_build_setting_name_defines_static_s, + fake_build_setting_name_environment_s, + fake_build_setting_name_flags_s, + fake_build_setting_name_flags_library_s, + fake_build_setting_name_flags_library_shared_s, + fake_build_setting_name_flags_library_static_s, + fake_build_setting_name_flags_program_s, + fake_build_setting_name_flags_program_shared_s, + fake_build_setting_name_flags_program_static_s, + fake_build_setting_name_flags_shared_s, + fake_build_setting_name_flags_static_s, + fake_build_setting_name_modes_s, + fake_build_setting_name_modes_default_s, + }; + + const f_array_length_t dynamics_length[] = { + fake_build_setting_name_build_libraries_s_length, + fake_build_setting_name_build_libraries_shared_s_length, + fake_build_setting_name_build_libraries_static_s_length, + fake_build_setting_name_build_sources_headers_s_length, + fake_build_setting_name_build_sources_headers_shared_s_length, + fake_build_setting_name_build_sources_headers_static_s_length, + fake_build_setting_name_build_sources_library_s_length, + fake_build_setting_name_build_sources_library_shared_s_length, + fake_build_setting_name_build_sources_library_static_s_length, + fake_build_setting_name_build_sources_program_s_length, + fake_build_setting_name_build_sources_program_shared_s_length, + fake_build_setting_name_build_sources_program_static_s_length, + fake_build_setting_name_build_sources_settings_s_length, + fake_build_setting_name_build_sources_script_s_length, + fake_build_setting_name_defines_s_length, + fake_build_setting_name_defines_library_s_length, + fake_build_setting_name_defines_library_shared_s_length, + fake_build_setting_name_defines_library_static_s_length, + fake_build_setting_name_defines_program_s_length, + fake_build_setting_name_defines_program_shared_s_length, + fake_build_setting_name_defines_program_static_s_length, + fake_build_setting_name_defines_shared_s_length, + fake_build_setting_name_defines_static_s_length, + fake_build_setting_name_environment_length_s, + fake_build_setting_name_flags_s_length, + fake_build_setting_name_flags_library_s_length, + fake_build_setting_name_flags_library_shared_s_length, + fake_build_setting_name_flags_library_static_s_length, + fake_build_setting_name_flags_program_s_length, + fake_build_setting_name_flags_program_shared_s_length, + fake_build_setting_name_flags_program_static_s_length, + fake_build_setting_name_flags_shared_s_length, + fake_build_setting_name_flags_static_s_length, + fake_build_setting_name_modes_s_length, + fake_build_setting_name_modes_default_s_length, + }; + + const f_string_dynamics_t dynamics_value[] = { + data_make->setting_build.build_libraries, + data_make->setting_build.build_libraries_shared, + data_make->setting_build.build_libraries_static, + data_make->setting_build.build_sources_headers, + data_make->setting_build.build_sources_headers_shared, + data_make->setting_build.build_sources_headers_static, + data_make->setting_build.build_sources_library, + data_make->setting_build.build_sources_library_shared, + data_make->setting_build.build_sources_library_static, + data_make->setting_build.build_sources_program, + data_make->setting_build.build_sources_program_shared, + data_make->setting_build.build_sources_program_static, + data_make->setting_build.build_sources_setting, + data_make->setting_build.build_sources_script, + data_make->setting_build.defines, + data_make->setting_build.defines_library, + data_make->setting_build.defines_library_shared, + data_make->setting_build.defines_library_static, + data_make->setting_build.defines_program, + data_make->setting_build.defines_program_shared, + data_make->setting_build.defines_program_static, + data_make->setting_build.defines_shared, + data_make->setting_build.defines_static, + data_make->setting_build.environment, + data_make->setting_build.flags, + data_make->setting_build.flags_library, + data_make->setting_build.flags_library_shared, + data_make->setting_build.flags_library_static, + data_make->setting_build.flags_program, + data_make->setting_build.flags_program_shared, + data_make->setting_build.flags_program_static, + data_make->setting_build.flags_shared, + data_make->setting_build.flags_static, + data_make->setting_build.modes, + data_make->setting_build.modes_default, + }; + + for (uint8_t i = 0; i < 35; ++i) { + + status = fl_string_dynamic_partial_compare_string(dynamics_name[i], data_make->buffer, dynamics_length[i], range_name); + + if (status == F_equal_to) { + unmatched = F_false; + + for (f_array_length_t j = 0; j < dynamics_value[i].used; ++j) { + + status = f_string_dynamic_mash(f_string_space_s, 1, dynamics_value[i].array[j], &value); + + if (F_status_is_error(status)) { + break; + } + } // for + + break; + } + } // for + } + + if (F_status_is_error(status)) { + macro_f_string_dynamic_t_delete_simple(value); + + return status; + } + + if (unmatched) { + macro_f_string_dynamic_t_delete_simple(value); + + return F_false; + } + + if (quoted) { + status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); + } + else { + status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); + + if (F_status_is_error_not(status)) { + status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); + + if (F_status_is_error_not(status)) { + status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); + + if (F_status_is_error_not(status)) { + ++arguments->used; + } + } + } + } + + macro_f_string_dynamic_t_delete_simple(value); + + if (F_status_is_error_not(status)) { + return F_true; + } + + return status; + } +#endif // _di_fake_make_operate_expand_build_ + +#ifndef _di_fake_make_operate_expand_environment_ + f_status_t fake_make_operate_expand_environment(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) { + + f_status_t status = F_none; + f_string_dynamic_t value = f_string_dynamic_t_initialize; + + bool unmatched = F_false; + + { + f_string_dynamic_t name = f_string_dynamic_t_initialize; + + status = f_string_dynamic_partial_append_nulless(data_make->buffer, range_name, &name); + if (F_status_is_error(status)) return status; + + status = f_environment_get(name.string, &value); + + macro_f_string_dynamic_t_delete_simple(name); + } + + if (F_status_is_error(status)) { + macro_f_string_dynamic_t_delete_simple(value); + + return status; + } + else if (status == F_exist_not) { + macro_f_string_dynamic_t_delete_simple(value); + + return F_false; + } + + if (quoted) { + status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); + } + else { + status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); + + if (F_status_is_error_not(status)) { + status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); + + if (F_status_is_error_not(status)) { + status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); + + if (F_status_is_error_not(status)) { + ++arguments->used; + } + } + } + } + + macro_f_string_dynamic_t_delete_simple(value); + + if (F_status_is_error_not(status)) { + return F_true; + } + + return status; + } +#endif // _di_fake_make_operate_expand_environment_ + +#ifndef _di_fake_make_operate_section_ + int fake_make_operate_section(fake_main_t * const main, const f_array_length_t id_section, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { + + if (F_status_is_error(*status) || *status == F_child) return main->child; + + if (id_section > data_make->fakefile.used) { + *status = F_status_set_error(F_parameter); + + fll_error_print(data_make->error, F_parameter, "fake_make_operate_section", F_true); + return 0; + } + + // Add the operation id to the operation stack. + if (section_stack->used + 1 > section_stack->size) { + macro_f_array_lengths_t_increase_by((*status), (*section_stack), F_memory_default_allocation_small_d); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "macro_f_array_lengths_t_increase_by", F_true); + return 0; + } + } + + section_stack->array[section_stack->used++] = id_section; + + const f_fss_named_t *section = &data_make->fakefile.array[id_section]; + + if (main->output.verbosity != f_console_verbosity_quiet) { + flockfile(main->output.to.stream); + + fl_print_format("%c%[Processing Section '%]", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important); + fl_print_format("%[%/Q%]", main->output.to.stream, main->context.set.notable, data_make->buffer, section->name, main->context.set.notable); + fl_print_format("%['.%]%c", main->output.to.stream, main->context.set.important, main->context.set.important, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + + if (!section->objects.used) { + --section_stack->used; + + return 0; + } + + const f_string_t operations_name[] = { + fake_make_operation_break_s, + fake_make_operation_build_s, + fake_make_operation_clean_s, + fake_make_operation_clone_s, + fake_make_operation_compile_s, + fake_make_operation_copy_s, + fake_make_operation_define_s, + fake_make_operation_delete_s, + fake_make_operation_deletes_s, + fake_make_operation_else_s, + fake_make_operation_exit_s, + fake_make_operation_fail_s, + fake_make_operation_group_s, + fake_make_operation_groups_s, + fake_make_operation_if_s, + fake_make_operation_index_s, + fake_make_operation_link_s, + fake_make_operation_mode_s, + fake_make_operation_modes_s, + fake_make_operation_move_s, + fake_make_operation_operate_s, + fake_make_operation_owner_s, + fake_make_operation_owners_s, + fake_make_operation_pop_s, + fake_make_operation_print_s, + fake_make_operation_run_s, + fake_make_operation_shell_s, + fake_make_operation_skeleton_s, + fake_make_operation_to_s, + fake_make_operation_top_s, + fake_make_operation_touch_s, + }; + + const f_array_length_t operations_length[] = { + fake_make_operation_break_s_length, + fake_make_operation_build_s_length, + fake_make_operation_clean_s_length, + fake_make_operation_clone_s_length, + fake_make_operation_compile_s_length, + fake_make_operation_copy_s_length, + fake_make_operation_define_s_length, + fake_make_operation_delete_s_length, + fake_make_operation_deletes_s_length, + fake_make_operation_else_s_length, + fake_make_operation_exit_s_length, + fake_make_operation_fail_s_length, + fake_make_operation_group_s_length, + fake_make_operation_groups_s_length, + fake_make_operation_if_s_length, + fake_make_operation_index_s_length, + fake_make_operation_link_s_length, + fake_make_operation_mode_s_length, + fake_make_operation_modes_s_length, + fake_make_operation_move_s_length, + fake_make_operation_operate_s_length, + fake_make_operation_owner_s_length, + fake_make_operation_owners_s_length, + fake_make_operation_pop_s_length, + fake_make_operation_print_s_length, + fake_make_operation_run_s_length, + fake_make_operation_shell_s_length, + fake_make_operation_skeleton_s_length, + fake_make_operation_to_s_length, + fake_make_operation_top_s_length, + fake_make_operation_touch_s_length, + }; + + const uint8_t operations_type[] = { + fake_make_operation_type_break, + fake_make_operation_type_build, + fake_make_operation_type_clean, + fake_make_operation_type_clone, + fake_make_operation_type_compile, + fake_make_operation_type_copy, + fake_make_operation_type_define, + fake_make_operation_type_delete, + fake_make_operation_type_deletes, + fake_make_operation_type_else, + fake_make_operation_type_exit, + fake_make_operation_type_fail, + fake_make_operation_type_group, + fake_make_operation_type_groups, + fake_make_operation_type_if, + fake_make_operation_type_index, + fake_make_operation_type_link, + fake_make_operation_type_mode, + fake_make_operation_type_modes, + fake_make_operation_type_move, + fake_make_operation_type_operate, + fake_make_operation_type_owner, + fake_make_operation_type_owners, + fake_make_operation_type_pop, + fake_make_operation_type_print, + fake_make_operation_type_run, + fake_make_operation_type_shell, + fake_make_operation_type_skeleton, + fake_make_operation_type_to, + fake_make_operation_type_top, + fake_make_operation_type_touch, + }; + + uint8_t operation = 0; + uint8_t operations[section->objects.used]; + uint8_t operation_if = 0; + + bool success = F_true; + + f_string_dynamics_t arguments[section->objects.used]; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + memset(operations, 0, section->objects.used); + memset(arguments, 0, sizeof(f_string_dynamics_t) * section->objects.used); + + for (i = 0; i < section->objects.used; ++i, *status = F_none) { + + operation = 0; + + if (!(i % fake_signal_check_short_d) && fake_signal_received(main)) { + *status = F_status_set_error(F_interrupt); + + break; + } + + for (j = 0; j < fake_make_operation_total_d; ++j) { + + if (fl_string_dynamic_partial_compare_string(operations_name[j], data_make->buffer, operations_length[j], section->objects.array[i]) == F_equal_to) { + operation = operations_type[j]; + + break; + } + } // for + + if (!operation) { + fake_print_message_section_operation_unknown(main, data_make->error, data_make->buffer, section->name, section->objects.array[i]); + + *status = F_status_set_error(F_valid_not); + } + else if (operation == fake_make_operation_type_operate) { + if (section_stack->used == fake_make_section_stack_max_d) { + fake_print_message_section_operation_stack_max(main, data_make->error, data_make->buffer, section->name, section->objects.array[i], fake_make_section_stack_max_d); + + *status = F_status_set_error(F_recurse); + } + } + + if (F_status_is_error_not(*status)) { + operations[i] = operation; + + fake_make_operate_expand(main, section->name, operation, section->contents.array[i], section->quotess.array[i], data_make, &arguments[i], status); + } + + if (operation_if == fake_make_operation_if_type_true_next) { + operation_if = fake_make_operation_if_type_true; + } + else if (operation_if == fake_make_operation_if_type_false_next) { + operation_if = fake_make_operation_if_type_false; + } + else if (operation_if == fake_make_operation_if_type_false_always_next) { + operation_if = fake_make_operation_if_type_false_always; + } + + fake_make_operate_validate(main, section->name, operation, arguments[i], &operation_if, data_make, section_stack, status); + + if (F_status_is_error_not(*status)) { + if (operation_if == fake_make_operation_if_type_false) { + operation_if = fake_make_operation_if_type_else_true_next; + continue; + } + else if (operation_if == fake_make_operation_if_type_false_always) { + operation_if = fake_make_operation_if_type_else_false_next_always; + continue; + } + else if (operation_if == fake_make_operation_if_type_else_false) { + operation_if = 0; + continue; + } + + const int result = fake_make_operate_process(main, section->name, operation, arguments[i], success, &operation_if, data_make, section_stack, status); + + if (*status == F_child) { + return result; + } + } + else { + if (operation == fake_make_operation_type_if) { + switch (operation_if) { + case fake_make_operation_if_type_if_defined: + case fake_make_operation_if_type_if_equal: + case fake_make_operation_if_type_if_equal_not: + case fake_make_operation_if_type_if_exists: + case fake_make_operation_if_type_if_failure: + case fake_make_operation_if_type_if_greater: + case fake_make_operation_if_type_if_greater_equal: + case fake_make_operation_if_type_if_group: + case fake_make_operation_if_type_if_is: + case fake_make_operation_if_type_if_less: + case fake_make_operation_if_type_if_less_equal: + case fake_make_operation_if_type_if_mode: + case fake_make_operation_if_type_if_owner: + case fake_make_operation_if_type_if_success: + operation_if = 0; + break; + } + } + + if (operation_if == fake_make_operation_if_type_false) { + operation_if = fake_make_operation_if_type_else_true_next; + } + else if (operation_if == fake_make_operation_if_type_false_always) { + operation_if = fake_make_operation_if_type_else_false_next_always; + } + else if (operation_if == fake_make_operation_if_type_else_false) { + operation_if = 0; + } + } + + if (F_status_set_fine(*status) == F_interrupt) { + break; + } + + if (operation_if == fake_make_operation_if_type_else_true || operation_if == fake_make_operation_if_type_else_false) { + + // No else condition provided, so clear the operation_if state. + if (operation != fake_make_operation_type_else) { + operation_if = 0; + } + } + else if (operation_if == fake_make_operation_if_type_true) { + operation_if = fake_make_operation_if_type_else_false_next; + } + else if (operation_if == fake_make_operation_if_type_false_always) { + operation_if = fake_make_operation_if_type_else_false_next_always; + } + + if (F_status_is_error(*status)) { + success = F_false; + + // Break acts identical to fail when at the top of the stack. + if (F_status_set_fine(*status) == F_signal_abort && !section_stack->used) { + data_make->setting_make.fail = fake_make_operation_fail_type_exit; + data_make->error.prefix = fl_print_error_s; + data_make->error.suffix = 0; + data_make->error.context = main->context.set.error; + data_make->error.notable = main->context.set.notable; + data_make->error.to.stream = F_type_error_d; + data_make->error.to.id = F_type_descriptor_error_d; + data_make->error.set = &main->context.set; + } + + fake_print_message_section_operation_failed(main, data_make->error, data_make->buffer, section->name, section->objects.array[i]); + + // F_signal_abort is used by the break section operation. + if (F_status_set_fine(*status) == F_signal_abort) { + break; + } + + // F_signal_abort is used by the exit section operation. + if (F_status_set_fine(*status) == F_signal_quit) { + if (!section_stack->used) { + *status = F_status_set_error(F_failure); + } + + break; + } + + if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { + operation_if = 0; + break; + } + } + else if (*status == F_signal_abort) { + success = F_true; + + // F_signal_abort is used by the break section operation. + break; + } + else if (*status == F_signal_quit) { + success = F_true; + + // F_signal_abort is used by the exit section operation. + if (!section_stack->used) { + *status = F_none; + } + + break; + } + else { + success = F_true; + } + } // for + + if (F_status_set_error(*status) == F_interrupt) { + for (i = 0; i < section->objects.used; ++i) { + macro_f_string_dynamics_t_delete_simple(arguments[i]); + } // for + + return 0; + } + + if (i == section->objects.used && (operation_if == fake_make_operation_if_type_true_next || operation_if == fake_make_operation_if_type_false_next || operation_if == fake_make_operation_if_type_else_true || operation_if == fake_make_operation_if_type_else_false)) { + + if (main->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SIncomplete '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, operation_if == fake_make_operation_if_type_true_next || operation_if == fake_make_operation_if_type_false_next ? fake_make_operation_if_s : fake_make_operation_else_s, data_make->error.notable); + fl_print_format("%[' at end of section.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + fake_print_message_section_operation_failed(main, data_make->error, data_make->buffer, section->name, section->objects.array[section->objects.used - 1]); + + *status = F_status_set_error(F_failure); + } + + // Ensure an error is returned during recursion if the last known section operation failed, except for the main operation. + if (success == F_false && F_status_is_error_not(*status) && section_stack->used > 1) { + *status = F_status_set_error(F_failure); + } + + for (i = 0; i < section->objects.used; ++i) { + macro_f_string_dynamics_t_delete_simple(arguments[i]); + } // for + + --section_stack->used; + + return 0; + } +#endif // _di_fake_make_operate_section_ + +#ifndef _di_fake_make_operate_process_ + int fake_make_operate_process(fake_main_t * const main, const f_string_range_t section_name, const uint8_t operation, const f_string_dynamics_t arguments, const bool success, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { + + if (*status == F_child) return main->child; + + if (operation == fake_make_operation_type_index) { + const f_status_t result = fake_execute(main, data_make->environment, data_make->setting_build.build_indexer, arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_execute", F_true); + } + + if (*status == F_child) { + return result; + } + + fake_make_operate_process_return(main, result, data_make, status); + + return 0; + } + + if (operation == fake_make_operation_type_break) { + + if (!arguments.used || fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to) { + *status = F_signal_abort; + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to) { + *status = F_status_set_error(F_signal_abort); + } + else { + return 0; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("%cBreaking as '", main->output.to.stream, f_string_eol_s[0]); + fl_print_format("%[%S%]", main->output.to.stream, main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, main->context.set.notable); + fl_print_format("'.%c", main->output.to.stream, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + + return 0; + } + + if (operation == fake_make_operation_type_build) { + f_string_static_t stub = f_string_static_t_initialize; + + *status = fake_build_operate(arguments.used ? arguments.array[0] : stub, main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + if (F_status_is_error(*status)) { + fake_make_operate_process_return(main, 1, data_make, status); + } + else { + fake_make_operate_process_return(main, 0, data_make, status); + } + + return 0; + } + + if (operation == fake_make_operation_type_clean) { + *status = fake_clean_operate(main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + if (F_status_is_error(*status)) { + fake_make_operate_process_return(main, 1, data_make, status); + } + else { + fake_make_operate_process_return(main, 0, data_make, status); + } + + return 0; + } + + if (operation == fake_make_operation_type_clone) { + const f_array_length_t total = arguments.used - 1; + f_status_t status_file = F_none; + + fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; + + f_array_length_t destination_length = 0; + + if (main->error.verbosity == f_console_verbosity_verbose) { + recurse.output = main->output.to; + recurse.verbose = fake_verbose_print_clone; + } + + bool existing = F_true; + + // in this case, the destination could be a file, so confirm this. + if (arguments.used == 2) { + status_file = f_directory_is(arguments.array[1].string); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); + + *status = F_status_set_error(F_failure); + return 0; + } + + if (status_file == F_false || status_file == F_file_found_not) { + existing = F_false; + } + } + + for (f_array_length_t i = 0; i < total; ++i) { + + destination_length = arguments.array[total].used; + + if (existing) { + destination_length += arguments.array[i].used + 1; + } + + char destination[destination_length + 1]; + + memcpy(destination, arguments.array[total].string, arguments.array[total].used); + + if (existing) { + memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); + destination[arguments.array[total].used] = f_path_separator_s[0]; + } + + destination[destination_length] = 0; + + status_file = f_directory_is(arguments.array[i].string); + + if (status_file == F_true) { + status_file = fl_directory_clone(arguments.array[i].string, destination, arguments.array[i].used, destination_length, F_true, recurse); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "fl_directory_clone", F_true, arguments.array[i].string, "clone", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } + else if (status_file == F_false) { + status_file = f_file_clone(arguments.array[i].string, destination, F_true, recurse.size_block, recurse.exclusive); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_clone", F_true, arguments.array[i].string, "clone", fll_error_file_type_file); + *status = F_status_set_error(F_failure); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("%cCloned '%[%Q%]' to '", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable); + fl_print_format("%[%S%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, destination, main->context.set.notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[i].string, "identify", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + break; + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_compile) { + const int result = fake_execute(main, data_make->environment, data_make->setting_build.build_compiler, arguments, status); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_execute", F_true); + } + + if (*status == F_child) { + return result; + } + + fake_make_operate_process_return(main, result, data_make, status); + + return 0; + } + + if (operation == fake_make_operation_type_copy) { + const f_array_length_t total = arguments.used -1; + f_status_t status_file = F_none; + + fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; + + f_array_length_t destination_length = 0; + + f_mode_t mode = f_mode_t_initialize; + + macro_f_mode_t_set_default_umask(mode, main->umask); + + if (main->error.verbosity == f_console_verbosity_verbose) { + recurse.output = main->output.to; + recurse.verbose = fake_verbose_print_copy; + } + + bool existing = F_true; + + // in this case, the destination could be a file, so confirm this. + if (arguments.used == 2) { + status_file = f_directory_is(arguments.array[1].string); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); + + *status = F_status_set_error(F_failure); + return 0; + } + + if (status_file == F_false || status_file == F_file_found_not) { + existing = F_false; + } + } + + for (f_array_length_t i = 0; i < total; ++i) { + + destination_length = arguments.array[total].used; + + if (existing) { + destination_length += arguments.array[i].used + 1; + } + + char destination[destination_length + 1]; + + memcpy(destination, arguments.array[total].string, arguments.array[total].used); + + if (existing) { + memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); + destination[arguments.array[total].used] = f_path_separator_s[0]; + } + + destination[destination_length] = 0; + + status_file = f_directory_is(arguments.array[i].string); + + if (status_file == F_true) { + status_file = fl_directory_copy(arguments.array[i].string, destination, arguments.array[i].used, destination_length, mode, recurse); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "fl_directory_copy", F_true, arguments.array[i].string, "copy", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } + else if (status_file == F_false) { + status_file = f_file_copy(arguments.array[i].string, destination, mode, recurse.size_block, recurse.exclusive); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_copy", F_true, arguments.array[i].string, "copy", fll_error_file_type_file); + *status = F_status_set_error(F_failure); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("%cCopied '%[%Q%]", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable); + fl_print_format("' to '%[%S%]'.%c", main->output.to.stream, main->context.set.notable, destination, main->context.set.notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[i].string, "identify", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + break; + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_define) { + + if (arguments.used > 1) { + *status = f_environment_set(arguments.array[0].string, arguments.array[1].string, F_true); + } + else { + *status = f_environment_set(arguments.array[0].string, f_string_empty_s, F_true); + } + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_environment_set", F_true); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cDefined environment variable '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[0], main->context.set.notable, f_string_eol_s[0]); + } + + return 0; + } + + if (operation == fake_make_operation_type_delete || operation == fake_make_operation_type_deletes) { + const int recursion_max = operation == fake_make_operation_type_delete ? 0 : F_directory_descriptors_max_d; + struct stat file_stat; + + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + memset(&file_stat, 0, sizeof(struct stat)); + + *status = f_file_stat(arguments.array[i].string, F_false, &file_stat); + + if (F_status_is_error(*status)) { + if (F_status_set_fine(*status) == F_file_found_not) { + if (main->warning.verbosity == f_console_verbosity_verbose) { + flockfile(main->warning.to.stream); + + fl_print_format("%c%[%SThe file '%]", main->warning.to.stream, main->warning.prefix, f_string_eol_s[0]); + fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, arguments.array[i], main->warning.notable); + fl_print_format("%[' was not found.%]%c", main->warning.to.stream, f_string_eol_s[0]); + + funlockfile(main->warning.to.stream); + } + + *status = F_none; + } + else { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_stat", F_true, arguments.array[i].string, "delete", fll_error_file_type_file); + return 0; + } + } + else if (macro_f_file_type_is_directory(file_stat.st_mode)) { + if (main->error.verbosity == f_console_verbosity_verbose) { + *status = f_directory_remove_custom(arguments.array[i].string, recursion_max, F_false, fake_clean_remove_recursively_verbosely); + } + else { + *status = f_directory_remove(arguments.array[i].string, recursion_max, F_false); + } + + if (F_status_set_fine(*status) == F_file_found_not) { + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cThe directory '%[%Q%]' does not exist.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); + } + + *status = F_none; + } + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_remove", F_true, arguments.array[i].string, "delete", fll_error_file_type_directory); + return 0; + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cRemoved '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); + } + } + else { + *status = f_file_remove(arguments.array[i].string); + + if (F_status_set_fine(*status) == F_file_found_not) { + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cThe file '%[%Q%]' does not exist.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); + } + + *status = F_none; + } + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_remove", F_true, arguments.array[i].string, "delete", fll_error_file_type_file); + return 0; + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cRemoved '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); + } + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_else) { + + if (*operation_if == fake_make_operation_if_type_else_false_next || *operation_if == fake_make_operation_if_type_else_false_next_always) { + *operation_if = fake_make_operation_if_type_else_false; + } + else if (*operation_if != fake_make_operation_if_type_else_true_next) { + *operation_if = fake_make_operation_if_type_else_true; + } + + return 0; + } + + if (operation == fake_make_operation_type_exit) { + + if (!arguments.used || fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to) { + *status = F_signal_quit; + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to) { + *status = F_status_set_error(F_signal_quit); + + // forcing exit forces fail mode. + data_make->setting_make.fail = fake_make_operation_fail_type_exit; + data_make->error.prefix = fl_print_error_s; + data_make->error.suffix = 0; + data_make->error.context = main->context.set.error; + data_make->error.notable = main->context.set.notable; + data_make->error.to.stream = F_type_error_d; + data_make->error.to.id = F_type_descriptor_error_d; + data_make->error.set = &main->context.set; + } + else { + return 0; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cExiting as '%[%S%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, main->context.set.notable, f_string_eol_s[0]); + } + + return 0; + } + + if (operation == fake_make_operation_type_fail) { + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_exit_s, arguments.array[0], fake_make_operation_argument_exit_s_length) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_exit; + data_make->error.prefix = fl_print_error_s; + data_make->error.suffix = 0; + data_make->error.context = main->context.set.error; + data_make->error.notable = main->context.set.notable; + data_make->error.to.stream = F_type_error_d; + data_make->error.to.id = F_type_descriptor_error_d; + data_make->error.set = &main->context.set; + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn_s, arguments.array[0], fake_make_operation_argument_warn_s_length) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_warn; + data_make->error.prefix = fl_print_warning_s; + data_make->error.suffix = 0; + data_make->error.context = main->context.set.warning; + data_make->error.notable = main->context.set.notable; + data_make->error.to.stream = F_type_warning_d; + data_make->error.to.id = F_type_descriptor_warning_d; + data_make->error.set = &main->context.set; + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore_s, arguments.array[0], fake_make_operation_argument_ignore_s_length) == F_equal_to) { + data_make->setting_make.fail = fake_make_operation_fail_type_ignore; + data_make->error.to.stream = 0; + data_make->error.to.id = -1; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + f_print_terminated("Set failure state to '", main->output.to.stream); + + if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { + fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_exit_s, main->context.set.notable); + } + else if (data_make->setting_make.fail == fake_make_operation_fail_type_warn) { + fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_warn_s, main->context.set.notable); + } + else if (data_make->setting_make.fail == fake_make_operation_fail_type_ignore) { + fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_ignore_s, main->context.set.notable); + } + + fl_print_format("'.%c", main->output.to.stream, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + + return 0; + } + + if (operation == fake_make_operation_type_group) { + gid_t id = 0; + + *status = fake_make_get_id_group(main, data_make->error, arguments.array[0], &id); + if (F_status_is_error(*status)) return 0; + + f_status_t status_file = F_none; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + continue; + } + + status_file = f_file_role_change(arguments.array[i].string, -1, id, F_false); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_role_change", F_true, arguments.array[i].string, "change group of", fll_error_file_type_file); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("Changed group of '%[%s%]", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable); + fl_print_format("' to %[%ul%].%c", main->output.to.stream, main->context.set.notable, id, main->context.set.notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_groups) { + gid_t id = 0; + + *status = fake_make_get_id_group(main, data_make->error, arguments.array[0], &id); + if (F_status_is_error(*status)) return 0; + + f_status_t status_file = F_none; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + continue; + } + + status_file = fll_file_role_change_all(arguments.array[i].string, -1, id, F_false, fake_make_operation_recursion_depth_max_d); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_role_change_all", F_true, arguments.array[i].string, "change group of", fll_error_file_type_file); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("Changed group of '%[%s%]", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable); + fl_print_format("' to %[%ul%].%c", main->output.to.stream, main->context.set.notable, id, main->context.set.notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_if) { + if (*operation_if == fake_make_operation_if_type_if_success) { + if (success) { + *operation_if = fake_make_operation_if_type_true_next; + } + else { + *operation_if = fake_make_operation_if_type_false_next; + } + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_failure) { + if (success) { + *operation_if = fake_make_operation_if_type_false_next; + } + else { + *operation_if = fake_make_operation_if_type_true_next; + } + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_group) { + uid_t id = 0; + + *status = fake_make_get_id_group(main, data_make->error, arguments.array[1], &id); + if (F_status_is_error(*status)) return 0; + + uid_t id_file = 0; + + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 2; i < arguments.used; ++i, id_file = 0) { + + *status = f_file_group_read(arguments.array[i].string, &id_file); + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_group_read", F_true, arguments.array[i].string, "get group of", fll_error_file_type_file); + break; + } + + if (id != id_file) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_mode) { + bool is = F_false; + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_is_s, arguments.array[1], fake_make_operation_argument_is_s_length) == F_equal_to) { + is = F_true; + } + + f_file_mode_t mode_rule = 0; + mode_t mode_match = 0; + + { + uint8_t mode_replace = 0; + + *status = fake_make_get_id_mode(main, data_make->error, arguments.array[2], &mode_rule, &mode_replace); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + return 0; + } + + *status = f_file_mode_to_mode(mode_rule, &mode_match); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_print(data_make->error, F_status_set_fine(*status), "f_file_mode_to_mode", F_true); + return 0; + } + } + + mode_t mode_file = 0; + + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 3; i < arguments.used; ++i, mode_file = 0) { + + *status = f_file_mode_read(arguments.array[i].string, &mode_file); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "get mode of", fll_error_file_type_file); + break; + } + + if (is) { + if (mode_match != (mode_file & F_file_mode_all_d)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else { + if (!(mode_match & mode_file)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_owner) { + uid_t id = 0; + + *status = fake_make_get_id_owner(main, data_make->error, arguments.array[1], &id); + if (F_status_is_error(*status)) return 0; + + uid_t id_file = 0; + + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 2; i < arguments.used; ++i, id_file = 0) { + + *status = f_file_owner_read(arguments.array[i].string, &id_file); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_owner_read", F_true, arguments.array[i].string, "get owner of", fll_error_file_type_file); + break; + } + + if (id != id_file) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_is) { + + // block = 0x1 (0000 0001) link = 0x10 (0001 0000) + // character = 0x2 (0000 0010) regular = 0x20 (0010 0000) + // directory = 0x4 (0000 0100) socket = 0x40 (0100 0000) + // fifo = 0x8 (0000 1000) invalid = 0x80 (1000 0000) + uint8_t type = 0; + + f_array_length_t i = 1; + + *status = F_none; + + for (; i < arguments.used; ++i) { + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_if_is_for_s, arguments.array[i], fake_make_operation_argument_if_is_for_s_length) == F_equal_to) { + ++i; + break; + } + + if (fl_string_dynamic_compare_string(F_file_type_name_block_s, arguments.array[i], F_file_type_name_block_s_length) == F_equal_to) { + type |= 0x1; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_character_s, arguments.array[i], F_file_type_name_character_s_length) == F_equal_to) { + type |= 0x2; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_directory_s, arguments.array[i], F_file_type_name_directory_s_length) == F_equal_to) { + type |= 0x4; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_fifo_s, arguments.array[i], F_file_type_name_fifo_s_length) == F_equal_to) { + type |= 0x8; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_link_s, arguments.array[i], F_file_type_name_link_s_length) == F_equal_to) { + type |= 0x10; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_regular_s, arguments.array[i], F_file_type_name_regular_s_length) == F_equal_to) { + type |= 0x20; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_socket_s, arguments.array[i], F_file_type_name_socket_s_length) == F_equal_to) { + type |= 0x40; + } + } // for + + uint8_t type_file = 0; + mode_t mode_file = 0; + + *operation_if = fake_make_operation_if_type_true_next; + + for (; i < arguments.used; ++i, mode_file = 0) { + + *status = f_file_mode_read(arguments.array[i].string, &mode_file); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "get mode of", fll_error_file_type_file); + break; + } + + if (macro_f_file_type_is_block(mode_file)) { + type_file = 0x1; + } + else if (macro_f_file_type_is_character(mode_file)) { + type_file = 0x2; + } + else if (macro_f_file_type_is_directory(mode_file)) { + type_file = 0x4; + } + else if (macro_f_file_type_is_fifo(mode_file)) { + type_file = 0x8; + } + else if (macro_f_file_type_is_link(mode_file)) { + type_file = 0x10; + } + else if (macro_f_file_type_is_regular(mode_file)) { + type_file = 0x20; + } + else if (macro_f_file_type_is_socket(mode_file)) { + type_file = 0x40; + } + + if (!(type & type_file)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_exists) { + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + *status = f_file_exists(arguments.array[i].string); + + if (F_status_is_error(*status)) { + *operation_if = fake_make_operation_if_type_false_always_next; + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_exists", F_true, arguments.array[i].string, "find", fll_error_file_type_file); + break; + } + + if (*status == F_false) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_defined) { + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to) { + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 2; i < arguments.used; ++i) { + + if (f_environment_exists(arguments.array[i].string) != F_true) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to) { + if (!data_make->setting_make.parameter.used) { + *operation_if = fake_make_operation_if_type_false_next; + return 0; + } + + f_array_length_t i = 2; + f_array_length_t j = 0; + bool missed = F_true; + + *operation_if = fake_make_operation_if_type_true_next; + + for (; i < arguments.used; ++i, missed = F_true) { + + for (j = 0; j < data_make->setting_make.parameter.used; ++j) { + + if (fl_string_dynamic_compare(arguments.array[i], data_make->setting_make.parameter.array[j].name) == F_equal_to) { + missed = F_false; + break; + } + } // for + + if (missed) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + } + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_equal) { + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 2; i < arguments.used; ++i) { + + if (fl_string_dynamic_compare(arguments.array[1], arguments.array[i]) == F_equal_to_not) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_equal_not) { + *operation_if = fake_make_operation_if_type_true_next; + + f_array_length_t i = 1; + f_array_length_t j = 0; + + for (; i < arguments.used; ++i) { + + for (j = i + 1; j < arguments.used; ++j) { + + if (fl_string_dynamic_compare(arguments.array[i], arguments.array[j]) == F_equal_to) { + *operation_if = fake_make_operation_if_type_false_next; + i = arguments.used; + break; + } + } // for + } // for + + return 0; + } + + if (*operation_if == fake_make_operation_if_type_if_greater || *operation_if == fake_make_operation_if_type_if_greater_equal || *operation_if == fake_make_operation_if_type_if_less || *operation_if == fake_make_operation_if_type_if_less_equal) { + + f_status_t status_number = F_none; + f_string_range_t range = f_string_range_t_initialize; + + f_number_unsigned_t number_left = 0; + f_number_unsigned_t number_right = 0; + + bool is_negative_left = F_false; + bool is_negative_right = F_false; + + f_array_length_t i = 1; + + const uint8_t type_if = *operation_if; + + *operation_if = fake_make_operation_if_type_true_next; + + // @fixme there needs to handle converting numbers with decimals (like 1.01), perhaps operate on them as strings or provide a special processor. + range.start = 0; + range.stop = arguments.array[i].used - 1; + + if (arguments.array[i].string[0] == '+') { + range.start = 1; + } + else if (arguments.array[i].string[0] == '-') { + range.start = 1; + is_negative_left = F_true; + } + + if (range.start > range.stop) { + status_number = F_status_set_error(F_failure); + } + else { + status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number_left); + } + + if (F_status_is_error_not(status_number)) { + for (i = 2; i < arguments.used; ++i, status_number = F_none, number_left = number_right, is_negative_left = is_negative_right) { + + if (arguments.array[i].used) { + range.start = 0; + range.stop = arguments.array[i].used - 1; + + is_negative_right = F_false; + + if (arguments.array[i].string[0] == '+') { + range.start = 1; + } + else if (arguments.array[i].string[0] == '-') { + range.start = 1; + is_negative_right = F_true; + } + + if (range.start > range.stop) { + status_number = F_status_set_error(F_failure); + } + else { + status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number_right); + } + } + else { + status_number = F_status_set_error(F_failure); + } + + if (F_status_is_error(status_number)) { + break; + } + + if (type_if == fake_make_operation_if_type_if_greater) { + + if (is_negative_left == is_negative_right) { + if (!(number_left > number_right)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (!is_negative_left && is_negative_right) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (type_if == fake_make_operation_if_type_if_greater_equal) { + + if (is_negative_left == is_negative_right) { + if (!(number_left >= number_right)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (!is_negative_left && is_negative_right) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (type_if == fake_make_operation_if_type_if_less) { + + if (is_negative_left == is_negative_right) { + if (!(number_left < number_right)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (is_negative_left && !is_negative_right) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (type_if == fake_make_operation_if_type_if_less_equal) { + + if (is_negative_left == is_negative_right) { + if (!(number_left <= number_right)) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + else if (is_negative_left && !is_negative_right) { + *operation_if = fake_make_operation_if_type_false_next; + break; + } + } + } // for + } + + if (F_status_is_error(status_number)) { + *status = F_status_set_error(F_failure); + *operation_if = fake_make_operation_if_type_false_always_next; + + if (main->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + if ((i == 1 && number_left > F_number_t_size_unsigned_d) || (i > 1 && number_right > F_number_t_size_unsigned_d)) { + fl_print_format("%c%[%SThe number '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%[' may only be between the ranges -%un to %un.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); + } + else { + fl_print_format("%c%[%SInvalid or unsupported number provided '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); + } + + funlockfile(data_make->error.to.stream); + } + } + + return 0; + } + + return 0; + } + + if (operation == fake_make_operation_type_link) { + *status = f_file_link(arguments.array[0].string, arguments.array[1].string); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_link", F_true, arguments.array[1].string, "create link", fll_error_file_type_file); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + fl_print_format("Created symbolic link from '%[%Q%]", main->output.to.stream, main->context.set.notable, arguments.array[1], main->context.set.notable); + fl_print_format("' to %[%Q%].%c", main->output.to.stream, main->context.set.notable, arguments.array[0], main->context.set.notable, f_string_eol_s[0]); + + funlockfile(main->output.to.stream); + } + + return 0; + } + + if (operation == fake_make_operation_type_mode) { + f_file_mode_t mode_rule = 0; + uint8_t replace = 0; + + *status = fake_make_get_id_mode(main, data_make->error, arguments.array[0], &mode_rule, &replace); + if (F_status_is_error(*status)) return 0; + + mode_t mode = 0; + mode_t mode_file = 0; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + mode = 0; + + *status = f_file_mode_read(arguments.array[i].string, &mode_file); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + *status = f_file_mode_determine(mode_file, mode_rule, replace, macro_f_file_type_is_directory(mode_file), &mode); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_determine", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + *status = f_file_mode_set(arguments.array[i].string, mode); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_set", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Changed mode of '%Q' to %#@u.%c", main->output.to.stream, arguments.array[i], mode, f_string_eol_s[0]); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_modes) { + f_file_mode_t mode_rule = 0; + uint8_t replace = 0; + + *status = fake_make_get_id_mode(main, data_make->error, arguments.array[0], &mode_rule, &replace); + if (F_status_is_error(*status)) return 0; + + mode_t mode = 0; + mode_t mode_file = 0; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + mode = 0; + + *status = f_file_mode_read(arguments.array[i].string, &mode_file); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + *status = f_file_mode_determine(mode_file, mode_rule, replace, macro_f_file_type_is_directory(mode_file), &mode); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_determine", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + *status = fll_file_mode_set_all(arguments.array[i].string, mode, fake_make_operation_recursion_depth_max_d); + + if (F_status_is_error(*status)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_mode_set_all", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); + break; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Changed mode of '%Q' to %#@u.%c", main->output.to.stream, arguments.array[i], mode, f_string_eol_s[0]); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_move) { + const f_array_length_t total = arguments.used -1; + f_status_t status_file = F_none; + + fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; + + f_array_length_t destination_length = 0; + + if (main->error.verbosity == f_console_verbosity_verbose) { + recurse.output = main->output.to; + recurse.verbose = fake_verbose_print_move; + } + + bool existing = F_true; + + // in this case, the destination could be a file, so confirm this. + if (arguments.used == 2) { + status_file = f_directory_is(arguments.array[1].string); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); + + *status = F_status_set_error(F_failure); + return 0; + } + + if (status_file == F_false || status_file == F_file_found_not) { + existing = F_false; + } + } + + for (f_array_length_t i = 0; i < total; ++i) { + + destination_length = arguments.array[total].used; + + if (existing) { + destination_length += arguments.array[i].used + 1; + } + + char destination[destination_length + 1]; + + memcpy(destination, arguments.array[total].string, arguments.array[total].used); + + if (existing) { + memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); + destination[arguments.array[total].used] = f_path_separator_s[0]; + } + + destination[destination_length] = 0; + + status_file = fll_file_move(arguments.array[i].string, destination, arguments.array[i].used, destination_length, recurse); + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_move", F_true, arguments.array[i].string, "move", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_operate) { + f_array_length_t id_section = 0; + + for (; id_section < data_make->fakefile.used; ++id_section) { + + if (fl_string_dynamic_partial_compare_string(arguments.array[0].string, data_make->buffer, arguments.array[0].used, data_make->fakefile.array[id_section].name) == F_equal_to) { + break; + } + } // for + + if (id_section == data_make->fakefile.used) { + return 0; + } + + const int result = fake_make_operate_section(main, id_section, data_make, section_stack, status); + + // Ensure that a break only happens within its active operation stack. + if (*status == F_signal_abort) { + *status = F_none; + } + else if (F_status_set_fine(*status) == F_signal_abort) { + *status = F_status_set_error(F_failure); + } + + return result; + } + + if (operation == fake_make_operation_type_owner) { + uid_t id = 0; + + *status = fake_make_get_id_owner(main, data_make->error, arguments.array[0], &id); + if (F_status_is_error(*status)) return 0; + + f_status_t status_file = F_none; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + continue; + } + + status_file = f_file_role_change(arguments.array[i].string, id, -1, F_false); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_role_change", F_true, arguments.array[i].string, "change owner of", fll_error_file_type_file); + break; + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Changed owner of '%Q' to %u.%c", main->output.to.stream, arguments.array[i], id, f_string_eol_s[0]); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_owners) { + uid_t id = 0; + + *status = fake_make_get_id_owner(main, data_make->error, arguments.array[0], &id); + if (F_status_is_error(*status)) return 0; + + f_status_t status_file = F_none; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + continue; + } + + status_file = fll_file_role_change_all(arguments.array[i].string, id, -1, F_false, fake_make_operation_recursion_depth_max_d); + + if (F_status_is_error(status_file)) { + *status = status_file; + + fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_role_change_all", F_true, arguments.array[i].string, "change owner of", fll_error_file_type_file); + } + else if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Changed owner of '%Q' to %u.%c", main->output.to.stream, arguments.array[i], id, f_string_eol_s[0]); + } + } // for + + return 0; + } + + if (operation == fake_make_operation_type_pop) { + macro_f_string_dynamic_t_delete_simple(data_make->path.stack.array[data_make->path.stack.used - 1]); + + --data_make->path.stack.used; + + *status = f_path_change(data_make->path.stack.array[data_make->path.stack.used - 1].string); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", data_make->path.stack.array[data_make->path.stack.used - 1].string); + + return 0; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + *status = fake_make_path_relative(main, data_make->path.stack.array[data_make->path.stack.used - 1], data_make); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_path_relative", F_true); + + return 0; + } + + fll_print_format("Changed to project path '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, data_make->path_cache, main->context.set.notable, f_string_eol_s[0]); + } + + return 0; + } + + if (operation == fake_make_operation_type_print) { + flockfile(main->output.to.stream); + + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + f_print_dynamic(arguments.array[i], main->output.to.stream); + + if (i + 1 < arguments.used) { + f_print_character(f_string_space_s[0], main->output.to.stream); + } + } // for + + f_print_character(f_string_space_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + + funlockfile(main->output.to.stream); + + return 0; + } + + if (operation == fake_make_operation_type_run) { + *status = fake_make_operate_process_run(main, arguments, F_false, data_make); + + return 0; + } + + if (operation == fake_make_operation_type_shell) { + *status = fake_make_operate_process_run(main, arguments, F_true, data_make); + + return 0; + } + + if (operation == fake_make_operation_type_skeleton) { + *status = fake_skeleton_operate(main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + if (F_status_is_error(*status)) { + fake_make_operate_process_return(main, 1, data_make, status); + } + else { + fake_make_operate_process_return(main, 0, data_make, status); + } + + return 0; + } + + if (operation == fake_make_operation_type_to) { + *status = fake_make_assure_inside_project(main, arguments.array[0], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[0].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + + return 0; + } + + *status = f_path_change(arguments.array[0].string); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); + } + else { + *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->path.stack); + + if (F_status_set_fine(*status) == F_array_too_large) { + fake_print_message_section_operation_path_stack_max(main, data_make->error, F_array_too_large, "f_string_dynamics_increase_by", "path stack"); + + return 0; + } + else if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "macro_f_string_dynamics_t_resize", F_true); + + return 0; + } + + // copy the entire real path, including the trailing NULL. + ++data_make->path_cache.used; + + f_string_dynamic_append(data_make->path_cache, &data_make->path.stack.array[data_make->path.stack.used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + + return 0; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + *status = fake_make_path_relative(main, data_make->path.stack.array[data_make->path.stack.used], data_make); + + if (F_status_is_error(*status)) { + + fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_path_relative", F_true); + return 0; + } + + fll_print_format("Changed to project path '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, data_make->path_cache, main->context.set.notable, f_string_eol_s[0]); + } + + ++data_make->path.stack.used; + } + + return 0; + } + + if (operation == fake_make_operation_type_top) { + + *status = f_path_change_at(data_make->path.top.id); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); + + return 0; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Changed to project path ''.%c", main->output.to.stream, f_string_eol_s[0]); + } + + // clear stack, except for the project root. + for (f_array_length_t i = 1; i < data_make->path.stack.used; ++i) { + macro_f_string_dynamic_t_delete_simple(data_make->path.stack.array[i]); + } // for + + data_make->path.stack.used = 1; + return 0; + } + + if (operation == fake_make_operation_type_touch) { + f_mode_t mode = f_mode_t_initialize; + + macro_f_mode_t_set_default_umask(mode, main->umask); + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_file_s, arguments.array[0], fake_make_operation_argument_file_s_length) == F_equal_to) { + *status = f_file_touch(arguments.array[i].string, mode.regular, F_false); + + if (F_status_is_error(*status)) { + if (F_status_is_error_not(fll_path_canonical(arguments.array[i].string, &data_make->path_cache))) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_touch", F_true, data_make->path_cache.string, "touch", fll_error_file_type_file); + } + else { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_touch", F_true, arguments.array[i].string, "touch", fll_error_file_type_file); + } + + break; + } + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory_s, arguments.array[0], fake_make_operation_argument_directory_s_length) == F_equal_to) { + *status = f_directory_touch(arguments.array[i].string, mode.directory); + + if (F_status_is_error(*status)) { + if (F_status_is_error_not(fll_path_canonical(arguments.array[i].string, &data_make->path_cache))) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_touch", F_true, data_make->path_cache.string, "touch", fll_error_file_type_directory); + } + else { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_touch", F_true, arguments.array[i].string, "touch", fll_error_file_type_directory); + } + + break; + } + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("Touched '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); + } + } // for + } + + return 0; + } +#endif // _di_fake_make_operate_process_ + +#ifndef _di_fake_make_operate_process_execute_ + f_status_t fake_make_operate_process_execute(fake_main_t * const main, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) { + + if (fake_signal_received(main)) { + return F_status_set_error(F_interrupt); + } + + f_status_t status = F_none; + + // reset the environment. + for (f_array_length_t i = 0; i < data_make->environment.used; ++i) { + + data_make->environment.array[i].name.used = 0; + data_make->environment.array[i].value.used = 0; + } // for + + data_make->environment.used = 0; + + status = fl_environment_load_names(data_make->setting_build.environment, &data_make->environment); + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "fl_environment_load_names", F_true); + + return status; + } + + if (main->error.verbosity == f_console_verbosity_verbose) { + flockfile(main->output.to.stream); + + f_print_dynamic_safely(program, main->output.to.stream); + + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + if (arguments.array[i].used) { + fll_print_format(" %Q", main->output.to.stream, arguments.array[i]); + } + } // for + + f_print_character(f_string_eol_s[0], main->output.to.stream); + + funlockfile(main->output.to.stream); + + // flush to stdout before executing command. + fflush(main->output.to.stream); + } + + int return_code = 0; + + // child processes should receive all signals, without blocking. + f_signal_how_t signals = f_signal_how_t_initialize; + f_signal_set_empty(&signals.block); + f_signal_set_fill(&signals.block_not); + + fl_execute_parameter_t parameter = macro_fl_execute_parameter_t_initialize(as_shell ? 0 : FL_execute_parameter_option_path_d, 0, &data_make->environment, &signals, 0); + + status = fll_execute_program(program.string, arguments, ¶meter, 0, (void *) &return_code); + + if (fake_signal_received(main)) { + return F_status_set_error(F_interrupt); + } + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_interrupt) { + return status; + } + + if (F_status_set_fine(status) == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find program '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, program, data_make->error.notable); + fl_print_format("%[' for executing.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + } + else if (F_status_set_fine(status) != F_failure) { + fll_error_print(data_make->error, F_status_set_fine(status), "fll_execute_program", F_true); + } + } + + fake_make_operate_process_return(main, return_code, data_make, &status); + + return status; + } +#endif // _di_fake_make_operate_process_execute_ + +#ifndef _di_fake_make_operate_process_return_ + void fake_make_operate_process_return(fake_main_t * const main, const int return_code, fake_make_data_t *data_make, f_status_t *status) { + + f_status_t status2 = F_none; + + data_make->setting_make.parameter.array[0].value.array[0].used = 0; + + if (!return_code) { + if (F_status_is_error(*status)) { + status2 = f_string_append("1", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + else { + status2 = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + + return; + } + else { + if (return_code) { + f_string_dynamic_t number = f_string_dynamic_t_initialize; + + status2 = f_conversion_number_signed_to_string(WEXITSTATUS(return_code), f_conversion_data_base_10_s, &number); + + if (F_status_is_error(status2)) { + *status = status2; + + fll_error_print(data_make->error, F_status_set_fine(*status), "f_conversion_number_signed_to_string", F_true); + + macro_f_string_dynamic_t_delete_simple(number); + return; + } + + status2 = f_string_dynamic_append(number, &data_make->setting_make.parameter.array[0].value.array[0]); + + macro_f_string_dynamic_t_delete_simple(number); + } + else { + status2 = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + } + + if (F_status_is_error(status2)) { + *status = status2; + + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); + return; + } + + status2 = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); + + if (F_status_is_error(status2)) { + *status = status2; + + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); + return; + } + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed with return code %]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%i%]", data_make->error.to.stream, data_make->error.notable, return_code, data_make->error.notable); + fl_print_format("%[.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { + *status = F_status_set_error(F_failure); + } + else { + *status = F_none; + } + } +#endif // _di_fake_make_operate_process_return_ + +#ifndef _di_fake_make_operate_process_run_ + f_status_t fake_make_operate_process_run(fake_main_t * const main, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) { + + const f_string_static_t *program = &arguments.array[0]; + + f_status_t status = F_none; + f_string_dynamics_t args = f_string_dynamics_t_initialize; + + if (arguments.used > 1) { + status = f_string_dynamics_resize(arguments.used - 1, &args); + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamics_resize", F_true); + return status; + } + + for (f_array_length_t i = 0; i < args.size; ++i) { + + status = f_string_dynamic_append(arguments.array[i + 1], &args.array[i]); + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamic_append", F_true); + + macro_f_string_dynamics_t_delete_simple(args); + return status; + } + + status = f_string_dynamic_terminate(&args.array[i]); + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamic_terminate", F_true); + + macro_f_string_dynamics_t_delete_simple(args); + return status; + } + + ++args.used; + } // for + } + + status = fake_make_operate_process_execute(main, *program, args, as_shell, data_make); + + macro_f_string_dynamics_t_delete_simple(args); + return status; + } +#endif // _di_fake_make_operate_process_run_ + +#ifndef _di_fake_make_operate_validate_ + void fake_make_operate_validate(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_string_dynamics_t arguments, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (operation == fake_make_operation_type_index || operation == fake_make_operation_type_run || operation == fake_make_operation_type_shell) { + if (!arguments.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (operation == fake_make_operation_type_index) { + if (!data_make->setting_build.build_indexer.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SNo indexer has been specified, cannot perform '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_index_s, data_make->error.notable); + fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + + return; + } + + if (operation == fake_make_operation_type_break) { + if (arguments.used > 1) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to_not) { + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported break type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + + return; + } + + if (operation == fake_make_operation_type_build) { + if (arguments.used > 1) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used) { + if (arguments.array[0].used) { + char path_file[main->path_data_build.used + arguments.array[0].used + 1]; + + memcpy(path_file, main->path_data_build.string, main->path_data_build.used); + memcpy(path_file + main->path_data_build.used, arguments.array[0].string, arguments.array[0].used); + + path_file[main->path_data_build.used + arguments.array[0].used] = 0; + + f_status_t status_file = f_file_is(path_file, F_file_type_regular_d, F_false); + + if (status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%S%]", data_make->error.to.stream, data_make->error.notable, path_file, data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(status_file); + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_is", F_true, path_file, "find", fll_error_file_type_file); + *status = status_file; + } + else if (!status_file) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, path_file, data_make->error.notable); + fl_print_format("%[' must be a regular file.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SFilename argument must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + } + + return; + } + + if (operation == fake_make_operation_type_clean || operation == fake_make_operation_type_pop || operation == fake_make_operation_type_top || operation == fake_make_operation_type_skeleton) { + if (arguments.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (operation == fake_make_operation_type_pop) { + if (data_make->path.stack.used == 1) { + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SMust not attempt to pop project root off of path stack.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + } + + return; + } + + if (operation == fake_make_operation_type_clone) { + if (arguments.used > 1) { + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } // for + + for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { + + if (f_file_exists(arguments.array[i].string) != F_true) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } // for + + if (arguments.used > 2) { + + // the last file must be a directory. + f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); + + if (status_file == F_false || status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "find", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } + else { + + // when the first file is a directory, then the second, if it exists, must also be a directory. + f_status_t status_file = f_directory_is(arguments.array[0].string); + + if (status_file == F_true) { + status_file = f_directory_is(arguments.array[1].string); + + if (status_file == F_false) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_compile) { + if (!arguments.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (data_make->setting_build.build_compiler.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SNo compiler has been specified, cannot perform '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_compile_s, data_make->error.notable); + fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_copy) { + if (arguments.used > 1) { + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } // for + + for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { + + if (f_file_exists(arguments.array[i].string) != F_true) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } // for + + if (arguments.used > 2) { + + // the last file must be a directory. + f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); + + if (status_file == F_false || status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "identify", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } + else { + + // when the first file is a directory, then the second, if it exists, must also be a directory. + f_status_t status_file = f_directory_is(arguments.array[0].string); + + if (status_file == F_true) { + status_file = f_directory_is(arguments.array[1].string); + + if (status_file == F_false) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_delete || operation == fake_make_operation_type_deletes) { + if (arguments.used) { + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } // for + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_define) { + if (arguments.used) { + *status = fake_make_operate_validate_define_name(arguments.array[0]); + + if (*status == F_none) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SDefine name must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (*status == F_false) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SInvalid characters in the define setting name '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%[', only alpha-numeric ASCII characters and underscore (without a leading digit) is allowed.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_else) { + if (*operation_if == fake_make_operation_if_type_else_true || *operation_if == fake_make_operation_if_type_else_false) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SMust not be used after another '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[else%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); + fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + *operation_if = 0; + + return; + } + + if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SMust not be used inside an '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[if%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); + fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + *operation_if = 0; + + return; + } + + if (*operation_if != fake_make_operation_if_type_else_true_next && *operation_if != fake_make_operation_if_type_else_false_next && *operation_if != fake_make_operation_if_type_else_false_next_always) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas no preceding if condition.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + *operation_if = 0; + + return; + } + + if (arguments.used) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + *operation_if = 0; + } + + return; + } + + if (operation == fake_make_operation_type_exit) { + if (arguments.used > 1) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported exit type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + + return; + } + + if (operation == fake_make_operation_type_fail) { + if (arguments.used) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_exit_s, arguments.array[0], fake_make_operation_argument_exit_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn_s, arguments.array[0], fake_make_operation_argument_warn_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore_s, arguments.array[0], fake_make_operation_argument_ignore_s_length) == F_equal_to_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported fail type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_group || operation == fake_make_operation_type_groups || operation == fake_make_operation_type_mode || operation == fake_make_operation_type_modes || operation == fake_make_operation_type_owner || operation == fake_make_operation_type_owners) { + if (arguments.used > 1) { + f_status_t status_file = F_none; + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + status_file = f_file_is(arguments.array[i].string, F_file_type_regular_d, F_false); + + if (status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(status_file); + } + else if (F_status_is_error(status_file)) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_is", F_true, arguments.array[i].string, "find", fll_error_file_type_directory); + } + + *status = status_file; + } + } + + return; + } + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + + return; + } + + if (operation == fake_make_operation_type_if) { + if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SMust not be used after another '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[if%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); + fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + *operation_if = 0; + + return; + } + + if (arguments.used) { + const f_string_t if_type_strings[] = { + fake_make_operation_argument_if_defined_s, + fake_make_operation_argument_if_equal_s, + fake_make_operation_argument_if_equal_not_s, + fake_make_operation_argument_if_exists_s, + fake_make_operation_argument_if_failure_s, + fake_make_operation_argument_if_greater_s, + fake_make_operation_argument_if_greater_equal_s, + fake_make_operation_argument_if_group_s, + fake_make_operation_argument_if_is_s, + fake_make_operation_argument_if_less_s, + fake_make_operation_argument_if_less_equal_s, + fake_make_operation_argument_if_mode_s, + fake_make_operation_argument_if_owner_s, + fake_make_operation_argument_if_success_s, + }; + + const f_array_length_t if_type_lengths[] = { + fake_make_operation_argument_if_defined_s_length, + fake_make_operation_argument_if_equal_s_length, + fake_make_operation_argument_if_equal_not_s_length, + fake_make_operation_argument_if_exists_s_length, + fake_make_operation_argument_if_failure_s_length, + fake_make_operation_argument_if_greater_s_length, + fake_make_operation_argument_if_greater_equal_s_length, + fake_make_operation_argument_if_group_s_length, + fake_make_operation_argument_if_is_s_length, + fake_make_operation_argument_if_less_s_length, + fake_make_operation_argument_if_less_equal_s_length, + fake_make_operation_argument_if_mode_s_length, + fake_make_operation_argument_if_owner_s_length, + fake_make_operation_argument_if_success_s_length, + }; + + const uint8_t if_type_codes[] = { + fake_make_operation_if_type_if_defined, + fake_make_operation_if_type_if_equal, + fake_make_operation_if_type_if_equal_not, + fake_make_operation_if_type_if_exists, + fake_make_operation_if_type_if_failure, + fake_make_operation_if_type_if_greater, + fake_make_operation_if_type_if_greater_equal, + fake_make_operation_if_type_if_group, + fake_make_operation_if_type_if_is, + fake_make_operation_if_type_if_less, + fake_make_operation_if_type_if_less_equal, + fake_make_operation_if_type_if_mode, + fake_make_operation_if_type_if_owner, + fake_make_operation_if_type_if_success, + }; + + const uint8_t if_type_minimum[] = { + 2, + 2, + 2, + 2, + 1, + 2, + 2, + 3, + 3, + 2, + 2, + 4, + 3, + 1, + }; + + f_array_length_t i = 0; + + for (; i < 14; ++i) { + + if (fl_string_dynamic_compare_string(if_type_strings[i], arguments.array[0], if_type_lengths[i]) == F_equal_to) { + *operation_if = if_type_codes[i]; + break; + } + } // for + + if (i == 14) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported if type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + *operation_if = fake_make_operation_if_type_false_always_next; + + return; + } + + if (arguments.used >= if_type_minimum[i]) { + if (*operation_if == fake_make_operation_if_type_if_success || *operation_if == fake_make_operation_if_type_if_failure) { + if (arguments.used > if_type_minimum[i]) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + *operation_if = fake_make_operation_if_type_false_always_next; + } + + return; + } + + if (*operation_if == fake_make_operation_if_type_if_mode || *operation_if == fake_make_operation_if_type_if_owner || *operation_if == fake_make_operation_if_type_if_group || *operation_if == fake_make_operation_if_type_if_is || *operation_if == fake_make_operation_if_type_if_exists) { + if (*operation_if == fake_make_operation_if_type_if_mode) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_is_s, arguments.array[1], fake_make_operation_argument_is_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_has_s, arguments.array[1], fake_make_operation_argument_has_s_length) == F_equal_to_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported mode type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + return; + } + } + + f_file_mode_t mode_rule = 0; + uint8_t replace = 0; + + *status = fake_make_get_id_mode(main, data_make->error, arguments.array[2], &mode_rule, &replace); + if (F_status_is_error(*status)) return; + + i = 3; + } + + if (*operation_if == fake_make_operation_if_type_if_owner) { + uid_t id = 0; + + *status = fake_make_get_id_owner(main, data_make->error, arguments.array[1], &id); + if (F_status_is_error(*status)) return; + + i = 2; + } + + if (*operation_if == fake_make_operation_if_type_if_group) { + gid_t id = 0; + + *status = fake_make_get_id_group(main, data_make->error, arguments.array[1], &id); + if (F_status_is_error(*status)) return; + + i = 2; + } + + if (*operation_if == fake_make_operation_if_type_if_is) { + + // block = 0x1 (0000 0001) link = 0x10 (0001 0000) + // character = 0x2 (0000 0010) regular = 0x20 (0010 0000) + // directory = 0x4 (0000 0100) socket = 0x40 (0100 0000) + // fifo = 0x8 (0000 1000) invalid = 0x80 (1000 0000) + uint8_t type_file = 0; + + for (i = 1; i < arguments.used; ++i) { + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_if_is_for_s, arguments.array[i], fake_make_operation_argument_if_is_for_s_length) == F_equal_to) { + ++i; + break; + } + + if (fl_string_dynamic_compare_string(F_file_type_name_block_s, arguments.array[i], F_file_type_name_block_s_length) == F_equal_to) { + type_file |= 0x1; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_character_s, arguments.array[i], F_file_type_name_character_s_length) == F_equal_to) { + type_file |= 0x2; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_directory_s, arguments.array[i], F_file_type_name_directory_s_length) == F_equal_to) { + type_file |= 0x4; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_fifo_s, arguments.array[i], F_file_type_name_fifo_s_length) == F_equal_to) { + type_file |= 0x8; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_link_s, arguments.array[i], F_file_type_name_link_s_length) == F_equal_to) { + type_file |= 0x10; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_regular_s, arguments.array[i], F_file_type_name_regular_s_length) == F_equal_to) { + type_file |= 0x20; + } + else if (fl_string_dynamic_compare_string(F_file_type_name_socket_s, arguments.array[i], F_file_type_name_socket_s_length) == F_equal_to) { + type_file |= 0x40; + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported file type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + type_file |= 0x80; + } + } // for + + if (type_file & 0x80) { + *status = F_status_set_error(F_failure); + *operation_if = fake_make_operation_if_type_false_always_next; + + return; + } + } + + if (*operation_if == fake_make_operation_if_type_if_exists) { + i = 1; + } + + if (i < arguments.used) { + for (f_status_t status_file = F_none; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(status_file)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(status_file), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + *operation_if = fake_make_operation_if_type_false_always_next; + + if (F_status_is_error_not(*status)) { + if (F_status_set_fine(status_file) == F_false) { + *status = F_status_set_error(F_failure); + } + else { + *status = status_file; + } + } + } + else if (*operation_if != fake_make_operation_if_type_if_exists && *operation_if != fake_make_operation_if_type_if_is) { + + // The existence tests do not need to happen here for *_if_exists and *_if_is as those two types will handle performing them during the process stage. + status_file = f_file_exists(arguments.array[i].string); + + if (status_file == F_false) { + status_file = F_status_set_error(F_file_found_not); + } + + if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_exists", F_true, arguments.array[i].string, "find", fll_error_file_type_file); + + *operation_if = fake_make_operation_if_type_false_always_next; + + if (F_status_is_error_not(*status)) { + *status = F_status_set_error(status_file); + } + } + } + } // for + + return; + } + } + + if (*operation_if == fake_make_operation_if_type_if_defined) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported define type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + + return; + } + + if (*operation_if == fake_make_operation_if_type_if_equal || *operation_if == fake_make_operation_if_type_if_equal_not) { + if (arguments.used < 3) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (*operation_if == fake_make_operation_if_type_if_greater || *operation_if == fake_make_operation_if_type_if_greater_equal || *operation_if == fake_make_operation_if_type_if_less || *operation_if == fake_make_operation_if_type_if_less_equal) { + if (arguments.used < 3) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + return; + } + + f_status_t status_number = F_none; + f_string_range_t range = f_string_range_t_initialize; + f_number_unsigned_t number = 0; + bool is_negative = F_false; + + // @fixme there needs to handle converting numbers with decimals (like 1.01), perhaps operate on them as strings or provide a special processor. + for (i = 1; i < arguments.used; ++i, status_number = F_none) { + + if (arguments.array[i].used) { + range.start = 0; + range.stop = arguments.array[i].used - 1; + + if (arguments.array[i].string[0] == '+') { + range.start = 1; + } + else if (arguments.array[i].string[0] == '-') { + range.start = 1; + is_negative = F_true; + } + + if (range.start > range.stop) { + status_number = F_status_set_error(F_failure); + } + else { + status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number); + } + } + else { + status_number = F_status_set_error(F_failure); + } + + if (F_status_is_error(status_number)) { + *status = F_status_set_error(F_failure); + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + if (number > F_number_t_size_unsigned_d) { + fl_print_format("%c%[%SThe number '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%[' may only be between the ranges -%un to %un.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); + } + else { + fl_print_format("%c%[%SInvalid or unsupported number provided '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + } + + funlockfile(data_make->error.to.stream); + } + } + } // for + + return; + } + } + } + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + *operation_if = fake_make_operation_if_type_false_always_next; + + return; + } + + if (operation == fake_make_operation_type_link) { + if (arguments.used > 2) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used == 2) { + *status = fake_make_assure_inside_project(main, arguments.array[0], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[0].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + + *status = fake_make_assure_inside_project(main, arguments.array[1], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[1].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_move) { + if (arguments.used > 1) { + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } // for + + for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { + + if (f_file_exists(arguments.array[i].string) != F_true) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } // for + + if (arguments.used > 2) { + + // the last file must be a directory. + f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); + + if (status_file == F_false || status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + else if (F_status_is_error(status_file)) { + fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "identify", fll_error_file_type_directory); + *status = F_status_set_error(F_failure); + } + } + else { + + // when the first file is a directory, then the second, if it exists, must also be a directory. + f_status_t status_file = f_directory_is(arguments.array[0].string); + + if (status_file == F_true) { + status_file = f_directory_is(arguments.array[1].string); + + if (status_file == F_false) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); + fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_operate) { + if (arguments.used > 1) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used == 1) { + f_array_length_t id_section = 0; + + for (; id_section < data_make->fakefile.used; ++id_section) { + + if (fl_string_dynamic_partial_compare_string(arguments.array[0].string, data_make->buffer, arguments.array[0].used, data_make->fakefile.array[id_section].name) == F_equal_to) { + break; + } + } // for + + if (id_section == data_make->fakefile.used) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SNo operation section named '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%[' was found.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + else { + for (f_array_length_t i = 0; i < section_stack->used; ++i) { + + if (section_stack->array[i] == id_section) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe section operation '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, data_make->fakefile.array[id_section].name, data_make->error.notable); + fl_print_format("%[' is already in the operation stack, recursion is not allowed.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + break; + } + } // for + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + return; + } + + if (operation == fake_make_operation_type_to) { + if (arguments.used > 1) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + else if (arguments.used) { + if (arguments.array[0].used) { + f_status_t status_file = f_file_is(arguments.array[0].string, F_file_type_directory_d, F_false); + + if (status_file == F_file_found_not) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(status_file); + } + else if (F_status_is_error(status_file)) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_is", F_true, main->file_data_build_fakefile.string, "find", fll_error_file_type_file); + } + + *status = status_file; + } + else if (!status_file) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SThe file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%[' must be a directory file.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SFilename argument must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + } + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (operation == fake_make_operation_type_touch) { + if (arguments.used > 1) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_file_s, arguments.array[0], fake_make_operation_argument_file_s_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory_s, arguments.array[0], fake_make_operation_argument_directory_s_length) == F_equal_to_not) { + + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SUnsupported file type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); + fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); + fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); + + funlockfile(data_make->error.to.stream); + } + + *status = F_status_set_error(F_failure); + } + } + + for (f_array_length_t i = 1; i < arguments.used; ++i) { + + *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + } + } // for + } + else { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); + } + + *status = F_status_set_error(F_failure); + } + + return; + } + + // note: there is nothing to validate for fake_make_operation_type_print. + } +#endif // _di_fake_make_operate_validate_ + +#ifndef _di_fake_make_operate_validate_define_name_ + f_status_t fake_make_operate_validate_define_name(const f_string_static_t name) { + + if (!name.used) return F_none; + + if (!(isalpha(name.string[0]) || name.string[0] == '_')) { + return F_false; + } + + for (f_array_length_t i = 0; i < name.used; ++i) { + + if (!(isalnum(name.string[i]) || name.string[i] == '_')) { + return F_false; + } + } // for + + return F_true; + } +#endif // _di_fake_make_operate_validate_define_name_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-make-operate.h b/level_3/fake/c/private-make-operate.h new file mode 100644 index 0000000..9b9924d --- /dev/null +++ b/level_3/fake/c/private-make-operate.h @@ -0,0 +1,293 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_make_operate_h +#define _PRIVATE_make_operate_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Execute the make sections and their respective operations. + * + * The first section operated on is the 'main' section. + * The 'settings' section is only loaded into settings and is never operated on. + * + * @param main + * The main program data. + * + * @return + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_ + extern f_status_t fake_make_operate(fake_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_ + +/** + * For a given make section operation, expand the content into an arguments array for that operation. + * + * This prints errors via data_make.error. + * + * @param main + * The main program data. + * @param section_name + * The section name. + * @param operation + * The operation being performed. + * @param content + * The content array. + * @param quoteds + * The array of quoted associated with the content. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param arguments + * The expanded arguments. + * @param status + * The return status. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_expand_ + extern void fake_make_operate_expand(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_fss_content_t content, const f_fss_quotes_t quoteds, fake_make_data_t *data_make, f_string_dynamics_t *arguments, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_expand_ + +/** + * Perform the expand operation, specifically for the environment variables. + * + * @param main + * The main program data. + * @param quoted + * The quoted associated with the content. + * @param range_name + * The range representing the variable content name string within the data_make->buffer. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param arguments + * The expanded arguments. + * + * @return + * F_true on success and match expanded. + * F_false on no matches to expand. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_expand_environment_ + extern f_status_t fake_make_operate_expand_environment(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_expand_environment_ + +/** + * Perform the expand operation, specifically for the build settings. + * + * @param main + * The main program data. + * @param quoted + * The quoted associated with the content. + * @param range_name + * The range representing the variable content name string within the data_make->buffer. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param arguments + * The expanded arguments. + * + * @return + * F_true on success and match expanded. + * F_false on no matches to expand. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_expand_build_ + extern f_status_t fake_make_operate_expand_build(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_expand_build_ + +/** + * Perform the make operations within the given section. + * + * @param main + * The main program data. + * @param id_section + * The array location id within the fakefile of the section to operate on. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param section_stack + * The current operation stack. + * @param status + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * F_recurse (with error bit) is returned if unable to recurse to another operation section (usually max stack depth reached). + * F_valid_not (with error bit) is returned if any part of the section is invalid, such as an invalid operation name. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_make_operate_section_ + int fake_make_operate_section(fake_main_t * const main, const f_array_length_t id_section, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_section_ + +/** + * Perform a specific make operation within the given section. + * + * @param main + * The main program data. + * @param section_name + * The section name. + * @param operation + * The operation type. + * @param arguments + * The expanded arguments. + * @param success + * Whether or not a previous section operation succeeded or failed. + * @param operation_if + * The if-condition status for the current operation. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param section_stack + * The current operation stack. + * @param status + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * + * Status codes (with error bit) are returned on any problem. + * + * @return + * The return code of the execution process. + * This generally is only needed when F_child is returned, where this holds the return status of the child process. + */ +#ifndef _di_fake_make_operate_process_ + extern int fake_make_operate_process(fake_main_t * const main, const f_string_range_t section_name, const uint8_t operation, const f_string_dynamics_t arguments, const bool success, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_ + +/** + * Execute either the run operation or the shell operation. + * + * @param main + * The main program data. + * @param program + * The program to be executed. + * @param arguments + * The arguments for the run or shell operation. + * @param as_shell + * When TRUE, this is a shell operation. + * When FALSE, this is a run operation. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * + * @return + * F_none on success. + * + * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_process_execute_ + extern f_status_t fake_make_operate_process_execute(fake_main_t * const main, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_execute_ + +/** + * Handle the return code, converting it to a number. + * + * @param main + * The main program data. + * @param return_code + * The return code to process. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param status + * The return status. + * + * F_none on success. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_process_return_ + extern void fake_make_operate_process_return(fake_main_t * const main, const int return_code, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_return_ + +/** + * Execute either the run operation or the shell operation. + * + * @param main + * The main program data. + * @param arguments + * The arguments for the run or shell operation. + * @param as_shell + * When TRUE, this is a shell operation. + * When FALSE, this is a run operation. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * + * @return + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_process_run_ + extern f_status_t fake_make_operate_process_run(fake_main_t * const main, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_run_ + +/** + * For a given make section operation, validate the given operation. + * + * This performs pre-operation validations. + * Additional issues may occure when running operations that are not detected nor detectable by this. + * + * @param main + * The main program data. + * @param section_name + * The section name. + * @param operation + * The operation being performed. + * @param arguments + * The expanded arguments. + * @param operation_if + * The if-condition status for the current operation. + * @param main_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param section_stack + * The current operation stack. + * @param status + * The return status. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_operate_validate_ + extern void fake_make_operate_validate(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_string_dynamics_t arguments, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_validate_ + +/** + * Validate that the given define variable name is valid. + * + * A valid define variable name must begin with an alpha-character or an underscore. + * Every character after that may be alphanumeric or underscore. + * All other characters, including Unicode characters, are invalid. + * + * @fixme make this UTF-8 friendly. + * + * @param name + * The variable name string to validate. + * + * @return + * F_true on valid. + * F_false on invalid. + * F_none if there is no string to validate (used = 0). + */ +#ifndef _di_fake_make_operate_validate_define_name_ + extern f_status_t fake_make_operate_validate_define_name(const f_string_static_t name) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_validate_define_name_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_make_operate_h diff --git a/level_3/fake/c/private-make.c b/level_3/fake/c/private-make.c index 1c40bf5..31cf531 100644 --- a/level_3/fake/c/private-make.c +++ b/level_3/fake/c/private-make.c @@ -4,6 +4,9 @@ #include "private-build.h" #include "private-clean.h" #include "private-make.h" +#include "private-make-load_fakefile.h" +#include "private-make-load_parameters.h" +#include "private-make-operate.h" #include "private-print.h" #include "private-skeleton.h" @@ -192,5356 +195,6 @@ extern "C" { } #endif // _di_fake_make_get_id_owner_ -#ifndef _di_fake_make_load_fakefile_ - void fake_make_load_fakefile(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - return; - } - - data_make->fakefile.used = 0; - - *status = fake_file_buffer(main, main->file_data_build_fakefile.string, &data_make->buffer); - if (F_status_is_error(*status)) return; - - if (!data_make->buffer.used) { - if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe fakefile '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, main->file_data_build_fakefile, main->warning.notable); - fl_print_format("%[' is empty.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - - return; - } - - f_fss_objects_t list_objects = f_fss_objects_t_initialize; - f_fss_contents_t list_contents = f_fss_contents_t_initialize; - - { - f_string_range_t range = macro_f_string_range_t_initialize(data_make->buffer.used); - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; - f_fss_comments_t comments = f_fss_comments_t_initialize; - - { - f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); - - *status = fll_fss_basic_list_read(data_make->buffer, state, &range, &list_objects, &list_contents, &delimits, 0, &comments); - } - - if (F_status_is_error(*status)) { - fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_basic_list_read", main->file_data_build_fakefile.string, range, F_true); - } - else { - *status = fl_fss_apply_delimit(delimits, &data_make->buffer); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); - } - } - - macro_f_fss_delimits_t_delete_simple(delimits); - macro_f_fss_comments_t_delete_simple(comments); - - if (F_status_is_error(*status)) { - macro_f_fss_objects_t_delete_simple(list_objects); - macro_f_fss_contents_t_delete_simple(list_contents); - - return; - } - } - - { - bool missing_main = F_true; - bool missing_settings = F_true; - - f_fss_set_t settings = f_fss_set_t_initialize; - - f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_fss, 0, (void *) &main, 0); - - const f_string_static_t name_settings = macro_f_string_static_t_initialize(fake_make_section_settings_s, fake_make_section_settings_s_length); - const f_string_static_t name_main = macro_f_string_static_t_initialize(fake_make_section_main_s, fake_make_section_main_s_length); - - const f_string_range_t name_settings_range = macro_f_string_range_t_initialize(fake_make_section_settings_s_length); - const f_string_range_t name_main_range = macro_f_string_range_t_initialize(fake_make_section_main_s_length); - - if (list_objects.used > data_make->fakefile.size) { - macro_f_fss_nameds_t_resize((*status), data_make->fakefile, list_objects.used); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "macro_f_fss_nameds_t_resize", F_true); - - macro_f_fss_set_t_delete_simple(settings); - macro_f_fss_objects_t_delete_simple(list_objects); - macro_f_fss_contents_t_delete_simple(list_contents); - - return; - } - - { - f_string_range_t content_range = f_string_range_t_initialize; - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; - - for (f_array_length_t i = 0; i < list_objects.used; ++i) { - - if (!(i % fake_signal_check_short_d) && fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - break; - } - - if (fl_string_dynamic_partial_compare(name_settings, data_make->buffer, name_settings_range, list_objects.array[i]) == F_equal_to) { - if (!missing_settings) { - fake_print_warning_settings_object_multiple(main, main->file_data_build_fakefile.string, "list", name_settings.string); - - continue; - } - - delimits.used = 0; - content_range = list_contents.array[i].array[0]; - - *status = fll_fss_extended_read(data_make->buffer, state, &content_range, &settings.objects, &settings.contents, 0, 0, &delimits, 0); - - if (F_status_is_error(*status)) { - fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_fakefile.string, content_range, F_true); - - break; - } - - *status = fl_fss_apply_delimit(delimits, &data_make->buffer); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); - - break; - } - - missing_settings = F_false; - - continue; - } - else if (fl_string_dynamic_partial_compare(name_main, data_make->buffer, name_main_range, list_objects.array[i]) == F_equal_to) { - if (!missing_main) { - fake_print_warning_settings_object_multiple(main, main->file_data_build_fakefile.string, "list", name_main.string); - continue; - } - - missing_main = F_false; - data_make->main = data_make->fakefile.used; - } - - data_make->fakefile.array[data_make->fakefile.used].name = list_objects.array[i]; - - delimits.used = 0; - content_range = list_contents.array[i].array[0]; - - *status = fll_fss_extended_read(data_make->buffer, state, &content_range, &data_make->fakefile.array[data_make->fakefile.used].objects, &data_make->fakefile.array[data_make->fakefile.used].contents, 0, &data_make->fakefile.array[data_make->fakefile.used].quotess, &delimits, 0); - - if (F_status_is_error(*status)) { - fake_print_error_fss(main, F_status_set_fine(*status), "fll_fss_extended_read", main->file_data_build_fakefile.string, content_range, F_true); - - break; - } - - *status = fl_fss_apply_delimit(delimits, &data_make->buffer); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fl_fss_apply_delimit", F_true); - - break; - } - - ++data_make->fakefile.used; - } // for - - macro_f_fss_delimits_t_delete_simple(delimits); - } - - macro_f_fss_objects_t_delete_simple(list_objects); - macro_f_fss_contents_t_delete_simple(list_contents); - - if (F_status_is_error(*status)) { - macro_f_fss_set_t_delete_simple(settings); - - return; - } - - if (missing_main) { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe fakefile '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, main->file_data_build_fakefile, main->error.notable); - fl_print_format("%[' is missing the required '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%]", main->error.to.stream, main->error.notable, fake_make_section_main_s, main->error.notable); - fl_print_format("%[' object.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_failure); - - macro_f_fss_set_t_delete_simple(settings); - - return; - } - - // Always have the parameter variable "return" map at index 0 and be pre-initialized. - { - f_string_t function_name = "macro_f_string_map_multis_t_resize"; - - macro_f_string_map_multis_t_resize(*status, data_make->setting_make.parameter, F_memory_default_allocation_small_d); - - if (F_status_is_error_not(*status)) { - data_make->setting_make.parameter.used = 1; - - function_name = "f_string_append"; - *status = f_string_append(fake_make_setting_return_s, fake_make_setting_return_s_length, &data_make->setting_make.parameter.array[0].name); - } - - if (F_status_is_error_not(*status)) { - function_name = "f_string_dynamic_terminate_after"; - *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].name); - } - - if (F_status_is_error_not(*status)) { - function_name = "f_string_dynamics_resize"; - *status = f_string_dynamics_resize(1, &data_make->setting_make.parameter.array[0].value); - } - - if (F_status_is_error_not(*status)) { - function_name = "f_string_dynamic_terminate_after"; - *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), function_name, F_true); - - macro_f_fss_set_t_delete_simple(settings); - return; - } - } - - f_string_range_t *range_compiler = 0; - f_string_range_t *range_indexer = 0; - - data_make->setting_make.parameter.array[0].value.used = 1; - data_make->setting_make.load_build = F_true; - data_make->setting_make.fail = fake_make_operation_fail_type_exit; - - if (settings.objects.used) { - bool unmatched_fail = F_true; - bool unmatched_load = F_true; - - for (f_array_length_t i = 0; i < settings.objects.used; ++i) { - - if (fl_string_dynamic_partial_compare_string(fake_make_setting_compiler_s, data_make->buffer, fake_make_setting_compiler_s_length, settings.objects.array[i]) == F_equal_to) { - if (range_compiler) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_compiler_s); - } - else { - if (settings.contents.array[i].used) { - range_compiler = &settings.contents.array[i].array[0]; - - if (settings.contents.array[i].used > 1) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_compiler_s); - } - } - else { - fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); - } - } - } - else if (fl_string_dynamic_partial_compare_string(fake_make_setting_environment_s, data_make->buffer, fake_make_setting_environment_s_length, settings.objects.array[i]) == F_equal_to) { - f_string_dynamic_t name_define = f_string_dynamic_t_initialize; - - f_array_length_t j = 0; - f_array_length_t k = 0; - - for (; j < settings.contents.array[i].used; ++j) { - - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, settings.contents.array[i].array[j], &name_define); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(&name_define); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - - // The environment settings are stored in the build settings rathe than the make settings. - if (fake_make_operate_validate_define_name(name_define) == F_true) { - for (k = 0; k < data_make->setting_build.environment.used; ++k) { - if (fl_string_dynamic_compare(name_define, data_make->setting_build.environment.array[k]) == F_equal_to) { - break; - } - } // for - - if (k == data_make->setting_build.environment.used) { - *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, &data_make->setting_build.environment); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); - break; - } - - // Include the terminating NULL when copying. - ++name_define.used; - - *status = f_string_dynamic_append(name_define, &data_make->setting_build.environment.array[data_make->setting_build.environment.used]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - break; - } - - // Ensure that the terminating NULL is after the end of the string used size. - --data_make->setting_build.environment.array[data_make->setting_build.environment.used++].used; - } - else if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe environment name '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, name_define, main->warning.notable); - fl_print_format("%[' is already added.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - else if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe environment name '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, name_define, main->warning.notable); - fl_print_format("%[' is invalid, ignoring.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - - name_define.used = 0; - } // for - - if (F_status_is_error(*status)) { - macro_f_string_dynamic_t_delete_simple(name_define); - break; - } - - *status = F_none; - macro_f_string_dynamic_t_delete_simple(name_define); - } - else if (fl_string_dynamic_partial_compare_string(fake_make_setting_fail_s, data_make->buffer, fake_make_setting_fail_s_length, settings.objects.array[i]) == F_equal_to) { - if (unmatched_fail) { - if (settings.contents.array[i].used) { - if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_exit_s, data_make->buffer, fake_make_operation_argument_exit_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_exit; - } - else if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_warn_s, data_make->buffer, fake_make_operation_argument_warn_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_warn; - } - else if (fl_string_dynamic_partial_compare_string(fake_make_operation_argument_ignore_s, data_make->buffer, fake_make_operation_argument_ignore_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_ignore; - } - else { - fake_print_warning_settings_content_invalid(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], settings.contents.array[i].array[0], fake_make_section_settings_s); - } - - if (settings.contents.array[i].used > 1) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_fail_s); - } - - unmatched_fail = F_false; - } - else { - fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); - } - } - else { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_fail_s); - } - } - else if (fl_string_dynamic_partial_compare_string(fake_make_setting_indexer_s, data_make->buffer, fake_make_setting_indexer_s_length, settings.objects.array[i]) == F_equal_to) { - if (range_indexer) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_indexer_s); - } - else { - if (settings.contents.array[i].used) { - range_indexer = &settings.contents.array[i].array[0]; - - if (settings.contents.array[i].used > 1) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_indexer_s); - } - } - else { - fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); - } - } - } - else if (fl_string_dynamic_partial_compare_string(fake_make_setting_load_build_s, data_make->buffer, fake_make_setting_load_build_s_length, settings.objects.array[i]) == F_equal_to) { - if (unmatched_load) { - if (settings.contents.array[i].used) { - if (fl_string_dynamic_partial_compare_string(fake_common_setting_bool_yes_s, data_make->buffer, fake_common_setting_bool_yes_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - data_make->setting_make.load_build = F_true; - } - else if (fl_string_dynamic_partial_compare_string(fake_common_setting_bool_no_s, data_make->buffer, fake_common_setting_bool_no_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - data_make->setting_make.load_build = F_false; - } - else { - fake_print_warning_settings_content_invalid(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], settings.contents.array[i].array[0], fake_make_section_settings_s); - } - - unmatched_load = F_false; - - if (settings.contents.array[i].used > 1) { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_load_build_s); - } - } - else { - fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); - } - } - else { - fake_print_warning_settings_content_multiple(main, main->file_data_build_fakefile.string, fake_make_setting_load_build_s); - } - } - else if (fl_string_dynamic_partial_compare_string(fake_make_setting_parameter_s, data_make->buffer, fake_make_setting_parameter_s_length, settings.objects.array[i]) == F_equal_to) { - if (settings.contents.array[i].used) { - if (fl_string_dynamic_partial_compare_string(fake_make_setting_return_s, data_make->buffer, fake_make_setting_return_s_length, settings.contents.array[i].array[0]) == F_equal_to) { - if (settings.contents.array[i].used > 1) { - f_string_t function_name = 0; - - // each define replaces the previous define. - data_make->setting_make.parameter.array[0].value.array[0].used = 0; - - for (f_array_length_t j = 1; j < settings.contents.array[i].used; ++j) { - - function_name = "f_string_dynamic_partial_append_nulless"; - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, settings.contents.array[i].array[j], &data_make->setting_make.parameter.array[0].value.array[0]); - - if (F_status_is_error_not(*status)) { - function_name = "f_string_dynamic_terminate_after"; - *status = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); - } - - if (F_status_is_error_not(*status) && j + 1 < settings.contents.array[i].used) { - function_name = "f_string_append_assure"; - *status = f_string_append_assure(f_string_space_s, 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), function_name, F_true); - break; - } - } // for - - if (F_status_is_error(*status)) { - break; - } - } - } - } - else { - fake_print_warning_settings_content_empty(main, main->file_data_build_fakefile.string, data_make->buffer, settings.objects.array[i], fake_make_section_settings_s); - } - } - } // for - - if (F_status_is_error(*status)) { - macro_f_fss_set_t_delete_simple(settings); - - return; - } - } - - if (F_status_is_error_not(*status) && data_make->setting_make.load_build) { - f_string_static_t stub = f_string_static_t_initialize; - - fake_build_load_setting(main, stub, &data_make->setting_build, status); - - if (F_status_is_error(*status) && *status != F_status_set_error(F_interrupt)) { - fll_error_print(main->error, F_status_set_fine(*status), "fake_build_load_setting", F_true); - } - } - - if (F_status_is_error(*status)) { - macro_f_fss_set_t_delete_simple(settings); - - return; - } - - // If either compiler or indexer is specified, each will replace any existing build_compiler or build_indexer, respectively. - if (range_compiler) { - data_make->setting_build.build_compiler.used = 0; - - *status = f_string_dynamic_partial_append(data_make->buffer, *range_compiler, &data_make->setting_build.build_compiler); - } - - if (F_status_is_error_not(*status) && range_indexer) { - data_make->setting_build.build_indexer.used = 0; - - *status = f_string_dynamic_partial_append(data_make->buffer, *range_indexer, &data_make->setting_build.build_indexer); - } - - if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) != F_interrupt) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_partial_append", F_true); - } - - macro_f_fss_set_t_delete_simple(settings); - return; - } - - f_string_map_multis_t define = f_string_map_multis_t_initialize; - - // Load the fakefile "settings" as if they are build "settings". - fake_build_load_setting_process(main, F_false, main->file_data_build_fakefile.string, data_make->buffer, settings.objects, settings.contents, &data_make->setting_build, status); - - if (F_status_is_error_not(*status) && settings.objects.used) { - const f_string_t settings_name[] = { - fake_make_setting_define_s, - fake_make_setting_parameter_s, - }; - - const f_array_length_t settings_length[] = { - fake_make_setting_define_s_length, - fake_make_setting_parameter_s_length, - }; - - f_string_map_multis_t *settings_value[] = { - &define, - &data_make->setting_make.parameter, - }; - - *status = fll_fss_snatch_map_apart(data_make->buffer, settings.objects, settings.contents, settings_name, settings_length, 2, settings_value, 0, 0); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "fll_fss_snatch_map_apart", F_true); - - macro_f_string_map_multis_t_delete_simple(define); - macro_f_fss_set_t_delete_simple(settings); - return; - } - } - - if (define.used) { - f_status_t status_validate = F_none; - f_string_dynamic_t combined = f_string_dynamic_t_initialize; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < define.used; ++i) { - - status_validate = fake_make_operate_validate_define_name(define.array[i].name); - - if (status_validate) { - combined.used = 0; - - for (j = 0; j < define.array[i].value.used; ++j) { - - *status = f_string_dynamic_mash(f_string_space_s, 1, define.array[i].value.array[j], &combined); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_mash_nulless", F_true); - break; - } - } // for - - if (F_status_is_error(*status)) break; - - *status = f_string_dynamic_terminate_after(&combined); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - break; - } - - *status = f_environment_set(define.array[i].name.string, combined.string, F_true); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_environment_set", F_true); - break; - } - } - else { - if (main->error.verbosity != f_console_verbosity_quiet) { - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SInvalid characters in the define setting name '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, define.array[i].name, main->error.notable); - fl_print_format("%[', only alpha-numeric ASCII characters and underscore (without a leading digit) are allowed.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } - - *status = F_status_set_error(F_failure); - break; - } - } // for - - macro_f_string_dynamic_t_delete_simple(combined); - } - - macro_f_string_map_multis_t_delete_simple(define); - macro_f_fss_set_t_delete_simple(settings); - } - } -#endif // _di_fake_make_load_fakefile_ - -#ifndef _di_fake_make_load_parameters_ - void fake_make_load_parameters(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (main->context.mode != F_color_mode_none_d) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter.color); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter_option.color); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - if (main->context.mode == F_color_mode_no_color_d) { - if (main->parameters[fake_parameter_no_color].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - else if (main->parameters[fake_parameter_no_color].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_no_color_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - } - else if (main->context.mode == F_color_mode_dark_d) { - if (main->parameters[fake_parameter_dark].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - else if (main->parameters[fake_parameter_dark].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_dark_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - } - else { - if (main->parameters[fake_parameter_light].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - else if (main->parameters[fake_parameter_light].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_light_s, 1, &data_make->parameter.color.array[data_make->parameter.color.used]); - } - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - - return; - } - - *status = f_string_dynamic_append(data_make->parameter.color.array[data_make->parameter.color.used], &data_make->parameter_option.color.array[data_make->parameter_option.color.used]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++data_make->parameter.color.used; - ++data_make->parameter_option.color.used; - } - - if (main->error.verbosity != f_console_verbosity_normal) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter.verbosity); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->parameter_option.verbosity); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - if (main->error.verbosity == f_console_verbosity_quiet) { - if (main->parameters[fake_parameter_verbosity_quiet].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - else if (main->parameters[fake_parameter_verbosity_quiet].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_quiet_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - if (main->parameters[fake_parameter_verbosity_verbose].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - else if (main->parameters[fake_parameter_verbosity_verbose].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_verbose_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - } - else { - if (main->parameters[fake_parameter_verbosity_debug].type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - else if (main->parameters[fake_parameter_verbosity_debug].type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(f_console_standard_short_debug_s, 1, &data_make->parameter.verbosity.array[data_make->parameter.verbosity.used]); - } - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - - return; - } - - *status = f_string_dynamic_append(data_make->parameter.verbosity.array[data_make->parameter.verbosity.used], &data_make->parameter_option.verbosity.array[data_make->parameter_option.verbosity.used]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++data_make->parameter.verbosity.used; - ++data_make->parameter_option.verbosity.used; - } - - { - const f_string_t parameter[] = { - fake_short_define_s, - fake_short_mode_s, - }; - - const f_console_parameter_t *console[] = { - &main->parameters[fake_parameter_define], - &main->parameters[fake_parameter_mode], - }; - - const f_string_dynamics_t *source[] = { - &main->define, - &main->mode, - }; - - f_string_dynamics_t * const destination[] = { - &data_make->parameter.define, - &data_make->parameter.mode, - }; - - f_string_dynamics_t * const destination_option[] = { - &data_make->parameter_option.define, - &data_make->parameter_option.mode, - }; - - f_string_dynamics_t * const destination_value[] = { - &data_make->parameter_value.define, - &data_make->parameter_value.mode, - }; - - uint8_t i = 0; - f_array_length_t j = 0; - - for (; i < 2; ++i) { - - if (console[i]->result == f_console_result_none) { - continue; - } - - for (j = 0; j < source[i]->used; ++j) { - - if (destination[i]->used + 2 > destination[i]->size) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - } - - *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_option[i]); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_value[i]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); - - return; - } - - if (console[i]->type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &destination[i]->array[destination[i]->used]); - } - else if (console[i]->type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &destination[i]->array[destination[i]->used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(parameter[i], 1, &destination[i]->array[destination[i]->used]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - - return; - } - - *status = f_string_dynamic_append(destination[i]->array[destination[i]->used], &destination_option[i]->array[destination_option[i]->used]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++destination[i]->used; - ++destination_option[i]->used; - - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - *status = f_string_dynamic_append(source[i]->array[j], &destination[i]->array[destination[i]->used]); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamic_append(source[i]->array[j], &destination_value[i]->array[destination_value[i]->used]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++destination[i]->used; - ++destination_value[i]->used; - } // for - } // for - } - - { - const f_string_t parameter[] = { - fake_short_fakefile_s, - fake_short_path_build_s, - fake_short_path_data_s, - fake_short_path_sources_s, - fake_short_path_work_s, - fake_short_process_s, - fake_short_settings_s, - }; - - const f_console_parameter_t *console[] = { - &main->parameters[fake_parameter_fakefile], - &main->parameters[fake_parameter_path_build], - &main->parameters[fake_parameter_path_data], - &main->parameters[fake_parameter_path_sources], - &main->parameters[fake_parameter_path_work], - &main->parameters[fake_parameter_process], - &main->parameters[fake_parameter_settings], - }; - - const f_string_dynamic_t *source[] = { - &main->fakefile, - &main->path_build, - &main->path_data, - &main->path_sources, - &main->path_work, - &main->process, - &main->settings, - }; - - f_string_dynamics_t * const destination[] = { - &data_make->parameter.fakefile, - &data_make->parameter.build, - &data_make->parameter.data, - &data_make->parameter.sources, - &data_make->parameter.work, - &data_make->parameter.process, - &data_make->parameter.settings, - }; - - f_string_dynamics_t * const destination_option[] = { - &data_make->parameter_option.fakefile, - &data_make->parameter_option.build, - &data_make->parameter_option.data, - &data_make->parameter_option.sources, - &data_make->parameter_option.work, - &data_make->parameter_option.process, - &data_make->parameter_option.settings, - }; - - f_string_dynamics_t * const destination_value[] = { - &data_make->parameter_value.fakefile, - &data_make->parameter_value.build, - &data_make->parameter_value.data, - &data_make->parameter_value.sources, - &data_make->parameter_value.work, - &data_make->parameter_value.process, - &data_make->parameter_value.settings, - }; - - for (uint8_t i = 0; i < 7; ++i) { - - if (console[i]->result == f_console_result_none) { - continue; - } - - if (destination[i]->used + 2 > destination[i]->size) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - } - - *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_option[i]); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamics_increase(F_memory_default_allocation_small_d, destination_value[i]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); - - return; - } - - if (console[i]->type == f_console_type_normal) { - *status = f_string_append(f_console_symbol_short_enable_s, 1, &destination[i]->array[destination[i]->used]); - } - else if (console[i]->type == f_console_type_inverse) { - *status = f_string_append(f_console_symbol_short_disable_s, 1, &destination[i]->array[destination[i]->used]); - } - - if (F_status_is_error_not(*status)) { - *status = f_string_append(parameter[i], 1, &destination[i]->array[destination[i]->used]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_append", F_true); - - return; - } - - *status = f_string_dynamic_append(destination[i]->array[destination[i]->used], &destination_option[i]->array[destination_option[i]->used]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++destination[i]->used; - ++destination_option[i]->used; - - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, destination[i]); - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - *status = f_string_dynamic_append(*source[i], &destination[i]->array[destination[i]->used]); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamic_append(*source[i], &destination_value[i]->array[destination_value[i]->used]); - } - - if (F_status_is_error(*status)) { - fll_error_print(main->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - return; - } - - ++destination[i]->used; - ++destination_value[i]->used; - } // for - } - } -#endif // _di_fake_make_load_parameters_ - -#ifndef _di_fake_make_operate_ - f_status_t fake_make_operate(fake_main_t * const main) { - - if (fake_signal_received(main)) { - return F_status_set_error(F_interrupt); - } - - if (main->output.verbosity != f_console_verbosity_quiet) { - fll_print_format("%c%[Making project.%]%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important, f_string_eol_s[0]); - } - - f_status_t status = F_none; - f_mode_t mode = f_mode_t_initialize; - - f_array_lengths_t section_stack = f_array_lengths_t_initialize; - fake_make_data_t data_make = fake_make_data_t_initialize; - - status = f_string_dynamics_increase(F_memory_default_allocation_small_d, &data_make.path.stack); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - - return status; - } - - status = f_path_current(F_true, &data_make.path.stack.array[0]); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_path_current", F_true); - - macro_fake_make_data_t_delete_simple(data_make); - - return status; - } - - status = f_directory_open(data_make.path.stack.array[0].string, F_false, &data_make.path.top.id); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_directory_open", F_true); - - macro_fake_make_data_t_delete_simple(data_make); - - return status; - } - - data_make.path.stack.used = 1; - - macro_f_mode_t_set_default_umask(mode, main->umask); - - fake_make_load_parameters(main, &data_make, &status); - - fake_make_load_fakefile(main, &data_make, &status); - - if (F_status_is_error(status)) { - macro_fake_make_data_t_delete_simple(data_make); - - return status; - } - - if (data_make.setting_make.fail == fake_make_operation_fail_type_exit) { - data_make.error.prefix = fl_print_error_s; - data_make.error.suffix = 0; - data_make.error.context = main->context.set.error; - data_make.error.notable = main->context.set.notable; - data_make.error.to.stream = F_type_error_d; - data_make.error.to.id = F_type_descriptor_error_d; - data_make.error.set = &main->context.set; - } - else if (data_make.setting_make.fail == fake_make_operation_fail_type_warn) { - data_make.error.prefix = fl_print_warning_s; - data_make.error.suffix = 0; - data_make.error.context = main->context.set.warning; - data_make.error.notable = main->context.set.notable; - data_make.error.to.stream = F_type_warning_d; - data_make.error.to.id = F_type_descriptor_warning_d; - data_make.error.set = &main->context.set; - } - else { - data_make.error.to.stream = 0; - data_make.error.prefix = 0; - data_make.error.suffix = 0; - data_make.error.to.id = -1; - data_make.error.set = &main->context.set; - } - - { - const int result = fake_make_operate_section(main, data_make.main, &data_make, §ion_stack, &status); - - if (status == F_child) { - main->child = result; - } - } - - if (data_make.path.current.stream) { - f_file_stream_close(F_true, &data_make.path.current); - } - - { - f_status_t status_path = f_path_change_at(data_make.path.top.id); - - if (F_status_is_error(status_path) && main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SFailed change back to orignal path '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, data_make.path.stack.array[0], main->warning.notable); - fl_print_format("%[', status code =%] ", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%ui%]", main->warning.to.stream, main->warning.notable, F_status_set_fine(status_path), main->warning.notable); - fl_print_format("%['.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - } - - f_file_stream_close(F_true, &data_make.path.top); - - macro_f_array_lengths_t_delete_simple(section_stack) - macro_fake_make_data_t_delete_simple(data_make) - - return status; - } -#endif // _di_fake_make_operate_ - -#ifndef _di_fake_make_operate_expand_ - void fake_make_operate_expand(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_fss_content_t content, const f_fss_quotes_t quotes, fake_make_data_t *data_make, f_string_dynamics_t *arguments, f_status_t *status) { - - if (F_status_is_error(*status)) return; - if (!content.used) return; - - // Pre-allocate the known arguments size. - *status = f_string_dynamics_increase_by(content.used, arguments); - - if (F_status_is_error(*status) || *status == F_string_too_large) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - const f_string_static_t vocabulary_define = macro_f_string_static_t_initialize(F_iki_vocabulary_0002_define_s, F_iki_vocabulary_0002_define_s_length); - const f_string_static_t vocabulary_parameter = macro_f_string_static_t_initialize(F_iki_vocabulary_0002_parameter_s, F_iki_vocabulary_0002_parameter_s_length); - - const f_string_range_t range_define = macro_f_string_range_t_initialize(F_iki_vocabulary_0002_define_s_length); - const f_string_range_t range_parameter = macro_f_string_range_t_initialize(F_iki_vocabulary_0002_parameter_s_length); - - f_iki_variable_t iki_variable = f_iki_variable_t_initialize; - f_iki_vocabulary_t iki_vocabulary = f_iki_vocabulary_t_initialize; - f_iki_content_t iki_content = f_iki_content_t_initialize; - f_iki_delimits_t iki_delimits = f_iki_delimits_t_initialize; - - f_state_t state = macro_f_state_t_initialize(fake_common_allocation_large_d, fake_common_allocation_small_d, 0, &fake_signal_state_interrupt_iki, 0, (void *) &main, 0); - - f_string_range_t range = f_string_range_t_initialize; - f_string_map_multis_t *parameter = &data_make->setting_make.parameter; - - bool unmatched = F_true; - bool parameter_is = F_false; - bool define_is = F_false; - - f_array_length_t i = 0; - f_array_length_t j = 0; - f_array_length_t k = 0; - f_array_length_t l = 0; - - f_array_length_t used_arguments = 0; - f_array_length_t previous = 0; - - const f_string_t reserved_name[] = { - fake_make_parameter_variable_build_s, - fake_make_parameter_variable_color_s, - fake_make_parameter_variable_data_s, - fake_make_parameter_variable_define_s, - fake_make_parameter_variable_fakefile_s, - fake_make_parameter_variable_mode_s, - fake_make_parameter_variable_process_s, - fake_make_parameter_variable_settings_s, - fake_make_parameter_variable_sources_s, - fake_make_parameter_variable_verbosity_s, - fake_make_parameter_variable_work_s, - fake_make_parameter_variable_option_build_s, - fake_make_parameter_variable_option_color_s, - fake_make_parameter_variable_option_data_s, - fake_make_parameter_variable_option_define_s, - fake_make_parameter_variable_option_fakefile_s, - fake_make_parameter_variable_option_mode_s, - fake_make_parameter_variable_option_process_s, - fake_make_parameter_variable_option_settings_s, - fake_make_parameter_variable_option_sources_s, - fake_make_parameter_variable_option_verbosity_s, - fake_make_parameter_variable_option_work_s, - fake_make_parameter_variable_value_build_s, - fake_make_parameter_variable_value_color_s, - fake_make_parameter_variable_value_data_s, - fake_make_parameter_variable_value_define_s, - fake_make_parameter_variable_value_fakefile_s, - fake_make_parameter_variable_value_mode_s, - fake_make_parameter_variable_value_process_s, - fake_make_parameter_variable_value_settings_s, - fake_make_parameter_variable_value_sources_s, - fake_make_parameter_variable_value_verbosity_s, - fake_make_parameter_variable_value_work_s, - }; - - const f_array_length_t reserved_length[] = { - fake_make_parameter_variable_build_s_length, - fake_make_parameter_variable_color_s_length, - fake_make_parameter_variable_data_s_length, - fake_make_parameter_variable_define_s_length, - fake_make_parameter_variable_fakefile_s_length, - fake_make_parameter_variable_mode_s_length, - fake_make_parameter_variable_process_s_length, - fake_make_parameter_variable_settings_s_length, - fake_make_parameter_variable_sources_s_length, - fake_make_parameter_variable_verbosity_s_length, - fake_make_parameter_variable_work_s_length, - fake_make_parameter_variable_build_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_color_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_data_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_define_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_fakefile_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_mode_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_process_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_settings_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_sources_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_verbosity_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_work_s_length + fake_make_parameter_iki_option_s_length, - fake_make_parameter_variable_build_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_color_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_data_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_define_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_fakefile_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_mode_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_process_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_settings_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_sources_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_verbosity_s_length + fake_make_parameter_iki_value_s_length, - fake_make_parameter_variable_work_s_length + fake_make_parameter_iki_value_s_length, - }; - - f_string_dynamics_t * const reserved_value[] = { - &data_make->parameter.build, - &data_make->parameter.color, - &data_make->parameter.data, - &data_make->parameter.define, - &data_make->parameter.fakefile, - &data_make->parameter.mode, - &data_make->parameter.process, - &data_make->parameter.settings, - &data_make->parameter.sources, - &data_make->parameter.verbosity, - &data_make->parameter.work, - &data_make->parameter_option.build, - &data_make->parameter_option.color, - &data_make->parameter_option.data, - &data_make->parameter_option.define, - &data_make->parameter_option.fakefile, - &data_make->parameter_option.mode, - &data_make->parameter_option.process, - &data_make->parameter_option.settings, - &data_make->parameter_option.sources, - &data_make->parameter_option.verbosity, - &data_make->parameter_option.work, - &data_make->parameter_value.build, - &data_make->parameter_value.color, - &data_make->parameter_value.data, - &data_make->parameter_value.define, - &data_make->parameter_value.fakefile, - &data_make->parameter_value.mode, - &data_make->parameter_value.process, - &data_make->parameter_value.settings, - &data_make->parameter_value.sources, - &data_make->parameter_value.verbosity, - &data_make->parameter_value.work, - }; - - for (; i < content.used; ++i) { - - if (content.array[i].start > content.array[i].stop) continue; - - range = content.array[i]; - - used_arguments = arguments->used; - - *status = fl_iki_read(state, &data_make->buffer, &range, &iki_variable, &iki_vocabulary, &iki_content, &iki_delimits); - - if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) != F_interrupt) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fl_iki_read", F_true); - } - - break; - } - - for (k = 0; k < iki_delimits.used; ++k) { - data_make->buffer.string[iki_delimits.array[k]] = f_iki_syntax_placeholder_s[0]; - } // for - - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - break; - } - - if (iki_variable.used) { - if (iki_variable.array[0].start > 0 && content.array[i].start < iki_variable.array[0].start) { - range.start = content.array[i].start; - range.stop = iki_variable.array[0].start - 1; - - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); - - break; - } - } - - for (j = 0, previous = iki_variable.array[0].start; j < iki_variable.used; ++j) { - - parameter_is = F_false; - define_is = F_false; - - if (previous + 1 < iki_variable.array[j].start) { - range.start = previous + 1; - range.stop = iki_variable.array[j].start - 1; - - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); - - break; - } - } - - *status = fl_string_dynamic_partial_compare(vocabulary_define, data_make->buffer, range_define, iki_vocabulary.array[j]); - - if (*status == F_equal_to) { - define_is = F_true; - } - else if (*status == F_equal_to_not) { - *status = fl_string_dynamic_partial_compare(vocabulary_parameter, data_make->buffer, range_parameter, iki_vocabulary.array[j]); - - if (*status == F_equal_to) { - parameter_is = F_true; - } - } - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fl_string_dynamic_partial_compare", F_true); - - break; - } - - if (parameter_is) { - unmatched = F_true; - - // Check against reserved parameter names and if matches use them instead. - if (fl_string_dynamic_partial_compare_string(fake_make_parameter_variable_return_s, data_make->buffer, fake_make_parameter_variable_return_s_length, iki_content.array[j]) == F_equal_to) { - if (data_make->setting_make.parameter.array[0].value.array[0].used) { - *status = f_string_dynamic_append(data_make->setting_make.parameter.array[0].value.array[0], &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - break; - } - } - else { - *status = f_string_append("0", 1, &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); - - break; - } - } - - ++arguments->used; - unmatched = F_false; - } - else { - for (k = 0; k < 33; ++k) { - - if (fl_string_dynamic_partial_compare_string(reserved_name[k], data_make->buffer, reserved_length[k], iki_content.array[j]) == F_equal_to) { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - - return; - } - - for (l = 0; l < reserved_value[k]->used; ++l) { - - if (l > 0) { - *status = f_string_append(f_string_space_s, 1, &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); - - break; - } - } - - *status = f_string_dynamic_append(reserved_value[k]->array[l], &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - - break; - } - } // for - - if (F_status_is_error_not(*status)) { - unmatched = F_false; - ++arguments->used; - } - else { - break; - } - } - } // for - } - - if (unmatched && parameter->used) { - for (k = 0; k < parameter->used; ++k) { - - // Check against iki variable list. - *status = fl_string_dynamic_partial_compare_dynamic(parameter->array[k].name, data_make->buffer, iki_content.array[j]); - - if (*status == F_equal_to) { - unmatched = F_false; - - if (parameter->array[k].value.used) { - if (quotes.array[i]) { - for (l = 0; l < parameter->array[k].value.used; ++l) { - - if (l > 0) { - *status = f_string_append(f_string_space_s, 1, &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); - break; - } - } - - *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - break; - } - } // for - } - else { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase_by", F_true); - break; - } - - for (l = 0; l < parameter->array[k].value.used; ++l) { - - *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - break; - } - - *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); - break; - } - - ++arguments->used; - } // for - } - } - - break; - } - else if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fl_string_dynamic_compare", F_true); - break; - } - } // for - } - - if (F_status_is_error(*status)) break; - - if (unmatched) { - *status = fake_make_operate_expand_build(main, quotes.array[i], iki_content.array[j], data_make, arguments); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_operate_expand_build", F_true); - break; - } - } - } - else if (define_is && data_make->setting_make.load_build) { - *status = fake_make_operate_expand_environment(main, quotes.array[i], iki_content.array[j], data_make, arguments); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_operate_expand_environment", F_true); - break; - } - } - - previous = iki_variable.array[j].stop; - } // for - - if (F_status_is_error(*status)) break; - - if (iki_variable.array[iki_variable.used - 1].stop < content.array[i].stop) { - range.start = iki_variable.array[iki_variable.used - 1].stop + 1; - range.stop = content.array[i].stop; - - // If arguments->used was not incremented, then use the value, otherwise arguments->used is past the value to append to, so subtract 1. - if (used_arguments == arguments->used) { - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used]); - } - else { - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, range, &arguments->array[arguments->used - 1]); - - if (F_status_is_error_not(*status)) { - *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used - 1]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); - break; - } - } - } - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_partial_append_nulless", F_true); - break; - } - } - } - else { - *status = f_string_dynamic_partial_append_nulless(data_make->buffer, content.array[i], &arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append_nulless", F_true); - break; - } - } - - // If iki variable did not match (results in empty string) or iki variable is inside quotes, then increment. - if (used_arguments == arguments->used) { - *status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_terminate_after", F_true); - break; - } - - ++arguments->used; - } - - macro_f_iki_variable_t_delete_simple(iki_variable); - macro_f_iki_vocabulary_t_delete_simple(iki_vocabulary); - macro_f_iki_content_t_delete_simple(iki_content); - macro_f_iki_delimits_t_delete_simple(iki_delimits); - } // for - - macro_f_iki_variable_t_delete_simple(iki_variable); - macro_f_iki_vocabulary_t_delete_simple(iki_vocabulary); - macro_f_iki_content_t_delete_simple(iki_content); - macro_f_iki_delimits_t_delete_simple(iki_delimits); - } -#endif // _di_fake_make_operate_expand_ - -#ifndef _di_fake_make_operate_expand_build_ - f_status_t fake_make_operate_expand_build(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) { - - f_status_t status = F_none; - f_string_dynamic_t value = f_string_dynamic_t_initialize; - - bool unmatched = F_true; - - { - const f_string_t uint8_name[] = { - fake_build_setting_name_build_language_s, - fake_build_setting_name_version_file_s, - fake_build_setting_name_version_target_s, - }; - - const f_array_length_t uint8_length[] = { - fake_build_setting_name_build_language_s_length, - fake_build_setting_name_version_file_s_length, - fake_build_setting_name_version_target_s_length, - }; - - const uint8_t uint8_value[] = { - data_make->setting_build.build_language, - data_make->setting_build.version_file, - data_make->setting_build.version_target, - }; - - for (uint8_t i = 0; i < 3; ++i) { - - status = fl_string_dynamic_partial_compare_string(uint8_name[i], data_make->buffer, uint8_length[i], range_name); - - if (status == F_equal_to) { - unmatched = F_false; - - status = f_conversion_number_unsigned_to_string(uint8_value[i], f_conversion_data_base_10_s, &value); - break; - } - } // for - } - - if (unmatched) { - const f_string_t bool_name[] = { - fake_build_setting_name_build_script_s, - fake_build_setting_name_build_shared_s, - fake_build_setting_name_build_static_s, - fake_build_setting_name_path_standard_s, - fake_build_setting_name_search_exclusive_s, - fake_build_setting_name_search_shared_s, - fake_build_setting_name_search_static_s, - }; - - const f_array_length_t bool_length[] = { - fake_build_setting_name_build_script_s_length, - fake_build_setting_name_build_shared_s_length, - fake_build_setting_name_build_static_s_length, - fake_build_setting_name_path_standard_s_length, - fake_build_setting_name_search_exclusive_s_length, - fake_build_setting_name_search_shared_s_length, - fake_build_setting_name_search_static_s_length, - }; - - const bool bool_value[] = { - data_make->setting_build.build_script, - data_make->setting_build.build_shared, - data_make->setting_build.build_static, - data_make->setting_build.path_standard, - data_make->setting_build.search_exclusive, - data_make->setting_build.search_shared, - data_make->setting_build.search_static, - }; - - for (uint8_t i = 0; i < 7; ++i) { - - status = fl_string_dynamic_partial_compare_string(bool_name[i], data_make->buffer, bool_length[i], range_name); - - if (status == F_equal_to) { - unmatched = F_false; - - if (bool_value[i]) { - status = f_string_append(fake_common_setting_bool_yes_s, fake_common_setting_bool_yes_s_length, &value); - } - else { - status = f_string_append(fake_common_setting_bool_no_s, fake_common_setting_bool_no_s_length, &value); - } - - break; - } - } // for - } - - if (unmatched) { - const f_string_t dynamic_name[] = { - fake_build_setting_name_build_compiler_s, - fake_build_setting_name_build_indexer_s, - fake_build_setting_name_path_headers_s, - fake_build_setting_name_path_language_s, - fake_build_setting_name_path_library_script_s, - fake_build_setting_name_path_library_shared_s, - fake_build_setting_name_path_library_static_s, - fake_build_setting_name_path_program_script_s, - fake_build_setting_name_path_program_shared_s, - fake_build_setting_name_path_program_static_s, - fake_build_setting_name_path_sources_s, - fake_build_setting_name_process_post_s, - fake_build_setting_name_process_pre_s, - fake_build_setting_name_project_name_s, - fake_build_setting_name_version_major_s, - fake_build_setting_name_version_micro_s, - fake_build_setting_name_version_minor_s, - }; - - const f_array_length_t dynamic_length[] = { - fake_build_setting_name_build_compiler_s_length, - fake_build_setting_name_build_indexer_s_length, - fake_build_setting_name_path_headers_s_length, - fake_build_setting_name_path_language_s_length, - fake_build_setting_name_path_library_script_s_length, - fake_build_setting_name_path_library_shared_s_length, - fake_build_setting_name_path_library_static_s_length, - fake_build_setting_name_path_program_script_s_length, - fake_build_setting_name_path_program_shared_s_length, - fake_build_setting_name_path_program_static_s_length, - fake_build_setting_name_path_sources_s_length, - fake_build_setting_name_process_post_s_length, - fake_build_setting_name_process_pre_s_length, - fake_build_setting_name_project_name_s_length, - fake_build_setting_name_version_major_s_length, - fake_build_setting_name_version_micro_s_length, - fake_build_setting_name_version_minor_s_length, - }; - - const f_string_dynamic_t dynamic_value[] = { - data_make->setting_build.build_compiler, - data_make->setting_build.build_indexer, - data_make->setting_build.path_headers, - data_make->setting_build.path_language, - data_make->setting_build.path_library_script, - data_make->setting_build.path_library_shared, - data_make->setting_build.path_library_static, - data_make->setting_build.path_program_script, - data_make->setting_build.path_program_shared, - data_make->setting_build.path_program_static, - data_make->setting_build.path_sources, - data_make->setting_build.process_post, - data_make->setting_build.process_pre, - data_make->setting_build.project_name, - data_make->setting_build.version_major, - data_make->setting_build.version_micro, - data_make->setting_build.version_minor, - }; - - for (uint8_t i = 0; i < 17; ++i) { - - status = fl_string_dynamic_partial_compare_string(dynamic_name[i], data_make->buffer, dynamic_length[i], range_name); - - if (status == F_equal_to) { - unmatched = F_false; - - status = f_string_dynamic_append(dynamic_value[i], &value); - break; - } - } // for - } - - if (unmatched) { - const f_string_t dynamics_name[] = { - fake_build_setting_name_build_libraries_s, - fake_build_setting_name_build_libraries_shared_s, - fake_build_setting_name_build_libraries_static_s, - fake_build_setting_name_build_sources_headers_s, - fake_build_setting_name_build_sources_headers_shared_s, - fake_build_setting_name_build_sources_headers_static_s, - fake_build_setting_name_build_sources_library_s, - fake_build_setting_name_build_sources_library_shared_s, - fake_build_setting_name_build_sources_library_static_s, - fake_build_setting_name_build_sources_program_s, - fake_build_setting_name_build_sources_program_shared_s, - fake_build_setting_name_build_sources_program_static_s, - fake_build_setting_name_build_sources_settings_s, - fake_build_setting_name_build_sources_script_s, - fake_build_setting_name_defines_s, - fake_build_setting_name_defines_library_s, - fake_build_setting_name_defines_library_shared_s, - fake_build_setting_name_defines_library_static_s, - fake_build_setting_name_defines_program_s, - fake_build_setting_name_defines_program_shared_s, - fake_build_setting_name_defines_program_static_s, - fake_build_setting_name_defines_shared_s, - fake_build_setting_name_defines_static_s, - fake_build_setting_name_environment_s, - fake_build_setting_name_flags_s, - fake_build_setting_name_flags_library_s, - fake_build_setting_name_flags_library_shared_s, - fake_build_setting_name_flags_library_static_s, - fake_build_setting_name_flags_program_s, - fake_build_setting_name_flags_program_shared_s, - fake_build_setting_name_flags_program_static_s, - fake_build_setting_name_flags_shared_s, - fake_build_setting_name_flags_static_s, - fake_build_setting_name_modes_s, - fake_build_setting_name_modes_default_s, - }; - - const f_array_length_t dynamics_length[] = { - fake_build_setting_name_build_libraries_s_length, - fake_build_setting_name_build_libraries_shared_s_length, - fake_build_setting_name_build_libraries_static_s_length, - fake_build_setting_name_build_sources_headers_s_length, - fake_build_setting_name_build_sources_headers_shared_s_length, - fake_build_setting_name_build_sources_headers_static_s_length, - fake_build_setting_name_build_sources_library_s_length, - fake_build_setting_name_build_sources_library_shared_s_length, - fake_build_setting_name_build_sources_library_static_s_length, - fake_build_setting_name_build_sources_program_s_length, - fake_build_setting_name_build_sources_program_shared_s_length, - fake_build_setting_name_build_sources_program_static_s_length, - fake_build_setting_name_build_sources_settings_s_length, - fake_build_setting_name_build_sources_script_s_length, - fake_build_setting_name_defines_s_length, - fake_build_setting_name_defines_library_s_length, - fake_build_setting_name_defines_library_shared_s_length, - fake_build_setting_name_defines_library_static_s_length, - fake_build_setting_name_defines_program_s_length, - fake_build_setting_name_defines_program_shared_s_length, - fake_build_setting_name_defines_program_static_s_length, - fake_build_setting_name_defines_shared_s_length, - fake_build_setting_name_defines_static_s_length, - fake_build_setting_name_environment_length_s, - fake_build_setting_name_flags_s_length, - fake_build_setting_name_flags_library_s_length, - fake_build_setting_name_flags_library_shared_s_length, - fake_build_setting_name_flags_library_static_s_length, - fake_build_setting_name_flags_program_s_length, - fake_build_setting_name_flags_program_shared_s_length, - fake_build_setting_name_flags_program_static_s_length, - fake_build_setting_name_flags_shared_s_length, - fake_build_setting_name_flags_static_s_length, - fake_build_setting_name_modes_s_length, - fake_build_setting_name_modes_default_s_length, - }; - - const f_string_dynamics_t dynamics_value[] = { - data_make->setting_build.build_libraries, - data_make->setting_build.build_libraries_shared, - data_make->setting_build.build_libraries_static, - data_make->setting_build.build_sources_headers, - data_make->setting_build.build_sources_headers_shared, - data_make->setting_build.build_sources_headers_static, - data_make->setting_build.build_sources_library, - data_make->setting_build.build_sources_library_shared, - data_make->setting_build.build_sources_library_static, - data_make->setting_build.build_sources_program, - data_make->setting_build.build_sources_program_shared, - data_make->setting_build.build_sources_program_static, - data_make->setting_build.build_sources_setting, - data_make->setting_build.build_sources_script, - data_make->setting_build.defines, - data_make->setting_build.defines_library, - data_make->setting_build.defines_library_shared, - data_make->setting_build.defines_library_static, - data_make->setting_build.defines_program, - data_make->setting_build.defines_program_shared, - data_make->setting_build.defines_program_static, - data_make->setting_build.defines_shared, - data_make->setting_build.defines_static, - data_make->setting_build.environment, - data_make->setting_build.flags, - data_make->setting_build.flags_library, - data_make->setting_build.flags_library_shared, - data_make->setting_build.flags_library_static, - data_make->setting_build.flags_program, - data_make->setting_build.flags_program_shared, - data_make->setting_build.flags_program_static, - data_make->setting_build.flags_shared, - data_make->setting_build.flags_static, - data_make->setting_build.modes, - data_make->setting_build.modes_default, - }; - - for (uint8_t i = 0; i < 35; ++i) { - - status = fl_string_dynamic_partial_compare_string(dynamics_name[i], data_make->buffer, dynamics_length[i], range_name); - - if (status == F_equal_to) { - unmatched = F_false; - - for (f_array_length_t j = 0; j < dynamics_value[i].used; ++j) { - - status = f_string_dynamic_mash(f_string_space_s, 1, dynamics_value[i].array[j], &value); - - if (F_status_is_error(status)) { - break; - } - } // for - - break; - } - } // for - } - - if (F_status_is_error(status)) { - macro_f_string_dynamic_t_delete_simple(value); - - return status; - } - - if (unmatched) { - macro_f_string_dynamic_t_delete_simple(value); - - return F_false; - } - - if (quoted) { - status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); - } - else { - status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); - - if (F_status_is_error_not(status)) { - ++arguments->used; - } - } - } - } - - macro_f_string_dynamic_t_delete_simple(value); - - if (F_status_is_error_not(status)) { - return F_true; - } - - return status; - } -#endif // _di_fake_make_operate_expand_build_ - -#ifndef _di_fake_make_operate_expand_environment_ - f_status_t fake_make_operate_expand_environment(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) { - - f_status_t status = F_none; - f_string_dynamic_t value = f_string_dynamic_t_initialize; - - bool unmatched = F_false; - - { - f_string_dynamic_t name = f_string_dynamic_t_initialize; - - status = f_string_dynamic_partial_append_nulless(data_make->buffer, range_name, &name); - if (F_status_is_error(status)) return status; - - status = f_environment_get(name.string, &value); - - macro_f_string_dynamic_t_delete_simple(name); - } - - if (F_status_is_error(status)) { - macro_f_string_dynamic_t_delete_simple(value); - - return status; - } - else if (status == F_exist_not) { - macro_f_string_dynamic_t_delete_simple(value); - - return F_false; - } - - if (quoted) { - status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); - } - else { - status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, arguments); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_append_nulless(value, &arguments->array[arguments->used]); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate_after(&arguments->array[arguments->used]); - - if (F_status_is_error_not(status)) { - ++arguments->used; - } - } - } - } - - macro_f_string_dynamic_t_delete_simple(value); - - if (F_status_is_error_not(status)) { - return F_true; - } - - return status; - } -#endif // _di_fake_make_operate_expand_environment_ - -#ifndef _di_fake_make_operate_section_ - int fake_make_operate_section(fake_main_t * const main, const f_array_length_t id_section, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { - - if (F_status_is_error(*status) || *status == F_child) return main->child; - - if (id_section > data_make->fakefile.used) { - *status = F_status_set_error(F_parameter); - - fll_error_print(data_make->error, F_parameter, "fake_make_operate_section", F_true); - return 0; - } - - // Add the operation id to the operation stack. - if (section_stack->used + 1 > section_stack->size) { - macro_f_array_lengths_t_increase_by((*status), (*section_stack), F_memory_default_allocation_small_d); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "macro_f_array_lengths_t_increase_by", F_true); - return 0; - } - } - - section_stack->array[section_stack->used++] = id_section; - - const f_fss_named_t *section = &data_make->fakefile.array[id_section]; - - if (main->output.verbosity != f_console_verbosity_quiet) { - flockfile(main->output.to.stream); - - fl_print_format("%c%[Processing Section '%]", main->output.to.stream, f_string_eol_s[0], main->context.set.important, main->context.set.important); - fl_print_format("%[%/Q%]", main->output.to.stream, main->context.set.notable, data_make->buffer, section->name, main->context.set.notable); - fl_print_format("%['.%]%c", main->output.to.stream, main->context.set.important, main->context.set.important, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - - if (!section->objects.used) { - --section_stack->used; - - return 0; - } - - const f_string_t operations_name[] = { - fake_make_operation_break_s, - fake_make_operation_build_s, - fake_make_operation_clean_s, - fake_make_operation_clone_s, - fake_make_operation_compile_s, - fake_make_operation_copy_s, - fake_make_operation_define_s, - fake_make_operation_delete_s, - fake_make_operation_deletes_s, - fake_make_operation_else_s, - fake_make_operation_exit_s, - fake_make_operation_fail_s, - fake_make_operation_group_s, - fake_make_operation_groups_s, - fake_make_operation_if_s, - fake_make_operation_index_s, - fake_make_operation_link_s, - fake_make_operation_mode_s, - fake_make_operation_modes_s, - fake_make_operation_move_s, - fake_make_operation_operate_s, - fake_make_operation_owner_s, - fake_make_operation_owners_s, - fake_make_operation_pop_s, - fake_make_operation_print_s, - fake_make_operation_run_s, - fake_make_operation_shell_s, - fake_make_operation_skeleton_s, - fake_make_operation_to_s, - fake_make_operation_top_s, - fake_make_operation_touch_s, - }; - - const f_array_length_t operations_length[] = { - fake_make_operation_break_s_length, - fake_make_operation_build_s_length, - fake_make_operation_clean_s_length, - fake_make_operation_clone_s_length, - fake_make_operation_compile_s_length, - fake_make_operation_copy_s_length, - fake_make_operation_define_s_length, - fake_make_operation_delete_s_length, - fake_make_operation_deletes_s_length, - fake_make_operation_else_s_length, - fake_make_operation_exit_s_length, - fake_make_operation_fail_s_length, - fake_make_operation_group_s_length, - fake_make_operation_groups_s_length, - fake_make_operation_if_s_length, - fake_make_operation_index_s_length, - fake_make_operation_link_s_length, - fake_make_operation_mode_s_length, - fake_make_operation_modes_s_length, - fake_make_operation_move_s_length, - fake_make_operation_operate_s_length, - fake_make_operation_owner_s_length, - fake_make_operation_owners_s_length, - fake_make_operation_pop_s_length, - fake_make_operation_print_s_length, - fake_make_operation_run_s_length, - fake_make_operation_shell_s_length, - fake_make_operation_skeleton_s_length, - fake_make_operation_to_s_length, - fake_make_operation_top_s_length, - fake_make_operation_touch_s_length, - }; - - const uint8_t operations_type[] = { - fake_make_operation_type_break, - fake_make_operation_type_build, - fake_make_operation_type_clean, - fake_make_operation_type_clone, - fake_make_operation_type_compile, - fake_make_operation_type_copy, - fake_make_operation_type_define, - fake_make_operation_type_delete, - fake_make_operation_type_deletes, - fake_make_operation_type_else, - fake_make_operation_type_exit, - fake_make_operation_type_fail, - fake_make_operation_type_group, - fake_make_operation_type_groups, - fake_make_operation_type_if, - fake_make_operation_type_index, - fake_make_operation_type_link, - fake_make_operation_type_mode, - fake_make_operation_type_modes, - fake_make_operation_type_move, - fake_make_operation_type_operate, - fake_make_operation_type_owner, - fake_make_operation_type_owners, - fake_make_operation_type_pop, - fake_make_operation_type_print, - fake_make_operation_type_run, - fake_make_operation_type_shell, - fake_make_operation_type_skeleton, - fake_make_operation_type_to, - fake_make_operation_type_top, - fake_make_operation_type_touch, - }; - - uint8_t operation = 0; - uint8_t operations[section->objects.used]; - uint8_t operation_if = 0; - - bool success = F_true; - - f_string_dynamics_t arguments[section->objects.used]; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - memset(operations, 0, section->objects.used); - memset(arguments, 0, sizeof(f_string_dynamics_t) * section->objects.used); - - for (i = 0; i < section->objects.used; ++i, *status = F_none) { - - operation = 0; - - if (!(i % fake_signal_check_short_d) && fake_signal_received(main)) { - *status = F_status_set_error(F_interrupt); - - break; - } - - for (j = 0; j < fake_make_operation_total_d; ++j) { - - if (fl_string_dynamic_partial_compare_string(operations_name[j], data_make->buffer, operations_length[j], section->objects.array[i]) == F_equal_to) { - operation = operations_type[j]; - - break; - } - } // for - - if (!operation) { - fake_print_message_section_operation_unknown(main, data_make->error, data_make->buffer, section->name, section->objects.array[i]); - - *status = F_status_set_error(F_valid_not); - } - else if (operation == fake_make_operation_type_operate) { - if (section_stack->used == fake_make_section_stack_max_d) { - fake_print_message_section_operation_stack_max(main, data_make->error, data_make->buffer, section->name, section->objects.array[i], fake_make_section_stack_max_d); - - *status = F_status_set_error(F_recurse); - } - } - - if (F_status_is_error_not(*status)) { - operations[i] = operation; - - fake_make_operate_expand(main, section->name, operation, section->contents.array[i], section->quotess.array[i], data_make, &arguments[i], status); - } - - if (operation_if == fake_make_operation_if_type_true_next) { - operation_if = fake_make_operation_if_type_true; - } - else if (operation_if == fake_make_operation_if_type_false_next) { - operation_if = fake_make_operation_if_type_false; - } - else if (operation_if == fake_make_operation_if_type_false_always_next) { - operation_if = fake_make_operation_if_type_false_always; - } - - fake_make_operate_validate(main, section->name, operation, arguments[i], &operation_if, data_make, section_stack, status); - - if (F_status_is_error_not(*status)) { - if (operation_if == fake_make_operation_if_type_false) { - operation_if = fake_make_operation_if_type_else_true_next; - continue; - } - else if (operation_if == fake_make_operation_if_type_false_always) { - operation_if = fake_make_operation_if_type_else_false_next_always; - continue; - } - else if (operation_if == fake_make_operation_if_type_else_false) { - operation_if = 0; - continue; - } - - const int result = fake_make_operate_process(main, section->name, operation, arguments[i], success, &operation_if, data_make, section_stack, status); - - if (*status == F_child) { - return result; - } - } - else { - if (operation == fake_make_operation_type_if) { - switch (operation_if) { - case fake_make_operation_if_type_if_defined: - case fake_make_operation_if_type_if_equal: - case fake_make_operation_if_type_if_equal_not: - case fake_make_operation_if_type_if_exists: - case fake_make_operation_if_type_if_failure: - case fake_make_operation_if_type_if_greater: - case fake_make_operation_if_type_if_greater_equal: - case fake_make_operation_if_type_if_group: - case fake_make_operation_if_type_if_is: - case fake_make_operation_if_type_if_less: - case fake_make_operation_if_type_if_less_equal: - case fake_make_operation_if_type_if_mode: - case fake_make_operation_if_type_if_owner: - case fake_make_operation_if_type_if_success: - operation_if = 0; - break; - } - } - - if (operation_if == fake_make_operation_if_type_false) { - operation_if = fake_make_operation_if_type_else_true_next; - } - else if (operation_if == fake_make_operation_if_type_false_always) { - operation_if = fake_make_operation_if_type_else_false_next_always; - } - else if (operation_if == fake_make_operation_if_type_else_false) { - operation_if = 0; - } - } - - if (F_status_set_fine(*status) == F_interrupt) { - break; - } - - if (operation_if == fake_make_operation_if_type_else_true || operation_if == fake_make_operation_if_type_else_false) { - - // No else condition provided, so clear the operation_if state. - if (operation != fake_make_operation_type_else) { - operation_if = 0; - } - } - else if (operation_if == fake_make_operation_if_type_true) { - operation_if = fake_make_operation_if_type_else_false_next; - } - else if (operation_if == fake_make_operation_if_type_false_always) { - operation_if = fake_make_operation_if_type_else_false_next_always; - } - - if (F_status_is_error(*status)) { - success = F_false; - - // Break acts identical to fail when at the top of the stack. - if (F_status_set_fine(*status) == F_signal_abort && !section_stack->used) { - data_make->setting_make.fail = fake_make_operation_fail_type_exit; - data_make->error.prefix = fl_print_error_s; - data_make->error.suffix = 0; - data_make->error.context = main->context.set.error; - data_make->error.notable = main->context.set.notable; - data_make->error.to.stream = F_type_error_d; - data_make->error.to.id = F_type_descriptor_error_d; - data_make->error.set = &main->context.set; - } - - fake_print_message_section_operation_failed(main, data_make->error, data_make->buffer, section->name, section->objects.array[i]); - - // F_signal_abort is used by the break section operation. - if (F_status_set_fine(*status) == F_signal_abort) { - break; - } - - // F_signal_abort is used by the exit section operation. - if (F_status_set_fine(*status) == F_signal_quit) { - if (!section_stack->used) { - *status = F_status_set_error(F_failure); - } - - break; - } - - if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { - operation_if = 0; - break; - } - } - else if (*status == F_signal_abort) { - success = F_true; - - // F_signal_abort is used by the break section operation. - break; - } - else if (*status == F_signal_quit) { - success = F_true; - - // F_signal_abort is used by the exit section operation. - if (!section_stack->used) { - *status = F_none; - } - - break; - } - else { - success = F_true; - } - } // for - - if (F_status_set_error(*status) == F_interrupt) { - for (i = 0; i < section->objects.used; ++i) { - macro_f_string_dynamics_t_delete_simple(arguments[i]); - } // for - - return 0; - } - - if (i == section->objects.used && (operation_if == fake_make_operation_if_type_true_next || operation_if == fake_make_operation_if_type_false_next || operation_if == fake_make_operation_if_type_else_true || operation_if == fake_make_operation_if_type_else_false)) { - - if (main->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SIncomplete '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, operation_if == fake_make_operation_if_type_true_next || operation_if == fake_make_operation_if_type_false_next ? fake_make_operation_if_s : fake_make_operation_else_s, data_make->error.notable); - fl_print_format("%[' at end of section.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - fake_print_message_section_operation_failed(main, data_make->error, data_make->buffer, section->name, section->objects.array[section->objects.used - 1]); - - *status = F_status_set_error(F_failure); - } - - // Ensure an error is returned during recursion if the last known section operation failed, except for the main operation. - if (success == F_false && F_status_is_error_not(*status) && section_stack->used > 1) { - *status = F_status_set_error(F_failure); - } - - for (i = 0; i < section->objects.used; ++i) { - macro_f_string_dynamics_t_delete_simple(arguments[i]); - } // for - - --section_stack->used; - - return 0; - } -#endif // _di_fake_make_operate_section_ - -#ifndef _di_fake_make_operate_process_ - int fake_make_operate_process(fake_main_t * const main, const f_string_range_t section_name, const uint8_t operation, const f_string_dynamics_t arguments, const bool success, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { - - if (*status == F_child) return main->child; - - if (operation == fake_make_operation_type_index) { - const f_status_t result = fake_execute(main, data_make->environment, data_make->setting_build.build_indexer, arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_execute", F_true); - } - - if (*status == F_child) { - return result; - } - - fake_make_operate_process_return(main, result, data_make, status); - - return 0; - } - - if (operation == fake_make_operation_type_break) { - - if (!arguments.used || fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to) { - *status = F_signal_abort; - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to) { - *status = F_status_set_error(F_signal_abort); - } - else { - return 0; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("%cBreaking as '", main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%S%]", main->output.to.stream, main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, main->context.set.notable); - fl_print_format("'.%c", main->output.to.stream, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - - return 0; - } - - if (operation == fake_make_operation_type_build) { - f_string_static_t stub = f_string_static_t_initialize; - - *status = fake_build_operate(arguments.used ? arguments.array[0] : stub, main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - if (F_status_is_error(*status)) { - fake_make_operate_process_return(main, 1, data_make, status); - } - else { - fake_make_operate_process_return(main, 0, data_make, status); - } - - return 0; - } - - if (operation == fake_make_operation_type_clean) { - *status = fake_clean_operate(main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - if (F_status_is_error(*status)) { - fake_make_operate_process_return(main, 1, data_make, status); - } - else { - fake_make_operate_process_return(main, 0, data_make, status); - } - - return 0; - } - - if (operation == fake_make_operation_type_clone) { - const f_array_length_t total = arguments.used - 1; - f_status_t status_file = F_none; - - fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; - - f_array_length_t destination_length = 0; - - if (main->error.verbosity == f_console_verbosity_verbose) { - recurse.output = main->output.to; - recurse.verbose = fake_verbose_print_clone; - } - - bool existing = F_true; - - // in this case, the destination could be a file, so confirm this. - if (arguments.used == 2) { - status_file = f_directory_is(arguments.array[1].string); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); - - *status = F_status_set_error(F_failure); - return 0; - } - - if (status_file == F_false || status_file == F_file_found_not) { - existing = F_false; - } - } - - for (f_array_length_t i = 0; i < total; ++i) { - - destination_length = arguments.array[total].used; - - if (existing) { - destination_length += arguments.array[i].used + 1; - } - - char destination[destination_length + 1]; - - memcpy(destination, arguments.array[total].string, arguments.array[total].used); - - if (existing) { - memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); - destination[arguments.array[total].used] = f_path_separator_s[0]; - } - - destination[destination_length] = 0; - - status_file = f_directory_is(arguments.array[i].string); - - if (status_file == F_true) { - status_file = fl_directory_clone(arguments.array[i].string, destination, arguments.array[i].used, destination_length, F_true, recurse); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "fl_directory_clone", F_true, arguments.array[i].string, "clone", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } - else if (status_file == F_false) { - status_file = f_file_clone(arguments.array[i].string, destination, F_true, recurse.size_block, recurse.exclusive); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_clone", F_true, arguments.array[i].string, "clone", fll_error_file_type_file); - *status = F_status_set_error(F_failure); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("%cCloned '%[%Q%]' to '", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable); - fl_print_format("%[%S%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, destination, main->context.set.notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[i].string, "identify", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - break; - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_compile) { - const int result = fake_execute(main, data_make->environment, data_make->setting_build.build_compiler, arguments, status); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_execute", F_true); - } - - if (*status == F_child) { - return result; - } - - fake_make_operate_process_return(main, result, data_make, status); - - return 0; - } - - if (operation == fake_make_operation_type_copy) { - const f_array_length_t total = arguments.used -1; - f_status_t status_file = F_none; - - fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; - - f_array_length_t destination_length = 0; - - f_mode_t mode = f_mode_t_initialize; - - macro_f_mode_t_set_default_umask(mode, main->umask); - - if (main->error.verbosity == f_console_verbosity_verbose) { - recurse.output = main->output.to; - recurse.verbose = fake_verbose_print_copy; - } - - bool existing = F_true; - - // in this case, the destination could be a file, so confirm this. - if (arguments.used == 2) { - status_file = f_directory_is(arguments.array[1].string); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); - - *status = F_status_set_error(F_failure); - return 0; - } - - if (status_file == F_false || status_file == F_file_found_not) { - existing = F_false; - } - } - - for (f_array_length_t i = 0; i < total; ++i) { - - destination_length = arguments.array[total].used; - - if (existing) { - destination_length += arguments.array[i].used + 1; - } - - char destination[destination_length + 1]; - - memcpy(destination, arguments.array[total].string, arguments.array[total].used); - - if (existing) { - memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); - destination[arguments.array[total].used] = f_path_separator_s[0]; - } - - destination[destination_length] = 0; - - status_file = f_directory_is(arguments.array[i].string); - - if (status_file == F_true) { - status_file = fl_directory_copy(arguments.array[i].string, destination, arguments.array[i].used, destination_length, mode, recurse); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "fl_directory_copy", F_true, arguments.array[i].string, "copy", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } - else if (status_file == F_false) { - status_file = f_file_copy(arguments.array[i].string, destination, mode, recurse.size_block, recurse.exclusive); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_copy", F_true, arguments.array[i].string, "copy", fll_error_file_type_file); - *status = F_status_set_error(F_failure); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("%cCopied '%[%Q%]", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable); - fl_print_format("' to '%[%S%]'.%c", main->output.to.stream, main->context.set.notable, destination, main->context.set.notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[i].string, "identify", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - break; - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_define) { - - if (arguments.used > 1) { - *status = f_environment_set(arguments.array[0].string, arguments.array[1].string, F_true); - } - else { - *status = f_environment_set(arguments.array[0].string, f_string_empty_s, F_true); - } - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_environment_set", F_true); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cDefined environment variable '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[0], main->context.set.notable, f_string_eol_s[0]); - } - - return 0; - } - - if (operation == fake_make_operation_type_delete || operation == fake_make_operation_type_deletes) { - const int recursion_max = operation == fake_make_operation_type_delete ? 0 : F_directory_descriptors_max_d; - struct stat file_stat; - - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - memset(&file_stat, 0, sizeof(struct stat)); - - *status = f_file_stat(arguments.array[i].string, F_false, &file_stat); - - if (F_status_is_error(*status)) { - if (F_status_set_fine(*status) == F_file_found_not) { - if (main->warning.verbosity == f_console_verbosity_verbose) { - flockfile(main->warning.to.stream); - - fl_print_format("%c%[%SThe file '%]", main->warning.to.stream, main->warning.prefix, f_string_eol_s[0]); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, arguments.array[i], main->warning.notable); - fl_print_format("%[' was not found.%]%c", main->warning.to.stream, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } - - *status = F_none; - } - else { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_stat", F_true, arguments.array[i].string, "delete", fll_error_file_type_file); - return 0; - } - } - else if (macro_f_file_type_is_directory(file_stat.st_mode)) { - if (main->error.verbosity == f_console_verbosity_verbose) { - *status = f_directory_remove_custom(arguments.array[i].string, recursion_max, F_false, fake_clean_remove_recursively_verbosely); - } - else { - *status = f_directory_remove(arguments.array[i].string, recursion_max, F_false); - } - - if (F_status_set_fine(*status) == F_file_found_not) { - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cThe directory '%[%Q%]' does not exist.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); - } - - *status = F_none; - } - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_remove", F_true, arguments.array[i].string, "delete", fll_error_file_type_directory); - return 0; - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cRemoved '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); - } - } - else { - *status = f_file_remove(arguments.array[i].string); - - if (F_status_set_fine(*status) == F_file_found_not) { - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cThe file '%[%Q%]' does not exist.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); - } - - *status = F_none; - } - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_remove", F_true, arguments.array[i].string, "delete", fll_error_file_type_file); - return 0; - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cRemoved '%[%Q%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); - } - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_else) { - - if (*operation_if == fake_make_operation_if_type_else_false_next || *operation_if == fake_make_operation_if_type_else_false_next_always) { - *operation_if = fake_make_operation_if_type_else_false; - } - else if (*operation_if != fake_make_operation_if_type_else_true_next) { - *operation_if = fake_make_operation_if_type_else_true; - } - - return 0; - } - - if (operation == fake_make_operation_type_exit) { - - if (!arguments.used || fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to) { - *status = F_signal_quit; - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to) { - *status = F_status_set_error(F_signal_quit); - - // forcing exit forces fail mode. - data_make->setting_make.fail = fake_make_operation_fail_type_exit; - data_make->error.prefix = fl_print_error_s; - data_make->error.suffix = 0; - data_make->error.context = main->context.set.error; - data_make->error.notable = main->context.set.notable; - data_make->error.to.stream = F_type_error_d; - data_make->error.to.id = F_type_descriptor_error_d; - data_make->error.set = &main->context.set; - } - else { - return 0; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cExiting as '%[%S%]'.%c", main->output.to.stream, f_string_eol_s[0], main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, main->context.set.notable, f_string_eol_s[0]); - } - - return 0; - } - - if (operation == fake_make_operation_type_fail) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_exit_s, arguments.array[0], fake_make_operation_argument_exit_s_length) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_exit; - data_make->error.prefix = fl_print_error_s; - data_make->error.suffix = 0; - data_make->error.context = main->context.set.error; - data_make->error.notable = main->context.set.notable; - data_make->error.to.stream = F_type_error_d; - data_make->error.to.id = F_type_descriptor_error_d; - data_make->error.set = &main->context.set; - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn_s, arguments.array[0], fake_make_operation_argument_warn_s_length) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_warn; - data_make->error.prefix = fl_print_warning_s; - data_make->error.suffix = 0; - data_make->error.context = main->context.set.warning; - data_make->error.notable = main->context.set.notable; - data_make->error.to.stream = F_type_warning_d; - data_make->error.to.id = F_type_descriptor_warning_d; - data_make->error.set = &main->context.set; - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore_s, arguments.array[0], fake_make_operation_argument_ignore_s_length) == F_equal_to) { - data_make->setting_make.fail = fake_make_operation_fail_type_ignore; - data_make->error.to.stream = 0; - data_make->error.to.id = -1; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - f_print_terminated("Set failure state to '", main->output.to.stream); - - if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { - fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_exit_s, main->context.set.notable); - } - else if (data_make->setting_make.fail == fake_make_operation_fail_type_warn) { - fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_warn_s, main->context.set.notable); - } - else if (data_make->setting_make.fail == fake_make_operation_fail_type_ignore) { - fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, fake_make_operation_argument_ignore_s, main->context.set.notable); - } - - fl_print_format("'.%c", main->output.to.stream, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - - return 0; - } - - if (operation == fake_make_operation_type_group) { - gid_t id = 0; - - *status = fake_make_get_id_group(main, data_make->error, arguments.array[0], &id); - if (F_status_is_error(*status)) return 0; - - f_status_t status_file = F_none; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - continue; - } - - status_file = f_file_role_change(arguments.array[i].string, -1, id, F_false); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_role_change", F_true, arguments.array[i].string, "change group of", fll_error_file_type_file); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("Changed group of '%[%s%]", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable); - fl_print_format("' to %[%ul%].%c", main->output.to.stream, main->context.set.notable, id, main->context.set.notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_groups) { - gid_t id = 0; - - *status = fake_make_get_id_group(main, data_make->error, arguments.array[0], &id); - if (F_status_is_error(*status)) return 0; - - f_status_t status_file = F_none; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - continue; - } - - status_file = fll_file_role_change_all(arguments.array[i].string, -1, id, F_false, fake_make_operation_recursion_depth_max_d); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_role_change_all", F_true, arguments.array[i].string, "change group of", fll_error_file_type_file); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("Changed group of '%[%s%]", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable); - fl_print_format("' to %[%ul%].%c", main->output.to.stream, main->context.set.notable, id, main->context.set.notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_if) { - if (*operation_if == fake_make_operation_if_type_if_success) { - if (success) { - *operation_if = fake_make_operation_if_type_true_next; - } - else { - *operation_if = fake_make_operation_if_type_false_next; - } - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_failure) { - if (success) { - *operation_if = fake_make_operation_if_type_false_next; - } - else { - *operation_if = fake_make_operation_if_type_true_next; - } - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_group) { - uid_t id = 0; - - *status = fake_make_get_id_group(main, data_make->error, arguments.array[1], &id); - if (F_status_is_error(*status)) return 0; - - uid_t id_file = 0; - - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 2; i < arguments.used; ++i, id_file = 0) { - - *status = f_file_group_read(arguments.array[i].string, &id_file); - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_group_read", F_true, arguments.array[i].string, "get group of", fll_error_file_type_file); - break; - } - - if (id != id_file) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_mode) { - bool is = F_false; - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_is_s, arguments.array[1], fake_make_operation_argument_is_s_length) == F_equal_to) { - is = F_true; - } - - f_file_mode_t mode_rule = 0; - mode_t mode_match = 0; - - { - uint8_t mode_replace = 0; - - *status = fake_make_get_id_mode(main, data_make->error, arguments.array[2], &mode_rule, &mode_replace); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - return 0; - } - - *status = f_file_mode_to_mode(mode_rule, &mode_match); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_print(data_make->error, F_status_set_fine(*status), "f_file_mode_to_mode", F_true); - return 0; - } - } - - mode_t mode_file = 0; - - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 3; i < arguments.used; ++i, mode_file = 0) { - - *status = f_file_mode_read(arguments.array[i].string, &mode_file); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "get mode of", fll_error_file_type_file); - break; - } - - if (is) { - if (mode_match != (mode_file & F_file_mode_all_d)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else { - if (!(mode_match & mode_file)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_owner) { - uid_t id = 0; - - *status = fake_make_get_id_owner(main, data_make->error, arguments.array[1], &id); - if (F_status_is_error(*status)) return 0; - - uid_t id_file = 0; - - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 2; i < arguments.used; ++i, id_file = 0) { - - *status = f_file_owner_read(arguments.array[i].string, &id_file); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_owner_read", F_true, arguments.array[i].string, "get owner of", fll_error_file_type_file); - break; - } - - if (id != id_file) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_is) { - - // block = 0x1 (0000 0001) link = 0x10 (0001 0000) - // character = 0x2 (0000 0010) regular = 0x20 (0010 0000) - // directory = 0x4 (0000 0100) socket = 0x40 (0100 0000) - // fifo = 0x8 (0000 1000) invalid = 0x80 (1000 0000) - uint8_t type = 0; - - f_array_length_t i = 1; - - *status = F_none; - - for (; i < arguments.used; ++i) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_if_is_for_s, arguments.array[i], fake_make_operation_argument_if_is_for_s_length) == F_equal_to) { - ++i; - break; - } - - if (fl_string_dynamic_compare_string(F_file_type_name_block_s, arguments.array[i], F_file_type_name_block_s_length) == F_equal_to) { - type |= 0x1; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_character_s, arguments.array[i], F_file_type_name_character_s_length) == F_equal_to) { - type |= 0x2; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_directory_s, arguments.array[i], F_file_type_name_directory_s_length) == F_equal_to) { - type |= 0x4; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_fifo_s, arguments.array[i], F_file_type_name_fifo_s_length) == F_equal_to) { - type |= 0x8; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_link_s, arguments.array[i], F_file_type_name_link_s_length) == F_equal_to) { - type |= 0x10; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_regular_s, arguments.array[i], F_file_type_name_regular_s_length) == F_equal_to) { - type |= 0x20; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_socket_s, arguments.array[i], F_file_type_name_socket_s_length) == F_equal_to) { - type |= 0x40; - } - } // for - - uint8_t type_file = 0; - mode_t mode_file = 0; - - *operation_if = fake_make_operation_if_type_true_next; - - for (; i < arguments.used; ++i, mode_file = 0) { - - *status = f_file_mode_read(arguments.array[i].string, &mode_file); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "get mode of", fll_error_file_type_file); - break; - } - - if (macro_f_file_type_is_block(mode_file)) { - type_file = 0x1; - } - else if (macro_f_file_type_is_character(mode_file)) { - type_file = 0x2; - } - else if (macro_f_file_type_is_directory(mode_file)) { - type_file = 0x4; - } - else if (macro_f_file_type_is_fifo(mode_file)) { - type_file = 0x8; - } - else if (macro_f_file_type_is_link(mode_file)) { - type_file = 0x10; - } - else if (macro_f_file_type_is_regular(mode_file)) { - type_file = 0x20; - } - else if (macro_f_file_type_is_socket(mode_file)) { - type_file = 0x40; - } - - if (!(type & type_file)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_exists) { - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - *status = f_file_exists(arguments.array[i].string); - - if (F_status_is_error(*status)) { - *operation_if = fake_make_operation_if_type_false_always_next; - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_exists", F_true, arguments.array[i].string, "find", fll_error_file_type_file); - break; - } - - if (*status == F_false) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_defined) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to) { - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 2; i < arguments.used; ++i) { - - if (f_environment_exists(arguments.array[i].string) != F_true) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to) { - if (!data_make->setting_make.parameter.used) { - *operation_if = fake_make_operation_if_type_false_next; - return 0; - } - - f_array_length_t i = 2; - f_array_length_t j = 0; - bool missed = F_true; - - *operation_if = fake_make_operation_if_type_true_next; - - for (; i < arguments.used; ++i, missed = F_true) { - - for (j = 0; j < data_make->setting_make.parameter.used; ++j) { - - if (fl_string_dynamic_compare(arguments.array[i], data_make->setting_make.parameter.array[j].name) == F_equal_to) { - missed = F_false; - break; - } - } // for - - if (missed) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - } - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_equal) { - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 2; i < arguments.used; ++i) { - - if (fl_string_dynamic_compare(arguments.array[1], arguments.array[i]) == F_equal_to_not) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_equal_not) { - *operation_if = fake_make_operation_if_type_true_next; - - f_array_length_t i = 1; - f_array_length_t j = 0; - - for (; i < arguments.used; ++i) { - - for (j = i + 1; j < arguments.used; ++j) { - - if (fl_string_dynamic_compare(arguments.array[i], arguments.array[j]) == F_equal_to) { - *operation_if = fake_make_operation_if_type_false_next; - i = arguments.used; - break; - } - } // for - } // for - - return 0; - } - - if (*operation_if == fake_make_operation_if_type_if_greater || *operation_if == fake_make_operation_if_type_if_greater_equal || *operation_if == fake_make_operation_if_type_if_less || *operation_if == fake_make_operation_if_type_if_less_equal) { - - f_status_t status_number = F_none; - f_string_range_t range = f_string_range_t_initialize; - - f_number_unsigned_t number_left = 0; - f_number_unsigned_t number_right = 0; - - bool is_negative_left = F_false; - bool is_negative_right = F_false; - - f_array_length_t i = 1; - - const uint8_t type_if = *operation_if; - - *operation_if = fake_make_operation_if_type_true_next; - - // @fixme there needs to handle converting numbers with decimals (like 1.01), perhaps operate on them as strings or provide a special processor. - range.start = 0; - range.stop = arguments.array[i].used - 1; - - if (arguments.array[i].string[0] == '+') { - range.start = 1; - } - else if (arguments.array[i].string[0] == '-') { - range.start = 1; - is_negative_left = F_true; - } - - if (range.start > range.stop) { - status_number = F_status_set_error(F_failure); - } - else { - status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number_left); - } - - if (F_status_is_error_not(status_number)) { - for (i = 2; i < arguments.used; ++i, status_number = F_none, number_left = number_right, is_negative_left = is_negative_right) { - - if (arguments.array[i].used) { - range.start = 0; - range.stop = arguments.array[i].used - 1; - - is_negative_right = F_false; - - if (arguments.array[i].string[0] == '+') { - range.start = 1; - } - else if (arguments.array[i].string[0] == '-') { - range.start = 1; - is_negative_right = F_true; - } - - if (range.start > range.stop) { - status_number = F_status_set_error(F_failure); - } - else { - status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number_right); - } - } - else { - status_number = F_status_set_error(F_failure); - } - - if (F_status_is_error(status_number)) { - break; - } - - if (type_if == fake_make_operation_if_type_if_greater) { - - if (is_negative_left == is_negative_right) { - if (!(number_left > number_right)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (!is_negative_left && is_negative_right) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (type_if == fake_make_operation_if_type_if_greater_equal) { - - if (is_negative_left == is_negative_right) { - if (!(number_left >= number_right)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (!is_negative_left && is_negative_right) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (type_if == fake_make_operation_if_type_if_less) { - - if (is_negative_left == is_negative_right) { - if (!(number_left < number_right)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (is_negative_left && !is_negative_right) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (type_if == fake_make_operation_if_type_if_less_equal) { - - if (is_negative_left == is_negative_right) { - if (!(number_left <= number_right)) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - else if (is_negative_left && !is_negative_right) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } - } // for - } - - if (F_status_is_error(status_number)) { - *status = F_status_set_error(F_failure); - *operation_if = fake_make_operation_if_type_false_always_next; - - if (main->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - if ((i == 1 && number_left > F_number_t_size_unsigned_d) || (i > 1 && number_right > F_number_t_size_unsigned_d)) { - fl_print_format("%c%[%SThe number '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%[' may only be between the ranges -%un to %un.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); - } - else { - fl_print_format("%c%[%SInvalid or unsupported number provided '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); - } - - funlockfile(data_make->error.to.stream); - } - } - - return 0; - } - - return 0; - } - - if (operation == fake_make_operation_type_link) { - *status = f_file_link(arguments.array[0].string, arguments.array[1].string); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_link", F_true, arguments.array[1].string, "create link", fll_error_file_type_file); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - fl_print_format("Created symbolic link from '%[%Q%]", main->output.to.stream, main->context.set.notable, arguments.array[1], main->context.set.notable); - fl_print_format("' to %[%Q%].%c", main->output.to.stream, main->context.set.notable, arguments.array[0], main->context.set.notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } - - return 0; - } - - if (operation == fake_make_operation_type_mode) { - f_file_mode_t mode_rule = 0; - uint8_t replace = 0; - - *status = fake_make_get_id_mode(main, data_make->error, arguments.array[0], &mode_rule, &replace); - if (F_status_is_error(*status)) return 0; - - mode_t mode = 0; - mode_t mode_file = 0; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - mode = 0; - - *status = f_file_mode_read(arguments.array[i].string, &mode_file); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - *status = f_file_mode_determine(mode_file, mode_rule, replace, macro_f_file_type_is_directory(mode_file), &mode); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_determine", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - *status = f_file_mode_set(arguments.array[i].string, mode); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_set", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Changed mode of '%Q' to %#@u.%c", main->output.to.stream, arguments.array[i], mode, f_string_eol_s[0]); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_modes) { - f_file_mode_t mode_rule = 0; - uint8_t replace = 0; - - *status = fake_make_get_id_mode(main, data_make->error, arguments.array[0], &mode_rule, &replace); - if (F_status_is_error(*status)) return 0; - - mode_t mode = 0; - mode_t mode_file = 0; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - mode = 0; - - *status = f_file_mode_read(arguments.array[i].string, &mode_file); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_read", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - *status = f_file_mode_determine(mode_file, mode_rule, replace, macro_f_file_type_is_directory(mode_file), &mode); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_mode_determine", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - *status = fll_file_mode_set_all(arguments.array[i].string, mode, fake_make_operation_recursion_depth_max_d); - - if (F_status_is_error(*status)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_mode_set_all", F_true, arguments.array[i].string, "change mode of", fll_error_file_type_file); - break; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Changed mode of '%Q' to %#@u.%c", main->output.to.stream, arguments.array[i], mode, f_string_eol_s[0]); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_move) { - const f_array_length_t total = arguments.used -1; - f_status_t status_file = F_none; - - fl_directory_recurse_t recurse = fl_directory_recurse_t_initialize; - - f_array_length_t destination_length = 0; - - if (main->error.verbosity == f_console_verbosity_verbose) { - recurse.output = main->output.to; - recurse.verbose = fake_verbose_print_move; - } - - bool existing = F_true; - - // in this case, the destination could be a file, so confirm this. - if (arguments.used == 2) { - status_file = f_directory_is(arguments.array[1].string); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_is", F_true, arguments.array[1].string, "identify", fll_error_file_type_directory); - - *status = F_status_set_error(F_failure); - return 0; - } - - if (status_file == F_false || status_file == F_file_found_not) { - existing = F_false; - } - } - - for (f_array_length_t i = 0; i < total; ++i) { - - destination_length = arguments.array[total].used; - - if (existing) { - destination_length += arguments.array[i].used + 1; - } - - char destination[destination_length + 1]; - - memcpy(destination, arguments.array[total].string, arguments.array[total].used); - - if (existing) { - memcpy(destination + arguments.array[total].used + 1, arguments.array[i].string, arguments.array[i].used); - destination[arguments.array[total].used] = f_path_separator_s[0]; - } - - destination[destination_length] = 0; - - status_file = fll_file_move(arguments.array[i].string, destination, arguments.array[i].used, destination_length, recurse); - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_move", F_true, arguments.array[i].string, "move", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_operate) { - f_array_length_t id_section = 0; - - for (; id_section < data_make->fakefile.used; ++id_section) { - - if (fl_string_dynamic_partial_compare_string(arguments.array[0].string, data_make->buffer, arguments.array[0].used, data_make->fakefile.array[id_section].name) == F_equal_to) { - break; - } - } // for - - if (id_section == data_make->fakefile.used) { - return 0; - } - - const int result = fake_make_operate_section(main, id_section, data_make, section_stack, status); - - // Ensure that a break only happens within its active operation stack. - if (*status == F_signal_abort) { - *status = F_none; - } - else if (F_status_set_fine(*status) == F_signal_abort) { - *status = F_status_set_error(F_failure); - } - - return result; - } - - if (operation == fake_make_operation_type_owner) { - uid_t id = 0; - - *status = fake_make_get_id_owner(main, data_make->error, arguments.array[0], &id); - if (F_status_is_error(*status)) return 0; - - f_status_t status_file = F_none; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - continue; - } - - status_file = f_file_role_change(arguments.array[i].string, id, -1, F_false); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_role_change", F_true, arguments.array[i].string, "change owner of", fll_error_file_type_file); - break; - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Changed owner of '%Q' to %u.%c", main->output.to.stream, arguments.array[i], id, f_string_eol_s[0]); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_owners) { - uid_t id = 0; - - *status = fake_make_get_id_owner(main, data_make->error, arguments.array[0], &id); - if (F_status_is_error(*status)) return 0; - - f_status_t status_file = F_none; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - continue; - } - - status_file = fll_file_role_change_all(arguments.array[i].string, id, -1, F_false, fake_make_operation_recursion_depth_max_d); - - if (F_status_is_error(status_file)) { - *status = status_file; - - fll_error_file_print(data_make->error, F_status_set_fine(*status), "fll_file_role_change_all", F_true, arguments.array[i].string, "change owner of", fll_error_file_type_file); - } - else if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Changed owner of '%Q' to %u.%c", main->output.to.stream, arguments.array[i], id, f_string_eol_s[0]); - } - } // for - - return 0; - } - - if (operation == fake_make_operation_type_pop) { - macro_f_string_dynamic_t_delete_simple(data_make->path.stack.array[data_make->path.stack.used - 1]); - - --data_make->path.stack.used; - - *status = f_path_change(data_make->path.stack.array[data_make->path.stack.used - 1].string); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", data_make->path.stack.array[data_make->path.stack.used - 1].string); - - return 0; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - *status = fake_make_path_relative(main, data_make->path.stack.array[data_make->path.stack.used - 1], data_make); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_path_relative", F_true); - - return 0; - } - - fll_print_format("Changed to project path '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, data_make->path_cache, main->context.set.notable, f_string_eol_s[0]); - } - - return 0; - } - - if (operation == fake_make_operation_type_print) { - flockfile(main->output.to.stream); - - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - f_print_dynamic(arguments.array[i], main->output.to.stream); - - if (i + 1 < arguments.used) { - f_print_character(f_string_space_s[0], main->output.to.stream); - } - } // for - - f_print_character(f_string_space_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - - funlockfile(main->output.to.stream); - - return 0; - } - - if (operation == fake_make_operation_type_run) { - *status = fake_make_operate_process_run(main, arguments, F_false, data_make); - - return 0; - } - - if (operation == fake_make_operation_type_shell) { - *status = fake_make_operate_process_run(main, arguments, F_true, data_make); - - return 0; - } - - if (operation == fake_make_operation_type_skeleton) { - *status = fake_skeleton_operate(main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - if (F_status_is_error(*status)) { - fake_make_operate_process_return(main, 1, data_make, status); - } - else { - fake_make_operate_process_return(main, 0, data_make, status); - } - - return 0; - } - - if (operation == fake_make_operation_type_to) { - *status = fake_make_assure_inside_project(main, arguments.array[0], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[0].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - - return 0; - } - - *status = f_path_change(arguments.array[0].string); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); - } - else { - *status = f_string_dynamics_increase_by(F_memory_default_allocation_small_d, &data_make->path.stack); - - if (F_status_set_fine(*status) == F_array_too_large) { - fake_print_message_section_operation_path_stack_max(main, data_make->error, F_array_too_large, "f_string_dynamics_increase_by", "path stack"); - - return 0; - } - else if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "macro_f_string_dynamics_t_resize", F_true); - - return 0; - } - - // copy the entire real path, including the trailing NULL. - ++data_make->path_cache.used; - - f_string_dynamic_append(data_make->path_cache, &data_make->path.stack.array[data_make->path.stack.used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - - return 0; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - *status = fake_make_path_relative(main, data_make->path.stack.array[data_make->path.stack.used], data_make); - - if (F_status_is_error(*status)) { - - fll_error_print(data_make->error, F_status_set_fine(*status), "fake_make_path_relative", F_true); - return 0; - } - - fll_print_format("Changed to project path '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, data_make->path_cache, main->context.set.notable, f_string_eol_s[0]); - } - - ++data_make->path.stack.used; - } - - return 0; - } - - if (operation == fake_make_operation_type_top) { - - *status = f_path_change_at(data_make->path.top.id); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_stack_max(main, data_make->error, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); - - return 0; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Changed to project path ''.%c", main->output.to.stream, f_string_eol_s[0]); - } - - // clear stack, except for the project root. - for (f_array_length_t i = 1; i < data_make->path.stack.used; ++i) { - macro_f_string_dynamic_t_delete_simple(data_make->path.stack.array[i]); - } // for - - data_make->path.stack.used = 1; - return 0; - } - - if (operation == fake_make_operation_type_touch) { - f_mode_t mode = f_mode_t_initialize; - - macro_f_mode_t_set_default_umask(mode, main->umask); - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_file_s, arguments.array[0], fake_make_operation_argument_file_s_length) == F_equal_to) { - *status = f_file_touch(arguments.array[i].string, mode.regular, F_false); - - if (F_status_is_error(*status)) { - if (F_status_is_error_not(fll_path_canonical(arguments.array[i].string, &data_make->path_cache))) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_touch", F_true, data_make->path_cache.string, "touch", fll_error_file_type_file); - } - else { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_touch", F_true, arguments.array[i].string, "touch", fll_error_file_type_file); - } - - break; - } - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory_s, arguments.array[0], fake_make_operation_argument_directory_s_length) == F_equal_to) { - *status = f_directory_touch(arguments.array[i].string, mode.directory); - - if (F_status_is_error(*status)) { - if (F_status_is_error_not(fll_path_canonical(arguments.array[i].string, &data_make->path_cache))) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_touch", F_true, data_make->path_cache.string, "touch", fll_error_file_type_directory); - } - else { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_directory_touch", F_true, arguments.array[i].string, "touch", fll_error_file_type_directory); - } - - break; - } - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("Touched '%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, arguments.array[i], main->context.set.notable, f_string_eol_s[0]); - } - } // for - } - - return 0; - } -#endif // _di_fake_make_operate_process_ - -#ifndef _di_fake_make_operate_process_execute_ - f_status_t fake_make_operate_process_execute(fake_main_t * const main, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) { - - if (fake_signal_received(main)) { - return F_status_set_error(F_interrupt); - } - - f_status_t status = F_none; - - // reset the environment. - for (f_array_length_t i = 0; i < data_make->environment.used; ++i) { - - data_make->environment.array[i].name.used = 0; - data_make->environment.array[i].value.used = 0; - } // for - - data_make->environment.used = 0; - - status = fl_environment_load_names(data_make->setting_build.environment, &data_make->environment); - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "fl_environment_load_names", F_true); - - return status; - } - - if (main->error.verbosity == f_console_verbosity_verbose) { - flockfile(main->output.to.stream); - - f_print_dynamic_safely(program, main->output.to.stream); - - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - if (arguments.array[i].used) { - fll_print_format(" %Q", main->output.to.stream, arguments.array[i]); - } - } // for - - f_print_character(f_string_eol_s[0], main->output.to.stream); - - funlockfile(main->output.to.stream); - - // flush to stdout before executing command. - fflush(main->output.to.stream); - } - - int return_code = 0; - - // child processes should receive all signals, without blocking. - f_signal_how_t signals = f_signal_how_t_initialize; - f_signal_set_empty(&signals.block); - f_signal_set_fill(&signals.block_not); - - fl_execute_parameter_t parameter = macro_fl_execute_parameter_t_initialize(as_shell ? 0 : FL_execute_parameter_option_path_d, 0, &data_make->environment, &signals, 0); - - status = fll_execute_program(program.string, arguments, ¶meter, 0, (void *) &return_code); - - if (fake_signal_received(main)) { - return F_status_set_error(F_interrupt); - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_interrupt) { - return status; - } - - if (F_status_set_fine(status) == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find program '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, program, data_make->error.notable); - fl_print_format("%[' for executing.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - } - else if (F_status_set_fine(status) != F_failure) { - fll_error_print(data_make->error, F_status_set_fine(status), "fll_execute_program", F_true); - } - } - - fake_make_operate_process_return(main, return_code, data_make, &status); - - return status; - } -#endif // _di_fake_make_operate_process_execute_ - -#ifndef _di_fake_make_operate_process_return_ - void fake_make_operate_process_return(fake_main_t * const main, const int return_code, fake_make_data_t *data_make, f_status_t *status) { - - f_status_t status2 = F_none; - - data_make->setting_make.parameter.array[0].value.array[0].used = 0; - - if (!return_code) { - if (F_status_is_error(*status)) { - status2 = f_string_append("1", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - else { - status2 = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - - return; - } - else { - if (return_code) { - f_string_dynamic_t number = f_string_dynamic_t_initialize; - - status2 = f_conversion_number_signed_to_string(WEXITSTATUS(return_code), f_conversion_data_base_10_s, &number); - - if (F_status_is_error(status2)) { - *status = status2; - - fll_error_print(data_make->error, F_status_set_fine(*status), "f_conversion_number_signed_to_string", F_true); - - macro_f_string_dynamic_t_delete_simple(number); - return; - } - - status2 = f_string_dynamic_append(number, &data_make->setting_make.parameter.array[0].value.array[0]); - - macro_f_string_dynamic_t_delete_simple(number); - } - else { - status2 = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - } - - if (F_status_is_error(status2)) { - *status = status2; - - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_append", F_true); - return; - } - - status2 = f_string_dynamic_terminate_after(&data_make->setting_make.parameter.array[0].value.array[0]); - - if (F_status_is_error(status2)) { - *status = status2; - - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_terminate_after", F_true); - return; - } - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed with return code %]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%i%]", data_make->error.to.stream, data_make->error.notable, return_code, data_make->error.notable); - fl_print_format("%[.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - if (data_make->setting_make.fail == fake_make_operation_fail_type_exit) { - *status = F_status_set_error(F_failure); - } - else { - *status = F_none; - } - } -#endif // _di_fake_make_operate_process_return_ - -#ifndef _di_fake_make_operate_process_run_ - f_status_t fake_make_operate_process_run(fake_main_t * const main, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) { - - const f_string_static_t *program = &arguments.array[0]; - - f_status_t status = F_none; - f_string_dynamics_t args = f_string_dynamics_t_initialize; - - if (arguments.used > 1) { - status = f_string_dynamics_resize(arguments.used - 1, &args); - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamics_resize", F_true); - return status; - } - - for (f_array_length_t i = 0; i < args.size; ++i) { - - status = f_string_dynamic_append(arguments.array[i + 1], &args.array[i]); - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamic_append", F_true); - - macro_f_string_dynamics_t_delete_simple(args); - return status; - } - - status = f_string_dynamic_terminate(&args.array[i]); - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_string_dynamic_terminate", F_true); - - macro_f_string_dynamics_t_delete_simple(args); - return status; - } - - ++args.used; - } // for - } - - status = fake_make_operate_process_execute(main, *program, args, as_shell, data_make); - - macro_f_string_dynamics_t_delete_simple(args); - return status; - } -#endif // _di_fake_make_operate_process_run_ - -#ifndef _di_fake_make_operate_validate_ - void fake_make_operate_validate(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_string_dynamics_t arguments, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (operation == fake_make_operation_type_index || operation == fake_make_operation_type_run || operation == fake_make_operation_type_shell) { - if (!arguments.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (operation == fake_make_operation_type_index) { - if (!data_make->setting_build.build_indexer.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SNo indexer has been specified, cannot perform '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_index_s, data_make->error.notable); - fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - - return; - } - - if (operation == fake_make_operation_type_break) { - if (arguments.used > 1) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to_not) { - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported break type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - - return; - } - - if (operation == fake_make_operation_type_build) { - if (arguments.used > 1) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used) { - if (arguments.array[0].used) { - char path_file[main->path_data_build.used + arguments.array[0].used + 1]; - - memcpy(path_file, main->path_data_build.string, main->path_data_build.used); - memcpy(path_file + main->path_data_build.used, arguments.array[0].string, arguments.array[0].used); - - path_file[main->path_data_build.used + arguments.array[0].used] = 0; - - f_status_t status_file = f_file_is(path_file, F_file_type_regular_d, F_false); - - if (status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%S%]", data_make->error.to.stream, data_make->error.notable, path_file, data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(status_file); - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_is", F_true, path_file, "find", fll_error_file_type_file); - *status = status_file; - } - else if (!status_file) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, path_file, data_make->error.notable); - fl_print_format("%[' must be a regular file.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SFilename argument must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - } - - return; - } - - if (operation == fake_make_operation_type_clean || operation == fake_make_operation_type_pop || operation == fake_make_operation_type_top || operation == fake_make_operation_type_skeleton) { - if (arguments.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (operation == fake_make_operation_type_pop) { - if (data_make->path.stack.used == 1) { - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SMust not attempt to pop project root off of path stack.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - } - - return; - } - - if (operation == fake_make_operation_type_clone) { - if (arguments.used > 1) { - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } // for - - for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { - - if (f_file_exists(arguments.array[i].string) != F_true) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } // for - - if (arguments.used > 2) { - - // the last file must be a directory. - f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); - - if (status_file == F_false || status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "find", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } - else { - - // when the first file is a directory, then the second, if it exists, must also be a directory. - f_status_t status_file = f_directory_is(arguments.array[0].string); - - if (status_file == F_true) { - status_file = f_directory_is(arguments.array[1].string); - - if (status_file == F_false) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_compile) { - if (!arguments.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (data_make->setting_build.build_compiler.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SNo compiler has been specified, cannot perform '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_compile_s, data_make->error.notable); - fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_copy) { - if (arguments.used > 1) { - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } // for - - for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { - - if (f_file_exists(arguments.array[i].string) != F_true) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } // for - - if (arguments.used > 2) { - - // the last file must be a directory. - f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); - - if (status_file == F_false || status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "identify", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } - else { - - // when the first file is a directory, then the second, if it exists, must also be a directory. - f_status_t status_file = f_directory_is(arguments.array[0].string); - - if (status_file == F_true) { - status_file = f_directory_is(arguments.array[1].string); - - if (status_file == F_false) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_delete || operation == fake_make_operation_type_deletes) { - if (arguments.used) { - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } // for - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_define) { - if (arguments.used) { - *status = fake_make_operate_validate_define_name(arguments.array[0]); - - if (*status == F_none) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SDefine name must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (*status == F_false) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SInvalid characters in the define setting name '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%[', only alpha-numeric ASCII characters and underscore (without a leading digit) is allowed.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_else) { - if (*operation_if == fake_make_operation_if_type_else_true || *operation_if == fake_make_operation_if_type_else_false) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SMust not be used after another '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[else%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); - fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - *operation_if = 0; - - return; - } - - if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SMust not be used inside an '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[if%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); - fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - *operation_if = 0; - - return; - } - - if (*operation_if != fake_make_operation_if_type_else_true_next && *operation_if != fake_make_operation_if_type_else_false_next && *operation_if != fake_make_operation_if_type_else_false_next_always) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas no preceding if condition.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - *operation_if = 0; - - return; - } - - if (arguments.used) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - *operation_if = 0; - } - - return; - } - - if (operation == fake_make_operation_type_exit) { - if (arguments.used > 1) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_success_s, arguments.array[0], fake_make_operation_argument_success_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_failure_s, arguments.array[0], fake_make_operation_argument_failure_s_length) == F_equal_to_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported exit type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - - return; - } - - if (operation == fake_make_operation_type_fail) { - if (arguments.used) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_exit_s, arguments.array[0], fake_make_operation_argument_exit_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn_s, arguments.array[0], fake_make_operation_argument_warn_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore_s, arguments.array[0], fake_make_operation_argument_ignore_s_length) == F_equal_to_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported fail type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_group || operation == fake_make_operation_type_groups || operation == fake_make_operation_type_mode || operation == fake_make_operation_type_modes || operation == fake_make_operation_type_owner || operation == fake_make_operation_type_owners) { - if (arguments.used > 1) { - f_status_t status_file = F_none; - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - status_file = f_file_is(arguments.array[i].string, F_file_type_regular_d, F_false); - - if (status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(status_file); - } - else if (F_status_is_error(status_file)) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_is", F_true, arguments.array[i].string, "find", fll_error_file_type_directory); - } - - *status = status_file; - } - } - - return; - } - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - - return; - } - - if (operation == fake_make_operation_type_if) { - if (*operation_if == fake_make_operation_if_type_true || *operation_if == fake_make_operation_if_type_false || *operation_if == fake_make_operation_if_type_false_always) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SMust not be used after another '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[if%]", data_make->error.to.stream, data_make->error.notable, data_make->error.notable); - fl_print_format("%[' section operation.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - *operation_if = 0; - - return; - } - - if (arguments.used) { - const f_string_t if_type_strings[] = { - fake_make_operation_argument_if_defined_s, - fake_make_operation_argument_if_equal_s, - fake_make_operation_argument_if_equal_not_s, - fake_make_operation_argument_if_exists_s, - fake_make_operation_argument_if_failure_s, - fake_make_operation_argument_if_greater_s, - fake_make_operation_argument_if_greater_equal_s, - fake_make_operation_argument_if_group_s, - fake_make_operation_argument_if_is_s, - fake_make_operation_argument_if_less_s, - fake_make_operation_argument_if_less_equal_s, - fake_make_operation_argument_if_mode_s, - fake_make_operation_argument_if_owner_s, - fake_make_operation_argument_if_success_s, - }; - - const f_array_length_t if_type_lengths[] = { - fake_make_operation_argument_if_defined_s_length, - fake_make_operation_argument_if_equal_s_length, - fake_make_operation_argument_if_equal_not_s_length, - fake_make_operation_argument_if_exists_s_length, - fake_make_operation_argument_if_failure_s_length, - fake_make_operation_argument_if_greater_s_length, - fake_make_operation_argument_if_greater_equal_s_length, - fake_make_operation_argument_if_group_s_length, - fake_make_operation_argument_if_is_s_length, - fake_make_operation_argument_if_less_s_length, - fake_make_operation_argument_if_less_equal_s_length, - fake_make_operation_argument_if_mode_s_length, - fake_make_operation_argument_if_owner_s_length, - fake_make_operation_argument_if_success_s_length, - }; - - const uint8_t if_type_codes[] = { - fake_make_operation_if_type_if_defined, - fake_make_operation_if_type_if_equal, - fake_make_operation_if_type_if_equal_not, - fake_make_operation_if_type_if_exists, - fake_make_operation_if_type_if_failure, - fake_make_operation_if_type_if_greater, - fake_make_operation_if_type_if_greater_equal, - fake_make_operation_if_type_if_group, - fake_make_operation_if_type_if_is, - fake_make_operation_if_type_if_less, - fake_make_operation_if_type_if_less_equal, - fake_make_operation_if_type_if_mode, - fake_make_operation_if_type_if_owner, - fake_make_operation_if_type_if_success, - }; - - const uint8_t if_type_minimum[] = { - 2, - 2, - 2, - 2, - 1, - 2, - 2, - 3, - 3, - 2, - 2, - 4, - 3, - 1, - }; - - f_array_length_t i = 0; - - for (; i < 14; ++i) { - - if (fl_string_dynamic_compare_string(if_type_strings[i], arguments.array[0], if_type_lengths[i]) == F_equal_to) { - *operation_if = if_type_codes[i]; - break; - } - } // for - - if (i == 14) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported if type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - *operation_if = fake_make_operation_if_type_false_always_next; - - return; - } - - if (arguments.used >= if_type_minimum[i]) { - if (*operation_if == fake_make_operation_if_type_if_success || *operation_if == fake_make_operation_if_type_if_failure) { - if (arguments.used > if_type_minimum[i]) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - *operation_if = fake_make_operation_if_type_false_always_next; - } - - return; - } - - if (*operation_if == fake_make_operation_if_type_if_mode || *operation_if == fake_make_operation_if_type_if_owner || *operation_if == fake_make_operation_if_type_if_group || *operation_if == fake_make_operation_if_type_if_is || *operation_if == fake_make_operation_if_type_if_exists) { - if (*operation_if == fake_make_operation_if_type_if_mode) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_is_s, arguments.array[1], fake_make_operation_argument_is_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_has_s, arguments.array[1], fake_make_operation_argument_has_s_length) == F_equal_to_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported mode type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - return; - } - } - - f_file_mode_t mode_rule = 0; - uint8_t replace = 0; - - *status = fake_make_get_id_mode(main, data_make->error, arguments.array[2], &mode_rule, &replace); - if (F_status_is_error(*status)) return; - - i = 3; - } - - if (*operation_if == fake_make_operation_if_type_if_owner) { - uid_t id = 0; - - *status = fake_make_get_id_owner(main, data_make->error, arguments.array[1], &id); - if (F_status_is_error(*status)) return; - - i = 2; - } - - if (*operation_if == fake_make_operation_if_type_if_group) { - gid_t id = 0; - - *status = fake_make_get_id_group(main, data_make->error, arguments.array[1], &id); - if (F_status_is_error(*status)) return; - - i = 2; - } - - if (*operation_if == fake_make_operation_if_type_if_is) { - - // block = 0x1 (0000 0001) link = 0x10 (0001 0000) - // character = 0x2 (0000 0010) regular = 0x20 (0010 0000) - // directory = 0x4 (0000 0100) socket = 0x40 (0100 0000) - // fifo = 0x8 (0000 1000) invalid = 0x80 (1000 0000) - uint8_t type_file = 0; - - for (i = 1; i < arguments.used; ++i) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_if_is_for_s, arguments.array[i], fake_make_operation_argument_if_is_for_s_length) == F_equal_to) { - ++i; - break; - } - - if (fl_string_dynamic_compare_string(F_file_type_name_block_s, arguments.array[i], F_file_type_name_block_s_length) == F_equal_to) { - type_file |= 0x1; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_character_s, arguments.array[i], F_file_type_name_character_s_length) == F_equal_to) { - type_file |= 0x2; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_directory_s, arguments.array[i], F_file_type_name_directory_s_length) == F_equal_to) { - type_file |= 0x4; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_fifo_s, arguments.array[i], F_file_type_name_fifo_s_length) == F_equal_to) { - type_file |= 0x8; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_link_s, arguments.array[i], F_file_type_name_link_s_length) == F_equal_to) { - type_file |= 0x10; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_regular_s, arguments.array[i], F_file_type_name_regular_s_length) == F_equal_to) { - type_file |= 0x20; - } - else if (fl_string_dynamic_compare_string(F_file_type_name_socket_s, arguments.array[i], F_file_type_name_socket_s_length) == F_equal_to) { - type_file |= 0x40; - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported file type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - type_file |= 0x80; - } - } // for - - if (type_file & 0x80) { - *status = F_status_set_error(F_failure); - *operation_if = fake_make_operation_if_type_false_always_next; - - return; - } - } - - if (*operation_if == fake_make_operation_if_type_if_exists) { - i = 1; - } - - if (i < arguments.used) { - for (f_status_t status_file = F_none; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(status_file)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(status_file), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - *operation_if = fake_make_operation_if_type_false_always_next; - - if (F_status_is_error_not(*status)) { - if (F_status_set_fine(status_file) == F_false) { - *status = F_status_set_error(F_failure); - } - else { - *status = status_file; - } - } - } - else if (*operation_if != fake_make_operation_if_type_if_exists && *operation_if != fake_make_operation_if_type_if_is) { - - // The existence tests do not need to happen here for *_if_exists and *_if_is as those two types will handle performing them during the process stage. - status_file = f_file_exists(arguments.array[i].string); - - if (status_file == F_false) { - status_file = F_status_set_error(F_file_found_not); - } - - if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_file_exists", F_true, arguments.array[i].string, "find", fll_error_file_type_file); - - *operation_if = fake_make_operation_if_type_false_always_next; - - if (F_status_is_error_not(*status)) { - *status = F_status_set_error(status_file); - } - } - } - } // for - - return; - } - } - - if (*operation_if == fake_make_operation_if_type_if_defined) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported define type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[1], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - - return; - } - - if (*operation_if == fake_make_operation_if_type_if_equal || *operation_if == fake_make_operation_if_type_if_equal_not) { - if (arguments.used < 3) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (*operation_if == fake_make_operation_if_type_if_greater || *operation_if == fake_make_operation_if_type_if_greater_equal || *operation_if == fake_make_operation_if_type_if_less || *operation_if == fake_make_operation_if_type_if_less_equal) { - if (arguments.used < 3) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - return; - } - - f_status_t status_number = F_none; - f_string_range_t range = f_string_range_t_initialize; - f_number_unsigned_t number = 0; - bool is_negative = F_false; - - // @fixme there needs to handle converting numbers with decimals (like 1.01), perhaps operate on them as strings or provide a special processor. - for (i = 1; i < arguments.used; ++i, status_number = F_none) { - - if (arguments.array[i].used) { - range.start = 0; - range.stop = arguments.array[i].used - 1; - - if (arguments.array[i].string[0] == '+') { - range.start = 1; - } - else if (arguments.array[i].string[0] == '-') { - range.start = 1; - is_negative = F_true; - } - - if (range.start > range.stop) { - status_number = F_status_set_error(F_failure); - } - else { - status_number = fl_conversion_string_to_number_unsigned(arguments.array[i].string, range, &number); - } - } - else { - status_number = F_status_set_error(F_failure); - } - - if (F_status_is_error(status_number)) { - *status = F_status_set_error(F_failure); - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - if (number > F_number_t_size_unsigned_d) { - fl_print_format("%c%[%SThe number '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%[' may only be between the ranges -%un to %un.%]%c", data_make->error.to.stream, data_make->error.context, F_number_t_size_unsigned_d, F_number_t_size_unsigned_d, data_make->error.context, f_string_eol_s[0]); - } - else { - fl_print_format("%c%[%SInvalid or unsupported number provided '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - } - - funlockfile(data_make->error.to.stream); - } - } - } // for - - return; - } - } - } - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - *operation_if = fake_make_operation_if_type_false_always_next; - - return; - } - - if (operation == fake_make_operation_type_link) { - if (arguments.used > 2) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used == 2) { - *status = fake_make_assure_inside_project(main, arguments.array[0], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[0].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - - *status = fake_make_assure_inside_project(main, arguments.array[1], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[1].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_move) { - if (arguments.used > 1) { - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } // for - - for (f_array_length_t i = 0; i < arguments.used - 1; ++i) { - - if (f_file_exists(arguments.array[i].string) != F_true) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[i], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } // for - - if (arguments.used > 2) { - - // the last file must be a directory. - f_status_t status_file = f_directory_is(arguments.array[arguments.used - 1].string); - - if (status_file == F_false || status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - else if (F_status_is_error(status_file)) { - fll_error_file_print(data_make->error, F_status_set_fine(status_file), "f_directory_is", F_true, arguments.array[arguments.used - 1].string, "identify", fll_error_file_type_directory); - *status = F_status_set_error(F_failure); - } - } - else { - - // when the first file is a directory, then the second, if it exists, must also be a directory. - f_status_t status_file = f_directory_is(arguments.array[0].string); - - if (status_file == F_true) { - status_file = f_directory_is(arguments.array[1].string); - - if (status_file == F_false) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe last file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[arguments.used - 1], data_make->error.notable); - fl_print_format("%[' must be a valid directory.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_operate) { - if (arguments.used > 1) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used == 1) { - f_array_length_t id_section = 0; - - for (; id_section < data_make->fakefile.used; ++id_section) { - - if (fl_string_dynamic_partial_compare_string(arguments.array[0].string, data_make->buffer, arguments.array[0].used, data_make->fakefile.array[id_section].name) == F_equal_to) { - break; - } - } // for - - if (id_section == data_make->fakefile.used) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SNo operation section named '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%[' was found.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - else { - for (f_array_length_t i = 0; i < section_stack->used; ++i) { - - if (section_stack->array[i] == id_section) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe section operation '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, data_make->fakefile.array[id_section].name, data_make->error.notable); - fl_print_format("%[' is already in the operation stack, recursion is not allowed.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - break; - } - } // for - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - return; - } - - if (operation == fake_make_operation_type_to) { - if (arguments.used > 1) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SHas too many arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - else if (arguments.used) { - if (arguments.array[0].used) { - f_status_t status_file = f_file_is(arguments.array[0].string, F_file_type_directory_d, F_false); - - if (status_file == F_file_found_not) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SFailed to find file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(status_file); - } - else if (F_status_is_error(status_file)) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_error_file_print(data_make->error, F_status_set_fine(*status), "f_file_is", F_true, main->file_data_build_fakefile.string, "find", fll_error_file_type_file); - } - - *status = status_file; - } - else if (!status_file) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SThe file '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%[' must be a directory file.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SFilename argument must not be an empty string.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - } - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (operation == fake_make_operation_type_touch) { - if (arguments.used > 1) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_file_s, arguments.array[0], fake_make_operation_argument_file_s_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory_s, arguments.array[0], fake_make_operation_argument_directory_s_length) == F_equal_to_not) { - - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SUnsupported file type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context); - fl_print_format("%[%Q%]", data_make->error.to.stream, data_make->error.notable, arguments.array[0], data_make->error.notable); - fl_print_format("%['.%]%c", data_make->error.to.stream, data_make->error.context, data_make->error.context, f_string_eol_s[0]); - - funlockfile(data_make->error.to.stream); - } - - *status = F_status_set_error(F_failure); - } - } - - for (f_array_length_t i = 1; i < arguments.used; ++i) { - - *status = fake_make_assure_inside_project(main, arguments.array[i], data_make); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(main, data_make->error, F_status_set_fine(*status), "fake_make_assure_inside_project", data_make->path_cache.used ? data_make->path_cache.string : arguments.array[i].string); - - if (F_status_set_fine(*status) == F_false) { - *status = F_status_set_error(F_failure); - } - } - } // for - } - else { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fll_print_format("%c%[%SRequires more arguments.%]%c", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, data_make->error.context, f_string_eol_s[0]); - } - - *status = F_status_set_error(F_failure); - } - - return; - } - - // note: there is nothing to validate for fake_make_operation_type_print. - } -#endif // _di_fake_make_operate_validate_ - -#ifndef _di_fake_make_operate_validate_define_name_ - f_status_t fake_make_operate_validate_define_name(const f_string_static_t name) { - - if (!name.used) return F_none; - - if (!(isalpha(name.string[0]) || name.string[0] == '_')) { - return F_false; - } - - for (f_array_length_t i = 0; i < name.used; ++i) { - - if (!(isalnum(name.string[i]) || name.string[i] == '_')) { - return F_false; - } - } // for - - return F_true; - } -#endif // _di_fake_make_operate_validate_define_name_ - #ifndef _di_fake_make_path_relative_ f_status_t fake_make_path_relative(fake_main_t * const main, const f_string_static_t path, fake_make_data_t *data_make) { diff --git a/level_3/fake/c/private-make.h b/level_3/fake/c/private-make.h index 60ed437..2399a8c 100644 --- a/level_3/fake/c/private-make.h +++ b/level_3/fake/c/private-make.h @@ -104,324 +104,6 @@ extern "C" { #endif // _di_fake_make_get_id_owner_ /** - * Find the fake file, load it, validate it, and process it. - * - * This will process any additional files as necessary, such as the build settings file. - * - * @param main - * The main program data. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param status - * The return status. - * - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - * - * @see fake_build_load_setting() - */ -#ifndef _di_fake_make_load_fakefile_ - extern void fake_make_load_fakefile(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_load_fakefile_ - -/** - * Load the environment variables into a structure more readily available for using in parameter expansion. - * - * @param main - * The main program data. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param status - * The return status. - * - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_load_parameters_ - extern void fake_make_load_parameters(fake_main_t * const main, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_load_parameters_ - -/** - * Execute the make sections and their respective operations. - * - * The first section operated on is the 'main' section. - * The 'settings' section is only loaded into settings and is never operated on. - * - * @param main - * The main program data. - * - * @return - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_ - extern f_status_t fake_make_operate(fake_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_ - -/** - * For a given make section operation, expand the content into an arguments array for that operation. - * - * This prints errors via data_make.error. - * - * @param main - * The main program data. - * @param section_name - * The section name. - * @param operation - * The operation being performed. - * @param content - * The content array. - * @param quoteds - * The array of quoted associated with the content. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param arguments - * The expanded arguments. - * @param status - * The return status. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_expand_ - extern void fake_make_operate_expand(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_fss_content_t content, const f_fss_quotes_t quoteds, fake_make_data_t *data_make, f_string_dynamics_t *arguments, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_expand_ - -/** - * Perform the expand operation, specifically for the environment variables. - * - * @param main - * The main program data. - * @param quoted - * The quoted associated with the content. - * @param range_name - * The range representing the variable content name string within the data_make->buffer. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param arguments - * The expanded arguments. - * - * @return - * F_true on success and match expanded. - * F_false on no matches to expand. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_expand_environment_ - extern f_status_t fake_make_operate_expand_environment(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_expand_environment_ - -/** - * Perform the expand operation, specifically for the build settings. - * - * @param main - * The main program data. - * @param quoted - * The quoted associated with the content. - * @param range_name - * The range representing the variable content name string within the data_make->buffer. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param arguments - * The expanded arguments. - * - * @return - * F_true on success and match expanded. - * F_false on no matches to expand. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_expand_build_ - extern f_status_t fake_make_operate_expand_build(fake_main_t * const main, const f_fss_quote_t quoted, const f_string_range_t range_name, fake_make_data_t *data_make, f_string_dynamics_t *arguments) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_expand_build_ - -/** - * Perform the make operations within the given section. - * - * @param main - * The main program data. - * @param id_section - * The array location id within the fakefile of the section to operate on. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param section_stack - * The current operation stack. - * @param status - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * F_recurse (with error bit) is returned if unable to recurse to another operation section (usually max stack depth reached). - * F_valid_not (with error bit) is returned if any part of the section is invalid, such as an invalid operation name. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_make_operate_section_ - int fake_make_operate_section(fake_main_t * const main, const f_array_length_t id_section, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_section_ - -/** - * Perform a specific make operation within the given section. - * - * @param main - * The main program data. - * @param section_name - * The section name. - * @param operation - * The operation type. - * @param arguments - * The expanded arguments. - * @param success - * Whether or not a previous section operation succeeded or failed. - * @param operation_if - * The if-condition status for the current operation. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param section_stack - * The current operation stack. - * @param status - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - * - * @return - * The return code of the execution process. - * This generally is only needed when F_child is returned, where this holds the return status of the child process. - */ -#ifndef _di_fake_make_operate_process_ - extern int fake_make_operate_process(fake_main_t * const main, const f_string_range_t section_name, const uint8_t operation, const f_string_dynamics_t arguments, const bool success, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_ - -/** - * Execute either the run operation or the shell operation. - * - * @param main - * The main program data. - * @param program - * The program to be executed. - * @param arguments - * The arguments for the run or shell operation. - * @param as_shell - * When TRUE, this is a shell operation. - * When FALSE, this is a run operation. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * - * @return - * F_none on success. - * - * F_interrupt (with error bit) on receiving a terminate process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_process_execute_ - extern f_status_t fake_make_operate_process_execute(fake_main_t * const main, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_execute_ - -/** - * Handle the return code, converting it to a number. - * - * @param main - * The main program data. - * @param return_code - * The return code to process. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param status - * The return status. - * - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_process_return_ - extern void fake_make_operate_process_return(fake_main_t * const main, const int return_code, fake_make_data_t *data_make, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_return_ - -/** - * Execute either the run operation or the shell operation. - * - * @param main - * The main program data. - * @param arguments - * The arguments for the run or shell operation. - * @param as_shell - * When TRUE, this is a shell operation. - * When FALSE, this is a run operation. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * - * @return - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_process_run_ - extern f_status_t fake_make_operate_process_run(fake_main_t * const main, const f_string_statics_t arguments, const bool as_shell, fake_make_data_t *data_make) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_run_ - -/** - * For a given make section operation, validate the given operation. - * - * This performs pre-operation validations. - * Additional issues may occure when running operations that are not detected nor detectable by this. - * - * @param main - * The main program data. - * @param section_name - * The section name. - * @param operation - * The operation being performed. - * @param arguments - * The expanded arguments. - * @param operation_if - * The if-condition status for the current operation. - * @param main_make - * All make related setting data, including data from the fakefile and optionally build settings file. - * @param section_stack - * The current operation stack. - * @param status - * The return status. - * - * Status codes (with error bit) are returned on any problem. - */ -#ifndef _di_fake_make_operate_validate_ - extern void fake_make_operate_validate(fake_main_t * const main, const f_string_range_t section_name, const f_array_length_t operation, const f_string_dynamics_t arguments, uint8_t *operation_if, fake_make_data_t *data_make, f_array_lengths_t *section_stack, f_status_t *status) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_validate_ - -/** - * Validate that the given define variable name is valid. - * - * A valid define variable name must begin with an alpha-character or an underscore. - * Every character after that may be alphanumeric or underscore. - * All other characters, including Unicode characters, are invalid. - * - * @fixme make this UTF-8 friendly. - * - * @param name - * The variable name string to validate. - * - * @return - * F_true on valid. - * F_false on invalid. - * F_none if there is no string to validate (used = 0). - */ -#ifndef _di_fake_make_operate_validate_define_name_ - extern f_status_t fake_make_operate_validate_define_name(const f_string_static_t name) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_validate_define_name_ - -/** * Get a path, relative to the project root. * * @param main diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index 61b1883..a9e13b4 100644 --- a/level_3/fake/data/build/settings +++ b/level_3/fake/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fake.c private-common.c private-fake.c private-clean.c private-build.c private-make.c private-print.c private-skeleton.c +build_sources_library fake.c private-build.c private-build-library.c private-build-load.c private-build-objects.c private-build-program.c private-build-skeleton.c private-clean.c private-common.c private-make.c private-fake.c private-fake-path_generate.c private-make-load_fakefile.c private-make-load_parameters.c private-make-operate.c private-print.c private-skeleton.c build_sources_library_shared build_sources_library_static build_sources_program main.c