From 5484da505f7553ea7a75cad0b9056dab7b8afa1e Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 26 Jun 2020 00:01:32 -0500 Subject: [PATCH] Progress: IKI Read Continue work on implementing iki_read. --- level_3/iki_read/c/iki_read.c | 440 +++++++++++++++++++--------------- level_3/iki_read/c/iki_read.h | 4 +- level_3/iki_read/c/private-iki_read.c | 183 +++++++++++++- level_3/iki_read/c/private-iki_read.h | 88 ++++++- 4 files changed, 507 insertions(+), 208 deletions(-) diff --git a/level_3/iki_read/c/iki_read.c b/level_3/iki_read/c/iki_read.c index 9ff64e0..5795d33 100644 --- a/level_3/iki_read/c/iki_read.c +++ b/level_3/iki_read/c/iki_read.c @@ -91,8 +91,13 @@ extern "C" { f_console_parameter_ids choices = { ids, 3 }; status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context); - if (F_status_is_error(status)) { + iki_read_print_error(data->context, data->verbosity, F_status_set_fine(status), "fll_program_parameter_process", F_true); + + if (data->verbosity == iki_read_verbosity_verbose) { + fprintf(f_type_error, "%c", f_string_eol[0]); + } + iki_read_delete_data(data); return F_status_set_error(status); } @@ -121,7 +126,8 @@ extern "C" { fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, f_console_standard_long_quiet); fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); } data->verbosity = iki_read_verbosity_verbose; @@ -133,271 +139,307 @@ extern "C" { data->verbosity = iki_read_verbosity_normal; } - if (data->remaining.used > 0 || data->process_pipe) { - if (data->parameters[iki_read_parameter_at].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_at); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number."); - fprintf(f_type_error, "%c", f_string_eol[0]); - } - - iki_read_delete_data(data); - return F_status_set_error(F_parameter); - } + if (F_status_is_fine(status)) { + if (data->remaining.used > 0 || data->process_pipe) { + if (data->parameters[iki_read_parameter_at].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_at); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number."); + } - if (data->parameters[iki_read_parameter_line].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_line); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number."); - fprintf(f_type_error, "%c", f_string_eol[0]); + status = F_status_set_error(F_parameter); } + else if (data->parameters[iki_read_parameter_at].result == f_console_result_additional) { + const f_string_length index = data->parameters[iki_read_parameter_at].additional.array[data->parameters[iki_read_parameter_at].additional.used - 1]; + const f_string_range range = f_macro_string_range_initialize(strlen(arguments.argv[index])); - iki_read_delete_data(data); - return F_status_set_error(F_parameter); - } - else if (data->parameters[iki_read_parameter_line].result == f_console_result_additional) { - const f_string_length index = data->parameters[iki_read_parameter_line].additional.array[data->parameters[iki_read_parameter_line].additional.used - 1]; - const f_string_range range = f_macro_string_range_initialize(strlen(arguments.argv[index])); + f_number_unsigned number = 0; - f_number_unsigned number = 0; - - status = fl_conversion_string_to_number_unsigned(arguments.argv[index], &number, range); - if (F_status_is_error(status)) { - iki_read_print_error_number_argument(data->context, data->verbosity, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", iki_read_long_line, arguments.argv[index]); - fprintf(f_type_error, "%c", f_string_eol[0]); + status = fl_conversion_string_to_number_unsigned(arguments.argv[index], &number, range); + if (F_status_is_error(status)) { + iki_read_print_error_number_argument(data->context, data->verbosity, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", iki_read_long_line, arguments.argv[index]); - iki_read_delete_data(data); - return F_status_set_error(F_parameter); - } + status = F_status_set_error(F_parameter); + } - data->line = number; + data->at = number; - // additional @todo - } + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_at); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } - if (data->parameters[iki_read_parameter_name].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_name); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a string."); - fprintf(f_type_error, "%c", f_string_eol[0]); + status = F_status_set_error(F_parameter); + } } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); - } - - if (data->parameters[iki_read_parameter_substitute].result != f_console_result_none) { - if (data->parameters[iki_read_parameter_substitute].result == f_console_result_found || data->parameters[iki_read_parameter_substitute].additional.used % 3 != 0) { + if (data->parameters[iki_read_parameter_line].result == f_console_result_found) { if (data->verbosity != iki_read_verbosity_quiet) { - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_substitute); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires 3 strings."); fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_line); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a positive number."); } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - } + else if (data->parameters[iki_read_parameter_line].result == f_console_result_additional) { + const f_string_length index = data->parameters[iki_read_parameter_line].additional.array[data->parameters[iki_read_parameter_line].additional.used - 1]; + const f_string_range range = f_macro_string_range_initialize(strlen(arguments.argv[index])); - if (data->parameters[iki_read_parameter_literal].result == f_console_result_found) { - if (data->parameters[iki_read_parameter_object].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + f_number_unsigned number = 0; + + status = fl_conversion_string_to_number_unsigned(arguments.argv[index], &number, range); + if (F_status_is_error(status)) { + iki_read_print_error_number_argument(data->context, data->verbosity, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", iki_read_long_line, arguments.argv[index]); + + status = F_status_set_error(F_parameter); } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + data->line = number; } - if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { + if (data->parameters[iki_read_parameter_name].result == f_console_result_found) { if (data->verbosity != iki_read_verbosity_quiet) { fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_name); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires a string."); } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + status = F_status_set_error(F_parameter); } - if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + if (data->parameters[iki_read_parameter_substitute].result != f_console_result_none) { + if (data->parameters[iki_read_parameter_substitute].result == f_console_result_found || data->parameters[iki_read_parameter_substitute].additional.used % 3 != 0) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_substitute); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' requires 3 strings."); + } + + status = F_status_set_error(F_parameter); } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_substitute); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } } - data->mode = iki_read_mode_literal; - } - else if (data->parameters[iki_read_parameter_object].result == f_console_result_found) { - if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + if (data->parameters[iki_read_parameter_expand].result == f_console_result_found) { + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_expand); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); } + } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + if (data->parameters[iki_read_parameter_literal].result == f_console_result_found) { + if (data->parameters[iki_read_parameter_object].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } + + if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } + + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_literal); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } + + data->mode = iki_read_mode_literal; } + else if (data->parameters[iki_read_parameter_object].result == f_console_result_found) { + if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } - if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_object); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); } - iki_read_delete_data(data); - return F_status_set_error(F_parameter); + data->mode = iki_read_mode_object; } + else if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { + if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); + fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); + } + + status = F_status_set_error(F_parameter); + } - data->mode = iki_read_mode_object; - } - else if (data->parameters[iki_read_parameter_raw].result == f_console_result_found) { - if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + data->mode = iki_read_mode_raw; + } + else if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { + data->mode = iki_read_mode_total; + } + else { + data->mode = iki_read_mode_content; + } + + if (F_status_is_error(status)) { if (data->verbosity != iki_read_verbosity_quiet) { fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_raw); - fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '"); - fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_read_long_total); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter."); - fprintf(f_type_error, "%c", f_string_eol[0]); } iki_read_delete_data(data); return F_status_set_error(F_parameter); } - data->mode = iki_read_mode_raw; - } - else if (data->parameters[iki_read_parameter_total].result == f_console_result_found) { - data->mode = iki_read_mode_total; - } - else { - data->mode = iki_read_mode_content; - } + if (data->process_pipe) { + f_file file = f_file_initialize; - if (data->process_pipe) { - f_file file = f_file_initialize; + file.id = f_type_descriptor_input; - file.id = f_type_descriptor_input; + status = f_file_read(file, &data->buffer); - status = f_file_read(file, &data->buffer); - - if (F_status_is_error(status)) { - iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read", "-", "process", F_true, F_true); - - iki_read_delete_data(data); - return status; - } + if (F_status_is_error(status)) { + iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read", "-", "process", F_true, F_true); + } + else { + status = iki_read_process_buffer(arguments, "-", data); + } - status = iki_read_main_process_file(arguments, "-", data); - if (F_status_is_error(status)) { - iki_read_delete_data(data); - return status; + // Clear buffers before continuing. + f_macro_string_dynamic_delete_simple(data->buffer); } - // Clear buffers before continuing. - f_macro_string_dynamic_delete_simple(data->buffer); - } - - if (data->remaining.used > 0) { - f_string_length i = 0; - f_string_length total = 0; - f_file file = f_file_initialize; + if (F_status_is_fine(status) && data->remaining.used > 0) { + f_string_length i = 0; + f_string_length total = 0; + f_file file = f_file_initialize; - for (; i < data->remaining.used; i++) { - f_macro_file_reset(file); - total = 0; + for (; i < data->remaining.used; i++) { + f_macro_file_reset(file); + total = 0; - status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); - if (F_status_is_error(status)) { - iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_open", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); + status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file); + if (F_status_is_error(status)) { + iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_open", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); + break; + } - iki_read_delete_data(data); - return status; - } + status = f_file_size_by_id(file.id, &total); + if (F_status_is_error(status)) { + iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_size_by_id", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); - status = f_file_size_by_id(file.id, &total); - if (F_status_is_error(status)) { - iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_size_by_id", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); + f_file_close(&file.id); + break; + } - f_file_close(&file.id); + // Skip past empty files. + if (total == 0) { + f_file_close(&file.id); + continue; + } - iki_read_delete_data(data); - return status; - } + status = f_file_read_until(file, &data->buffer, total); - // Skip past empty files. - if (total == 0) { f_file_close(&file.id); - continue; - } - - status = f_file_read_until(file, &data->buffer, total); - f_file_close(&file.id); + if (F_status_is_error(status)) { + iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read_until", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); + break; + } - if (F_status_is_error(status)) { - iki_read_print_error_file(data->context, data->verbosity, F_status_set_fine(status), "f_file_read_until", arguments.argv[data->remaining.array[i]], "process", F_true, F_true); - - iki_read_delete_data(data); - return status; - } + status = iki_read_process_buffer(arguments, arguments.argv[data->remaining.array[i]], data); + if (F_status_is_error(status)) break; - status = iki_read_main_process_file(arguments, arguments.argv[data->remaining.array[i]], data); - if (F_status_is_error(status)) { - iki_read_delete_data(data); - return status; - } + // Clear buffers before repeating the loop. + f_macro_string_dynamic_delete_simple(data->buffer); + } // for + } + } + else { + if (data->verbosity != iki_read_verbosity_quiet) { + fprintf(f_type_error, "%c", f_string_eol[0]); + fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files."); + } - // Clear buffers before repeating the loop. - f_macro_string_dynamic_delete_simple(data->buffer); - } // for + status = F_status_set_error(F_parameter); } } - else { - if (data->verbosity != iki_read_verbosity_quiet) { - fprintf(f_type_error, "%c", f_string_eol[0]); - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files."); + + // ensure a newline is always put at the end of the program execution, unless in quite mode. + if (data->verbosity != iki_read_verbosity_quiet) { + if (F_status_is_error(status) || data->mode == 0) { fprintf(f_type_error, "%c", f_string_eol[0]); } - - status = F_status_set_error(F_parameter); } iki_read_delete_data(data); diff --git a/level_3/iki_read/c/iki_read.h b/level_3/iki_read/c/iki_read.h index 526977a..4838005 100644 --- a/level_3/iki_read/c/iki_read.h +++ b/level_3/iki_read/c/iki_read.h @@ -56,7 +56,7 @@ extern "C" { #endif // _di_iki_read_version_ #ifndef _di_iki_read_name_ - #define iki_read_name "IKI_read" + #define iki_read_name "iki_read" #define iki_read_name_long "IKI Read" #endif // _di_iki_read_name_ @@ -248,6 +248,7 @@ extern "C" { f_string_lengths remaining; bool process_pipe; + f_number_unsigned at; f_number_unsigned line; uint8_t mode; @@ -268,6 +269,7 @@ extern "C" { 0, \ 0, \ 0, \ + 0, \ f_string_dynamic_initialize, \ iki_read_replacements_initialize, \ fl_color_context_initialize, \ diff --git a/level_3/iki_read/c/private-iki_read.c b/level_3/iki_read/c/private-iki_read.c index c284af5..8fd5ff3 100644 --- a/level_3/iki_read/c/private-iki_read.c +++ b/level_3/iki_read/c/private-iki_read.c @@ -275,23 +275,198 @@ extern "C" { } #endif // _di_iki_read_print_error_number_argument_ -#ifndef _di_iki_read_main_process_file_ - f_return_status iki_read_main_process_file(const f_console_arguments arguments, const f_string filename, iki_read_data *data) { +#ifndef _di_iki_read_process_at_ + f_return_status iki_read_process_at(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_string_range *range) { + if (data->parameters[iki_read_parameter_line].result != f_console_result_additional) return F_false; + + if (data->line < data->buffer.used) { + f_string_length line = 0; + + range->start = 0; + if (data->line > 0) { + for (; line < data->line && range->start < data->buffer.used; range->start++) { + if (data->buffer.string[range->start] == f_string_eol[0]) line++; + } // for + } + + range->stop = range->start; + for (; range->stop < data->buffer.used; range->stop++) { + if (data->buffer.string[range->stop] == f_string_eol[0]) break; + } // for + } + else { + range->start = data->buffer.used + 1; + } + + return F_true; + } +#endif // _di_iki_read_process_at_ + +#ifndef _di_iki_read_process_buffer_ + f_return_status iki_read_process_buffer(const f_console_arguments arguments, const f_string file_name, iki_read_data *data) { f_status status = F_none; f_iki_variable variable = f_iki_variable_initialize; f_iki_vocabulary vocabulary = f_iki_vocabulary_initialize; f_iki_content content = f_iki_content_initialize; - // @todo + if (data->mode == iki_read_mode_content) { + status = iki_read_process_buffer_ranges(arguments, file_name, data, &variable, &vocabulary, &content, &content); + } + else if (data->mode == iki_read_mode_literal) { + status = iki_read_process_buffer_ranges(arguments, file_name, data, &variable, &vocabulary, &content, &variable); + } + else if (data->mode == iki_read_mode_object) { + status = iki_read_process_buffer_ranges(arguments, file_name, data, &variable, &vocabulary, &content, &vocabulary); + } + else if (data->mode == iki_read_mode_raw) { + // @todo + } + else if (data->mode == iki_read_mode_total) { + status = iki_read_process_buffer_total(arguments, file_name, data, &variable, &vocabulary, &content); + } f_macro_iki_variable_delete_simple(variable); f_macro_iki_vocabulary_delete_simple(vocabulary); f_macro_iki_content_delete_simple(content); + return status; + } +#endif // _di_iki_read_process_buffer_ + +#ifndef _di_iki_read_process_buffer_ranges_ + f_return_status iki_read_process_buffer_ranges(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content, f_string_ranges *ranges) { + f_status status = F_none; + f_string_range range = f_macro_string_range_initialize(data->buffer.used); + + bool unmatched = F_true; + + if (iki_read_process_at(arguments, file_name, data, &range)) { + if (range.start > data->buffer.used) { + return F_data_not; + } + } + + status = fl_iki_read(&data->buffer, &range, variable, vocabulary, content); + if (F_status_is_error(status)) { + iki_read_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_iki_read", F_true); + return status; + } + + if (data->parameters[iki_read_parameter_name].result == f_console_result_additional) { + f_string_dynamic name = f_string_dynamic_initialize; + + f_array_length index = 0; + f_array_length i = 0; + f_array_length j = 0; + + range.start = 0; + + for (; i < data->parameters[iki_read_parameter_name].additional.used; i++) { + index = data->parameters[iki_read_parameter_name].additional.array[i]; + name.used = 0; + + status = fl_string_append_nulless(arguments.argv[index], strlen(arguments.argv[index]), &name); + if (F_status_is_error(status)) { + iki_read_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_string_append_nulless", F_true); + + f_macro_string_dynamic_delete_simple(name); + return status; + } + + range.stop = name.used - 1; + + for (j = 0; j < vocabulary->used; j++) { + status = fl_string_dynamic_partial_compare(name, data->buffer, range, vocabulary->array[j]); + + if (status == F_equal_to) { + unmatched = F_false; + + f_print_string_dynamic_partial(f_type_output, data->buffer, ranges->array[j]); + printf("%c", f_string_eol[0]); + } + } // for + } // for + + f_macro_string_dynamic_delete_simple(name); + + if (unmatched) return F_data_not; + } + else if (ranges->used) { + for (f_array_length i = 0; i < ranges->used; i++) { + f_print_string_dynamic_partial(f_type_output, data->buffer, ranges->array[i]); + printf("%c", f_string_eol[0]); + } // for + } + else { + return F_data_not; + } + + return F_none; + } +#endif // _di_iki_read_process_buffer_ranges_ + +#ifndef _di_iki_read_process_buffer_total_ + f_return_status iki_read_process_buffer_total(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content) { + f_status status = F_none; + f_string_range range = f_macro_string_range_initialize(data->buffer.used); + + if (iki_read_process_at(arguments, file_name, data, &range)) { + if (range.start > data->buffer.used) { + printf("0\n"); + return F_none; + } + } + + status = fl_iki_read(&data->buffer, &range, variable, vocabulary, content); + if (F_status_is_error(status)) { + iki_read_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_iki_read", F_true); + return status; + } + + f_array_length total = 0; + + if (data->parameters[iki_read_parameter_name].result == f_console_result_additional) { + f_string_dynamic name = f_string_dynamic_initialize; + + f_array_length index = 0; + f_array_length i = 0; + f_array_length j = 0; + + range.start = 0; + + for (; i < data->parameters[iki_read_parameter_name].additional.used; i++) { + index = data->parameters[iki_read_parameter_name].additional.array[i]; + name.used = 0; + + status = fl_string_append_nulless(arguments.argv[index], strlen(arguments.argv[index]), &name); + if (F_status_is_error(status)) { + iki_read_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_string_append_nulless", F_true); + + f_macro_string_dynamic_delete_simple(name); + return status; + } + + range.stop = name.used - 1; + + for (j = 0; j < vocabulary->used; j++) { + status = fl_string_dynamic_partial_compare(name, data->buffer, range, vocabulary->array[j]); + + if (status == F_equal_to) total++; + } // for + } // for + + f_macro_string_dynamic_delete_simple(name); + } + else { + total = variable->used; + } + + printf("%llu\n", total); + return F_none; } -#endif // _di_iki_read_main_process_file_ +#endif // _di_iki_read_process_buffer_total_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/iki_read/c/private-iki_read.h b/level_3/iki_read/c/private-iki_read.h index 9679c91..d132daa 100644 --- a/level_3/iki_read/c/private-iki_read.h +++ b/level_3/iki_read/c/private-iki_read.h @@ -89,7 +89,81 @@ extern "C" { #endif // _di_iki_read_print_error_number_argument_ /** - * Process a given file. + * Determine the range based on the --at parameter. + * + * If the --at parameter is not specified in the console arguments, then range is untouched. + * The range.start will be greater than data->buffer.used if the --at range is not found before buffer end is reached. + * + * @param arguments + * The console arguments passed to the program. + * @param file_name + * The name of the file being processed. + * @param data + * The program specific data. + * @param range + * The range value to represent the --at values. + * + * @return + * F_true is returned if the range is processed. + * F_false is returned if the range is not processed. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_iki_read_process_at_ + extern f_return_status iki_read_process_at(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_string_range *range) f_gcc_attribute_visibility_internal; +#endif // _di_iki_read_process_at_ + +/** + * Process a given buffer. + * + * @param arguments + * The console arguments passed to the program. + * @param file_name + * The name of the file being processed. + * @param data + * The program specific data. + * + * @return + * F_none on success. + * F_data_not on success, but nothing done. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_iki_read_process_buffer_ + extern f_return_status iki_read_process_buffer(const f_console_arguments arguments, const f_string file_name, iki_read_data *data) f_gcc_attribute_visibility_internal; +#endif // _di_iki_read_process_buffer_ + +/** + * Process a given buffer, printing the given range. + * + * @param arguments + * The console arguments passed to the program. + * @param file_name + * The name of the file being processed. + * @param data + * The program specific data. + * @param variable + * The ranges representing a variable. + * @param vocabulary + * The ranges representing a vocabulary. + * @param content + * The ranges representing content. + * @param ranges + * The ranges to print when matched. + * Should be one of: variable, vocabulary, or content. + * + * @return + * F_none on success. + * F_data_not on success, but nothing to print. + * + * Status codes (with error bit) are returned on any problem. + */ +#ifndef _di_iki_read_process_buffer_ranges_ + extern f_return_status iki_read_process_buffer_ranges(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content, f_string_ranges *ranges) f_gcc_attribute_visibility_internal; +#endif // _di_iki_read_process_buffer_ranges_ + +/** + * Process a given buffer, printing the total. * * @param arguments * The console arguments passed to the program. @@ -97,15 +171,21 @@ extern "C" { * The name of the file being processed. * @param data * The program specific data. + * @param variable + * The ranges representing a variable. + * @param vocabulary + * The ranges representing a vocabulary. + * @param content + * The ranges representing content. * * @return * F_none on success. * * Status codes (with error bit) are returned on any problem. */ -#ifndef _di_iki_read_main_process_file_ - extern f_return_status iki_read_main_process_file(const f_console_arguments arguments, const f_string file_name, iki_read_data *data) f_gcc_attribute_visibility_internal; -#endif // _di_iki_read_main_process_file_ +#ifndef _di_iki_read_process_buffer_total_ + extern f_return_status iki_read_process_buffer_total(const f_console_arguments arguments, const f_string file_name, iki_read_data *data, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content) f_gcc_attribute_visibility_internal; +#endif // _di_iki_read_process_buffer_total_ #ifdef __cplusplus } // extern "C" -- 1.8.3.1