From: Kevin Day Date: Thu, 23 Dec 2021 21:45:37 +0000 (-0600) Subject: Cleanup: Move the process and validate functions into their own files. X-Git-Tag: 0.5.7~2 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=124d655b62269678914626d924d76dd454adbdf1;p=fll Cleanup: Move the process and validate functions into their own files. As for the naming structure, the "make" represents the group and the "operate", "operate_process", etc.. are relevant parts of the function name. --- diff --git a/level_3/fake/c/private-make-load_fakefile.c b/level_3/fake/c/private-make-load_fakefile.c index f1de9a8..5a561ac 100644 --- a/level_3/fake/c/private-make-load_fakefile.c +++ b/level_3/fake/c/private-make-load_fakefile.c @@ -6,7 +6,7 @@ #include "private-clean.h" #include "private-make.h" #include "private-make-load_fakefile.h" -#include "private-make-operate.h" +#include "private-make-operate_validate.h" #include "private-print.h" #include "private-skeleton.h" diff --git a/level_3/fake/c/private-make-operate.c b/level_3/fake/c/private-make-operate.c index 7dc30cc..2ae52f6 100644 --- a/level_3/fake/c/private-make-operate.c +++ b/level_3/fake/c/private-make-operate.c @@ -7,7 +7,9 @@ #include "private-make-load_parameters.h" #include "private-make-load_fakefile.h" #include "private-make-operate.h" -#include "private-make-operate-type.h" +#include "private-make-operate_process.h" +#include "private-make-operate_process_type.h" +#include "private-make-operate_validate.h" #include "private-print.h" #include "private-skeleton.h" @@ -1410,2133 +1412,6 @@ extern "C" { } #endif // _di_fake_make_operate_section_ -#ifndef _di_fake_make_operate_process_ - int fake_make_operate_process(fake_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, const bool success, fake_state_process_t *state_process, f_array_lengths_t *section_stack, f_status_t *status) { - - if (*status == F_child) return data_make->main->child; - - if (state_process->operation == fake_make_operation_type_index) { - const f_status_t result = fake_execute(data_make->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; - } - - *status = fake_make_operate_process_return(data_make, result); - - return 0; - } - - if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { - flockfile(data_make->main->output.to.stream); - - fl_print_format("%cBreaking as '", data_make->main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%S%]", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, data_make->main->context.set.notable); - fl_print_format("'.%c", data_make->main->output.to.stream, f_string_eol_s[0]); - - funlockfile(data_make->main->output.to.stream); - } - - return 0; - } - - if (state_process->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, data_make->main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_clean) { - *status = fake_clean_operate(data_make->main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_clone) { - *status = fake_make_operate_process_type_copy(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_compile) { - const int result = fake_execute(data_make->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; - } - - *status = fake_make_operate_process_return(data_make, result); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_copy) { - *status = fake_make_operate_process_type_copy(data_make, arguments, F_false); - - return 0; - } - - if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cDefined environment variable '%[%Q%]'.%c", data_make->main->output.to.stream, f_string_eol_s[0], data_make->main->context.set.notable, arguments.array[0], data_make->main->context.set.notable, f_string_eol_s[0]); - } - - return 0; - } - - if (state_process->operation == fake_make_operation_type_delete) { - *status = fake_make_operate_process_type_deletes(data_make, arguments, F_false); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_deletes) { - *status = fake_make_operate_process_type_deletes(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_else) { - - // Setup the block so that subsequent operations can know the current block and the result (which is preserved across to the else condition). - state_process->block = fake_make_operation_if_type_else; - - return 0; - } - - if (state_process->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 = data_make->main->context.set.error; - data_make->error.notable = data_make->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 = &data_make->main->context.set; - } - else { - return 0; - } - - if (data_make->main->error.verbosity == f_console_verbosity_verbose) { - fll_print_format("%cExiting as '%[%S%]'.%c", data_make->main->output.to.stream, f_string_eol_s[0], data_make->main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, data_make->main->context.set.notable, f_string_eol_s[0]); - } - - return 0; - } - - if (state_process->operation == fake_make_operation_type_fail) { - fake_make_operate_process_type_fail(data_make, arguments); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_group) { - *status = fake_make_operate_process_type_groups(data_make, arguments, F_false); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_groups) { - *status = fake_make_operate_process_type_groups(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_if || state_process->operation == fake_make_operation_type_and || state_process->operation == fake_make_operation_type_or) { - if (state_process->condition == fake_make_operation_if_type_if_success) { - if (success) { - state_process->condition_result = fake_condition_result_true; - } - else { - state_process->condition_result = fake_condition_result_false; - } - } - else if (state_process->condition == fake_make_operation_if_type_if_defined) { - fake_make_operate_process_type_if_defined(data_make, arguments, F_false, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_exists) { - *status = fake_make_operate_process_type_if_exists(data_make, arguments, F_false, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_failure) { - if (success) { - state_process->condition_result = fake_condition_result_false; - } - else { - state_process->condition_result = fake_condition_result_true; - } - } - else if (state_process->condition == fake_make_operation_if_type_if_group) { - *status = fake_make_operate_process_type_if_group(data_make, arguments, F_false, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_is) { - *status = fake_make_operate_process_type_if_is(data_make, arguments, F_false, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_mode) { - *status = fake_make_operate_process_type_if_mode(data_make, arguments, F_false, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_defined) { - fake_make_operate_process_type_if_defined(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_equal) { - state_process->condition_result = fake_condition_result_true; - - 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) { - state_process->condition_result = fake_condition_result_false; - - break; - } - } // for - } - else if (state_process->condition == fake_make_operation_if_type_if_equal_not) { - state_process->condition_result = fake_condition_result_true; - - 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) { - state_process->condition_result = fake_condition_result_false; - i = arguments.used; - - break; - } - } // for - } // for - } - else if (state_process->condition == fake_make_operation_if_type_if_greater || state_process->condition == fake_make_operation_if_type_if_greater_equal || state_process->condition == fake_make_operation_if_type_if_less || state_process->condition == fake_make_operation_if_type_if_less_equal) { - *status = fake_make_operate_process_type_if_greater_if_lesser(data_make, arguments, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_exists) { - *status = fake_make_operate_process_type_if_exists(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_group) { - *status = fake_make_operate_process_type_if_group(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_is) { - *status = fake_make_operate_process_type_if_is(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_mode) { - *status = fake_make_operate_process_type_if_mode(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_not_owner) { - *status = fake_make_operate_process_type_if_owner(data_make, arguments, F_true, state_process); - } - else if (state_process->condition == fake_make_operation_if_type_if_owner) { - *status = fake_make_operate_process_type_if_owner(data_make, arguments, F_false, state_process); - } - - // Setup the block for subsequent operations. - state_process->block = fake_make_operation_if_type_if; - - if (state_process->condition_result == fake_condition_result_done || state_process->operation == fake_make_operation_type_if) { - state_process->block_result = state_process->condition_result; - } - else if (state_process->operation == fake_make_operation_type_or) { - if (state_process->block_result == fake_condition_result_true || state_process->condition_result == fake_condition_result_true) { - state_process->block_result = fake_condition_result_true; - } - else { - state_process->block_result = fake_condition_result_false; - } - } - else { - if (state_process->block_result == fake_condition_result_true && state_process->condition_result == fake_condition_result_true) { - state_process->block_result = fake_condition_result_true; - } - else { - state_process->block_result = fake_condition_result_false; - } - } - - return 0; - } - - if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { - flockfile(data_make->main->output.to.stream); - - fl_print_format("Created symbolic link from '%[%Q%]", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.array[1], data_make->main->context.set.notable); - fl_print_format("' to %[%Q%].%c", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.array[0], data_make->main->context.set.notable, f_string_eol_s[0]); - - funlockfile(data_make->main->output.to.stream); - } - - return 0; - } - - if (state_process->operation == fake_make_operation_type_mode) { - *status = fake_make_operate_process_type_modes(data_make, arguments, F_false); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_modes) { - *status = fake_make_operate_process_type_modes(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_move) { - *status = fake_make_operate_process_type_move(data_make, arguments); - - return 0; - } - - if (state_process->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(data_make, id_section, section_stack, status); - - // Ensure that a break only happens within its active state_process->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 (state_process->operation == fake_make_operation_type_owner) { - *status = fake_make_operate_process_type_owners(data_make, arguments, F_false); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_owners) { - *status = fake_make_operate_process_type_owners(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_parameter) { - *status = fake_make_operate_process_type_parameter(data_make, arguments); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_pop) { - *status = fake_make_operate_process_type_pop(data_make, arguments); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_print) { - flockfile(data_make->main->output.to.stream); - - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - f_print_dynamic(arguments.array[i], data_make->main->output.to.stream); - - if (i + 1 < arguments.used) { - f_print_character(f_string_space_s[0], data_make->main->output.to.stream); - } - } // for - - f_print_character(f_string_space_s[0], data_make->main->output.to.stream); - f_print_character(f_string_eol_s[0], data_make->main->output.to.stream); - - funlockfile(data_make->main->output.to.stream); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_run) { - *status = fake_make_operate_process_run(data_make, arguments, F_false); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_shell) { - *status = fake_make_operate_process_run(data_make, arguments, F_true); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_skeleton) { - *status = fake_skeleton_operate(data_make->main); - - if (F_status_set_fine(*status) == F_interrupt) { - return 0; - } - - *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_to) { - *status = fake_make_operate_process_type_to(data_make, arguments); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_top) { - *status = fake_make_operate_process_type_top(data_make, arguments); - - return 0; - } - - if (state_process->operation == fake_make_operation_type_touch) { - *status = fake_make_operate_process_type_touch(data_make, arguments); - } - - return 0; - } -#endif // _di_fake_make_operate_process_ - -#ifndef _di_fake_make_operate_process_execute_ - f_status_t fake_make_operate_process_execute(fake_make_data_t * const data_make, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell) { - - if (fake_signal_received(data_make->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { - flockfile(data_make->main->output.to.stream); - - f_print_dynamic_safely(program, data_make->main->output.to.stream); - - for (f_array_length_t i = 0; i < arguments.used; ++i) { - - if (arguments.array[i].used) { - fll_print_format(" %Q", data_make->main->output.to.stream, arguments.array[i]); - } - } // for - - f_print_character(f_string_eol_s[0], data_make->main->output.to.stream); - - funlockfile(data_make->main->output.to.stream); - - // flush to stdout before executing command. - fflush(data_make->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(data_make->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); - } - } - - return fake_make_operate_process_return(data_make, return_code); - } -#endif // _di_fake_make_operate_process_execute_ - -#ifndef _di_fake_make_operate_process_return_ - f_status_t fake_make_operate_process_return(fake_make_data_t * const data_make, const int return_code) { - - f_status_t status = F_none; - - data_make->setting_make.parameter.array[0].value.array[0].used = 0; - - if (!return_code) { - if (F_status_is_error(status)) { - status = f_string_append("1", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - else { - status = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_string_append", F_true); - } - - return status; - } - - if (return_code) { - f_string_dynamic_t number = f_string_dynamic_t_initialize; - - status = f_conversion_number_signed_to_string(WEXITSTATUS(return_code), f_conversion_data_base_10_s, &number); - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_conversion_number_signed_to_string", F_true); - - f_string_dynamic_resize(0, &number); - - return status; - } - - status = f_string_dynamic_append(number, &data_make->setting_make.parameter.array[0].value.array[0]); - - f_string_dynamic_resize(0, &number); - } - else { - status = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); - } - - if (F_status_is_error(status)) { - fll_error_print(data_make->error, F_status_set_fine(status), "f_string_append", F_true); - - return status; - } - - 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(data_make->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - return status; - } - - 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) { - return F_status_set_error(F_failure); - } - - return 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_make_data_t * const data_make, const f_string_statics_t arguments, const bool as_shell) { - - 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); - - f_string_dynamics_resize(0, &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); - - f_string_dynamics_resize(0, &args); - - return status; - } - - ++args.used; - } // for - } - - status = fake_make_operate_process_execute(data_make, *program, args, as_shell); - - f_string_dynamics_resize(0, &args); - - return status; - } -#endif // _di_fake_make_operate_process_run_ - -#ifndef _di_fake_make_operate_validate_ - void fake_make_operate_validate(fake_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, fake_state_process_t *state_process, f_array_lengths_t *section_stack, f_status_t *status) { - - if (F_status_is_error(*status)) return; - - if (state_process->operation == fake_make_operation_type_index || state_process->operation == fake_make_operation_type_run || state_process->operation == fake_make_operation_type_shell) { - if (!arguments.used) { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - else if (state_process->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 (state_process->operation == fake_make_operation_type_break) { - if (arguments.used > 1) { - fake_print_error_too_many_arguments(data_make); - - *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 (state_process->operation == fake_make_operation_type_build) { - if (arguments.used > 1) { - fake_print_error_too_many_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - else if (arguments.used) { - if (arguments.array[0].used) { - char path_file[data_make->main->path_data_build.used + arguments.array[0].used + 1]; - - memcpy(path_file, data_make->main->path_data_build.string, data_make->main->path_data_build.used); - memcpy(path_file + data_make->main->path_data_build.used, arguments.array[0].string, arguments.array[0].used); - - path_file[data_make->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 (state_process->operation == fake_make_operation_type_clean || state_process->operation == fake_make_operation_type_pop || state_process->operation == fake_make_operation_type_top || state_process->operation == fake_make_operation_type_skeleton) { - if (arguments.used) { - fake_print_error_too_many_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - else if (state_process->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 (state_process->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(data_make, arguments.array[i]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_compile) { - if (!arguments.used) { - fake_print_error_requires_more_arguments(data_make); - - *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 (state_process->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(data_make, arguments.array[i]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_delete || state_process->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(data_make, arguments.array[i]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_else) { - if (state_process->block == fake_make_operation_if_type_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%[%SMust not be used immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_else_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 (state_process->operation_previous == fake_make_operation_type_if || state_process->operation_previous == fake_make_operation_type_and || state_process->operation_previous == fake_make_operation_type_or) { - 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 immediately after 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); - fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); - fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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 (state_process->block != fake_make_operation_if_type_done) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - fl_print_format("%c%[%SHas no preceding '%]", 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_if_s, data_make->error.notable); - fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); - fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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]); - } - - *status = F_status_set_error(F_failure); - - return; - } - - if (arguments.used) { - fake_print_error_too_many_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_exit) { - if (arguments.used > 1) { - fake_print_error_too_many_arguments(data_make); - - *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 (state_process->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_group || state_process->operation == fake_make_operation_type_groups || state_process->operation == fake_make_operation_type_mode || state_process->operation == fake_make_operation_type_modes || state_process->operation == fake_make_operation_type_owner || state_process->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; - } - - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - - return; - } - - if (state_process->operation == fake_make_operation_type_if || state_process->operation == fake_make_operation_type_and || state_process->operation == fake_make_operation_type_or) { - if (state_process->operation == fake_make_operation_type_if) { - if (state_process->block == fake_make_operation_type_if) { - 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 immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); - fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); - fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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; - } - } - else { - if (!(state_process->operation_previous == fake_make_operation_type_if || state_process->operation_previous == fake_make_operation_type_and || state_process->operation_previous == fake_make_operation_type_or)) { - if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { - flockfile(data_make->error.to.stream); - - fl_print_format("%c%[%SMay only be used immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); - fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); - fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); - fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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 (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_not_s, - fake_make_operation_argument_if_defined_s, // If not defined, represented by just "defined". - fake_make_operation_argument_if_exists_s, // If not exists, represented by just "exists". - fake_make_operation_argument_if_group_s, // If not group, represented by just "group". - fake_make_operation_argument_if_is_s, // If not is, represented by just "is". - fake_make_operation_argument_if_mode_s, // If not mode, represented by just "mode". - fake_make_operation_argument_if_owner_s, // If not owner, represented by just "owner". - 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_not_s_length, - fake_make_operation_argument_if_defined_s_length, // if not defined, represented by just "defined". - fake_make_operation_argument_if_exists_s_length, // if not exists, represented by just "exists". - fake_make_operation_argument_if_group_s_length, // if not group, represented by just "group". - fake_make_operation_argument_if_is_s_length, // if not is, represented by just "is". - fake_make_operation_argument_if_mode_s_length, // if not mode, represented by just "mode". - fake_make_operation_argument_if_owner_s_length, // if not owner, represented by just "owner". - 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_not, - fake_make_operation_if_type_if_not_defined, - fake_make_operation_if_type_if_not_exists, - fake_make_operation_if_type_if_not_group, - fake_make_operation_if_type_if_not_is, - fake_make_operation_if_type_if_not_mode, - fake_make_operation_if_type_if_not_owner, - fake_make_operation_if_type_if_owner, - fake_make_operation_if_type_if_success, - }; - - const uint8_t if_type_minimum[] = { - 3, // If defined. - 2, // If equal (==). - 2, // If equal not (<>). - 2, // If exists. - 1, // If failure. - 2, // If greater (>). - 2, // If greater equal (>=). - 3, // If group. - 3, // If is. - 2, // If less (<). - 2, // If less equal (<=). - 4, // If mode. - 3, // If not. - 5, // If not defined. - 3, // If not exists. - 4, // If not group. - 4, // If not is. - 5, // If not mode. - 4, // If not owner. - 3, // If owner. - 1, // If success. - }; - - const f_string_t if_not_type_strings[] = { - fake_make_operation_argument_if_defined_s, - fake_make_operation_argument_if_exists_s, - fake_make_operation_argument_if_group_s, - fake_make_operation_argument_if_is_s, - fake_make_operation_argument_if_mode_s, - fake_make_operation_argument_if_owner_s, - }; - - const f_array_length_t if_not_type_lengths[] = { - fake_make_operation_argument_if_defined_s_length, - fake_make_operation_argument_if_exists_s_length, - fake_make_operation_argument_if_group_s_length, - fake_make_operation_argument_if_is_s_length, - fake_make_operation_argument_if_mode_s_length, - fake_make_operation_argument_if_owner_s_length, - }; - - const uint8_t if_not_type_codes[] = { - fake_make_operation_if_type_if_not_defined, - fake_make_operation_if_type_if_not_exists, - fake_make_operation_if_type_if_not_group, - fake_make_operation_if_type_if_not_is, - fake_make_operation_if_type_if_not_mode, - fake_make_operation_if_type_if_not_owner, - }; - - const uint8_t if_not_type_minimum[] = { - 4, // If not defined. - 3, // If not exists. - 4, // If not group. - 4, // If not is. - 5, // If not mode. - 4, // If not owner. - }; - - f_array_length_t i = 0; - f_array_length_t j = 0; - f_string_t if_and_or; - - if (state_process->operation == fake_make_operation_type_and) { - if_and_or = fake_make_operation_and_s; - } - else if (state_process->operation == fake_make_operation_type_or) { - if_and_or = fake_make_operation_or_s; - } - else { - if_and_or = fake_make_operation_if_s; - } - - for (; i < 21; ++i) { - - // Skip the "if not XXX" types as they are determined later on. - if (i > 12 && i < 19) continue; - - if (fl_string_dynamic_compare_string(if_type_strings[i], arguments.array[0], if_type_lengths[i]) == F_equal_to) { - state_process->condition = if_type_codes[i]; - - break; - } - } // for - - if (i == 21) { - 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 '%s' type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, if_and_or, 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; - } - - // Identify and convert to the appropriate if not condition. - if (state_process->condition == fake_make_operation_if_type_if_not) { - if (arguments.used < 2) { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - - return; - } - - for (; j < 6; ++j) { - - if (fl_string_dynamic_compare_string(if_not_type_strings[j], arguments.array[1], if_not_type_lengths[j]) == F_equal_to) { - state_process->condition = if_not_type_codes[j]; - - break; - } - } // for - - if (j == 6) { - 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 '%s' not type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, if_and_or, 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; - } - } - else { - j = 6; - } - - if (j == 6 && arguments.used >= if_type_minimum[i] || arguments.used >= if_not_type_minimum[j]) { - if (state_process->condition == fake_make_operation_if_type_if_success || state_process->condition == fake_make_operation_if_type_if_failure) { - - // The success and failure operations minimum is also the maximum. - if (arguments.used > if_type_minimum[i]) { - fake_print_error_too_many_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->condition == fake_make_operation_if_type_if_defined || state_process->condition == fake_make_operation_if_type_if_not_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; - } - else if (state_process->condition == fake_make_operation_if_type_if_equal || state_process->condition == fake_make_operation_if_type_if_equal_not) { - if (arguments.used < 3) { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - else if (state_process->condition == fake_make_operation_if_type_if_exists || state_process->condition == fake_make_operation_if_type_if_not_exists) { - return; - } - else if (state_process->condition == fake_make_operation_if_type_if_group || state_process->condition == fake_make_operation_if_type_if_is || state_process->condition == fake_make_operation_if_type_if_mode || state_process->condition > fake_make_operation_if_type_if_not_exists && state_process->condition < fake_make_operation_if_type_if_success) { - - if (state_process->condition == fake_make_operation_if_type_if_mode || state_process->condition == fake_make_operation_if_type_if_not_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 %smode type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, j == 6 ? "" : "not ", 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(data_make->main, data_make->error, j == 6 ? arguments.array[2] : arguments.array[3], &mode_rule, &replace); - if (F_status_is_error(*status)) return; - - i = j == 6 ? 3 : 4; - } - else if (state_process->condition == fake_make_operation_if_type_if_group || state_process->condition == fake_make_operation_if_type_if_not_group) { - gid_t id = 0; - - *status = fake_make_get_id_group(data_make->main, data_make->error, j == 6 ? arguments.array[1] : arguments.array[2], &id); - if (F_status_is_error(*status)) return; - - i = j == 6 ? 2 : 3; - } - else if (state_process->condition == fake_make_operation_if_type_if_is || state_process->condition == fake_make_operation_if_type_if_not_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 = j == 6 ? 1 : 2; 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); - - return; - } - } - else if (state_process->condition == fake_make_operation_if_type_if_owner || state_process->condition == fake_make_operation_if_type_if_not_owner) { - uid_t id = 0; - - *status = fake_make_get_id_owner(data_make->main, data_make->error, arguments.array[1], &id); - if (F_status_is_error(*status)) return; - - i = j == 6 ? 2 : 3; - } - - if (i < arguments.used) { - for (f_status_t status_file = F_none; i < arguments.used; ++i) { - - status_file = fake_make_assure_inside_project(data_make, arguments.array[i]); - - if (F_status_is_error(status_file)) { - fake_print_message_section_operation_path_outside(data_make->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); - - 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 (state_process->condition != fake_make_operation_if_type_if_exists && state_process->condition != 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); - - if (F_status_is_error_not(*status)) { - *status = F_status_set_error(status_file); - } - } - } - } // for - } - } - else if (state_process->condition == fake_make_operation_if_type_if_greater || state_process->condition == fake_make_operation_if_type_if_greater_equal || state_process->condition == fake_make_operation_if_type_if_less || state_process->condition == fake_make_operation_if_type_if_less_equal) { - if (arguments.used < 3) { - fake_print_error_requires_more_arguments(data_make); - - *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; - } - - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - - return; - } - - if (state_process->operation == fake_make_operation_type_link) { - if (arguments.used > 2) { - fake_print_error_too_many_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - else if (arguments.used == 2) { - *status = fake_make_assure_inside_project(data_make, arguments.array[0]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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(data_make, arguments.array[1]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->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(data_make, arguments.array[i]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_operate) { - if (arguments.used > 1) { - fake_print_error_too_many_arguments(data_make); - - *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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_parameter) { - if (arguments.used) { - 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, - }; - - for (f_array_length_t i = 0; i < 33; ++i) { - - if (fl_string_dynamic_compare_string(reserved_name[i], arguments.array[0], reserved_length[i]) == F_equal_to) { - fll_print_format("%c%[%SCannot assign a value to the parameter name '%s' because it is a reserved parameter name.%]%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; - } - } // for - } - else { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->operation == fake_make_operation_type_to) { - if (arguments.used > 1) { - fake_print_error_too_many_arguments(data_make); - - *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, data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - if (state_process->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(data_make, arguments.array[i]); - - if (F_status_is_error(*status)) { - fake_print_message_section_operation_path_outside(data_make->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 { - fake_print_error_requires_more_arguments(data_make); - - *status = F_status_set_error(F_failure); - } - - return; - } - - // Note: there is nothing to validate for fake_make_operation_type_print. - return; - } -#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 index 57b2ddf..6c1d2d9 100644 --- a/level_3/fake/c/private-make-operate.h +++ b/level_3/fake/c/private-make-operate.h @@ -128,153 +128,6 @@ extern "C" { int fake_make_operate_section(fake_make_data_t * const data_make, const f_array_length_t id_section, 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 data_make - * All make related setting data, including data from the fakefile and the build settings file. - * @param section_name - * The section name. - * @param arguments - * The expanded arguments. - * @param success - * Whether or not a previous section operation succeeded or failed. - * @param state_process - * The operation and if-condition states. - * @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_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, const bool success, fake_state_process_t *state_process, 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 data_make - * All make related setting data, including data from the fakefile and the build settings file. - * @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. - * - * @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_make_data_t * const data_make, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_execute_ - -/** - * Handle the return code, converting it to a standard return number and store it as a string. - * - * The return value is stored in: data_make.setting_make.parameter.array[0].value.array[0]. - * - * @param data_make - * All make related setting data, including data from the fakefile and the build settings file. - * @param return_code - * The return code to process. - * - * @return - * F_none on success. - * F_failure (with error bit) on identifying the return code as an error code and fail mode is set to fake_make_operation_fail_type_exit. - * - * Errors (with error bit) from: f_conversion_number_signed_to_string(). - * Errors (with error bit) from: f_string_append(). - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see f_conversion_number_signed_to_string() - * @see f_string_append() - * @see f_string_dynamic_append() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_fake_make_operate_process_return_ - extern f_status_t fake_make_operate_process_return(fake_make_data_t * const data_make, const int return_code) F_attribute_visibility_internal_d; -#endif // _di_fake_make_operate_process_return_ - -/** - * Execute either the run operation or the shell operation. - * - * @param data_make - * All make related setting data, including data from the fakefile and the build settings file. - * @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. - * - * @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_make_data_t * const data_make, const f_string_statics_t arguments, const bool as_shell) 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 data_make - * All make related setting data, including data from the fakefile and the build settings file. - * @param section_name - * The section name. - * @param arguments - * The expanded arguments. - * @param state_process - * The operation and if-condition operation states. - * This condition will be updated by this as appropriate. - * @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_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, fake_state_process_t *state_process, 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 diff --git a/level_3/fake/c/private-make-operate_process.c b/level_3/fake/c/private-make-operate_process.c new file mode 100644 index 0000000..1a95539 --- /dev/null +++ b/level_3/fake/c/private-make-operate_process.c @@ -0,0 +1,679 @@ +#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-operate.h" +#include "private-make-operate_process.h" +#include "private-make-operate_process_type.h" +#include "private-print.h" +#include "private-skeleton.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_make_operate_process_ + int fake_make_operate_process(fake_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, const bool success, fake_state_process_t *state_process, f_array_lengths_t *section_stack, f_status_t *status) { + + if (*status == F_child) return data_make->main->child; + + if (state_process->operation == fake_make_operation_type_index) { + const f_status_t result = fake_execute(data_make->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; + } + + *status = fake_make_operate_process_return(data_make, result); + + return 0; + } + + if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { + flockfile(data_make->main->output.to.stream); + + fl_print_format("%cBreaking as '", data_make->main->output.to.stream, f_string_eol_s[0]); + fl_print_format("%[%S%]", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, data_make->main->context.set.notable); + fl_print_format("'.%c", data_make->main->output.to.stream, f_string_eol_s[0]); + + funlockfile(data_make->main->output.to.stream); + } + + return 0; + } + + if (state_process->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, data_make->main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_clean) { + *status = fake_clean_operate(data_make->main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_clone) { + *status = fake_make_operate_process_type_copy(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_compile) { + const int result = fake_execute(data_make->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; + } + + *status = fake_make_operate_process_return(data_make, result); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_copy) { + *status = fake_make_operate_process_type_copy(data_make, arguments, F_false); + + return 0; + } + + if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cDefined environment variable '%[%Q%]'.%c", data_make->main->output.to.stream, f_string_eol_s[0], data_make->main->context.set.notable, arguments.array[0], data_make->main->context.set.notable, f_string_eol_s[0]); + } + + return 0; + } + + if (state_process->operation == fake_make_operation_type_delete) { + *status = fake_make_operate_process_type_deletes(data_make, arguments, F_false); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_deletes) { + *status = fake_make_operate_process_type_deletes(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_else) { + + // Setup the block so that subsequent operations can know the current block and the result (which is preserved across to the else condition). + state_process->block = fake_make_operation_if_type_else; + + return 0; + } + + if (state_process->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 = data_make->main->context.set.error; + data_make->error.notable = data_make->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 = &data_make->main->context.set; + } + else { + return 0; + } + + if (data_make->main->error.verbosity == f_console_verbosity_verbose) { + fll_print_format("%cExiting as '%[%S%]'.%c", data_make->main->output.to.stream, f_string_eol_s[0], data_make->main->context.set.notable, arguments.used ? arguments.array[0].string : fake_make_operation_argument_success_s, data_make->main->context.set.notable, f_string_eol_s[0]); + } + + return 0; + } + + if (state_process->operation == fake_make_operation_type_fail) { + fake_make_operate_process_type_fail(data_make, arguments); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_group) { + *status = fake_make_operate_process_type_groups(data_make, arguments, F_false); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_groups) { + *status = fake_make_operate_process_type_groups(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_if || state_process->operation == fake_make_operation_type_and || state_process->operation == fake_make_operation_type_or) { + if (state_process->condition == fake_make_operation_if_type_if_success) { + if (success) { + state_process->condition_result = fake_condition_result_true; + } + else { + state_process->condition_result = fake_condition_result_false; + } + } + else if (state_process->condition == fake_make_operation_if_type_if_defined) { + fake_make_operate_process_type_if_defined(data_make, arguments, F_false, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_exists) { + *status = fake_make_operate_process_type_if_exists(data_make, arguments, F_false, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_failure) { + if (success) { + state_process->condition_result = fake_condition_result_false; + } + else { + state_process->condition_result = fake_condition_result_true; + } + } + else if (state_process->condition == fake_make_operation_if_type_if_group) { + *status = fake_make_operate_process_type_if_group(data_make, arguments, F_false, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_is) { + *status = fake_make_operate_process_type_if_is(data_make, arguments, F_false, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_mode) { + *status = fake_make_operate_process_type_if_mode(data_make, arguments, F_false, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_defined) { + fake_make_operate_process_type_if_defined(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_equal) { + state_process->condition_result = fake_condition_result_true; + + 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) { + state_process->condition_result = fake_condition_result_false; + + break; + } + } // for + } + else if (state_process->condition == fake_make_operation_if_type_if_equal_not) { + state_process->condition_result = fake_condition_result_true; + + 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) { + state_process->condition_result = fake_condition_result_false; + i = arguments.used; + + break; + } + } // for + } // for + } + else if (state_process->condition == fake_make_operation_if_type_if_greater || state_process->condition == fake_make_operation_if_type_if_greater_equal || state_process->condition == fake_make_operation_if_type_if_less || state_process->condition == fake_make_operation_if_type_if_less_equal) { + *status = fake_make_operate_process_type_if_greater_if_lesser(data_make, arguments, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_exists) { + *status = fake_make_operate_process_type_if_exists(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_group) { + *status = fake_make_operate_process_type_if_group(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_is) { + *status = fake_make_operate_process_type_if_is(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_mode) { + *status = fake_make_operate_process_type_if_mode(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_not_owner) { + *status = fake_make_operate_process_type_if_owner(data_make, arguments, F_true, state_process); + } + else if (state_process->condition == fake_make_operation_if_type_if_owner) { + *status = fake_make_operate_process_type_if_owner(data_make, arguments, F_false, state_process); + } + + // Setup the block for subsequent operations. + state_process->block = fake_make_operation_if_type_if; + + if (state_process->condition_result == fake_condition_result_done || state_process->operation == fake_make_operation_type_if) { + state_process->block_result = state_process->condition_result; + } + else if (state_process->operation == fake_make_operation_type_or) { + if (state_process->block_result == fake_condition_result_true || state_process->condition_result == fake_condition_result_true) { + state_process->block_result = fake_condition_result_true; + } + else { + state_process->block_result = fake_condition_result_false; + } + } + else { + if (state_process->block_result == fake_condition_result_true && state_process->condition_result == fake_condition_result_true) { + state_process->block_result = fake_condition_result_true; + } + else { + state_process->block_result = fake_condition_result_false; + } + } + + return 0; + } + + if (state_process->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { + flockfile(data_make->main->output.to.stream); + + fl_print_format("Created symbolic link from '%[%Q%]", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.array[1], data_make->main->context.set.notable); + fl_print_format("' to %[%Q%].%c", data_make->main->output.to.stream, data_make->main->context.set.notable, arguments.array[0], data_make->main->context.set.notable, f_string_eol_s[0]); + + funlockfile(data_make->main->output.to.stream); + } + + return 0; + } + + if (state_process->operation == fake_make_operation_type_mode) { + *status = fake_make_operate_process_type_modes(data_make, arguments, F_false); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_modes) { + *status = fake_make_operate_process_type_modes(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_move) { + *status = fake_make_operate_process_type_move(data_make, arguments); + + return 0; + } + + if (state_process->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(data_make, id_section, section_stack, status); + + // Ensure that a break only happens within its active state_process->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 (state_process->operation == fake_make_operation_type_owner) { + *status = fake_make_operate_process_type_owners(data_make, arguments, F_false); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_owners) { + *status = fake_make_operate_process_type_owners(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_parameter) { + *status = fake_make_operate_process_type_parameter(data_make, arguments); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_pop) { + *status = fake_make_operate_process_type_pop(data_make, arguments); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_print) { + flockfile(data_make->main->output.to.stream); + + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + f_print_dynamic(arguments.array[i], data_make->main->output.to.stream); + + if (i + 1 < arguments.used) { + f_print_character(f_string_space_s[0], data_make->main->output.to.stream); + } + } // for + + f_print_character(f_string_space_s[0], data_make->main->output.to.stream); + f_print_character(f_string_eol_s[0], data_make->main->output.to.stream); + + funlockfile(data_make->main->output.to.stream); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_run) { + *status = fake_make_operate_process_run(data_make, arguments, F_false); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_shell) { + *status = fake_make_operate_process_run(data_make, arguments, F_true); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_skeleton) { + *status = fake_skeleton_operate(data_make->main); + + if (F_status_set_fine(*status) == F_interrupt) { + return 0; + } + + *status = fake_make_operate_process_return(data_make, F_status_is_error(*status) ? 1 : 0); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_to) { + *status = fake_make_operate_process_type_to(data_make, arguments); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_top) { + *status = fake_make_operate_process_type_top(data_make, arguments); + + return 0; + } + + if (state_process->operation == fake_make_operation_type_touch) { + *status = fake_make_operate_process_type_touch(data_make, arguments); + } + + return 0; + } +#endif // _di_fake_make_operate_process_ + +#ifndef _di_fake_make_operate_process_execute_ + f_status_t fake_make_operate_process_execute(fake_make_data_t * const data_make, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell) { + + if (fake_signal_received(data_make->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 (data_make->main->error.verbosity == f_console_verbosity_verbose) { + flockfile(data_make->main->output.to.stream); + + f_print_dynamic_safely(program, data_make->main->output.to.stream); + + for (f_array_length_t i = 0; i < arguments.used; ++i) { + + if (arguments.array[i].used) { + fll_print_format(" %Q", data_make->main->output.to.stream, arguments.array[i]); + } + } // for + + f_print_character(f_string_eol_s[0], data_make->main->output.to.stream); + + funlockfile(data_make->main->output.to.stream); + + // flush to stdout before executing command. + fflush(data_make->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(data_make->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); + } + } + + return fake_make_operate_process_return(data_make, return_code); + } +#endif // _di_fake_make_operate_process_execute_ + +#ifndef _di_fake_make_operate_process_return_ + f_status_t fake_make_operate_process_return(fake_make_data_t * const data_make, const int return_code) { + + f_status_t status = F_none; + + data_make->setting_make.parameter.array[0].value.array[0].used = 0; + + if (!return_code) { + if (F_status_is_error(status)) { + status = f_string_append("1", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + else { + status = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_string_append", F_true); + } + + return status; + } + + if (return_code) { + f_string_dynamic_t number = f_string_dynamic_t_initialize; + + status = f_conversion_number_signed_to_string(WEXITSTATUS(return_code), f_conversion_data_base_10_s, &number); + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_conversion_number_signed_to_string", F_true); + + f_string_dynamic_resize(0, &number); + + return status; + } + + status = f_string_dynamic_append(number, &data_make->setting_make.parameter.array[0].value.array[0]); + + f_string_dynamic_resize(0, &number); + } + else { + status = f_string_append("0", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + } + + if (F_status_is_error(status)) { + fll_error_print(data_make->error, F_status_set_fine(status), "f_string_append", F_true); + + return status; + } + + 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(data_make->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); + + return status; + } + + 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) { + return F_status_set_error(F_failure); + } + + return 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_make_data_t * const data_make, const f_string_statics_t arguments, const bool as_shell) { + + 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); + + f_string_dynamics_resize(0, &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); + + f_string_dynamics_resize(0, &args); + + return status; + } + + ++args.used; + } // for + } + + status = fake_make_operate_process_execute(data_make, *program, args, as_shell); + + f_string_dynamics_resize(0, &args); + + return status; + } +#endif // _di_fake_make_operate_process_run_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fake/c/private-make-operate_process.h b/level_3/fake/c/private-make-operate_process.h new file mode 100644 index 0000000..2d5d99d --- /dev/null +++ b/level_3/fake/c/private-make-operate_process.h @@ -0,0 +1,119 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_make_operate_process_h +#define _PRIVATE_make_operate_process_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Perform a specific make operation within the given section. + * + * @param data_make + * All make related setting data, including data from the fakefile and the build settings file. + * @param section_name + * The section name. + * @param arguments + * The expanded arguments. + * @param success + * Whether or not a previous section operation succeeded or failed. + * @param state_process + * The operation and if-condition states. + * @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_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, const bool success, fake_state_process_t *state_process, 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 data_make + * All make related setting data, including data from the fakefile and the build settings file. + * @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. + * + * @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_make_data_t * const data_make, const f_string_static_t program, const f_string_statics_t arguments, const bool as_shell) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_execute_ + +/** + * Handle the return code, converting it to a standard return number and store it as a string. + * + * The return value is stored in: data_make.setting_make.parameter.array[0].value.array[0]. + * + * @param data_make + * All make related setting data, including data from the fakefile and the build settings file. + * @param return_code + * The return code to process. + * + * @return + * F_none on success. + * F_failure (with error bit) on identifying the return code as an error code and fail mode is set to fake_make_operation_fail_type_exit. + * + * Errors (with error bit) from: f_conversion_number_signed_to_string(). + * Errors (with error bit) from: f_string_append(). + * Errors (with error bit) from: f_string_dynamic_append(). + * Errors (with error bit) from: f_string_dynamic_terminate_after(). + * + * @see f_conversion_number_signed_to_string() + * @see f_string_append() + * @see f_string_dynamic_append() + * @see f_string_dynamic_terminate_after() + */ +#ifndef _di_fake_make_operate_process_return_ + extern f_status_t fake_make_operate_process_return(fake_make_data_t * const data_make, const int return_code) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_return_ + +/** + * Execute either the run operation or the shell operation. + * + * @param data_make + * All make related setting data, including data from the fakefile and the build settings file. + * @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. + * + * @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_make_data_t * const data_make, const f_string_statics_t arguments, const bool as_shell) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_run_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_make_operate_process_h diff --git a/level_3/fake/c/private-make-operate-type.c b/level_3/fake/c/private-make-operate_process_type.c similarity index 99% rename from level_3/fake/c/private-make-operate-type.c rename to level_3/fake/c/private-make-operate_process_type.c index 8481055..62f32b2 100644 --- a/level_3/fake/c/private-make-operate-type.c +++ b/level_3/fake/c/private-make-operate_process_type.c @@ -4,10 +4,8 @@ #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-make-operate-type.h" +#include "private-make-operate_process_type.h" #include "private-print.h" #include "private-skeleton.h" diff --git a/level_3/fake/c/private-make-operate-type.h b/level_3/fake/c/private-make-operate_process_type.h similarity index 100% rename from level_3/fake/c/private-make-operate-type.h rename to level_3/fake/c/private-make-operate_process_type.h diff --git a/level_3/fake/c/private-make-operate_validate.c b/level_3/fake/c/private-make-operate_validate.c new file mode 100644 index 0000000..a5b2105 --- /dev/null +++ b/level_3/fake/c/private-make-operate_validate.c @@ -0,0 +1,1485 @@ +#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-operate.h" +#include "private-make-operate_validate.h" +#include "private-print.h" +#include "private-skeleton.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fake_make_operate_validate_ + void fake_make_operate_validate(fake_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, fake_state_process_t *state_process, f_array_lengths_t *section_stack, f_status_t *status) { + + if (F_status_is_error(*status)) return; + + if (state_process->operation == fake_make_operation_type_index || state_process->operation == fake_make_operation_type_run || state_process->operation == fake_make_operation_type_shell) { + if (!arguments.used) { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + else if (state_process->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 (state_process->operation == fake_make_operation_type_break) { + if (arguments.used > 1) { + fake_print_error_too_many_arguments(data_make); + + *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 (state_process->operation == fake_make_operation_type_build) { + if (arguments.used > 1) { + fake_print_error_too_many_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + else if (arguments.used) { + if (arguments.array[0].used) { + char path_file[data_make->main->path_data_build.used + arguments.array[0].used + 1]; + + memcpy(path_file, data_make->main->path_data_build.string, data_make->main->path_data_build.used); + memcpy(path_file + data_make->main->path_data_build.used, arguments.array[0].string, arguments.array[0].used); + + path_file[data_make->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 (state_process->operation == fake_make_operation_type_clean || state_process->operation == fake_make_operation_type_pop || state_process->operation == fake_make_operation_type_top || state_process->operation == fake_make_operation_type_skeleton) { + if (arguments.used) { + fake_print_error_too_many_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + else if (state_process->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 (state_process->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(data_make, arguments.array[i]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_compile) { + if (!arguments.used) { + fake_print_error_requires_more_arguments(data_make); + + *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 (state_process->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(data_make, arguments.array[i]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_delete || state_process->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(data_make, arguments.array[i]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_else) { + if (state_process->block == fake_make_operation_if_type_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%[%SMust not be used immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_else_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 (state_process->operation_previous == fake_make_operation_type_if || state_process->operation_previous == fake_make_operation_type_and || state_process->operation_previous == fake_make_operation_type_or) { + 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 immediately after 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); + fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); + fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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 (state_process->block != fake_make_operation_if_type_done) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + fl_print_format("%c%[%SHas no preceding '%]", 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_if_s, data_make->error.notable); + fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); + fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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]); + } + + *status = F_status_set_error(F_failure); + + return; + } + + if (arguments.used) { + fake_print_error_too_many_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_exit) { + if (arguments.used > 1) { + fake_print_error_too_many_arguments(data_make); + + *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 (state_process->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_group || state_process->operation == fake_make_operation_type_groups || state_process->operation == fake_make_operation_type_mode || state_process->operation == fake_make_operation_type_modes || state_process->operation == fake_make_operation_type_owner || state_process->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; + } + + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + + return; + } + + if (state_process->operation == fake_make_operation_type_if || state_process->operation == fake_make_operation_type_and || state_process->operation == fake_make_operation_type_or) { + if (state_process->operation == fake_make_operation_type_if) { + if (state_process->block == fake_make_operation_type_if) { + 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 immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); + fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); + fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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; + } + } + else { + if (!(state_process->operation_previous == fake_make_operation_type_if || state_process->operation_previous == fake_make_operation_type_and || state_process->operation_previous == fake_make_operation_type_or)) { + if (data_make->error.verbosity != f_console_verbosity_quiet && data_make->error.to.stream) { + flockfile(data_make->error.to.stream); + + fl_print_format("%c%[%SMay only be used immediately 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("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_if_s, data_make->error.notable); + fl_print_format("%[', '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_and_s, data_make->error.notable); + fl_print_format("%[', or '%]", data_make->error.to.stream, data_make->error.context, data_make->error.context); + fl_print_format("%[%s%]", data_make->error.to.stream, data_make->error.notable, fake_make_operation_or_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 (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_not_s, + fake_make_operation_argument_if_defined_s, // If not defined, represented by just "defined". + fake_make_operation_argument_if_exists_s, // If not exists, represented by just "exists". + fake_make_operation_argument_if_group_s, // If not group, represented by just "group". + fake_make_operation_argument_if_is_s, // If not is, represented by just "is". + fake_make_operation_argument_if_mode_s, // If not mode, represented by just "mode". + fake_make_operation_argument_if_owner_s, // If not owner, represented by just "owner". + 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_not_s_length, + fake_make_operation_argument_if_defined_s_length, // if not defined, represented by just "defined". + fake_make_operation_argument_if_exists_s_length, // if not exists, represented by just "exists". + fake_make_operation_argument_if_group_s_length, // if not group, represented by just "group". + fake_make_operation_argument_if_is_s_length, // if not is, represented by just "is". + fake_make_operation_argument_if_mode_s_length, // if not mode, represented by just "mode". + fake_make_operation_argument_if_owner_s_length, // if not owner, represented by just "owner". + 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_not, + fake_make_operation_if_type_if_not_defined, + fake_make_operation_if_type_if_not_exists, + fake_make_operation_if_type_if_not_group, + fake_make_operation_if_type_if_not_is, + fake_make_operation_if_type_if_not_mode, + fake_make_operation_if_type_if_not_owner, + fake_make_operation_if_type_if_owner, + fake_make_operation_if_type_if_success, + }; + + const uint8_t if_type_minimum[] = { + 3, // If defined. + 2, // If equal (==). + 2, // If equal not (<>). + 2, // If exists. + 1, // If failure. + 2, // If greater (>). + 2, // If greater equal (>=). + 3, // If group. + 3, // If is. + 2, // If less (<). + 2, // If less equal (<=). + 4, // If mode. + 3, // If not. + 5, // If not defined. + 3, // If not exists. + 4, // If not group. + 4, // If not is. + 5, // If not mode. + 4, // If not owner. + 3, // If owner. + 1, // If success. + }; + + const f_string_t if_not_type_strings[] = { + fake_make_operation_argument_if_defined_s, + fake_make_operation_argument_if_exists_s, + fake_make_operation_argument_if_group_s, + fake_make_operation_argument_if_is_s, + fake_make_operation_argument_if_mode_s, + fake_make_operation_argument_if_owner_s, + }; + + const f_array_length_t if_not_type_lengths[] = { + fake_make_operation_argument_if_defined_s_length, + fake_make_operation_argument_if_exists_s_length, + fake_make_operation_argument_if_group_s_length, + fake_make_operation_argument_if_is_s_length, + fake_make_operation_argument_if_mode_s_length, + fake_make_operation_argument_if_owner_s_length, + }; + + const uint8_t if_not_type_codes[] = { + fake_make_operation_if_type_if_not_defined, + fake_make_operation_if_type_if_not_exists, + fake_make_operation_if_type_if_not_group, + fake_make_operation_if_type_if_not_is, + fake_make_operation_if_type_if_not_mode, + fake_make_operation_if_type_if_not_owner, + }; + + const uint8_t if_not_type_minimum[] = { + 4, // If not defined. + 3, // If not exists. + 4, // If not group. + 4, // If not is. + 5, // If not mode. + 4, // If not owner. + }; + + f_array_length_t i = 0; + f_array_length_t j = 0; + f_string_t if_and_or; + + if (state_process->operation == fake_make_operation_type_and) { + if_and_or = fake_make_operation_and_s; + } + else if (state_process->operation == fake_make_operation_type_or) { + if_and_or = fake_make_operation_or_s; + } + else { + if_and_or = fake_make_operation_if_s; + } + + for (; i < 21; ++i) { + + // Skip the "if not XXX" types as they are determined later on. + if (i > 12 && i < 19) continue; + + if (fl_string_dynamic_compare_string(if_type_strings[i], arguments.array[0], if_type_lengths[i]) == F_equal_to) { + state_process->condition = if_type_codes[i]; + + break; + } + } // for + + if (i == 21) { + 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 '%s' type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, if_and_or, 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; + } + + // Identify and convert to the appropriate if not condition. + if (state_process->condition == fake_make_operation_if_type_if_not) { + if (arguments.used < 2) { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + + return; + } + + for (; j < 6; ++j) { + + if (fl_string_dynamic_compare_string(if_not_type_strings[j], arguments.array[1], if_not_type_lengths[j]) == F_equal_to) { + state_process->condition = if_not_type_codes[j]; + + break; + } + } // for + + if (j == 6) { + 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 '%s' not type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, if_and_or, 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; + } + } + else { + j = 6; + } + + if (j == 6 && arguments.used >= if_type_minimum[i] || arguments.used >= if_not_type_minimum[j]) { + if (state_process->condition == fake_make_operation_if_type_if_success || state_process->condition == fake_make_operation_if_type_if_failure) { + + // The success and failure operations minimum is also the maximum. + if (arguments.used > if_type_minimum[i]) { + fake_print_error_too_many_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->condition == fake_make_operation_if_type_if_defined || state_process->condition == fake_make_operation_if_type_if_not_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; + } + else if (state_process->condition == fake_make_operation_if_type_if_equal || state_process->condition == fake_make_operation_if_type_if_equal_not) { + if (arguments.used < 3) { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + else if (state_process->condition == fake_make_operation_if_type_if_exists || state_process->condition == fake_make_operation_if_type_if_not_exists) { + return; + } + else if (state_process->condition == fake_make_operation_if_type_if_group || state_process->condition == fake_make_operation_if_type_if_is || state_process->condition == fake_make_operation_if_type_if_mode || state_process->condition > fake_make_operation_if_type_if_not_exists && state_process->condition < fake_make_operation_if_type_if_success) { + + if (state_process->condition == fake_make_operation_if_type_if_mode || state_process->condition == fake_make_operation_if_type_if_not_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 %smode type '%]", data_make->error.to.stream, f_string_eol_s[0], data_make->error.context, data_make->error.prefix, j == 6 ? "" : "not ", 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(data_make->main, data_make->error, j == 6 ? arguments.array[2] : arguments.array[3], &mode_rule, &replace); + if (F_status_is_error(*status)) return; + + i = j == 6 ? 3 : 4; + } + else if (state_process->condition == fake_make_operation_if_type_if_group || state_process->condition == fake_make_operation_if_type_if_not_group) { + gid_t id = 0; + + *status = fake_make_get_id_group(data_make->main, data_make->error, j == 6 ? arguments.array[1] : arguments.array[2], &id); + if (F_status_is_error(*status)) return; + + i = j == 6 ? 2 : 3; + } + else if (state_process->condition == fake_make_operation_if_type_if_is || state_process->condition == fake_make_operation_if_type_if_not_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 = j == 6 ? 1 : 2; 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); + + return; + } + } + else if (state_process->condition == fake_make_operation_if_type_if_owner || state_process->condition == fake_make_operation_if_type_if_not_owner) { + uid_t id = 0; + + *status = fake_make_get_id_owner(data_make->main, data_make->error, arguments.array[1], &id); + if (F_status_is_error(*status)) return; + + i = j == 6 ? 2 : 3; + } + + if (i < arguments.used) { + for (f_status_t status_file = F_none; i < arguments.used; ++i) { + + status_file = fake_make_assure_inside_project(data_make, arguments.array[i]); + + if (F_status_is_error(status_file)) { + fake_print_message_section_operation_path_outside(data_make->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); + + 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 (state_process->condition != fake_make_operation_if_type_if_exists && state_process->condition != 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); + + if (F_status_is_error_not(*status)) { + *status = F_status_set_error(status_file); + } + } + } + } // for + } + } + else if (state_process->condition == fake_make_operation_if_type_if_greater || state_process->condition == fake_make_operation_if_type_if_greater_equal || state_process->condition == fake_make_operation_if_type_if_less || state_process->condition == fake_make_operation_if_type_if_less_equal) { + if (arguments.used < 3) { + fake_print_error_requires_more_arguments(data_make); + + *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; + } + + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + + return; + } + + if (state_process->operation == fake_make_operation_type_link) { + if (arguments.used > 2) { + fake_print_error_too_many_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + else if (arguments.used == 2) { + *status = fake_make_assure_inside_project(data_make, arguments.array[0]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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(data_make, arguments.array[1]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->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(data_make, arguments.array[i]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_operate) { + if (arguments.used > 1) { + fake_print_error_too_many_arguments(data_make); + + *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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_parameter) { + if (arguments.used) { + 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, + }; + + for (f_array_length_t i = 0; i < 33; ++i) { + + if (fl_string_dynamic_compare_string(reserved_name[i], arguments.array[0], reserved_length[i]) == F_equal_to) { + fll_print_format("%c%[%SCannot assign a value to the parameter name '%s' because it is a reserved parameter name.%]%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; + } + } // for + } + else { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->operation == fake_make_operation_type_to) { + if (arguments.used > 1) { + fake_print_error_too_many_arguments(data_make); + + *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, data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + if (state_process->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(data_make, arguments.array[i]); + + if (F_status_is_error(*status)) { + fake_print_message_section_operation_path_outside(data_make->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 { + fake_print_error_requires_more_arguments(data_make); + + *status = F_status_set_error(F_failure); + } + + return; + } + + // Note: there is nothing to validate for fake_make_operation_type_print. + return; + } +#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_validate.h b/level_3/fake/c/private-make-operate_validate.h new file mode 100644 index 0000000..28b56dd --- /dev/null +++ b/level_3/fake/c/private-make-operate_validate.h @@ -0,0 +1,66 @@ +/** + * FLL - Level 3 + * + * Project: Featureless Make + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_make_operate_validate_h +#define _PRIVATE_make_operate_validate_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * 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 data_make + * All make related setting data, including data from the fakefile and the build settings file. + * @param section_name + * The section name. + * @param arguments + * The expanded arguments. + * @param state_process + * The operation and if-condition operation states. + * This condition will be updated by this as appropriate. + * @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_make_data_t * const data_make, const f_string_range_t section_name, const f_string_dynamics_t arguments, fake_state_process_t *state_process, 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_validate_h diff --git a/level_3/fake/data/build/settings b/level_3/fake/data/build/settings index 1aed9aa..dcf25b1 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-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-make-operate-type.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-make-operate_process.c private-make-operate_process_type.c private-make-operate_validate.c private-print.c private-skeleton.c build_sources_library_shared build_sources_library_static build_sources_program main.c