From 8487f7fa658e74d06d5072358f0668ac2952ef10 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 11 Jan 2022 21:48:43 -0600 Subject: [PATCH] Regression: The "failure" operation if condition type is not working as intended. The documentation and specification is out of date and refers to this as "fail". This is instead the word "failure". This is also different from the setting "fail" that designates what to do on failure. With one of the recent re-designs of the process logic, the failure status is no longer being passed. When the "fail" setting is set to "warn" or "ignore", the status code of F_none is returned. Change the return status to "F_failure" without the error bit to designate that this is a failure but it is not being treated as an error due to the state of the "fail" setting. Then process the "F_failure" without the error bit to remember the state that a failure occurred. This then allows for the "failure" if condition type to get triggered. The recent if/else logic changes introduced behavior where a failure in the processing of the if/else commands should also trigger the "failure" if condition type. This failure is not associated with the if condition results. When an if condition results in either true or false, then this is considered a "success" rather than a "failure". Generally, syntax failures are what trigger the "failure" state. Programs that are executed, such as when using the "run" operation, will result in "failure" if a non-zero value is returned by the program. --- level_3/fake/c/private-make-operate.c | 39 ++++++++++++++++++++++++++- level_3/fake/c/private-make-operate_process.c | 2 +- level_3/fake/c/private-make-operate_process.h | 2 ++ level_3/fake/documents/fakefile.txt | 2 +- level_3/fake/specifications/fakefile.txt | 2 +- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/level_3/fake/c/private-make-operate.c b/level_3/fake/c/private-make-operate.c index cde0d7e..f96d8be 100644 --- a/level_3/fake/c/private-make-operate.c +++ b/level_3/fake/c/private-make-operate.c @@ -1276,6 +1276,7 @@ extern "C" { fake_state_process_t state_process = fake_state_process_t_initialize; bool success = F_true; + bool success_block = F_true; int result; f_string_dynamics_t arguments = f_string_dynamics_t_initialize; @@ -1336,11 +1337,19 @@ extern "C" { if (state_process.operation != fake_make_operation_type_else_e) { state_process.block = 0; state_process.block_result = 0; + + // When the block ends and the block success is false, pass the failure to the success variable so that "failure" conditions can catch this. + if (success && !success_block) { + success = F_false; + } + + success_block = F_true; } } if (F_status_is_error(*status)) { if (state_process.block || state_process.operation == fake_make_operation_type_if_e || state_process.operation == fake_make_operation_type_and_e || state_process.operation == fake_make_operation_type_or_e) { + success_block = F_false; // Setting error result informs the post-process that the operate process is not run due to an error during the pre-process. if (state_process.operation == fake_make_operation_type_if_e || state_process.operation == fake_make_operation_type_and_e || state_process.operation == fake_make_operation_type_or_e || state_process.operation == fake_make_operation_type_else_e) { @@ -1357,8 +1366,9 @@ extern "C" { return result; } - if (state_process.block && F_status_is_error(result)) { + if (state_process.block && F_status_is_error(*status)) { state_process.block_result == fake_condition_result_error_e; + success_block = F_false; } } @@ -1368,10 +1378,18 @@ extern "C" { if (state_process.operation == fake_make_operation_type_if_e || state_process.operation == fake_make_operation_type_else_e) { state_process.block = 0; state_process.block_result = 0; + + // When the block ends and the block success is false, pass the failure to the success variable so that "failure" conditions can catch this. + if (success && !success_block) { + success = F_false; + } + + success_block = F_true; } else if (state_process.operation == fake_make_operation_type_and_e || state_process.operation == fake_make_operation_type_or_e) { if (state_process.block_result == fake_condition_result_error_e) { state_process.block_result = fake_condition_result_false_e; + success_block = F_false; } } else { @@ -1382,6 +1400,10 @@ extern "C" { else if (state_process.block_result == fake_condition_result_false_e || state_process.block_result == fake_condition_result_error_e) { state_process.block = fake_state_process_block_next_e; state_process.block_result = fake_condition_result_false_e; + + if (state_process.block_result == fake_condition_result_error_e) { + success_block = F_false; + } } else { state_process.block = fake_state_process_block_skip_e; @@ -1416,6 +1438,13 @@ extern "C" { else { state_process.block = 0; state_process.block_result = 0; + + // When the block ends and the block success is false, pass the failure to the success variable so that "failure" conditions can catch this. + if (success && !success_block) { + success = F_false; + } + + success_block = F_true; } } } @@ -1423,6 +1452,7 @@ extern "C" { if (state_process.block_result == fake_condition_result_error_e) { state_process.block = fake_state_process_block_if_skip_e; state_process.block_result = fake_condition_result_false_e; + success_block = F_false; } else { state_process.block = fake_state_process_block_if_e; @@ -1487,6 +1517,13 @@ extern "C" { break; } + else if (*status == F_failure) { + + // When F_failure (without the error bit) is returned, an error occured but the exit mode is not set to exit. + // Record the success state and set the status to F_none. + *status = F_none; + success = F_false; + } else { success = F_true; } diff --git a/level_3/fake/c/private-make-operate_process.c b/level_3/fake/c/private-make-operate_process.c index 4fca8f0..b9a5705 100644 --- a/level_3/fake/c/private-make-operate_process.c +++ b/level_3/fake/c/private-make-operate_process.c @@ -644,7 +644,7 @@ extern "C" { return F_status_set_error(F_failure); } - return F_none; + return F_failure; } #endif // _di_fake_make_operate_process_return_ diff --git a/level_3/fake/c/private-make-operate_process.h b/level_3/fake/c/private-make-operate_process.h index 6cc6dce..8ac9dc7 100644 --- a/level_3/fake/c/private-make-operate_process.h +++ b/level_3/fake/c/private-make-operate_process.h @@ -78,6 +78,8 @@ extern "C" { * * @return * F_none on success. + * F_failure on identifying the return code as an error code and fail mode is not set to fake_make_operation_fail_type_exit_e. + * * 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_e. * * Errors (with error bit) from: f_conversion_number_signed_to_string(). diff --git a/level_3/fake/documents/fakefile.txt b/level_3/fake/documents/fakefile.txt index 4a0c719..253bd3d 100644 --- a/level_3/fake/documents/fakefile.txt +++ b/level_3/fake/documents/fakefile.txt @@ -248,7 +248,7 @@ Fakefile Documentation: Test if file exists. For example, "if exists "a.txt" "b.txt" would test if both the file a.txt and b.txt exist. - - fail\: + - failure\: Test if the previous section operation failed. - group "some mode" "some file"\: diff --git a/level_3/fake/specifications/fakefile.txt b/level_3/fake/specifications/fakefile.txt index e6d935d..c94b058 100644 --- a/level_3/fake/specifications/fakefile.txt +++ b/level_3/fake/specifications/fakefile.txt @@ -82,7 +82,7 @@ Fakefile Specification: - <=: Two or more Content. - <>: Two or more Content. - defined: First Content is either "parameter" or "environment". Second or more Content are valid names, such that for "parameter" it is a valid IKI name and for "environment" it is a valid environment variable name. - - fail: has no other Content. + - failure: has no other Content. - group: First Content is the name of a group. Second or more Content are paths to files. - is: First Content is a list of "block", "character", "directory", "fifo", "link", "regular" , or "socket" followed by "for" and then the Remaining Content that are paths to files. - mode: First Content is either "is" or "has". Second Content is a valid file mode. Third or more Content are paths to files. -- 1.8.3.1