From 58aaa66917b43bd9166b8d66e40181be451a8380 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 18 Jul 2020 00:08:58 -0500 Subject: [PATCH] Progress: featureless make. Wrap up the path change operations. Cleanup additional print functions that are no longer needed. --- level_3/fake/c/private-make.c | 302 +++++++++++++++++++++++++++++++-------- level_3/fake/c/private-make.h | 24 +++- level_3/fake/c/private-print.c | 112 ++++++--------- level_3/fake/c/private-print.h | 28 +--- level_3/fake/data/build/fakefile | 25 +--- 5 files changed, 316 insertions(+), 175 deletions(-) diff --git a/level_3/fake/c/private-make.c b/level_3/fake/c/private-make.c index b6f4739..1f41a86 100644 --- a/level_3/fake/c/private-make.c +++ b/level_3/fake/c/private-make.c @@ -13,23 +13,27 @@ extern "C" { #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; + data_make->path_cache.used = 0; - f_status status = f_path_real(path.string, &data_make->path_real); + f_status status = f_path_real(path.string, &data_make->path_cache); if (F_status_is_error(status)) return status; + if (data_make->path_cache.used < data_make->path.stack.array[0].used) { + return F_status_set_error(F_false); + } + 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); + status = fl_string_dynamic_partial_compare(data_make->path.stack.array[0], data_make->path_cache, 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) { + if (data_make->path_cache.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]) { + if (data_make->path_cache.string[data_make->path.stack.array[0].used] == f_path_separator[0]) { return F_true; } } @@ -365,6 +369,8 @@ extern "C" { return status; } + data_make.path.stack.used = 1; + f_macro_mode_set_default_umask(mode, data.umask); data_make.fail = fake_make_operation_fail_type_exit; @@ -816,9 +822,9 @@ extern "C" { operation_if = fake_make_operation_if_type_if; } - if (F_status_is_error(*status)) break; - - fake_make_operate_perform(data, section->name, operation, *operation_name, arguments[i], operation_if, data_make, status); + if (F_status_is_fine(*status)) { + fake_make_operate_perform(data, section->name, operation, *operation_name, arguments[i], operation_if, data_make, status); + } if (F_status_is_error(*status)) { fake_print_error_fakefile_section_operation_failed(data, data_make->buffer, section->name, section->objects.array[i]); @@ -938,7 +944,35 @@ extern "C" { } if (operation == fake_make_operation_type_pop) { - // @todo: change directory. + f_macro_string_dynamic_delete_simple(data_make->path.stack.array[data_make->path.stack.used - 1]); + + data_make->path.stack.used--; + + *status = f_path_change(data_make->path.stack.array[data_make->path.stack.used - 1].string); + if (F_status_is_error(*status)) { + fake_print_error_fakefile_path_stack(data, F_status_set_fine(*status), "f_path_change", data_make->path.stack.array[data_make->path.stack.used - 1].string); + return; + } + + if (data.verbosity == fake_verbosity_verbose) { + *status = fake_make_path_relative(data, data_make->path.stack.array[data_make->path.stack.used - 1], data_make); + if (F_status_is_error(*status)) { + fake_print_error(data, F_status_set_fine(*status), "fake_make_path_relative", F_true); + return; + } + + printf("%c", f_string_eol[0]); + printf("Changed to project path '"); + + if (data_make->path_cache.used) { + fl_color_print_code(f_type_output, data.context.notable); + f_print_string_dynamic(f_type_output, data_make->path_cache); + fl_color_print_code(f_type_error, data.context.reset); + } + + printf("'.%c", f_string_eol[0]); + } + return; } @@ -979,7 +1013,7 @@ extern "C" { if (operation == fake_make_operation_type_to) { *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, *status, "fake_make_assure_inside_project", arguments.array[0].string); + fake_print_error_fakefile_section_operation_path_outside(data, F_status_set_fine(*status), "fake_make_assure_inside_project", arguments.array[0].string); if (F_status_set_fine(*status) == F_false) { *status = F_status_set_error(F_failure); @@ -990,13 +1024,13 @@ extern "C" { *status = f_path_change(arguments.array[0].string); if (F_status_is_error(*status)) { - fake_print_error_fakefile_section_line(data, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); + fake_print_error_fakefile_path_stack(data, F_status_set_fine(*status), "f_path_change", 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, F_buffer_too_large, "f_macro_string_dynamics_resize", "path stack"); + fake_print_error_fakefile_path_stack(data, F_buffer_too_large, "f_macro_string_dynamics_resize", "path stack"); return; } @@ -1008,27 +1042,41 @@ extern "C" { } if (F_status_is_error(*status)) { - fake_print_error_fakefile_section_line(data, F_status_set_fine(*status), "f_macro_string_dynamics_resize", 0); + fake_print_error(data, F_status_set_fine(*status), "f_macro_string_dynamics_resize", F_true); 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]); + data_make->path_cache.used++; - // reset the used to disclude the trailing NULL. - data_make->path_real.used--; + fl_string_dynamic_append(data_make->path_cache, &data_make->path.stack.array[data_make->path.stack.used]); if (F_status_is_error(*status)) { - fake_print_error_fakefile_section_line(data, F_status_set_fine(*status), "fl_string_dynamic_append_nulless", 0); + fake_print_error(data, F_status_set_fine(*status), "fl_string_dynamic_append_nulless", F_true); return; } - data_make->path.stack.used++; + if (data.verbosity == fake_verbosity_verbose) { + *status = fake_make_path_relative(data, data_make->path.stack.array[data_make->path.stack.used], data_make); + if (F_status_is_error(*status)) { + fake_print_error(data, F_status_set_fine(*status), "fake_make_path_relative", F_true); + return; + } + + printf("%c", f_string_eol[0]); + printf("Changed to project path '"); + + if (data_make->path_cache.used) { + fl_color_print_code(f_type_output, data.context.notable); + f_print_string_dynamic(f_type_output, data_make->path_cache); + fl_color_print_code(f_type_error, data.context.reset); + } - // @todo: if verbose, then print the directory change (strip out the project root part of the path when printing). + printf("'.%c", f_string_eol[0]); + } + + data_make->path.stack.used++; } return; @@ -1036,6 +1084,23 @@ extern "C" { if (operation == fake_make_operation_type_top) { *status = f_path_change_at(data_make->path.top); + if (F_status_is_error(*status)) { + fake_print_error_fakefile_path_stack(data, F_status_set_fine(*status), "f_path_change", arguments.array[0].string); + return; + } + + if (data.verbosity == fake_verbosity_verbose) { + printf("%c", f_string_eol[0]); + printf("Changed to project path ''.%c", f_string_eol[0]); + } + + // clear stack, except for the project root. + for (f_array_length i = 1; i < data_make->path.stack.used; i++) { + f_macro_string_dynamic_delete_simple(data_make->path.stack.array[i]); + } // for + + data_make->path.stack.used = 1; + return; } @@ -1060,7 +1125,7 @@ extern "C" { // @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, F_status_set_fine(*status), "fake_clean_operate", data_make.buffer, section_name, operation_range, arguments.array[0].string); + // fake_print_error_fakefile_path_stack(data, 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.) @@ -1087,13 +1152,17 @@ extern "C" { 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) { if (arguments.used == 0) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } else if (operation == fake_make_operation_type_build) { if (arguments.used > 1) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has too many arguments."); + *status = F_status_set_error(F_failure); } else if (arguments.used) { @@ -1101,29 +1170,52 @@ extern "C" { f_status status_file = f_file_is(arguments.array[0].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[0].string); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); + *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[0].string); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: The file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' must be a regular file."); + *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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Filename argument must not be an empty string."); + + *status = F_status_set_error(F_failure); } } } else if (operation == fake_make_operation_type_clean || operation == fake_make_operation_type_pop || operation == fake_make_operation_type_top || operation == fake_make_operation_type_skeleton) { if (arguments.used) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has too many arguments."); + *status = F_status_set_error(F_failure); } + else if (operation == fake_make_operation_type_pop) { + if (data_make.path.stack.used == 1) { + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Must not attempt to pop project root off of path stack."); + + *status = F_status_set_error(F_failure); + } + } } else if (operation == fake_make_operation_type_compile) { if (arguments.used == 0) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } @@ -1131,29 +1223,43 @@ extern "C" { if (arguments.used) { 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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: 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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Third argument must be either '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", fake_make_operation_argument_recursive); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' or not provided at all."); + *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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Unsupported file type '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); + *status = F_status_set_error(F_failure); } } else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } @@ -1163,17 +1269,23 @@ extern "C" { // @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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } else if (operation == fake_make_operation_type_else) { if (operation_if == fake_make_operation_if_type_else) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "must not be used after another else condition"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Must not be used after another else condition."); + *status = F_status_set_error(F_failure); } else if (!operation_if) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has no preceding if condition"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has no preceding if condition."); + *status = F_status_set_error(F_failure); } } @@ -1182,57 +1294,83 @@ extern "C" { 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Unsupported file type '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); + *status = F_status_set_error(F_failure); } } } } else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } else if (operation == fake_make_operation_type_group || operation == fake_make_operation_type_mode || operation == fake_make_operation_type_owner) { if (arguments.used > 3) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has too many arguments."); + *status = F_status_set_error(F_failure); } else if (arguments.used > 1) { 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[1].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); + *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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: The file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[1].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' must be a regular file."); + *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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Third argument must be either '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", fake_make_operation_argument_recursive); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' or not provided at all."); + *status = F_status_set_error(F_failure); } } } else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } else if (operation == fake_make_operation_type_if) { if (operation_if == fake_make_operation_if_type_if) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "must not be used after another if condition"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Must not be used after another if condition."); + *status = F_status_set_error(F_failure); } } else if (operation == fake_make_operation_type_link) { // @todo validate link is outside that the link is or is not outside the project directory. if (arguments.used > 2) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has too many arguments."); + *status = F_status_set_error(F_failure); } else if (arguments.used == 2) { @@ -1242,7 +1380,10 @@ extern "C" { 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); if (status_file == F_false) { *status = F_status_set_error(F_failure); @@ -1253,7 +1394,9 @@ extern "C" { } } 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); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: The %s filename argument must not be an empty string.", fake_make_operation_argument_target); + *status = F_status_set_error(F_failure); } @@ -1261,7 +1404,10 @@ extern "C" { 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[1].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); if (status_file == F_false) { *status = F_status_set_error(F_failure); @@ -1272,12 +1418,16 @@ extern "C" { } } 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); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: 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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } @@ -1287,7 +1437,9 @@ extern "C" { } else if (operation == fake_make_operation_type_to) { if (arguments.used > 1) { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "has too many arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Has too many arguments."); + *status = F_status_set_error(F_failure); } else if (arguments.used) { @@ -1295,21 +1447,32 @@ extern "C" { 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); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Failed to find file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "'."); + *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 directory file", arguments.array[0].string); + printf("%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: The file '"); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", arguments.array[0].string); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' must be a directory file."); + *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"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Filename argument must not be an empty string."); } } else { - fake_print_error_section_operation(data, data_make.buffer,section_name, operation_name, "requires arguments"); + printf("%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "ERROR: Requires arguments."); + *status = F_status_set_error(F_failure); } } @@ -1336,6 +1499,33 @@ extern "C" { } #endif // _di_fake_make_operate_validate_define_name_ +#ifndef _di_fake_make_path_relative_ + f_return_status fake_make_path_relative(const fake_data data, const f_string_static path, fake_make_data *data_make) { + data_make->path_cache.used = 0; + + if (!path.used || path.used == data_make->path.stack.array[0].used) { + return F_none; + } + + if (path.used < data_make->path.stack.array[0].used) { + return F_status_set_error(F_failure); + } + + f_string_range range = f_string_range_initialize; + + range.start = data_make->path.stack.array[0].used + 1; + range.stop = range.start + (path.used - range.start) - 1; + + f_status status = fl_string_dynamic_partial_append(path, range, &data_make->path_cache); + if (F_status_is_error(status)) return status; + + status = fl_string_dynamic_terminate(&data_make->path_cache); + if (F_status_is_error(status)) return status; + + return status; + } +#endif // _di_fake_make_path_relative_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/c/private-make.h b/level_3/fake/c/private-make.h index 359ce2a..dc75baf 100644 --- a/level_3/fake/c/private-make.h +++ b/level_3/fake/c/private-make.h @@ -273,7 +273,7 @@ extern "C" { f_fss_nameds fakefile; f_string_dynamic buffer; - f_string_dynamic path_real; // used as a cache for determining a real path. + f_string_dynamic path_cache; f_array_length main; @@ -301,7 +301,7 @@ extern "C" { 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.path_real) + f_macro_string_dynamic_delete_simple(data.path_cache) #endif // _di_fake_make_data_ /** @@ -313,7 +313,7 @@ extern "C" { * 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. + * The data_make.path_cache will be updated to reflect the full path to this file. * * @return * F_true if inside the project. @@ -504,6 +504,24 @@ extern "C" { extern f_return_status fake_make_operate_validate_define_name(const f_string_static name) f_gcc_attribute_visibility_internal; #endif // _di_fake_make_operate_validate_define_name_ +/** + * Get a path, relative to the project root. + * + * @param data + * The program data. + * @param path + * The NULL terminated path to get the relative path of. + * @param data_make + * All make related setting data, including data from the fakefile and optionally build settings file. + * The relative path is stored in data_make.path_cache. + * + * @return + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_fake_make_path_relative_ + extern f_return_status fake_make_path_relative(const fake_data data, const f_string_static path, fake_make_data *data_make) f_gcc_attribute_visibility_internal; +#endif // _di_fake_make_path_relative_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fake/c/private-print.c b/level_3/fake/c/private-print.c index d81c48a..413950f 100644 --- a/level_3/fake/c/private-print.c +++ b/level_3/fake/c/private-print.c @@ -12,9 +12,16 @@ extern "C" { if (status == F_parameter) { if (data.verbosity != fake_verbosity_quiet) { fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Invalid parameter when calling function "); - fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); - fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Invalid parameter"); + + if (function) { + fl_color_print(f_type_error, data.context.error, data.context.reset, " when calling function "); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + } + else { + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); + } } return F_none; @@ -23,9 +30,16 @@ extern "C" { if (status == F_memory_allocation || status == F_memory_reallocation) { if (data.verbosity != fake_verbosity_quiet) { fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Unable to allocate memory in function "); - fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); - fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Unable to allocate memory"); + + if (function) { + fl_color_print(f_type_error, data.context.error, data.context.reset, " in function "); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + } + else { + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); + } } return F_none; @@ -35,9 +49,16 @@ extern "C" { fprintf(f_type_error, "%c", f_string_eol[0]); fl_color_print(f_type_error, data.context.error, data.context.reset, "UNKNOWN ERROR: ("); fl_color_print(f_type_error, data.context.notable, data.context.reset, "%llu", status); - fl_color_print(f_type_error, data.context.error, data.context.reset, ") in function "); - fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); - fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + fl_color_print(f_type_error, data.context.error, data.context.reset, ")"); + + if (function) { + fl_color_print(f_type_error, data.context.error, data.context.reset, " in function "); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "()."); + } + else { + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); + } } return F_unknown; @@ -265,36 +286,27 @@ extern "C" { } #endif // _di_fake_print_error_build_operation_file_ -#ifndef _di_fake_print_error_fakefile_section_line_ - void fake_print_error_fakefile_section_line(const fake_data data, const f_status status, const f_string function, const f_string string) { +#ifndef _di_fake_print_error_fakefile_path_stack_ + void fake_print_error_fakefile_path_stack(const fake_data data, const f_status status, const f_string function, const f_string string) { if (data.verbosity == fake_verbosity_quiet) return; - fprintf(f_type_error, "%c", f_string_eol[0]); + if (status == F_buffer_too_large) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Maximum size reached for %s array", string); - if (status == F_parameter) { - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Invalid parameter"); - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Unable to allocate memory"); - } - else if (status == F_buffer_too_large) { - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Maximum size reached for%s%s array", string ? " " : "", string ? string : ""); + if (function) { + fl_color_print(f_type_error, data.context.error, data.context.reset, " while calling "); + fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); + fl_color_print(f_type_error, data.context.error, data.context.reset, "()"); + } + + fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); } else { - fl_color_print(f_type_error, data.context.error, data.context.reset, "UNKNOWN ERROR: ("); - fl_color_print(f_type_error, data.context.notable, data.context.reset, "%llu", status); - fl_color_print(f_type_error, data.context.error, data.context.reset, ") occurred"); + fake_print_error(data, status, function, F_true); } - - if (function) { - fl_color_print(f_type_error, data.context.error, data.context.reset, " while calling "); - fl_color_print(f_type_error, data.context.notable, data.context.reset, "%s", function); - fl_color_print(f_type_error, data.context.error, data.context.reset, "()"); - } - - fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); } -#endif // _di_fake_print_error_fakefile_section_line_ +#endif // _di_fake_print_error_fakefile_path_stack_ #ifndef _di_fake_print_error_fakefile_section_operation_failed_ void fake_print_error_fakefile_section_operation_failed(const fake_data data, const f_string_static buffer, const f_string_range section_name, const f_string_range operation_name) { @@ -654,42 +666,6 @@ extern "C" { } #endif // _di_fake_print_error_parameter_too_many_ -#ifndef _di_fake_print_error_section_operation_ - void fake_print_error_section_operation(const fake_data data, const f_string_static buffer, const f_string_range section_name, const f_string_static operation_name, const f_string message, ...) { - if (data.verbosity == fake_verbosity_quiet) return; - - fprintf(f_type_error, "%c", f_string_eol[0]); - - fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: Section '"); - - fl_color_print_code(f_type_error, data.context.notable); - f_print_string_dynamic_partial(f_type_error, buffer, section_name); - fl_color_print_code(f_type_error, data.context.reset); - - fl_color_print(f_type_error, data.context.error, data.context.reset, "' operation '"); - - fl_color_print_code(f_type_error, data.context.notable); - f_print_string_dynamic(f_type_error, operation_name); - fl_color_print_code(f_type_error, data.context.reset); - - fl_color_print(f_type_error, data.context.error, data.context.reset, "' "); - - f_print_string_dynamic(f_type_error, data.context.error); - - va_list ap; - - va_start(ap, message); - - vfprintf(f_type_error, message, ap); - - va_end(ap); - - f_print_string_dynamic(f_type_error, data.context.reset); - - fl_color_print_line(f_type_error, data.context.error, data.context.reset, "."); - } -#endif // _di_fake_print_error_section_operation_ - #ifndef _di_fake_print_warning_fakefile_object_multiple_ void fake_print_warning_fakefile_object_multiple(const fake_data data, const f_string path_file, const f_string label, const f_string name_object) { if (data.verbosity != fake_verbosity_verbose) return; diff --git a/level_3/fake/c/private-print.h b/level_3/fake/c/private-print.h index 969c435..f76bb82 100644 --- a/level_3/fake/c/private-print.h +++ b/level_3/fake/c/private-print.h @@ -21,6 +21,7 @@ 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 fallback * Set to F_true to print the fallback error message for unknown errors. * @@ -76,11 +77,10 @@ extern "C" { * Set to 0 to disable. * @param string * A string used by certain error conditions. - * Set to 0 disable. */ -#ifndef _di_fake_print_error_fakefile_section_line_ - extern void fake_print_error_fakefile_section_line(const fake_data data, const f_status status, const f_string function, const f_string string) f_gcc_attribute_visibility_internal; -#endif // _di_fake_print_error_fakefile_section_line_ +#ifndef _di_fake_print_error_fakefile_path_stack_ + extern void fake_print_error_fakefile_path_stack(const fake_data data, const f_status status, const f_string function, const f_string string) f_gcc_attribute_visibility_internal; +#endif // _di_fake_print_error_fakefile_path_stack_ /** * Print error messages when processing some fakefile section, for a specific line and operation, and that operation failed. @@ -245,26 +245,6 @@ extern "C" { #endif // _di_fake_print_error_parameter_too_many_ /** - * Print a specific error message for a named section operation. - * - * @param data - * The program data. - * @param buffer - * A buffer containing the contents of the fakefile file. - * @param section_name - * The range within the buffer representing the section name. - * @param operation_name - * The name of the operation designated to have an error. - * @param message - * The error message. - * @param ... - * Variable arguments, processed in the same way fprintf() processes them. - */ -#ifndef _di_fake_print_error_section_operation_ - extern void fake_print_error_section_operation(const fake_data data, const f_string_static buffer, const f_string_range section_name, const f_string_static operation_name, const f_string message, ...) f_gcc_attribute_visibility_internal; -#endif // _di_fake_print_error_section_operation_ - -/** * Print warning message when fakefile has too many objects with the same name. * * @param data diff --git a/level_3/fake/data/build/fakefile b/level_3/fake/data/build/fakefile index 0f6aa6a..bf8dd0a 100644 --- a/level_3/fake/data/build/fakefile +++ b/level_3/fake/data/build/fakefile @@ -6,31 +6,8 @@ settings: parameter verbose +v main: - print Begin processing the \"main" program. - - print - print First, cleaning any previous work. - clean - - print Result = \'parameter:"result"' - - print - print Second, building the skeleton. skeleton - print Result = \'parameter:"result"' + clean - print - print Third, executing the build process. 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. -- 1.8.3.1