From 2e21a1c549ea753be7175a6fd13f8a92c8ae5264 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 19 Dec 2021 12:18:03 -0600 Subject: [PATCH] Bugfix: The "if defined parameter .." is not supporting reserved parameters. There are several reserved parameters that are supposed to be supported. Add code checking for the reserved words for the "if defined parameter" operation. Update the documentation to better communicate these reserved words and how they operate. Move the operation into its own function. --- level_3/fake/c/private-make-operate.c | 215 +++++++++++++++++++++++++------ level_3/fake/c/private-make-operate.h | 15 +++ level_3/fake/documents/fakefile.txt | 103 +++++++++------ level_3/fake/specifications/fakefile.txt | 4 + 4 files changed, 258 insertions(+), 79 deletions(-) diff --git a/level_3/fake/c/private-make-operate.c b/level_3/fake/c/private-make-operate.c index c600cb7..ffb14e6 100644 --- a/level_3/fake/c/private-make-operate.c +++ b/level_3/fake/c/private-make-operate.c @@ -2205,46 +2205,7 @@ extern "C" { } if (*operation_if == fake_make_operation_if_type_if_defined) { - - if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to) { - *operation_if = fake_make_operation_if_type_true_next; - - for (f_array_length_t i = 2; i < arguments.used; ++i) { - - if (f_environment_exists(arguments.array[i].string) != F_true) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to) { - if (!data_make->setting_make.parameter.used) { - *operation_if = fake_make_operation_if_type_false_next; - return 0; - } - - f_array_length_t i = 2; - f_array_length_t j = 0; - bool missed = F_true; - - *operation_if = fake_make_operation_if_type_true_next; - - for (; i < arguments.used; ++i, missed = F_true) { - - for (j = 0; j < data_make->setting_make.parameter.used; ++j) { - - if (fl_string_dynamic_compare(arguments.array[i], data_make->setting_make.parameter.array[j].name) == F_equal_to) { - missed = F_false; - break; - } - } // for - - if (missed) { - *operation_if = fake_make_operation_if_type_false_next; - break; - } - } // for - } + fake_make_operate_process_type_if_defined(main, data_make, arguments, operation_if); return 0; } @@ -2994,6 +2955,180 @@ extern "C" { } #endif // _di_fake_make_operate_process_execute_ +#ifndef _di_fake_make_operate_process_type_if_defined_ + void fake_make_operate_process_type_if_defined(fake_main_t * const main, fake_make_data_t * const data_make, const f_string_dynamics_t arguments, uint8_t *operation_if) { + + 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, + }; + + const bool reserved_defined[] = { + main->path_build.used, + F_true, + main->path_data.used, + main->define.used, + main->fakefile.used, + main->mode.used, + main->process.used, + main->settings.used, + main->path_sources.used, + F_true, + main->path_work.used, + main->parameters[fake_parameter_path_build].result == f_console_result_additional, + main->parameters[fake_parameter_light].result == f_console_result_found || main->parameters[fake_parameter_dark].result == f_console_result_found || main->parameters[fake_parameter_no_color].result == f_console_result_found, + main->parameters[fake_parameter_path_data].result == f_console_result_additional, + main->parameters[fake_parameter_define].result == f_console_result_additional, + main->parameters[fake_parameter_fakefile].result == f_console_result_additional, + main->parameters[fake_parameter_mode].result == f_console_result_additional, + main->parameters[fake_parameter_process].result == f_console_result_additional, + main->parameters[fake_parameter_settings].result == f_console_result_additional, + main->parameters[fake_parameter_path_sources].result == f_console_result_additional, + main->parameters[fake_parameter_verbosity_quiet].result == f_console_result_found || main->parameters[fake_parameter_verbosity_normal].result == f_console_result_found || main->parameters[fake_parameter_verbosity_verbose].result == f_console_result_found || main->parameters[fake_parameter_verbosity_debug].result == f_console_result_found, + main->parameters[fake_parameter_path_work].result == f_console_result_additional, + data_make->parameter_value.build.used, + data_make->parameter_value.color.used, + data_make->parameter_value.data.used, + data_make->parameter_value.define.used, + data_make->parameter_value.fakefile.used, + data_make->parameter_value.mode.used, + data_make->parameter_value.process.used, + data_make->parameter_value.settings.used, + data_make->parameter_value.sources.used, + data_make->parameter_value.verbosity.used, + data_make->parameter_value.work.used, + }; + + if (fl_string_dynamic_compare_string(fake_make_operation_argument_environment_s, arguments.array[1], fake_make_operation_argument_environment_s_length) == F_equal_to) { + *operation_if = fake_make_operation_if_type_true_next; + + for (f_array_length_t i = 2; i < arguments.used; ++i) { + + if (f_environment_exists(arguments.array[i].string) != F_true) { + *operation_if = fake_make_operation_if_type_false_next; + + break; + } + } // for + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_parameter_s, arguments.array[1], fake_make_operation_argument_parameter_s_length) == F_equal_to) { + + f_array_length_t i = 2; + f_array_length_t j = 0; + + // 0 = unknown, 1 = fail, 2 = pass. + uint8_t result = 0; + + *operation_if = fake_make_operation_if_type_true_next; + + // Multiple properties may pass and so if any of them fail, then they all fail. + for (; i < arguments.used; ++i) { + + for (j = 0; j < 33; ++j) { + + if (fl_string_dynamic_compare_string(reserved_name[j], arguments.array[i], reserved_length[j]) == F_equal_to) { + result = reserved_defined[j] ? 2 : 1; + + break; + } + } // for + + if (!result) { + for (j = 0; j < data_make->setting_make.parameter.used; ++j) { + + if (fl_string_dynamic_compare(arguments.array[i], data_make->setting_make.parameter.array[j].name) == F_equal_to) { + result = 2; + + break; + } + } // for + } + + if (result < 2) { + result = 1; + + break; + } + + if (i + 1 < arguments.used) { + result = 0; + } + } // for + + if (result < 2) { + *operation_if = fake_make_operation_if_type_false_next; + } + } + } +#endif // fake_make_operate_process_type_if_defined + #ifndef _di_fake_make_operate_process_return_ void fake_make_operate_process_return(fake_main_t * const main, const int return_code, fake_make_data_t *data_make, f_status_t *status) { diff --git a/level_3/fake/c/private-make-operate.h b/level_3/fake/c/private-make-operate.h index 4b74b77..17e5f5d 100644 --- a/level_3/fake/c/private-make-operate.h +++ b/level_3/fake/c/private-make-operate.h @@ -197,6 +197,21 @@ extern "C" { #endif // _di_fake_make_operate_process_execute_ /** + * Perform the if defined operation process. + * + * @param main + * The main program data. + * @param data_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * @param arguments + * The arguments for the run or shell operation. + * @param operation_if + * The if-condition status for the current operation. + */ +#ifndef _di_fake_make_operate_process_type_if_defined_ + extern void fake_make_operate_process_type_if_defined(fake_main_t * const main, fake_make_data_t * const data_make, const f_string_dynamics_t arguments, uint8_t *operation_if) F_attribute_visibility_internal_d; +#endif // _di_fake_make_operate_process_type_if_defined_ +/** * Handle the return code, converting it to a number. * * @param main diff --git a/level_3/fake/documents/fakefile.txt b/level_3/fake/documents/fakefile.txt index 3be5808..7a48426 100644 --- a/level_3/fake/documents/fakefile.txt +++ b/level_3/fake/documents/fakefile.txt @@ -169,71 +169,96 @@ Fakefile Documentation: conditions\: == "left" "right"\: - compare all parameters to be equal. - requires 2 or more after the "==". - for example, "if == 'a' 'b' 'c' 'd'" would test: 'a' == 'b' && 'b' == 'c' && 'c' == 'd'. - this performs only string-based comparisons. + Compare all parameters to be equal. + Requires 2 or more after the "==". + For example, "if == 'a' 'b' 'c' 'd'" would test: 'a' == 'b' && 'b' == 'c' && 'c' == 'd'. + This performs only string-based comparisons. > "left string" "right string"\: - compare "left" to "right" for greater than. - requires 2 or more after the ">". - for example, "if > 0 1 2 3" would test: 0 > 1 && 1 > 2 && 2 > 3. - this performs only number-based comparisons. + Compare "left" to "right" for greater than. + Requires 2 or more after the ">". + For example, "if > 0 1 2 3" would test: 0 > 1 && 1 > 2 && 2 > 3. + This performs only number-based comparisons. < "left string" "right string"\: - compare "left" to "right" for less than. - requires 2 or more after the ">". - for example, "if < 0 1 2 3" would test: 0 < 1 && 1 < 2 && 2 < 3. - this performs only number-based comparisons. + Compare "left" to "right" for less than. + Requires 2 or more after the ">". + For example, "if < 0 1 2 3" would test: 0 < 1 && 1 < 2 && 2 < 3. + This performs only number-based comparisons. >= "left string" "right string"\: - compare "left" to "right" for greater than or equal to. - requires 2 or more after the ">=". - for example, "if >= 0 1 2 3" would test: 0 >= 1 && 1 >= 2 && 2 >= 3. - this performs only number-based comparisons. + Compare "left" to "right" for greater than or equal to. + Requires 2 or more after the ">=". + For example, "if >= 0 1 2 3" would test: 0 >= 1 && 1 >= 2 && 2 >= 3. + This performs only number-based comparisons. <= "left string" "right string"\: - compare "left" to "right" for less than or equal to. - requires 2 or more after the ">=". - for example, "if <= 0 1 2 3" would test: 0 <= 1 && 1 <= 2 && 2 <= 3. - this performs only number-based comparisons. + Compare "left" to "right" for less than or equal to. + Requires 2 or more after the ">=". + For example, "if <= 0 1 2 3" would test: 0 <= 1 && 1 <= 2 && 2 <= 3. + This performs only number-based comparisons. <> "left" "right"\: - compare all parameters to be not equal. - requires 2 or more after the "==". - for example, "if <> 'a' 'b' 'c'" would test: 'a' <> 'b' && 'b' <> 'c' && 'a' <> 'c'. - this performs only string-based comparisons. + Compare all parameters to be not equal. + Requires 2 or more after the "==". + For example, "if <> 'a' 'b' 'c'" would test: 'a' <> 'b' && 'b' <> 'c' && 'a' <> 'c'. + This performs only string-based comparisons. exists "file path"\: - test if file exists. - for example, "if exists "a.txt" "b.txt" would test if both the file a.txt and b.txt exist. + Test if file exists. + For example, "if exists "a.txt" "b.txt" would test if both the file a.txt and b.txt exist. is block character directory fifo link regular socket for "file path"\: - test if one or more files exist and if each file is any of the given types followed by "for" to designate where the the file paths begin. - for example, "if is regular directory for "a.txt" "b.txt" would test if both the file a.txt and b.txt exist and are either of type "regular" or type "directory". + Test if one or more files exist and if each file is any of the given types followed by "for" to designate where the the file paths begin. + For example, "if is regular directory for "a.txt" "b.txt" would test if both the file a.txt and b.txt exist and are either of type "regular" or type "directory". fail\: - test if the previous section operation failed. + Test if the previous section operation failed. succeed\: - test if the previous section operation succeeded. + Test if the previous section operation succeeded. mode is/has "some mode" "some file"\: - test if one or more files has the exact mode ("is") or has at least the given modes ("has"). - for example, "if mode is u+r a.txt b.txt" would test if both file a.txt and b.txt only have owner set to read. - for example, "if mode has u+r a.txt b.txt" would test if both file a.txt and b.txt has owner set to read, and all other modes can be anything. + Test if one or more files has the exact mode ("is") or has at least the given modes ("has"). + For example, "if mode is u+r a.txt b.txt" would test if both file a.txt and b.txt only have owner set to read. + For example, "if mode has u+r a.txt b.txt" would test if both file a.txt and b.txt has owner set to read, and all other modes can be anything. owner "some mode" "some file"\: - test if one or more files has the given owner. - for example, "if owner me a.txt b.txt" would test if both file a.txt and b.txt have an owner named "me". + Test if one or more files has the given owner. + For example, "if owner me a.txt b.txt" would test if both file a.txt and b.txt have an owner named "me". group "some mode" "some file"\: - for example, "if owner we a.txt b.txt" would test if both file a.txt and b.txt have a group named "we". + For example, "if owner we a.txt b.txt" would test if both file a.txt and b.txt have a group named "we". defined parameter/environment "some define name"\: - test if one or more names are defined as a "parameter" or an "environment" variable. - for example, "if defined parameter verbose silent" would test if both the "verbose" and the "silent" variables are defined via the "parameter" setting. - for example, "if defined environment PWD SHELL" would test if both the "PWD" and the "SHELL" variables are defined via the "environment" variables. + Test if one or more names are defined as a "parameter" or an "environment" variable. + For example, "if defined parameter verbose silent" would test if both the "verbose" and the "silent" variables are defined via the "parameter" setting. + For example, "if defined environment PWD SHELL" would test if both the "PWD" and the "SHELL" variables are defined via the "environment" variables. + + Reserved parameters that represent program arguments, three forms are available. + For example, the program argument -w/--work has the reserved word "work" and has three forms: + 1) "work". + 2) "work:option". + 3) "work:value". + + In the case of form 1, the "if defined parameter work" would be true if the argument is passed to the program or a default is provided. + In the case of form 2, the "if defined parameter work:option" would be true if the argument is passed to the program. + In the case of form 3, the "if defined parameter work:value" would be true if the argument is passed to the program and has a non-zero value. + + Some reserved parameters, such as the "verbosity", has no "value" and in this case would always return false for "if defined parameter verbosity:value". + + The following are reserved parameters: + - build: Associated with -b/--build parameter. + - color: Associated with +d/++dark, +l/++light, and +n/++no_color parameters. + - data: Associated with -D/--data parameter. + - define: Associated with -d/--define parameter. + - fakefile: Associated with -f/--fakefile parameter. + - mode: Associated with -m/--mode parameter and possibly with the build settings default mode "modes_default". + - process: Associated with -p/--process parameter. + - settings: Associated with -s/--settings parameter. + - sources: Associated with -S/--sources parameter. + - verbosity: Associated with +q/++quiet, +N/++normal, +V/++verbose, and +D/++debug parameters. + - work: Associated with -w/--work parameter. - index\: Execute the linker program, such as "ar". diff --git a/level_3/fake/specifications/fakefile.txt b/level_3/fake/specifications/fakefile.txt index ae4b6df..335e449 100644 --- a/level_3/fake/specifications/fakefile.txt +++ b/level_3/fake/specifications/fakefile.txt @@ -102,3 +102,7 @@ Fakefile Specification: - < - >= - <= + + The "if" Section Operation condition "defined"\: + The following reserved words are available for parameter names: build, color, data, define, fakefile, mode, process, settings, sources, verbosity, and work. + Each of the reserved words supports having ":option" and ":value" appended, such as: "work:value". -- 1.8.3.1