From: Kevin Day Date: Tue, 12 May 2020 03:16:44 +0000 (-0500) Subject: Progress: Featureless Make X-Git-Tag: 0.5.0~259 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=6fd22d76eaf5d5f91bc0dad0802e8df019ab5b89;p=fll Progress: Featureless Make --- diff --git a/level_3/fake/c/fake.c b/level_3/fake/c/fake.c index db67b5a..9f8f0f7 100644 --- a/level_3/fake/c/fake.c +++ b/level_3/fake/c/fake.c @@ -83,7 +83,11 @@ extern "C" { f_return_status fake_main(const f_console_arguments arguments, fake_data *data) { f_status status = f_none; - uint8_t operations[fake_operations_total] = fake_operations_initialize; + uint8_t operations[fake_operations_total]; + f_string operations_name[fake_operations_total]; + + memset(&operations, 0, sizeof(uint8_t) * fake_operations_total); + memset(&operations_name, 0, sizeof(f_string) * fake_operations_total); { f_console_parameters parameters = { data->parameters, fake_total_parameters }; @@ -144,6 +148,7 @@ extern "C" { if (data->parameters[fake_parameter_operation_build].result == f_console_result_found) { operations[0] = fake_operation_build; operations_id[0] = fake_parameter_operation_build; + operations_name[0] = fake_other_operation_build; order_total = 1; } @@ -155,6 +160,9 @@ extern "C" { operations_id[0] = fake_parameter_operation_build; operations_id[1] = fake_parameter_operation_clean; + + operations_name[0] = fake_other_operation_build; + operations_name[1] = fake_other_operation_clean; } else { operations[0] = fake_operation_clean; @@ -162,6 +170,9 @@ extern "C" { operations_id[0] = fake_parameter_operation_clean; operations_id[1] = fake_parameter_operation_build; + + operations_name[0] = fake_other_operation_clean; + operations_name[1] = fake_other_operation_build; } order_total = 2; @@ -169,6 +180,7 @@ extern "C" { else { operations[0] = fake_operation_clean; operations_id[0] = fake_parameter_operation_clean; + operations_name[0] = fake_other_operation_clean; order_total = 1; } } @@ -184,15 +196,18 @@ extern "C" { if (i == order_total) { operations[order_total] = fake_operation_make; operations_id[order_total] = fake_parameter_operation_make; + operations_name[order_total] = fake_other_operation_make; } else { for (uint8_t j = order_total; j > i; j-- ) { operations[j] = operations[j - 1]; operations_id[j] = operations_id[j - 1]; + operations_name[j] = operations_name[j - 1]; } // for operations[i] = fake_operation_make; operations_id[i] = fake_parameter_operation_make; + operations_name[i] = fake_other_operation_make; } order_total++; @@ -200,6 +215,7 @@ extern "C" { else { operations[0] = fake_operation_make; operations_id[0] = fake_parameter_operation_make; + operations_name[0] = fake_other_operation_make; order_total = 1; } } @@ -215,21 +231,25 @@ extern "C" { if (i == order_total) { operations[order_total] = fake_operation_skeleton; operations_id[order_total] = fake_parameter_operation_skeleton; + operations_name[order_total] = fake_other_operation_skeleton; } else { for (uint8_t j = order_total; j > i; j--) { operations[j] = operations[j - 1]; operations_id[j] = operations_id[j - 1]; + operations_name[j] = operations_name[j - 1]; } // for operations[i] = fake_operation_skeleton; operations_id[i] = fake_parameter_operation_skeleton; + operations_name[i] = fake_other_operation_skeleton; } order_total++; } else { operations[0] = fake_operation_skeleton; + operations_name[0] = fake_other_operation_skeleton; } } } @@ -244,6 +264,8 @@ extern "C" { fll_program_print_version(fake_version); } else if (operations[0]) { + bool validate_parameter_directories = f_true; + status = fake_process_console_parameters(arguments, data); if (!f_status_is_error(status)) { @@ -259,50 +281,68 @@ extern "C" { data->operation = operations[i]; if (operations[i] == fake_operation_build) { - status = fake_build_operate(*data); - - if (f_status_is_error(status)) { - if (data->verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_build); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); - } + if (validate_parameter_directories) { + status = fake_validate_parameter_directories(arguments, *data); + validate_parameter_directories = f_false; + } - break; + if (!f_status_is_error(status)) { + status = fake_build_operate(*data); } } else if (operations[i] == fake_operation_clean) { - status = fake_clean_operate(*data); - - if (f_status_is_error(status)) { - if (data->verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_clean); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); - } + if (validate_parameter_directories) { + status = fake_validate_parameter_directories(arguments, *data); + validate_parameter_directories = f_false; + } - break; + if (!f_status_is_error(status)) { + status = fake_clean_operate(*data); } } else if (operations[i] == fake_operation_make) { + if (validate_parameter_directories) { + status = fake_validate_parameter_directories(arguments, *data); + validate_parameter_directories = f_false; + } + if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_make); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); } } else if (operations[i] == fake_operation_skeleton) { + status = fake_skeleton_operate(*data); + } + + if (f_status_is_error(status)) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", fake_other_operation_skeleton); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is not yet implemented."); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", operations_name[i]); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' failed."); } + + break; } } // for + + // ensure a newline is always put at the end of the program execution, unless in quite mode. + if (data->verbosity != fake_verbosity_quiet) { + if (f_status_is_error(status)) { + fprintf(f_standard_error, "%c", f_string_eol); + } + else { + fprintf(f_standard_output, "%c", f_string_eol); + } + } } else { if (data->verbosity != fake_verbosity_quiet) { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify an operation."); + fprintf(f_standard_error, "%c", f_string_eol); } status = f_status_set_error(f_invalid_parameter); diff --git a/level_3/fake/c/fake.h b/level_3/fake/c/fake.h index 901db04..61a030e 100644 --- a/level_3/fake/c/fake.h +++ b/level_3/fake/c/fake.h @@ -117,6 +117,7 @@ #include #include #include +#include // fll-1 includes #include @@ -161,21 +162,29 @@ extern "C" { * For example path_build_documents will become "build/documents/" if the fake_default_path_build is used. */ #ifndef _di_fake_path_ - #define fake_path_directory_separator "/" // @todo this should be provided by a f_path library. - - #define fake_path_build_documents "documents" fake_path_directory_separator - #define fake_path_build_includes "includes" fake_path_directory_separator - #define fake_path_build_libraries "libraries" fake_path_directory_separator - #define fake_path_build_libraries_script "script" fake_path_directory_separator - #define fake_path_build_libraries_shared "shared" fake_path_directory_separator - #define fake_path_build_libraries_static "static" fake_path_directory_separator - #define fake_path_build_objects "objects" fake_path_directory_separator - #define fake_path_build_process "process" fake_path_directory_separator - #define fake_path_build_programs "programs" fake_path_directory_separator - #define fake_path_build_programs_script "script" fake_path_directory_separator - #define fake_path_build_programs_shared "shared" fake_path_directory_separator - #define fake_path_build_programs_static "static" fake_path_directory_separator - #define fake_path_build_settings "settings" fake_path_directory_separator + #define fake_path_documents "documents" f_path_separator + #define fake_path_data "data" f_path_separator + #define fake_path_licenses "licenses" f_path_separator + #define fake_path_sources "sources" f_path_separator + + #define fake_path_documents_length 9 + #define fake_path_data_length 4 + #define fake_path_licenses_length 8 + #define fake_path_sources_length 7 + + #define fake_path_build_documents "documents" f_path_separator + #define fake_path_build_includes "includes" f_path_separator + #define fake_path_build_libraries "libraries" f_path_separator + #define fake_path_build_libraries_script "script" f_path_separator + #define fake_path_build_libraries_shared "shared" f_path_separator + #define fake_path_build_libraries_static "static" f_path_separator + #define fake_path_build_objects "objects" f_path_separator + #define fake_path_build_process "process" f_path_separator + #define fake_path_build_programs "programs" f_path_separator + #define fake_path_build_programs_script "script" f_path_separator + #define fake_path_build_programs_shared "shared" f_path_separator + #define fake_path_build_programs_static "static" f_path_separator + #define fake_path_build_settings "settings" f_path_separator #define fake_path_build_documents_length 10 #define fake_path_build_includes_length 9 @@ -190,10 +199,31 @@ extern "C" { #define fake_path_build_programs_shared_length 7 #define fake_path_build_programs_static_length 7 #define fake_path_build_settings_length 9 + + // these paths are suffixes to be appended onto the work directory, if the work directory is supplied. + #define fake_path_work_includes "includes" f_path_separator + #define fake_path_work_libraries "libraries" f_path_separator + #define fake_path_work_libraries_script "libraries" f_path_separator "script" f_path_separator + #define fake_path_work_libraries_shared "libraries" f_path_separator "shared" f_path_separator + #define fake_path_work_libraries_static "libraries" f_path_separator "static" f_path_separator + #define fake_path_work_programs "programs" f_path_separator + #define fake_path_work_programs_script "programs" f_path_separator "script" f_path_separator + #define fake_path_work_programs_shared "programs" f_path_separator "shared" f_path_separator + #define fake_path_work_programs_static "programs" f_path_separator "static" f_path_separator + + #define fake_path_work_includes_length 9 + #define fake_path_work_libraries_length 10 + #define fake_path_work_libraries_script_length 17 + #define fake_path_work_libraries_shared_length 17 + #define fake_path_work_libraries_static_length 17 + #define fake_path_work_programs_length 9 + #define fake_path_work_programs_script_length 16 + #define fake_path_work_programs_shared_length 16 + #define fake_path_work_programs_static_length 16 #endif // _di_fake_path_ #ifndef _di_fake_defaults_ - #define fake_default_path_build "build" fake_path_directory_separator + #define fake_default_path_build "build" f_path_separator #define fake_default_path_work "" #define fake_default_path_build_length 6 @@ -209,13 +239,13 @@ extern "C" { #define fake_default_process_length 0 #define fake_default_settings_length 8 - #define fake_default_path_source_build "data" fake_path_directory_separator "build" fake_path_directory_separator - #define fake_default_path_source_codes "sources" fake_path_directory_separator - #define fake_default_path_source_common "data" fake_path_directory_separator "common" fake_path_directory_separator - #define fake_default_path_source_data "data" fake_path_directory_separator - #define fake_default_path_source_documents "data" fake_path_directory_separator "documents" fake_path_directory_separator - #define fake_default_path_source_licenses "licenses" fake_path_directory_separator - #define fake_default_path_source_settings "data" fake_path_directory_separator "build" fake_path_directory_separator + #define fake_default_path_source_build "data" f_path_separator "build" f_path_separator + #define fake_default_path_source_codes "sources" f_path_separator + #define fake_default_path_source_common "data" f_path_separator "common" f_path_separator + #define fake_default_path_source_data "data" f_path_separator + #define fake_default_path_source_documents "data" f_path_separator "documents" f_path_separator + #define fake_default_path_source_licenses "licenses" f_path_separator + #define fake_default_path_source_settings "data" f_path_separator "build" f_path_separator #define fake_default_path_source_build_length 11 #define fake_default_path_source_codes_length 8 @@ -225,30 +255,32 @@ extern "C" { #define fake_default_path_source_licenses_length 9 #define fake_default_path_source_settings_length 11 - #define fake_default_language_c "c" fake_path_directory_separator - #define fake_default_language_cpp "c++" fake_path_directory_separator - #define fake_default_language_shell "shell" fake_path_directory_separator + #define fake_default_language_bash "bash" f_path_separator + #define fake_default_language_c "c" f_path_separator + #define fake_default_language_cpp "c++" f_path_separator - #define fake_default_language_c_length 2 - #define fake_default_language_cpp_length 4 - #define fake_default_language_shell_length 6 + #define fake_default_language_bash_length 5 + #define fake_default_language_c_length 2 + #define fake_default_language_cpp_length 4 #endif // _di_fake_defaults_ #ifndef _di_fake_build_language_ enum { - fake_build_language_c = 1, + fake_build_language_bash = 1, + fake_build_language_c, fake_build_language_cpp, - fake_build_language_shell, }; - #define fake_build_language_c "c" - #define fake_build_language_cpp "c++" - #define fake_build_language_shell "shell" + #define fake_build_language_bash "bash" + #define fake_build_language_c "c" + #define fake_build_language_cpp "c++" + + #define fake_build_language_bash_length 4 + #define fake_build_language_c_length 1 + #define fake_build_language_cpp_length 3 #endif // _di_fake_build_language_ #ifndef _di_fake_defines_ - #define fake_directory_max_recursion 2048 - enum { fake_operation_build = 1, fake_operation_clean, diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 6bc3166..42e026a 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -6,8 +6,239 @@ extern "C" { #endif -#ifndef _di_fake_build_load_settings_ - f_return_status fake_build_load_settings(const fake_data data, fake_build_settings *settings) { +#ifndef _di_fake_build_execute_process_script_ + f_return_status fake_build_execute_process_script(const fake_data data, const fake_build_settings settings, const f_string_static process_script) { + if (process_script.used == 0) return f_none; + + f_status status = f_none; + + const f_string parameter_prefixs[] = { + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + f_console_symbol_short_enable, + }; + + const f_string_length parameter_prefixs_length[] = { + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + f_console_symbol_short_enable_length, + }; + + const f_string parameter_names[] = { + fake_short_defines, + fake_short_process, + fake_short_settings, + fake_short_path_build, + fake_short_path_work, + fake_short_path_source_build, + fake_short_path_source_common, + fake_short_path_source_data, + fake_short_path_source_documents, + fake_short_path_source_codes, + fake_short_path_source_licenses, + fake_short_path_source_settings, + }; + + const f_string_length parameter_names_length[] = { + fake_short_defines_length, + fake_short_process_length, + fake_short_settings_length, + fake_short_path_build_length, + fake_short_path_work_length, + fake_short_path_source_build_length, + fake_short_path_source_common_length, + fake_short_path_source_data_length, + fake_short_path_source_documents_length, + fake_short_path_source_codes_length, + fake_short_path_source_licenses_length, + fake_short_path_source_settings_length, + }; + + const f_string parameter_values[] = { + data.defines.string, + data.process.string, + data.settings.string, + data.path_build.string, + data.path_work.string, + data.path_source_build.string, + data.path_source_common.string, + data.path_source_data.string, + data.path_source_documents.string, + data.path_source_codes.string, + data.path_source_licenses.string, + data.path_source_settings.string, + }; + + const f_string_length parameter_values_length[] = { + data.defines.used, + data.process.used, + data.settings.used, + data.path_build.used, + data.path_work.used, + data.path_source_build.used, + data.path_source_common.used, + data.path_source_data.used, + data.path_source_documents.used, + data.path_source_codes.used, + data.path_source_licenses.used, + data.path_source_settings.used, + }; + + f_string_dynamics arguments = f_string_dynamics_initialize; + + status = fll_execute_arguments_add(fake_other_operation_build, fake_other_operation_build_length, &arguments); + + // ensure console color mode is passed to the scripts so that they can also react to color mode. + if (!f_status_is_error(status) && data.context.mode != f_color_mode_none) { + char argument[3] = { f_console_symbol_disable, 0, 0 }; + + if (data.context.mode == f_color_mode_dark) { + argument[1] = f_console_standard_short_dark[0]; + } + else if (data.context.mode == f_color_mode_light) { + argument[1] = f_console_standard_short_light[0]; + } + else if (data.context.mode == f_color_mode_no_color) { + argument[1] = f_console_standard_short_no_color[0]; + } + + status = fll_execute_arguments_add(argument, 2, &arguments); + } + + // ensure verbosity level is passed to the scripts so that they can also react to requested verbosity. + if (!f_status_is_error(status) && data.verbosity != fake_verbosity_normal) { + char argument[3] = { f_console_symbol_disable, 0, 0 }; + + if (data.verbosity == fake_verbosity_quiet) { + argument[1] = f_console_standard_short_quiet[0]; + } + else if (data.verbosity == fake_verbosity_verbose) { + argument[1] = f_console_standard_short_verbose[0]; + } + else if (data.verbosity == fake_verbosity_debug) { + argument[1] = f_console_standard_short_debug[0]; + } + + status = fll_execute_arguments_add(argument, 2, &arguments); + } + + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fll_execute_arguments_add", f_true); + + f_macro_string_dynamics_delete_simple(arguments); + return status; + } + + status = fll_execute_arguments_add_parameter_set(parameter_prefixs, parameter_prefixs_length, parameter_names, parameter_names_length, parameter_values, parameter_values_length, 12, &arguments); + + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fll_execute_arguments_add_parameter_set", f_true); + + f_macro_string_dynamics_delete_simple(arguments); + return status; + } + + f_string_dynamic path = f_string_dynamic_initialize; + + if (process_script.string[0] != '/') { + status = fl_string_dynamic_append(data.path_source_settings, &path); + } + + if (!f_status_is_error(status)) { + status = fl_string_dynamic_append(process_script, &path); + } + + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fl_string_dynamic_append", f_true); + + f_macro_string_dynamic_delete_simple(path); + return status; + } + + int results = 0; + + status = fll_execute_path(path.string, arguments, &results); + + if (f_status_is_error(status)) { + if (f_status_set_fine(status) == f_failure) { + if (data.verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to execute script: "); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s", path.string); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "."); + } + } + else { + fake_print_error(data.context, data.verbosity != fake_verbosity_quiet, f_status_set_fine(status), "fll_execute_path", f_true); + } + } + + f_macro_string_dynamic_delete_simple(path); + f_macro_string_dynamics_delete_simple(arguments); + + return status; + } +#endif // _di_fake_build_execute_process_script_ + +#ifndef _di_fake_build_operate_ + f_return_status fake_build_operate(const fake_data data) { + f_status status = f_none; + fake_build_settings settings = fake_build_settings_initialize; + + status = fake_build_settings_load(data, &settings); + + if (f_status_is_error(status)) { + fake_macro_build_settings_delete_simple(settings); + return f_status_set_error(status); + } + + status = fake_build_execute_process_script(data, settings, settings.process_pre); + if (f_status_is_error(status)) { + // @todo handle errors. + } + + // @todo: may have to process all data intended to be used in parameters, exploding them into console parameters. + // Steps: + // 1) copy sources settings to build settings + // 2) copy sources headers to build headers + // 3) if shared=yes and library sources exist, compile shared libraries and make links. + // 4) if shared=yes and program sources exist, compile shared programs. + // 5) if static=yes and library sources exist, compile static objects. + // 6) if static=yes and library sources exist, link static objects into static library (appending objects to path for static programs to compile against). + // 7) if static=yes and program sources exist, compile static programs (include any static objects). + // 8) touch build file designating that build fully completed. + + status = fake_build_execute_process_script(data, settings, settings.process_post); + if (f_status_is_error(status)) { + // @todo handle errors. + } + + fake_macro_build_settings_delete_simple(settings); + + return status; + } +#endif // _di_fake_build_operate_ + +#ifndef _di_fake_build_settings_load_ + f_return_status fake_build_settings_load(const fake_data data, fake_build_settings *settings) { f_status status = f_none; f_file file = f_file_initialize; f_string_dynamic buffer = f_string_dynamic_initialize; @@ -73,6 +304,7 @@ extern "C" { if (status == f_status_set_error(f_incomplete_utf_on_stop)) { if (data.verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data.context.error, data.context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at stop position (at "); fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%d", range.start); fl_color_print(f_standard_error, data.context.error, data.context.reset, " of settings file '"); @@ -82,6 +314,7 @@ extern "C" { } else if (status == f_status_set_error(f_incomplete_utf_on_stop)) { if (data.verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data.context.error, data.context.reset, "ENCODING ERROR: error occurred on invalid UTF-8 character at end of string (at "); fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%d", range.start); fl_color_print(f_standard_error, data.context.error, data.context.reset, " of settings file '"); @@ -254,6 +487,7 @@ extern "C" { if (f_status_is_error(status)) { if (status == f_status_set_error(f_string_too_large)) { if (data.verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: a setting in the build settings file '"); fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s", path); fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' is too long."); @@ -276,243 +510,7 @@ extern "C" { return status; } -#endif // _di_fake_build_load_settings_ - -#ifndef _di_fake_build_operate_ - f_return_status fake_build_operate(const fake_data data) { - f_status status = f_none; - fake_build_settings settings = fake_build_settings_initialize; - - status = fake_build_load_settings(data, &settings); - - if (f_status_is_error(status)) { - fake_macro_build_settings_delete_simple(settings); - return f_status_set_error(status); - } - - status = fake_build_execute_process_script(data, settings, settings.process_pre); - if (f_status_is_error(status)) { - // @todo handle errors. - } - - // @todo: may have to process all data intended to be used in parameters, exploding them into console parameters. - // Steps: - // 1) copy sources settings to build settings - // 2) copy sources headers to build headers - // 3) if shared=yes and library sources exist, compile shared libraries and make links. - // 4) if shared=yes and program sources exist, compile shared programs. - // 5) if static=yes and library sources exist, compile static objects. - // 6) if static=yes and library sources exist, link static objects into static library (appending objects to path for static programs to compile against). - // 7) if static=yes and program sources exist, compile static programs (include any static objects). - // 8) touch build file designating that build fully completed. - - status = fake_build_execute_process_script(data, settings, settings.process_post); - if (f_status_is_error(status)) { - // @todo handle errors. - } - - fake_macro_build_settings_delete_simple(settings); - - return status; - } -#endif // _di_fake_build_operate_ - -#ifndef _di_fake_build_execute_process_script_ - f_return_status fake_build_execute_process_script(const fake_data data, const fake_build_settings settings, const f_string_static process_script) { - if (process_script.used == 0) return f_none; - - f_status status = f_none; - - //fake_file_extension_built - - //if (fake_build_file_exists - - const f_string parameter_prefixs[] = { - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - f_console_symbol_short_enable, - }; - - const f_string_length parameter_prefixs_length[] = { - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - f_console_symbol_short_enable_length, - }; - - const f_string parameter_names[] = { - fake_short_defines, - fake_short_process, - fake_short_settings, - fake_short_path_build, - fake_short_path_work, - fake_short_path_source_build, - fake_short_path_source_common, - fake_short_path_source_data, - fake_short_path_source_documents, - fake_short_path_source_codes, - fake_short_path_source_licenses, - fake_short_path_source_settings, - }; - - const f_string_length parameter_names_length[] = { - fake_short_defines_length, - fake_short_process_length, - fake_short_settings_length, - fake_short_path_build_length, - fake_short_path_work_length, - fake_short_path_source_build_length, - fake_short_path_source_common_length, - fake_short_path_source_data_length, - fake_short_path_source_documents_length, - fake_short_path_source_codes_length, - fake_short_path_source_licenses_length, - fake_short_path_source_settings_length, - }; - - const f_string parameter_values[] = { - data.defines.string, - data.process.string, - data.settings.string, - data.path_build.string, - data.path_work.string, - data.path_source_build.string, - data.path_source_common.string, - data.path_source_data.string, - data.path_source_documents.string, - data.path_source_codes.string, - data.path_source_licenses.string, - data.path_source_settings.string, - }; - - const f_string_length parameter_values_length[] = { - data.defines.used, - data.process.used, - data.settings.used, - data.path_build.used, - data.path_work.used, - data.path_source_build.used, - data.path_source_common.used, - data.path_source_data.used, - data.path_source_documents.used, - data.path_source_codes.used, - data.path_source_licenses.used, - data.path_source_settings.used, - }; - - const uint8_t parameters_total = 12; - - f_string_dynamics arguments = f_string_dynamics_initialize; - - status = fll_execute_arguments_add(fake_other_operation_build, fake_other_operation_build_length, &arguments); - - // ensure console color mode is passed to the scripts so that they can also react to color mode. - if (!f_status_is_error(status) && data.context.mode != f_color_mode_none) { - char argument[3] = { f_console_symbol_disable, 0, 0 }; - - if (data.context.mode == f_color_mode_dark) { - argument[1] = f_console_standard_short_dark[0]; - } - else if (data.context.mode == f_color_mode_light) { - argument[1] = f_console_standard_short_light[0]; - } - else if (data.context.mode == f_color_mode_no_color) { - argument[1] = f_console_standard_short_no_color[0]; - } - - status = fll_execute_arguments_add(argument, 2, &arguments); - } - - // ensure verbosity level is passed to the scripts so that they can also react to requested verbosity. - if (!f_status_is_error(status) && data.verbosity != fake_verbosity_normal) { - char argument[3] = { f_console_symbol_disable, 0, 0 }; - - if (data.verbosity == fake_verbosity_quiet) { - argument[1] = f_console_standard_short_quiet[0]; - } - else if (data.verbosity == fake_verbosity_verbose) { - argument[1] = f_console_standard_short_verbose[0]; - } - else if (data.verbosity == fake_verbosity_debug) { - argument[1] = f_console_standard_short_debug[0]; - } - - status = fll_execute_arguments_add(argument, 2, &arguments); - } - - if (f_status_is_error(status)) { - fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fll_execute_arguments_add", f_true); - - f_macro_string_dynamics_delete_simple(arguments); - return status; - } - - status = fll_execute_arguments_add_parameter_set(parameter_prefixs, parameter_prefixs_length, parameter_names, parameter_names_length, parameter_values, parameter_values_length, parameters_total, &arguments); - - if (f_status_is_error(status)) { - fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fll_execute_arguments_add_parameter_set", f_true); - - f_macro_string_dynamics_delete_simple(arguments); - return status; - } - - f_string_dynamic path = f_string_dynamic_initialize; - - if (process_script.string[0] != '/') { - status = fl_string_dynamic_append(data.path_source_settings, &path); - } - - if (!f_status_is_error(status)) { - status = fl_string_dynamic_append(process_script, &path); - } - - if (f_status_is_error(status)) { - fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fl_string_dynamic_append", f_true); - - f_macro_string_dynamic_delete_simple(path); - return status; - } - - int results = 0; - - status = fll_execute_path(path.string, arguments, &results); - - if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_failure) { - if (data.verbosity != fake_verbosity_quiet) { - fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to execute script: "); - fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s", path.string); - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "."); - } - } - else { - fake_print_error(data.context, data.verbosity != fake_verbosity_quiet, f_status_set_fine(status), "fll_execute_path", f_true); - } - } - - f_macro_string_dynamic_delete_simple(path); - f_macro_string_dynamics_delete_simple(arguments); - - return status; - } -#endif // _di_fake_execute_process_pre_ +#endif // _di_fake_build_settings_load_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fake/c/private-build.h b/level_3/fake/c/private-build.h index 5ccb37b..8c22513 100644 --- a/level_3/fake/c/private-build.h +++ b/level_3/fake/c/private-build.h @@ -282,21 +282,23 @@ extern "C" { #endif // _di_fake_build_settings_ /** - * Find the build settings file, load it, validate it, and process it. + * Execute the Pre-Process or Post-pocess build script. * * @param data * The program data. * @param settings - * All build related settings data from the build settings file are loaded into this. - * These settings will have any specified mode property applied. + * All build related settings data from the build settings file. + * @param process_script + * The setting_data file name fo the appropriate process script. + * This is expected to be either settings.process_pre or settings.process_post. * * @return * f_none on success. * Status codes (with error bit) are returned on any problem. */ -#ifndef _di_fake_build_load_settings_ - extern f_return_status fake_build_load_settings(const fake_data data, fake_build_settings *settings) f_gcc_attribute_visibility_internal; -#endif // _di_fake_build_load_settings_ +#ifndef _di_fake_build_execute_process_script_ + extern f_return_status fake_build_execute_process_script(const fake_data data, const fake_build_settings settings, const f_string_static process_script) f_gcc_attribute_visibility_internal; +#endif // _di_fake_build_execute_process_script_ /** * Execute the build operation. @@ -313,23 +315,21 @@ extern "C" { #endif // _di_fake_build_operate_ /** - * Execute the Pre-Process or Post-pocess build script. + * Find the build settings file, load it, validate it, and process it. * * @param data * The program data. * @param settings - * All build related settings data from the build settings file. - * @param process_script - * The setting_data file name fo the appropriate process script. - * This is expected to be either settings.process_pre or settings.process_post. + * All build related settings data from the build settings file are loaded into this. + * These settings will have any specified mode property applied. * * @return * f_none on success. * Status codes (with error bit) are returned on any problem. */ -#ifndef _di_fake_build_execute_process_script_ - extern f_return_status fake_build_execute_process_script(const fake_data data, const fake_build_settings settings, const f_string_static process_script) f_gcc_attribute_visibility_internal; -#endif // _di_fake_build_execute_process_script_ +#ifndef _di_fake_build_settings_load_ + extern f_return_status fake_build_settings_load(const fake_data data, fake_build_settings *settings) f_gcc_attribute_visibility_internal; +#endif // _di_fake_build_settings_load_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fake/c/private-clean.c b/level_3/fake/c/private-clean.c index 61e17ba..74bc98e 100644 --- a/level_3/fake/c/private-clean.c +++ b/level_3/fake/c/private-clean.c @@ -18,10 +18,10 @@ extern "C" { } if (data.verbosity == fake_verbosity_verbose) { - status = f_directory_remove_custom(data.path_build.string, fake_directory_max_recursion, f_true, fake_clean_remove_recursively_verbosely); + status = f_directory_remove_custom(data.path_build.string, f_directory_max_recursion, f_true, fake_clean_remove_recursively_verbosely); } else { - status = f_directory_remove(data.path_build.string, fake_directory_max_recursion, f_true); + status = f_directory_remove(data.path_build.string, f_directory_max_recursion, f_true); } if (f_status_is_error(status)) { diff --git a/level_3/fake/c/private-clean.h b/level_3/fake/c/private-clean.h index df83f07..140c850 100644 --- a/level_3/fake/c/private-clean.h +++ b/level_3/fake/c/private-clean.h @@ -26,7 +26,6 @@ extern "C" { extern f_return_status fake_clean_operate(const fake_data data) f_gcc_attribute_visibility_internal; #endif // _di_fake_clean_operate_ - /** * A special function intended to be used directly by nftw(). * diff --git a/level_3/fake/c/private-fake.c b/level_3/fake/c/private-fake.c index 5ad664e..31f799f 100644 --- a/level_3/fake/c/private-fake.c +++ b/level_3/fake/c/private-fake.c @@ -42,9 +42,7 @@ extern "C" { &data->path_build_settings, }; - const uint8_t total = 7; - - for (i = 0; i < total; i++) { + for (i = 0; i < 7; i++) { status = fl_string_dynamic_append_nulless(data->path_build, parameter_values[i]); if (f_status_is_error(status)) break; @@ -84,9 +82,7 @@ extern "C" { &data->path_build_libraries_static, }; - const uint8_t total = 3; - - for (i = 0; i < total; i++) { + for (i = 0; i < 3; i++) { status = fl_string_dynamic_append_nulless(data->path_build_libraries, parameter_values[i]); if (f_status_is_error(status)) break; @@ -126,9 +122,7 @@ extern "C" { &data->path_build_programs_static, }; - const uint8_t total = 3; - - for (i = 0; i < total; i++) { + for (i = 0; i < 3; i++) { status = fl_string_dynamic_append_nulless(data->path_build_programs, parameter_values[i]); if (f_status_is_error(status)) break; @@ -163,6 +157,7 @@ extern "C" { if (status == f_invalid_parameter) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter in function "); fl_color_print(f_standard_error, context.notable, context.reset, "%s", function); fl_color_print_line(f_standard_error, context.error, context.reset, "()."); @@ -173,6 +168,7 @@ extern "C" { if (status == f_error_allocation || status == f_error_reallocation) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Unable to allocate memory in function "); fl_color_print(f_standard_error, context.notable, context.reset, "%s", function); fl_color_print_line(f_standard_error, context.error, context.reset, "()."); @@ -182,6 +178,7 @@ extern "C" { } if (fallback && verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "UNKNOWN ERROR: ("); fl_color_print(f_standard_error, context.notable, context.reset, "%d", status); fl_color_print(f_standard_error, context.error, context.reset, ") in function "); @@ -202,6 +199,7 @@ extern "C" { if (status == f_file_not_found) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -212,6 +210,7 @@ extern "C" { if (status == f_invalid_parameter) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ", function, name); fl_color_print(f_standard_error, context.notable, context.reset, "%s", function); fl_color_print(f_standard_error, context.error, context.reset, "() for the %s '", file_or_directory); @@ -224,6 +223,7 @@ extern "C" { if (status == f_invalid_name) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Invalid %s name '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -234,6 +234,7 @@ extern "C" { if (status == f_out_of_memory) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to access %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -244,6 +245,7 @@ extern "C" { if (status == f_number_overflow) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Overflow while trying to access %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -254,6 +256,7 @@ extern "C" { if (status == f_invalid_directory) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Invalid directory while trying to access %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -264,6 +267,7 @@ extern "C" { if (status == f_access_denied) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Access denied while trying to access %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -274,6 +278,7 @@ extern "C" { if (status == f_loop) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: Loop while trying to access %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -287,6 +292,7 @@ extern "C" { else { if (status == f_directory_not_found) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to find %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -297,6 +303,7 @@ extern "C" { if (status == f_no_data) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: could not find %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -307,6 +314,7 @@ extern "C" { if (status == f_failure) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: failed to read the %s '", file_or_directory); fl_color_print(f_standard_error, context.notable, context.reset, "%s", name); fl_color_print_line(f_standard_error, context.error, context.reset, "'."); @@ -317,6 +325,7 @@ extern "C" { } if (fake_print_error(context, verbosity, status, function, f_false) == f_unknown && fallback && verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "UNKNOWN ERROR: ("); fl_color_print(f_standard_error, context.notable, context.reset, "%d", status); fl_color_print(f_standard_error, context.error, context.reset, ") occurred for %s '", file_or_directory); @@ -331,6 +340,7 @@ extern "C" { #ifndef _di_fake_print_error_parameter_missing_value_ void fake_print_error_parameter_missing_value(const fl_color_context context, const uint8_t verbosity, const f_string parameter) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The parameter '"); fl_color_print(f_standard_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter); fl_color_print_line(f_standard_error, context.error, context.reset, "' was specified, but no value was given."); @@ -341,6 +351,7 @@ extern "C" { #ifndef _di_fake_print_error_parameter_too_many_ void fake_print_error_parameter_too_many(const fl_color_context context, const uint8_t verbosity, const f_string parameter) { if (verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, context.error, context.reset, "ERROR: the parameter '"); fl_color_print(f_standard_error, context.notable, context.reset, "%s%s", f_console_symbol_long_enable, parameter); fl_color_print_line(f_standard_error, context.error, context.reset, "' specified too many times."); @@ -355,8 +366,6 @@ extern "C" { // @todo move as many of the inline error printing code into more general functions where possible to provide more accurate error reporting. { - const uint8_t total = 4; - const uint8_t parameter_ids[] = { fake_parameter_operation_build, fake_parameter_operation_clean, @@ -371,9 +380,10 @@ extern "C" { fake_other_operation_skeleton, }; - for (uint8_t i = 0; i < total; i++) { + for (uint8_t i = 0; i < 4; i++) { if (data->parameters[parameter_ids[i]].total > 1) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the operation '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", parameter_names[i]); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' specified too many times."); @@ -385,8 +395,6 @@ extern "C" { } { - const uint8_t total = 2; - const uint8_t parameter_ids[] = { fake_parameter_process, fake_parameter_settings, @@ -412,7 +420,7 @@ extern "C" { &data->settings, }; - for (uint8_t i = 0; i < total; i++) { + for (uint8_t i = 0; i < 2; i++) { if (data->parameters[parameter_ids[i]].result == f_console_result_found) { fake_print_error_parameter_missing_value(data->context, data->verbosity, parameter_names[i]); return f_status_set_error(f_invalid_parameter); @@ -432,6 +440,7 @@ extern "C" { if (f_status_is_error(status)) { if (status == f_status_set_error(f_string_too_large)) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is too long."); @@ -450,6 +459,7 @@ extern "C" { if (length == 0 || status == f_no_data) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' must not be empty and must not contain only whitespace."); @@ -476,8 +486,6 @@ extern "C" { } { - const uint8_t total = 9; - const uint8_t parameter_ids[] = { fake_parameter_path_build, fake_parameter_path_source_build, @@ -526,18 +534,6 @@ extern "C" { fake_default_path_work_length, }; - const bool parameters_required[] = { - f_true, - f_true, - f_true, - f_false, - f_true, - f_false, - f_false, - f_false, - f_false, - }; - f_string_dynamic *parameter_values[] = { &data->path_build, &data->path_source_build, @@ -550,7 +546,7 @@ extern "C" { &data->path_work, }; - for (uint8_t i = 0; i < total; i++) { + for (uint8_t i = 0; i < 9; i++) { if (data->parameters[parameter_ids[i]].result == f_console_result_found) { fake_print_error_parameter_missing_value(data->context, data->verbosity, parameter_names[i]); return f_status_set_error(f_invalid_parameter); @@ -565,6 +561,7 @@ extern "C" { if (f_status_is_error(status)) { if (fake_print_error(data->context, data->verbosity, f_status_set_fine(status), "fl_console_parameter_to_string_dynamic_directory", f_false) == f_unknown && data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: failed to process parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); @@ -578,6 +575,7 @@ extern "C" { if (f_status_is_error(status)) { if (fake_print_error(data->context, data->verbosity, f_status_set_fine(status), "f_macro_string_dynamic_new", f_false) == f_unknown && data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: failed to load default for the parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); @@ -589,30 +587,6 @@ extern "C" { memcpy(parameter_values[i]->string, parameter_defaults[i], parameter_default_lengths[i]); parameter_values[i]->used = parameter_default_lengths[i]; } - - if (parameter_values[i]->used > 0) { - struct stat directory_stat; - - memset(&directory_stat, 0, sizeof(struct stat)); - - status = f_file_stat(parameter_values[i]->string, &directory_stat); - - if (status == f_status_set_error(f_file_not_found)) status = f_status_set_error(f_directory_not_found); - - if (f_status_is_error(status)) { - if (f_status_set_fine(status) != f_directory_not_found || parameters_required[i]) { - fake_print_error_file(data->context, data->verbosity, f_status_set_fine(status), "f_file_stat", parameter_values[i]->string, f_false, f_true); - return status; - } - } - } - else if (parameters_required[i]) { - fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: No valid path for the (required) directory parameter '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' was found."); - - return f_status_set_error(f_directory_not_found); - } } // for } @@ -622,6 +596,7 @@ extern "C" { if (f_status_is_error(status)) { if (status == f_status_set_error(f_string_too_large)) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the (combined) parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, fake_long_defines); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' is too long."); @@ -644,6 +619,7 @@ extern "C" { if (f_status_is_error(status)) { if (fake_print_error(data->context, data->verbosity, f_status_set_fine(status), "fll_program_parameter_additional_rip", f_false) == f_unknown && data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: failed to process the parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, fake_long_mode); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); @@ -664,6 +640,7 @@ extern "C" { if (f_status_is_error(status)) { if (fake_print_error(data->context, data->verbosity, f_status_set_fine(status), "f_utf_is_word_dash_plus", f_false) == f_unknown && data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: failed to process the parameter '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, fake_long_mode); fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); @@ -674,6 +651,7 @@ extern "C" { if (status == f_false) { if (data->verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, fake_long_mode); fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameters value '"); @@ -691,6 +669,112 @@ extern "C" { } #endif // _di_fake_process_console_parameters_ +#ifndef _di_fake_validate_directories_ + f_return_status fake_validate_parameter_directories(const f_console_arguments arguments, const fake_data data) { + const uint8_t parameter_ids[] = { + fake_parameter_path_build, + fake_parameter_path_source_build, + fake_parameter_path_source_codes, + fake_parameter_path_source_common, + fake_parameter_path_source_data, + fake_parameter_path_source_documents, + fake_parameter_path_source_licenses, + fake_parameter_path_source_settings, + fake_parameter_path_work, + }; + + const f_string parameter_names[] = { + fake_long_path_build, + fake_long_path_source_build, + fake_long_path_source_codes, + fake_long_path_source_common, + fake_long_path_source_data, + fake_long_path_source_documents, + fake_long_path_source_licenses, + fake_long_path_source_settings, + fake_long_path_work, + }; + + const f_string parameter_defaults[] = { + fake_default_path_build, + fake_default_path_source_build, + fake_default_path_source_codes, + fake_default_path_source_common, + fake_default_path_source_data, + fake_default_path_source_documents, + fake_default_path_source_licenses, + fake_default_path_source_settings, + fake_default_path_work, + }; + + const f_string_length parameter_default_lengths[] = { + fake_default_path_build_length, + fake_default_path_source_build_length, + fake_default_path_source_codes_length, + fake_default_path_source_common_length, + fake_default_path_source_data_length, + fake_default_path_source_documents_length, + fake_default_path_source_licenses_length, + fake_default_path_source_settings_length, + fake_default_path_work_length, + }; + + const bool parameters_required[] = { + f_true, + f_true, + f_true, + f_false, + f_true, + f_false, + f_false, + f_false, + f_false, + }; + + const f_string_dynamic *parameter_values[] = { + &data.path_build, + &data.path_source_build, + &data.path_source_codes, + &data.path_source_common, + &data.path_source_data, + &data.path_source_documents, + &data.path_source_licenses, + &data.path_source_settings, + &data.path_work, + }; + + struct stat directory_stat; + f_status status = f_none; + + for (uint8_t i = 0; i < 9; i++) { + if (parameter_values[i]->used > 0) { + memset(&directory_stat, 0, sizeof(struct stat)); + + status = f_file_stat(parameter_values[i]->string, &directory_stat); + + if (status == f_status_set_error(f_file_not_found)) status = f_status_set_error(f_directory_not_found); + + if (f_status_is_error(status)) { + if (f_status_set_fine(status) != f_directory_not_found || parameters_required[i]) { + fake_print_error_file(data.context, data.verbosity, f_status_set_fine(status), "f_file_stat", parameter_values[i]->string, f_false, f_true); + return status; + } + } + } + else if (parameters_required[i]) { + fprintf(f_standard_error, "%c", f_string_eol); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: No valid path for the (required) directory parameter '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s%s", f_console_symbol_long_enable, parameter_names[i]); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' was found."); + + return f_status_set_error(f_directory_not_found); + } + } // for + + return f_none; + } +#endif // _di_fake_validate_parameter_directories_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/c/private-fake.h b/level_3/fake/c/private-fake.h index 2e9092e..4b34936 100644 --- a/level_3/fake/c/private-fake.h +++ b/level_3/fake/c/private-fake.h @@ -118,6 +118,24 @@ extern "C" { extern f_return_status fake_process_console_parameters(const f_console_arguments arguments, fake_data *data) f_gcc_attribute_visibility_internal; #endif // _di_validate_console_parameters_ +/** + * Validate directories and print any relating error messages. + * + * This should not be called for skeleton as in that case the directories probably do not exist. + * + * @param arguments + * The parameters passed to the process. + * @param data + * The program data. + * + * @return + * f_none on success. + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_validate_parameter_directories_ + extern f_return_status fake_validate_parameter_directories(const f_console_arguments arguments, const fake_data data) f_gcc_attribute_visibility_internal; +#endif // _di_fake_validate_parameter_directories_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/c/private-skeleton.c b/level_3/fake/c/private-skeleton.c index 7e1d1ff..65879a4 100644 --- a/level_3/fake/c/private-skeleton.c +++ b/level_3/fake/c/private-skeleton.c @@ -6,6 +6,175 @@ extern "C" { #endif +#ifndef _di_fake_skeleton_operate_ + f_return_status fake_skeleton_operate(const fake_data data) { + f_status status = f_none; + + if (data.verbosity != fake_verbosity_quiet) { + printf("%c", f_string_eol); + fl_color_print_line(f_standard_output, data.context.important, data.context.reset, "Generating skeleton structure."); + } + + status = fake_skeleton_operate_directory_create(data, fake_path_documents); + if (f_status_is_error(status)) return status; + + status = fake_skeleton_operate_directory_create(data, fake_path_data); + if (f_status_is_error(status)) return status; + + status = fake_skeleton_operate_directory_create(data, fake_path_licenses); + if (f_status_is_error(status)) return status; + + status = fake_skeleton_operate_directory_create(data, fake_path_sources); + if (f_status_is_error(status)) return status; + + { + const f_string_static parameter_strings[] = { + data.path_build, + data.path_build_documents, + data.path_build_includes, + data.path_build_libraries, + data.path_build_libraries_script, + data.path_build_libraries_shared, + data.path_build_libraries_static, + data.path_build_objects, + data.path_build_process, + data.path_build_programs, + data.path_build_programs_script, + data.path_build_programs_shared, + data.path_build_programs_static, + data.path_build_settings, + data.path_work, + data.path_source_build, + data.path_source_common, + data.path_source_data, + data.path_source_documents, + data.path_source_codes, + data.path_source_licenses, + data.path_source_settings, + }; + + // @todo this needs to create parent directories as well, for some paths. + for (f_array_length i = 0; i < 22; i++) { + if (parameter_strings[i].used == 0) continue; + + status = fake_skeleton_operate_directory_create(data, parameter_strings[i].string); + if (f_status_is_error(status)) return status; + } // for + } + + if (data.path_work.used > 0) { + const f_string parameter_strings[] = { + fake_path_work_includes, + fake_path_work_libraries, + fake_path_work_libraries_script, + fake_path_work_libraries_shared, + fake_path_work_libraries_static, + fake_path_work_programs, + fake_path_work_programs_script, + fake_path_work_programs_shared, + fake_path_work_programs_static, + }; + + const uint8_t parameter_strings_length[] = { + fake_path_work_includes_length, + fake_path_work_libraries_length, + fake_path_work_libraries_script_length, + fake_path_work_libraries_shared_length, + fake_path_work_libraries_static_length, + fake_path_work_programs_length, + fake_path_work_programs_script_length, + fake_path_work_programs_shared_length, + fake_path_work_programs_static_length, + }; + + f_string_dynamic path = f_string_dynamic_initialize; + + status = fl_string_dynamic_append_nulless(data.path_work, &path); + if (f_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(path); + return status; + } + + for (f_array_length i = 0; i < 9; i++) { + path.used = data.path_work.used; + + status = fl_string_append_nulless(parameter_strings[i], parameter_strings_length[i], &path); + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fl_string_dynamic_append_nulless", f_true); + f_macro_string_dynamic_delete_simple(path); + return status; + } + + status = fl_string_dynamic_terminate(&path); + if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "fl_string_dynamic_terminate", f_true); + f_macro_string_dynamic_delete_simple(path); + return status; + } + + status = fake_skeleton_operate_directory_create(data, path.string); + if (f_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(path); + return status; + } + } // for + + f_macro_string_dynamic_delete_simple(path); + } + + return f_none; + } +#endif // _di_fake_skeleton_operate_ + +#ifndef _di_fake_skeleton_operate_directory_create_ + f_return_status fake_skeleton_operate_directory_create(const fake_data data, const f_string path) { + f_status status = f_none; + + status = f_directory_is(path); + if (status == f_true) { + if (data.verbosity == fake_verbosity_verbose) { + printf("Directory '%s' already exists.%c", path, f_string_eol); + } + } + else if (status == f_false) { + if (data.verbosity != fake_verbosity_quiet) { + fprintf(f_standard_error, "%c", f_string_eol); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The path '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s", path); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' exists but is not a directory."); + } + + return f_status_set_error(f_failure); + } + else if (status == f_file_not_found) { + status = f_directory_create(path, f_file_mode_all_rwx); + + if (f_status_is_error(status)) { + if (f_status_set_fine(status) == f_file_not_found) { + fprintf(f_standard_error, "%c", f_string_eol); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The path '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%s", path); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' could not be created, a parent directory does not exist."); + } + else { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "f_directory_create", f_true); + } + + return status; + } + + if (data.verbosity == fake_verbosity_verbose) { + printf("Directory '%s' created.%c", path, f_string_eol); + } + } + else if (f_status_is_error(status)) { + fake_print_error(data.context, data.verbosity, f_status_set_fine(status), "f_directory_is", f_true); + return status; + } + + return f_none; + } +#endif // _di_fake_skeleton_operate_directory_create_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fake/c/private-skeleton.h b/level_3/fake/c/private-skeleton.h index f9d2ff8..f078ed3 100644 --- a/level_3/fake/c/private-skeleton.h +++ b/level_3/fake/c/private-skeleton.h @@ -12,6 +12,36 @@ extern "C" { #endif +/** + * Execute the skeleton operation. + * + * @param data + * The program data. + * + * @return + * f_none on success. + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_skeleton_operate_ + extern f_return_status fake_skeleton_operate(const fake_data data) f_gcc_attribute_visibility_internal; +#endif // _di_fake_keleton_operate_ + +/** + * Create a directory if it does not exist, ignore it if it does, and error if path exists but is not a directory. + * + * @param data + * The program data. + * @param path + * The file path for the directory to create. + * + * @return + * f_none on success. + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_skeleton_operate_directory_create_ + extern f_return_status fake_skeleton_operate_directory_create(const fake_data data, const f_string path) f_gcc_attribute_visibility_internal; +#endif // _di_fake_skeleton_operate_directory_create_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/data/build/dependencies b/level_3/fake/data/build/dependencies index c7ca115..c3e5a15 100644 --- a/level_3/fake/data/build/dependencies +++ b/level_3/fake/data/build/dependencies @@ -7,6 +7,7 @@ f_console f_conversion f_fss f_file +f_path f_print f_utf fl_color