From: Kevin Day Date: Sat, 18 Jul 2020 05:08:58 +0000 (-0500) Subject: Progress: featureless make. X-Git-Tag: 0.5.0~79 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=c04157605f8e5519ae8850302e0918d6690868c1;p=fll Progress: featureless make. I flip-flopped on how I wanted to handle the print functions and need to update/rewrite them again after this commit. The end of an operation always prints the section, line number, etc.., so I do not need as many custom print functions as I ended up doing in this commit. This begins processing the stack path. The pre-process idea just will not work because the argument length is not known until after expansion. This throws away the idea of having a pre-process validation on the operation rules, unfortunately. There are some mistakes in the expand function when handling arguments that need to be fixed. --- diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 5f653de..3a570b4 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -235,7 +235,7 @@ extern "C" { if (F_status_is_error(*status)) { if (data.verbosity == fake_verbosity_verbose) { for (f_string_length j = 0; j < failures.used; j++) { - fake_print_error_operation(data.context, data.verbosity, F_status_set_fine(*status), "fl_directory_copy_content", "copy contents of", "to", path_source.string, destination.string, F_true); + fake_print_error_build_operation_file(data.context, data.verbosity, F_status_set_fine(*status), "fl_directory_copy_content", "copy contents of", "to", path_source.string, destination.string, F_true); } // for if (F_status_set_fine(*status) != F_failure) { @@ -245,7 +245,7 @@ extern "C" { break; } else if (data.verbosity != fake_verbosity_quiet) { - fake_print_error_operation(data.context, data.verbosity, F_status_set_fine(*status), "fl_directory_copy_content", "copy contents of", "to", path_source.string, destination.string, F_true); + fake_print_error_build_operation_file(data.context, data.verbosity, F_status_set_fine(*status), "fl_directory_copy_content", "copy contents of", "to", path_source.string, destination.string, F_true); } break; @@ -269,7 +269,7 @@ extern "C" { *status = f_file_copy(path_source.string, destination_file.string, mode, f_file_default_read_size, F_false); if (F_status_is_error(*status)) { - fake_print_error_operation(data.context, data.verbosity, F_status_set_fine(*status), "f_file_copy", "copy", "to", path_source.string, destination_file.string, F_true); + fake_print_error_build_operation_file(data.context, data.verbosity, F_status_set_fine(*status), "f_file_copy", "copy", "to", path_source.string, destination_file.string, F_true); break; } diff --git a/level_3/fake/c/private-make.c b/level_3/fake/c/private-make.c index 92b04c0..9fe2566 100644 --- a/level_3/fake/c/private-make.c +++ b/level_3/fake/c/private-make.c @@ -10,6 +10,35 @@ extern "C" { #endif +#ifndef _di_fake_make_assure_inside_project_ + f_return_status fake_make_assure_inside_project(const fake_data data, const f_string_static path, fake_make_data *data_make) { + + data_make->path_real.used = 0; + + f_status status = f_path_real(path.string, &data_make->path_real); + if (F_status_is_error(status)) return status; + + const f_string_range range = f_macro_string_range_initialize(data_make->path.stack.array[0].used); + + if (range.start <= range.stop) { + status = fl_string_dynamic_partial_compare(data_make->path.stack.array[0], path, range, range); + if (F_status_is_error(status)) return status; + + if (status) { + if (data_make->path_real.used == data_make->path.stack.array[0].used) { + return F_true; + } + + if (data_make->path_real.string[data_make->path.stack.array[0].used] == f_path_separator[0]) { + return F_true; + } + } + } + + return F_status_set_error(F_false); + } +#endif // _di_fake_make_assure_inside_project_ + #ifndef _di_fake_make_load_fakefile_ void fake_make_load_fakefile(const fake_data data, fake_make_data *data_make, f_status *status) { if (F_status_is_error(*status)) return; @@ -733,97 +762,69 @@ extern "C" { memset(operations, 0, sizeof(uint8_t) * section->objects.used); memset(arguments, 0, sizeof(f_string_dynamics) * section->objects.used); - bool error_none = F_true; - bool process = F_true; - - do { - // pre-process the list to identify invalid commands so that nothing is processed if any operation can be detected as invalid by the pre-process validation. - process = !process; - - for (i = 0; i < section->objects.used; i++) { - operation = 0; - operation_name = 0; + for (i = 0; i < section->objects.used; i++) { + operation = 0; + operation_name = 0; - for (j = 0; j < fake_make_operation_total; j++) { - if (fl_string_dynamic_partial_compare(operations_name[j], data_make->buffer, operations_range[j], section->objects.array[i]) == F_equal_to) { - operation = operations_type[j]; - operation_name = &operations_name[j]; - break; - } - } // for + for (j = 0; j < fake_make_operation_total; j++) { + if (fl_string_dynamic_partial_compare(operations_name[j], data_make->buffer, operations_range[j], section->objects.array[i]) == F_equal_to) { + operation = operations_type[j]; + operation_name = &operations_name[j]; + break; + } + } // for - if (operation == 0) { - fake_print_error_fakefile_section_operation_unknown(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i]); + if (operation == 0) { + fake_print_error_fakefile_section_operation_unknown(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i]); - *status = F_status_set_error(F_invalid); - } - else if (operation == fake_make_operation_type_operate) { - if (section_stack->used == fake_make_section_stack_max) { - fake_print_error_fakefile_section_operation_stack_max(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i], fake_make_section_stack_max); + *status = F_status_set_error(F_invalid); + } + else if (operation == fake_make_operation_type_operate) { + if (section_stack->used == fake_make_section_stack_max) { + fake_print_error_fakefile_section_operation_stack_max(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i], fake_make_section_stack_max); - *status = F_status_set_error(F_recurse); - } + *status = F_status_set_error(F_recurse); } + } - // find and report all unknown operations before exiting. - if (F_status_is_error(*status)) { - error_none = F_false; - *status = F_none; - continue; - } + if (F_status_is_error(*status)) break; - operations[i] = operation; + operations[i] = operation; - if (process) { - fake_make_operate_expand(data, section->name, operation, *operation_name, section->contents.array[i], section->quotedss.array[i], data_make, &arguments[i], status); - if (F_status_is_error(*status)) { - error_none = F_false; - continue; - } - } + fake_make_operate_expand(data, section->name, operation, *operation_name, section->contents.array[i], section->quotedss.array[i], data_make, &arguments[i], status); + if (F_status_is_error(*status)) break; - fake_make_operate_validate(data, section->name, operation, *operation_name, *data_make, arguments[i], operation_if, process, status); + fake_make_operate_validate(data, section->name, operation, *operation_name, *data_make, arguments[i], operation_if, status); - if (operation_if) { - if (operation_if == fake_make_operation_if_type_if) { - operation_if = fake_make_operation_if_type_else; - } - else if (operation_if == fake_make_operation_if_type_else) { - if (operation == fake_make_operation_type_if) { - operation_if = fake_make_operation_if_type_if; - } - else { - operation_if = 0; - } + if (operation_if) { + if (operation_if == fake_make_operation_if_type_if) { + operation_if = fake_make_operation_if_type_else; + } + else if (operation_if == fake_make_operation_if_type_else) { + if (operation == fake_make_operation_type_if) { + operation_if = fake_make_operation_if_type_if; } else { operation_if = 0; } } - else if (operation == fake_make_operation_type_if) { - operation_if = fake_make_operation_if_type_if; - } - - if (F_status_is_error(*status)) { - error_none = F_false; - *status = F_none; - continue; + else { + operation_if = 0; } + } + else if (operation == fake_make_operation_type_if) { + operation_if = fake_make_operation_if_type_if; + } - if (error_none && process) { - fake_make_operate_perform(data, section->name, operation, *operation_name, arguments[i], operation_if, data_make, status); + if (F_status_is_error(*status)) break; - if (F_status_is_error(*status)) { - fake_print_error_fakefile_section_operation_failed(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i]); - break; - } - } - } // for - } while (error_none && !process); + fake_make_operate_perform(data, section->name, operation, *operation_name, section->objects.array[i], arguments[i], operation_if, data_make, status); - if (!error_none && F_status_is_fine(*status)) { - *status = F_status_set_error(F_failure); - } + if (F_status_is_error(*status)) { + fake_print_error_fakefile_section_operation_failed(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i]); + break; + } + } // for for (i = 0; i < section->objects.used; i++) { f_macro_string_dynamics_delete_simple(arguments[i]); @@ -832,7 +833,7 @@ extern "C" { #endif // _di_fake_make_operate_section_ #ifndef _di_fake_make_operate_perform_ - void fake_make_operate_perform(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) { + void fake_make_operate_perform(const fake_data data, const f_string_range section_name, const uint8_t operation, const f_string_static operation_name, const f_string_range operation_range, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) { if (F_status_is_error(*status)) return; if (operation == fake_make_operation_type_archive) { @@ -865,6 +866,7 @@ extern "C" { } if (operation == fake_make_operation_type_create) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -877,6 +879,7 @@ extern "C" { } if (operation == fake_make_operation_type_delete) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -893,6 +896,7 @@ extern "C" { } if (operation == fake_make_operation_type_group) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -905,6 +909,7 @@ extern "C" { } if (operation == fake_make_operation_type_link) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -912,6 +917,7 @@ extern "C" { } if (operation == fake_make_operation_type_mode) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -924,6 +930,7 @@ extern "C" { } if (operation == fake_make_operation_type_owner) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -970,16 +977,70 @@ extern "C" { } if (operation == fake_make_operation_type_to) { - // @todo: change directory. + *status = fake_make_assure_inside_project(data, arguments.array[0], data_make); + if (F_status_is_error(*status)) { + fake_print_error_fakefile_section_operation_path_outside(data.context, data.verbosity, *status, "fake_make_assure_inside_project", data_make->buffer, section_name, operation_range, arguments.array[0].string); + + if (F_status_set_fine(*status) == F_false) { + *status = F_status_set_error(F_failure); + } + + return; + } + + *status = f_path_change(arguments.array[0].string); + if (F_status_is_error(*status)) { + fake_print_error_fakefile_section_line(data.context, data.verbosity, F_status_set_fine(*status), "f_path_change", data_make->buffer, section_name, operation_range, arguments.array[0].string); + } + else { + if (data_make->path.stack.used == data_make->path.stack.size) { + if (data_make->path.stack.used + 1 >= f_array_length_size) { + *status = F_status_set_error(F_buffer_too_large); + fake_print_error_fakefile_section_line(data.context, data.verbosity, F_buffer_too_large, "f_macro_string_dynamics_resize", data_make->buffer, section_name, operation_range, "path stack"); + return; + } + + if (data_make->path.stack.used + f_memory_default_allocation_step >= f_array_length_size) { + f_macro_string_dynamics_resize(*status, data_make->path.stack, data_make->path.stack.size + 1); + } + else { + f_macro_string_dynamics_resize(*status, data_make->path.stack, data_make->path.stack.size + f_memory_default_allocation_step); + } + + if (F_status_is_error(*status)) { + fake_print_error_fakefile_section_line(data.context, data.verbosity, F_status_set_fine(*status), "f_macro_string_dynamics_resize", data_make->buffer, section_name, operation_range, 0); + return; + } + } + + // copy the entire real path, including the trailing NULL. + data_make->path_real.used++; + + fl_string_dynamic_append_nulless(data_make->path_real, &data_make->path.stack.array[data_make->path.stack.used]); + + // reset the used to disclude the trailing NULL. + data_make->path_real.used--; + + if (F_status_is_error(*status)) { + fake_print_error_fakefile_section_line(data.context, data.verbosity, F_status_set_fine(*status), "fl_string_dynamic_append_nulless", data_make->buffer, section_name, operation_range, 0); + return; + } + + data_make->path.stack.used++; + + // @todo: if verbose, then print the directory change (strip out the project root part of the path when printing). + } + return; } if (operation == fake_make_operation_type_top) { - // @todo: change directory. + *status = f_path_change_at(data_make->path.top); return; } if (operation == fake_make_operation_type_touch) { + // fake_make_assure_inside_project // *status = fll_execute_arguments_add(values[i], lengths[i], &arguments); //fake_build_arguments_standard_add(data, data_build, F_true, F_true, &arguments, status); //fake_build_execute(data, data_build, data_build.setting.build_compiler, arguments, status); @@ -998,6 +1059,8 @@ extern "C" { if (F_status_is_error(*status)) { // @todo: convert F_status_set_fine(*status) to a string and assign that instead of 1. (need a convert function from llu to string.) status2 = fl_string_append("1", 1, &data_make->setting_make.parameter.array[0].value.array[0]); + + // fake_print_error_fakefile_section_line(data.context, data.verbosity, F_status_set_fine(*status), "fake_clean_operate", data_make.buffer, section_name, operation_range, arguments.array[0].string); } else { // @todo: convert return_code to a string and assign that instead of 0. (need a convert function from llu to string.) @@ -1019,7 +1082,7 @@ extern "C" { #endif // _di_fake_make_operate_perform_process_return_ #ifndef _di_fake_make_operate_validate_ - void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, const bool process, f_status *status) { + void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, f_status *status) { if (F_status_is_error(*status)) return; if (operation == fake_make_operation_type_archive || operation == fake_make_operation_type_run || operation == fake_make_operation_type_shell || operation == fake_make_operation_type_touch) { @@ -1033,7 +1096,7 @@ extern "C" { fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); *status = F_status_set_error(F_failure); } - else if (arguments.used && process) { + else if (arguments.used) { if (arguments.array[0].used) { f_status status_file = f_file_is(arguments.array[0].string, f_file_type_regular); @@ -1066,30 +1129,28 @@ extern "C" { } else if (operation == fake_make_operation_type_create || operation == fake_make_operation_type_delete) { if (arguments.used) { - if (process) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_file, arguments.array[0], fake_make_operation_argument_file_length) == F_equal_to) { - if (arguments.used > 2) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); - *status = F_status_set_error(F_failure); - } + if (fl_string_dynamic_compare_string(fake_make_operation_argument_file, arguments.array[0], fake_make_operation_argument_file_length) == F_equal_to) { + if (arguments.used > 2) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + *status = F_status_set_error(F_failure); } - else if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory, arguments.array[0], fake_make_operation_argument_directory_length) == F_equal_to) { - if (arguments.used > 3) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + } + else if (fl_string_dynamic_compare_string(fake_make_operation_argument_directory, arguments.array[0], fake_make_operation_argument_directory_length) == F_equal_to) { + if (arguments.used > 3) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + *status = F_status_set_error(F_failure); + } + else if (arguments.used == 3) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_recursive, arguments.array[0], fake_make_operation_argument_recursive_length) == F_equal_to_not) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "third argument must be either '%s' or not provided at all", fake_make_operation_argument_recursive); *status = F_status_set_error(F_failure); } - else if (arguments.used == 3) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_recursive, arguments.array[0], fake_make_operation_argument_recursive_length) == F_equal_to_not) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "third argument must be either '%s' or not provided at all", fake_make_operation_argument_recursive); - *status = F_status_set_error(F_failure); - } - } - } - else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "unsupported file type '%s'", arguments.array[0].string); - *status = F_status_set_error(F_failure); } } + else { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "unsupported file type '%s'", arguments.array[0].string); + *status = F_status_set_error(F_failure); + } } else { fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); @@ -1098,10 +1159,8 @@ extern "C" { } else if (operation == fake_make_operation_type_define) { if (arguments.used) { - if (process) { - // @todo: validate that first argument is a valid define name. - // @todo: if arguments.used is 1, then value is assigned to null. - } + // @todo: validate that first argument is a valid define name. + // @todo: if arguments.used is 1, then value is assigned to null. } else { fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); @@ -1120,13 +1179,11 @@ extern "C" { } else if (operation == fake_make_operation_type_fail) { if (arguments.used) { - if (process) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_error, arguments.array[0], fake_make_operation_argument_error_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn, arguments.array[0], fake_make_operation_argument_warn_length) == F_equal_to_not) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore, arguments.array[0], fake_make_operation_argument_ignore_length) == F_equal_to_not) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "unsupported fail type '%s'", arguments.array[0].string); - *status = F_status_set_error(F_failure); - } + if (fl_string_dynamic_compare_string(fake_make_operation_argument_error, arguments.array[0], fake_make_operation_argument_error_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_warn, arguments.array[0], fake_make_operation_argument_warn_length) == F_equal_to_not) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_ignore, arguments.array[0], fake_make_operation_argument_ignore_length) == F_equal_to_not) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "unsupported fail type '%s'", arguments.array[0].string); + *status = F_status_set_error(F_failure); } } } @@ -1142,24 +1199,22 @@ extern "C" { *status = F_status_set_error(F_failure); } else if (arguments.used > 1) { - if (process) { - f_status status_file = f_file_is(arguments.array[1].string, f_file_type_regular); + f_status status_file = f_file_is(arguments.array[1].string, f_file_type_regular); - if (F_status_is_error(status_file)) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[1].string); - *status = status_file; - } + if (F_status_is_error(status_file)) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[1].string); + *status = status_file; + } - if (!status_file) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "the file '%s' must be a regular file", arguments.array[1].string); - *status = F_status_set_error(F_failure); - } + if (!status_file) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "the file '%s' must be a regular file", arguments.array[1].string); + *status = F_status_set_error(F_failure); + } - if (arguments.used == 3) { - if (fl_string_dynamic_compare_string(fake_make_operation_argument_recursive, arguments.array[2], fake_make_operation_argument_recursive_length) == F_equal_to_not) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "third argument must be either '%s' or not provided at all", fake_make_operation_argument_recursive); - *status = F_status_set_error(F_failure); - } + if (arguments.used == 3) { + if (fl_string_dynamic_compare_string(fake_make_operation_argument_recursive, arguments.array[2], fake_make_operation_argument_recursive_length) == F_equal_to_not) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "third argument must be either '%s' or not provided at all", fake_make_operation_argument_recursive); + *status = F_status_set_error(F_failure); } } } @@ -1181,47 +1236,45 @@ extern "C" { *status = F_status_set_error(F_failure); } else if (arguments.used == 2) { - if (process) { - f_status status_file = F_none; + f_status status_file = F_none; - if (arguments.array[0].used) { - status_file = f_file_exists(arguments.array[0].string); + if (arguments.array[0].used) { + status_file = f_file_exists(arguments.array[0].string); - if (F_status_is_error(status_file) || !status_file) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[0].string); + if (F_status_is_error(status_file) || !status_file) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[0].string); - if (status_file == F_false) { - *status = F_status_set_error(F_failure); - } - else { - *status = status_file; - } + if (status_file == F_false) { + *status = F_status_set_error(F_failure); + } + else { + *status = status_file; } } - else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "%s filename argument must not be an empty string", fake_make_operation_argument_target); - *status = F_status_set_error(F_failure); - } + } + else { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "%s filename argument must not be an empty string", fake_make_operation_argument_target); + *status = F_status_set_error(F_failure); + } - if (arguments.array[1].used) { - status_file = f_file_exists(arguments.array[1].string); + if (arguments.array[1].used) { + status_file = f_file_exists(arguments.array[1].string); - if (F_status_is_error(status_file) || !status_file) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[1].string); + if (F_status_is_error(status_file) || !status_file) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[1].string); - if (status_file == F_false) { - *status = F_status_set_error(F_failure); - } - else { - *status = status_file; - } + if (status_file == F_false) { + *status = F_status_set_error(F_failure); + } + else { + *status = status_file; } - } - else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "%s filename argument must not be an empty string", fake_make_operation_argument_point); - *status = F_status_set_error(F_failure); } } + else { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "%s filename argument must not be an empty string", fake_make_operation_argument_point); + *status = F_status_set_error(F_failure); + } } else { fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); @@ -1238,24 +1291,22 @@ extern "C" { *status = F_status_set_error(F_failure); } else if (arguments.used) { - if (process) { - if (arguments.array[0].used) { - f_status status_file = f_file_is(arguments.array[0].string, f_file_type_directory); - - if (F_status_is_error(status_file)) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[0].string); - *status = status_file; - } + if (arguments.array[0].used) { + f_status status_file = f_file_is(arguments.array[0].string, f_file_type_directory); - if (!status_file) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "the file '%s' must be a directory file", arguments.array[0].string); - *status = F_status_set_error(F_failure); - } + if (F_status_is_error(status_file)) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "failed to find file '%s'", arguments.array[0].string); + *status = status_file; } - else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "filename argument must not be an empty string"); + + if (!status_file) { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "the file '%s' must be a directory file", arguments.array[0].string); + *status = F_status_set_error(F_failure); } } + else { + fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "filename argument must not be an empty string"); + } } else { fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); diff --git a/level_3/fake/c/private-make.h b/level_3/fake/c/private-make.h index b0a3330..b237fb9 100644 --- a/level_3/fake/c/private-make.h +++ b/level_3/fake/c/private-make.h @@ -271,7 +271,9 @@ extern "C" { fake_make_path path; f_fss_nameds fakefile; + f_string_dynamic buffer; + f_string_dynamic path_real; // used as a cache for determining a real path. f_array_length main; @@ -286,6 +288,7 @@ extern "C" { fake_make_path_initialize, \ f_fss_nameds_initialize, \ f_string_dynamic_initialize, \ + f_string_dynamic_initialize, \ 0, \ 0, \ } @@ -297,10 +300,32 @@ extern "C" { fake_macro_make_parameter_delete_simple(data.parameter) \ fake_macro_make_path_delete_simple(data.path) \ f_macro_fss_nameds_delete_simple(data.fakefile) \ - f_macro_string_dynamic_delete_simple(data.buffer) + f_macro_string_dynamic_delete_simple(data.buffer) \ + f_macro_string_dynamic_delete_simple(data.path_real) #endif // _di_fake_make_data_ /** + * Assure that a path is within the project root path. + * + * @param data + * The program data. + * @param path + * file path to get the real path of. + * @param data_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * The data_make.path_real will be updated to reflect the full path to this file. + * + * @return + * F_true if inside the project. + * F_false (with error bit) if path exists outside of the root project path. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_assure_inside_project_ + extern f_return_status fake_make_assure_inside_project(const fake_data data, const f_string_static path, fake_make_data *data_make) f_gcc_attribute_visibility_internal; +#endif // _di_fake_make_assure_inside_project_ + +/** * Find the fake file, load it, validate it, and process it. * * This will process any additional files as necessary, such as the build settings file. @@ -312,7 +337,6 @@ extern "C" { * @param status * The return status. * - * @return * F_none on success. * * Status codes (with error bit) are returned on any problem. @@ -398,9 +422,11 @@ extern "C" { * @param section_name * The section name. * @param operation - * The operation being performed. + * The operation type. * @param operation_name * The operation name. + * @param operation_range + * The range within the buffer pointing to the operation. * @param arguments * The expanded arguments. * @param operation_if @@ -413,7 +439,7 @@ extern "C" { * Status codes (with error bit) are returned on any problem. */ #ifndef _di_fake_make_operate_perform_ - extern void fake_make_operate_perform(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) f_gcc_attribute_visibility_internal; + extern void fake_make_operate_perform(const fake_data data, const f_string_range section_name, const uint8_t operation, const f_string_static operation_name, const f_string_range operation_range, const f_string_dynamics arguments, const uint8_t operation_if, fake_make_data *data_make, f_status *status) f_gcc_attribute_visibility_internal; #endif // _di_fake_make_operate_perform_ /** @@ -452,16 +478,13 @@ extern "C" { * The expanded arguments. * @param operation_if * The if-condition status for the current operation. - * @param process - * Set to TRUE if this is a process validation, FALSE if this is a pre-process validation. - * A pre-process validation does not check for content because content is not yet expanded. * @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(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, const bool process, f_status *status) f_gcc_attribute_visibility_internal; + extern void fake_make_operate_validate(const fake_data data, const f_string_range section_name, const f_array_length operation, const f_string_static operation_name, const fake_make_data data_make, const f_string_dynamics arguments, const uint8_t operation_if, f_status *status) f_gcc_attribute_visibility_internal; #endif // _di_fake_make_operate_validate_ /** diff --git a/level_3/fake/c/private-print.c b/level_3/fake/c/private-print.c index 466b982..68d495e 100644 --- a/level_3/fake/c/private-print.c +++ b/level_3/fake/c/private-print.c @@ -44,6 +44,227 @@ extern "C" { } #endif // _di_fake_print_error_ +#ifndef _di_fake_print_error_build_operation_file_ + bool fake_print_error_build_operation_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string operation, const f_string how, const f_string source, const f_string destination, const bool fallback) { + + if (status == F_file_found_not) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to find '"); + + if (f_file_exists(source) == F_true) { + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + else { + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + } + + fl_color_print(f_type_error, context.error, context.reset, "' while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_parameter) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling "); + fl_color_print(f_type_error, context.notable, context.reset, "%s", function); + fl_color_print(f_type_error, context.error, context.reset, "() to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_name) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid name for '"); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' or '"); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_memory_out) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_number_overflow) { + if (verbosity != fake_verbosity_quiet) { + + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Overflow while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_directory) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid directory while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_access_denied) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Access denied while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_loop) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Loop while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_prohibited) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Prohibited by system while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (status == F_directory_found_not) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path."); + } + + return F_false; + } + + if (status == F_failure) { + if (verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_false; + } + + if (fake_print_error(context, verbosity, status, function, F_false) == F_unknown && fallback && verbosity != fake_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: ("); + fl_color_print(f_type_error, context.notable, context.reset, "%llu", status); + fl_color_print(f_type_error, context.error, context.reset, ") occurred while trying to %s '", operation); + fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + + if (destination) { + fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); + fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + } + + fl_color_print_line(f_type_error, context.error, context.reset, "'."); + } + + return F_true; + } +#endif // _di_fake_print_error_build_operation_file_ + #ifndef _di_fake_print_error_fakefile_section_ bool fake_print_error_fakefile_section(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const bool fallback) { @@ -67,36 +288,52 @@ extern "C" { #endif // _di_fake_print_error_fakefile_section_ #ifndef _di_fake_print_error_fakefile_section_line_ - bool fake_print_error_fakefile_section_line(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const bool fallback) { + void fake_print_error_fakefile_section_line(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const f_string string) { + if (verbosity == fake_verbosity_quiet) return; f_string_length line = 0; f_fss_count_lines(buffer, operation_name.start, &line); - if (fake_print_error(context, verbosity, status, function, F_false) == F_unknown && fallback && verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); + fprintf(f_type_error, "%c", f_string_eol[0]); + + if (status == F_parameter) { + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid parameter"); + } + else if (status == F_memory_allocation || status == F_memory_reallocation) { + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Unable to allocate memory"); + } + else if (status == F_buffer_too_large) { + fl_color_print(f_type_error, context.error, context.reset, "ERROR: Maximum size reached for %s array", string ? string : ""); + } + else { fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: ("); fl_color_print(f_type_error, context.notable, context.reset, "%llu", status); - fl_color_print(f_type_error, context.error, context.reset, ") occurred while calling "); + fl_color_print(f_type_error, context.error, context.reset, ") occurred"); + } + + if (function) { + fl_color_print(f_type_error, context.error, context.reset, " while calling "); fl_color_print(f_type_error, context.notable, context.reset, "%s", function); fl_color_print(f_type_error, context.error, context.reset, "() for section '"); + } + else { + fl_color_print(f_type_error, context.error, context.reset, " while operating section '"); + } - fl_color_print_code(f_type_error, context.notable); - f_print_string_dynamic_partial(f_type_error, buffer, section_name); - fl_color_print_code(f_type_error, context.reset); - - fl_color_print(f_type_error, context.error, context.reset, " on line "); - fl_color_print(f_type_error, context.notable, context.reset, "%llu", line); - fl_color_print(f_type_error, context.error, context.reset, ", operation '"); + fl_color_print_code(f_type_error, context.notable); + f_print_string_dynamic_partial(f_type_error, buffer, section_name); + fl_color_print_code(f_type_error, context.reset); - fl_color_print_code(f_type_error, context.notable); - f_print_string_dynamic_partial(f_type_error, buffer, operation_name); - fl_color_print_code(f_type_error, context.reset); + fl_color_print(f_type_error, context.error, context.reset, " on line "); + fl_color_print(f_type_error, context.notable, context.reset, "%llu", line); + fl_color_print(f_type_error, context.error, context.reset, ", operation '"); - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } + fl_color_print_code(f_type_error, context.notable); + f_print_string_dynamic_partial(f_type_error, buffer, operation_name); + fl_color_print_code(f_type_error, context.reset); - return F_true; + fl_color_print_line(f_type_error, context.error, context.reset, "'."); } #endif // _di_fake_print_error_fakefile_section_line_ @@ -416,226 +653,40 @@ extern "C" { } #endif // _di_fake_print_error_fss -#ifndef _di_fake_print_error_operation_ - bool fake_print_error_operation(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string operation, const f_string how, const f_string source, const f_string destination, const bool fallback) { - - if (status == F_file_found_not) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to find '"); - - if (f_file_exists(source) == F_true) { - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - else { - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - } - - fl_color_print(f_type_error, context.error, context.reset, "' while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_parameter) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling "); - fl_color_print(f_type_error, context.notable, context.reset, "%s", function); - fl_color_print(f_type_error, context.error, context.reset, "() to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_name) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid name for '"); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' or '"); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_memory_out) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_number_overflow) { - if (verbosity != fake_verbosity_quiet) { - - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Overflow while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_directory) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid directory while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_access_denied) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Access denied while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_loop) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Loop while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } - - return F_false; - } - - if (status == F_prohibited) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Prohibited by system while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } +#ifndef _di_fake_print_error_fakefile_section_operation_path_outside_ + void fake_print_error_fakefile_section_operation_path_outside(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const f_string path) { + if (verbosity != fake_verbosity_quiet) { - fl_color_print_line(f_type_error, context.error, context.reset, "'."); - } + if (F_status_set_fine(status) == F_false) { + f_string_length line = 0; - return F_false; - } + f_fss_count_lines(buffer, operation_name.start, &line); - if (status == F_directory_found_not) { - if (verbosity != fake_verbosity_quiet) { fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } + fl_color_print(f_type_error, context.error, context.reset, "ERROR: the path '"); + fl_color_print(f_type_error, context.notable, context.reset, "%s", path); + fl_color_print(f_type_error, context.error, context.reset, "' is outside the project root for section '"); - fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path."); - } - - return F_false; - } + fl_color_print_code(f_type_error, context.notable); + f_print_string_dynamic_partial(f_type_error, buffer, section_name); + fl_color_print_code(f_type_error, context.reset); - if (status == F_failure) { - if (verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); + fl_color_print(f_type_error, context.error, context.reset, " on line "); + fl_color_print(f_type_error, context.notable, context.reset, "%llu", line); + fl_color_print(f_type_error, context.error, context.reset, ", operation '"); - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); - } + fl_color_print_code(f_type_error, context.notable); + f_print_string_dynamic_partial(f_type_error, buffer, operation_name); + fl_color_print_code(f_type_error, context.reset); fl_color_print_line(f_type_error, context.error, context.reset, "'."); } - - return F_false; - } - - if (fake_print_error(context, verbosity, status, function, F_false) == F_unknown && fallback && verbosity != fake_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: ("); - fl_color_print(f_type_error, context.notable, context.reset, "%llu", status); - fl_color_print(f_type_error, context.error, context.reset, ") occurred while trying to %s '", operation); - fl_color_print(f_type_error, context.notable, context.reset, "%s", source); - - if (destination) { - fl_color_print(f_type_error, context.error, context.reset, "' %s '", how); - fl_color_print(f_type_error, context.notable, context.reset, "%s", destination); + else { + fake_print_error_fakefile_section_line(context, verbosity, status, function, buffer, section_name, operation_name, path); } - - fl_color_print_line(f_type_error, context.error, context.reset, "'."); } - - return F_true; } -#endif // _di_fake_print_error_operation_ +#endif // _di_fake_print_error_fakefile_section_operation_path_outside_ #ifndef _di_fake_print_error_parameter_missing_value_ void fake_print_error_parameter_missing_value(const fl_color_context context, const uint8_t verbosity, const f_string parameter) { diff --git a/level_3/fake/c/private-print.h b/level_3/fake/c/private-print.h index 86d42ef..7260465 100644 --- a/level_3/fake/c/private-print.h +++ b/level_3/fake/c/private-print.h @@ -35,6 +35,40 @@ extern "C" { #endif // _di_fake_print_error_ /** + * Print build operation file error messages. + * + * @param context + * The color context. + * @param verbosity + * The verbosity level, which determines if and what should be printed. + * @param status + * The error status code to report on. + * @param function + * The name of the function where the error happened. + * @param operation + * The operation performed. + * @param source + * The operation source. + * Set to 0 to disable. + * @param destination + * The operation destination, if applicable. + * Requires source to be non-zero. + * Set to 0 to disable. + * @param how + * The how the operation is perform, such as "to" in "copy" source "to" destination. + * Requires source and destination to be non-zero. + * @param fallback + * Set to F_true to print the fallback error message for unknown errors. + * + * @return + * F_true is returned if the status code has no print message. + * F_false is returned on successful print of known errors. + */ +#ifndef _di_fake_print_error_operation_file_ + extern bool fake_print_error_build_operation_file(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string operation, const f_string source, const f_string destination, const f_string how, const bool fallback) f_gcc_attribute_visibility_internal; +#endif // _di_fake_print_error_operation_file_ + +/** * Print error messages when processing some fakefile section. * * @param context @@ -71,21 +105,19 @@ extern "C" { * The status code representing an error. * @param function * The name of the function where the error happened. + * Set to 0 to disable. * @param buffer * The buffer containing the fakefile data. * @param section_name * The range within the buffer representing the section name. * @param operation_name * The range within the buffer representing the operation name within the section. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * - * @return - * F_none is returned on successful print of known errors. - * F_unknown is returned if the status code has no print message. + * @param string + * A string used by certain error conditions. + * Set to 0 disable. */ #ifndef _di_fake_print_error_fakefile_section_line_ - extern bool fake_print_error_fakefile_section_line(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const bool fallback) f_gcc_attribute_visibility_internal; + extern void fake_print_error_fakefile_section_line(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const f_string string) f_gcc_attribute_visibility_internal; #endif // _di_fake_print_error_fakefile_section_line_ /** @@ -107,6 +139,30 @@ extern "C" { #endif // _di_fake_print_error_fakefile_section_operation_failed_ /** + * Print error messages when processing some fakefile section, for a specific line and operation, and that operation has a path outside of the project root. + * + * @param context + * The color context. + * @param verbosity + * The verbosity level, which determines if and what should be printed. + * @param status + * The status code representing an error. + * @param function + * The name of the function where the error happened. + * @param buffer + * The buffer containing the fakefile data. + * @param section_name + * The range within the buffer representing the section name. + * @param operation_name + * The range within the buffer representing the operation name within the section. + * @param path + * The path that is outside of the project path. + */ +#ifndef _di_fake_print_error_fakefile_section_operation_path_outside_ + extern void fake_print_error_fakefile_section_operation_path_outside(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name, const f_string path) f_gcc_attribute_visibility_internal; +#endif // _fake_print_error_fakefile_section_operation_path_outside_ + +/** * Print error messages when processing some fakefile section, for a specific line and operation, and that the max stack depth is reached. * * @param context @@ -218,40 +274,9 @@ extern "C" { * F_true is returned if the status code has no print message. * F_false is returned on successful print of known errors. */ -#ifndef _di_fake_print_error_fss +#ifndef _di_fake_print_error_fss_ extern bool fake_print_error_fss(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string path_file, const f_string_range range, const bool fallback) f_gcc_attribute_visibility_internal; -#endif // _di_fake_print_error_fss - -/** - * Print operation error messages. - * - * @param context - * The color context. - * @param verbosity - * The verbosity level, which determines if and what should be printed. - * @param status - * The error status code to report on. - * @param function - * The name of the function where the error happened. - * @param operation - * The operation performed. - * @param how - * The how the operation is perform, such as "to" in "copy" source "to" destination. - * @param source - * The operation source. - * @param destination - * The operation destination, if applicable. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * - * @return - * F_true is returned if the status code has no print message. - * F_false is returned on successful print of known errors. - */ -#ifndef _di_fake_print_error_operation_ - extern bool fake_print_error_operation(const fl_color_context context, const uint8_t verbosity, const f_status status, const f_string function, const f_string operation, const f_string how, const f_string source, const f_string destination, const bool fallback) f_gcc_attribute_visibility_internal; -#endif // _di_fake_print_error_operation_ +#endif // _di_fake_print_error_fss_ /** * Print an error message for when the parameter is missing its accompanying value. diff --git a/level_3/fake/data/build/fakefile b/level_3/fake/data/build/fakefile index 979692e..0f6aa6a 100644 --- a/level_3/fake/data/build/fakefile +++ b/level_3/fake/data/build/fakefile @@ -25,3 +25,12 @@ main: build print Result = \'parameter:"result"' + + to sources + print should have changed to sources + + to invalid + print should have errored before this + + to /tmp + print should not be allowed to leave project root.