From d22a6b6510d4b5242b71b883bbf1645e3eaf31a5 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 15 Nov 2019 22:20:56 -0600 Subject: [PATCH] Update: finish implementing fss_basic_list_read --- .../fss_basic_list_read/c/fss_basic_list_read.c | 187 ++++-- .../fss_basic_list_read/c/fss_basic_list_read.h | 4 + .../c/private-fss_basic_list_read.c | 738 ++++++++++++--------- .../c/private-fss_basic_list_read.h | 58 +- 4 files changed, 587 insertions(+), 400 deletions(-) diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.c b/level_3/fss_basic_list_read/c/fss_basic_list_read.c index 0c14259..dcb9898 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.c @@ -19,15 +19,20 @@ extern "C" { fll_program_print_help_option(data.context, fss_basic_list_read_short_at, fss_basic_list_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); fll_program_print_help_option(data.context, fss_basic_list_read_short_depth, fss_basic_list_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); + fll_program_print_help_option(data.context, fss_basic_list_read_short_empty, fss_basic_list_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); fll_program_print_help_option(data.context, fss_basic_list_read_short_line, fss_basic_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print only the content at the given line."); fll_program_print_help_option(data.context, fss_basic_list_read_short_name, fss_basic_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); fll_program_print_help_option(data.context, fss_basic_list_read_short_object, fss_basic_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object instead of the content."); fll_program_print_help_option(data.context, fss_basic_list_read_short_select, fss_basic_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); - fll_program_print_help_option(data.context, fss_basic_list_read_short_total, fss_basic_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of objects."); + fll_program_print_help_option(data.context, fss_basic_list_read_short_total, fss_basic_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); fll_program_print_help_usage(data.context, fss_basic_list_read_name, "filename(s)"); - printf(" This program will print the content associated with the given object and content data based on the FSS-0002 Basic List standard.%c", f_string_eol); + fl_color_print(f_standard_output, data.context.important, data.context.reset, " Notes:"); + + printf("%c", f_string_eol, f_string_eol); + + printf(" This program will print the content associated with the given object and content data based on the FSS-0000 Basic standard.%c", f_string_eol); printf("%c", f_string_eol); @@ -53,21 +58,13 @@ extern "C" { printf(" The parameter "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_depth); - printf(" should be in numeric order, but values in between may be skipped.%c", f_string_eol); + printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol); printf(" ('-d 0 -a 1 -d 2 -a 2' would specify index 1 at depth 0, any index at depth 1, and index 2 at depth 2.)%c", f_string_eol); printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol); printf("%c", f_string_eol); printf(" The parameter "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_at); - printf(" cannot be used with the parameter "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_name); - printf(" at the same depth.%c", f_string_eol); - - printf("%c", f_string_eol); - - printf(" The parameter "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_select); printf(" selects a content index at a given depth.%c", f_string_eol); printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol); @@ -75,10 +72,10 @@ extern "C" { printf("%c", f_string_eol); printf(" Specify both "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_total); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_object); printf(" and the "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_line); - printf(" parameters to get the total lines.%c", f_string_eol); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_total); + printf(" parameters to get the total objects.%c", f_string_eol); printf("%c", f_string_eol); @@ -124,9 +121,7 @@ extern "C" { status = f_none; } - f_status status2 = f_none; - - // execute parameter results + // Execute parameter results. if (data->parameters[fss_basic_list_read_parameter_help].result == f_console_result_found) { fss_basic_list_read_print_help(*data); } @@ -134,8 +129,48 @@ extern "C" { fll_program_print_version(fss_basic_list_read_version); } else if (data->remaining.used > 0 || data->process_pipe) { + if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_at); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_depth); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_line); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_name); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a string."); + + return f_status_set_error(f_invalid_parameter); + } + + if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_select); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' requires a positive number."); + + return f_status_set_error(f_invalid_parameter); + } + if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) { - if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) { + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_object); fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter with the '"); @@ -156,14 +191,24 @@ extern "C" { } } - f_string_length counter = 0; - f_string_length target = 0; - f_string_length original_size = data->file_position.total_elements; + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_line); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter with the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_total); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' parameter."); - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - target = (f_string_length) atoll(arguments.argv[data->parameters[fss_basic_list_read_parameter_at].additional.array[0]]); + return f_status_set_error(f_invalid_parameter); + } } + fss_basic_list_read_depths depths = fss_basic_list_read_depths_initialize; + f_status status2 = f_none; + + f_string_length counter = 0; + f_string_length original_size = data->file_position.total_elements; + status = fss_basic_list_read_main_preprocess_depth(arguments, *data, &depths); if (f_status_is_error(status)) { macro_fss_basic_list_read_depths_delete(status2, depths); @@ -174,19 +219,18 @@ extern "C" { // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. if (depths.used > 0 && depths.array[0].depth > 0) { if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_standard_output, "0%s", f_string_eol); + fprintf(f_standard_output, "0%c", f_string_eol); return f_none; } return f_none; } - // This standard does not support nesting, so it can be determined that --name is in use with --total and --object, which is not allowed. - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found && data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '--%s' parameter, the ' '--%s' parameter, and the '--%s' parameter together.", fss_basic_list_read_long_object, fss_basic_list_read_long_line); - return f_status_set_error(f_invalid_parameter); - } + if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) { + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_list_read_long_select); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' parameter requires a positive number."); + return f_status_set_error(f_invalid_parameter); } if (data->process_pipe) { @@ -198,70 +242,81 @@ extern "C" { if (f_status_is_error(status)) { fss_basic_list_read_print_file_error(data->context, "fl_file_read_fifo", "-", f_status_set_fine(status)); + macro_fss_basic_list_read_depths_delete(status2, depths); fss_basic_list_read_delete_data(data); return status; } - status = fss_basic_list_read_main_process_file(arguments, data, "-", target); + status = fss_basic_list_read_main_process_file(arguments, data, "-", depths); if (f_status_is_error(status)) { + macro_fss_basic_list_read_depths_delete(status2, depths); + fss_basic_list_read_delete_data(data); return status; } - // clear buffers before continuing + // Clear buffers before continuing. f_macro_fss_contents_delete(status2, data->contents); f_macro_fss_objects_delete(status2, data->objects); f_macro_string_dynamic_delete(status2, data->buffer); } - for (; counter < data->remaining.used; counter++) { - f_file file = f_file_initialize; + if (data->remaining.used > 0) { + for (; counter < data->remaining.used; counter++) { + f_file file = f_file_initialize; - status = f_file_open(&file, arguments.argv[data->remaining.array[counter]]); + status = f_file_open(&file, arguments.argv[data->remaining.array[counter]]); - data->file_position.total_elements = original_size; + data->file_position.total_elements = original_size; - if (f_status_is_error(status)) { - fss_basic_list_read_print_file_error(data->context, "f_file_open", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); - fss_basic_list_read_delete_data(data); - return f_status_set_error(status); - } + if (f_status_is_error(status)) { + fss_basic_list_read_print_file_error(data->context, "f_file_open", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); + macro_fss_basic_list_read_depths_delete(status2, depths); + fss_basic_list_read_delete_data(data); + return status; + } - if (data->file_position.total_elements == 0) { - fseek(file.address, 0, SEEK_END); + if (data->file_position.total_elements == 0) { + fseek(file.address, 0, SEEK_END); - data->file_position.total_elements = ftell(file.address); + data->file_position.total_elements = ftell(file.address); - // skip past empty files - if (data->file_position.total_elements == 0) { - f_file_close(&file); - continue; + // Sskip past empty files. + if (data->file_position.total_elements == 0) { + f_file_close(&file); + continue; + } + + fseek(file.address, 0, SEEK_SET); } - fseek(file.address, 0, SEEK_SET); - } + status = fl_file_read(file, data->file_position, &data->buffer); - status = fl_file_read(file, data->file_position, &data->buffer); + f_file_close(&file); - f_file_close(&file); + if (f_status_is_error(status)) { + fss_basic_list_read_print_file_error(data->context, "fl_file_read", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); + macro_fss_basic_list_read_depths_delete(status2, depths); + fss_basic_list_read_delete_data(data); + return status; + } - if (f_status_is_error(status)) { - fss_basic_list_read_print_file_error(data->context, "fl_file_read", arguments.argv[data->remaining.array[counter]], f_status_set_fine(status)); - fss_basic_list_read_delete_data(data); - return f_status_set_error(status); - } + status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths); - status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], target); + if (f_status_is_error(status)) { + macro_fss_basic_list_read_depths_delete(status2, depths); + fss_basic_list_read_delete_data(data); + return status; + } - if (f_status_is_error(status)) { - return status; - } + // Clear buffers before repeating the loop. + f_macro_fss_contents_delete(status2, data->contents); + f_macro_fss_objects_delete(status2, data->objects); + f_macro_string_dynamic_delete(status2, data->buffer); + } // for + } - // clear buffers before repeating the loop - f_macro_fss_contents_delete(status2, data->contents); - f_macro_fss_objects_delete(status2, data->objects); - f_macro_string_dynamic_delete(status2, data->buffer); - } // for + macro_fss_basic_list_read_depths_delete(status2, depths); } else { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ERROR: you failed to specify one or more files."); diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.h b/level_3/fss_basic_list_read/c/fss_basic_list_read.h index 0ff11b0..6557052 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.h @@ -58,6 +58,7 @@ extern "C" { #ifndef _di_fss_basic_list_read_defines_ #define fss_basic_list_read_short_at "a" #define fss_basic_list_read_short_depth "d" + #define fss_basic_list_read_short_empty "e" #define fss_basic_list_read_short_line "l" #define fss_basic_list_read_short_name "n" #define fss_basic_list_read_short_object "o" @@ -66,6 +67,7 @@ extern "C" { #define fss_basic_list_read_long_at "at" #define fss_basic_list_read_long_depth "depth" + #define fss_basic_list_read_long_empty "empty" #define fss_basic_list_read_long_line "line" #define fss_basic_list_read_long_name "name" #define fss_basic_list_read_long_object "object" @@ -81,6 +83,7 @@ extern "C" { fss_basic_list_read_parameter_at, fss_basic_list_read_parameter_depth, + fss_basic_list_read_parameter_empty, fss_basic_list_read_parameter_line, fss_basic_list_read_parameter_name, fss_basic_list_read_parameter_object, @@ -97,6 +100,7 @@ extern "C" { f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, f_false, f_console_type_inverse), \ f_console_parameter_initialize(fss_basic_list_read_short_at, fss_basic_list_read_long_at, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_read_short_depth, fss_basic_list_read_long_depth, 0, f_true, f_console_type_normal), \ + f_console_parameter_initialize(fss_basic_list_read_short_empty, fss_basic_list_read_long_empty, 0, f_false, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_read_short_line, fss_basic_list_read_long_line, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_read_short_name, fss_basic_list_read_long_name, 0, f_true, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_read_short_object, fss_basic_list_read_long_object, 0, f_false, f_console_type_normal), \ diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c index 763f4c3..0ae20df 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c @@ -66,169 +66,199 @@ extern "C" { } #endif // _di_fss_basic_list_read_print_file_error_ +#ifndef _di_fss_basic_list_read_print_number_argument_error_ + void fss_basic_list_read_print_number_argument_error(const fl_color_context context, const f_string function_name, const f_string parameter_name, const f_string argument, const f_status status) { + + if (status == f_invalid_parameter) { + fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling "); + fl_color_print(f_standard_error, context.notable, context.reset, "%s()", function_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "."); + } + else if (status == f_invalid_number) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is not a valid number for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_underflow) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is too small for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_overflow) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is too large for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_negative_number) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' is negative, which is not allowed for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_positive_number) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The argument '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print(f_standard_error, context.error, context.reset, "' contains a '"); + fl_color_print(f_standard_error, context.notable, context.reset, "+"); + fl_color_print(f_standard_error, context.error, context.reset, "', which is not allowed for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + else if (status == f_no_data) { + fl_color_print(f_standard_error, context.error, context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print_line(f_standard_error, context.error, context.reset, "' must not be an empty string."); + } + else { + fl_color_print(f_standard_error, context.error, context.reset, "INTERNAL ERROR: An unhandled error ("); + fl_color_print(f_standard_error, context.notable, context.reset, "%u", status); + fl_color_print(f_standard_error, context.error, context.reset, ") has occured while calling "); + fl_color_print(f_standard_error, context.notable, context.reset, "%s()", function_name); + fl_color_print(f_standard_error, context.error, context.reset, "' for the parameter '"); + fl_color_print(f_standard_error, context.notable, context.reset, "--%s", parameter_name); + fl_color_print(f_standard_error, context.error, context.reset, "' with the value '"); + fl_color_print(f_standard_error, context.notable, context.reset, "%s", argument); + fl_color_print_line(f_standard_error, context.error, context.reset, "'."); + } + } +#endif // _di_fss_basic_list_read_print_number_argument_error_ + #ifndef _di_fss_basic_list_read_main_preprocess_depth_ f_return_status fss_basic_list_read_main_preprocess_depth(const f_console_arguments arguments, const fss_basic_list_read_data data, fss_basic_list_read_depths *depths) { f_status status = f_none; - // pre-process the depth and depth-sensitive parameters. - if (data.parameters[fss_basic_list_read_parameter_depth].result == f_console_result_additional) { - macro_fss_basic_list_read_depths_new(status, (*depths), data.parameters[fss_basic_list_read_parameter_depth].locations.used); + { + f_array_length depth_size = 1; + + if (data.parameters[fss_basic_list_read_parameter_depth].result == f_console_result_additional) { + depth_size = data.parameters[fss_basic_list_read_parameter_depth].additional.used; + } + + macro_fss_basic_list_read_depths_new(status, (*depths), depth_size); if (f_status_is_error(status)) { - f_status status2 = f_none; fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); - - macro_fss_basic_list_read_depths_delete(status2, (*depths)); - return f_status_set_error(f_invalid_parameter); + return status; } - f_array_length depth_position = data.parameters[fss_basic_list_read_parameter_depth].additional.array[0]; - f_array_length at_index = 0; - f_array_length name_index = 0; + depths->used = depth_size; + } + + f_array_length position_depth = 0; + f_array_length position_at = 0; + f_array_length position_name = 0; + + for (f_array_length i = 0; i < depths->used; i++) { + depths->array[i].depth = 0; + depths->array[i].index_at = 0; + depths->array[i].index_name = 0; + depths->array[i].value_at = 0; + depths->array[i].value_name = f_string_eos; + + if (data.parameters[fss_basic_list_read_parameter_depth].additional.used == 0) { + position_depth = 0; + } + else { + position_depth = data.parameters[fss_basic_list_read_parameter_depth].additional.array[i]; - depths->array[0].depth = (f_string_length) atoll(arguments.argv[depth_position]); - depths->array[0].parameter = 0; - depths->array[0].position = 0; - depths->used = 1; + status = fl_console_parameter_to_number_unsigned(arguments.argv[position_depth], &depths->array[i].depth); - f_string_length depth_previous = depths->array[0].depth; - f_string_length depth_current = depths->array[0].depth; + if (f_status_is_error(status)) { + fss_basic_list_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_list_read_long_depth, arguments.argv[position_depth], f_status_set_fine(status)); + return status; + } + } if (data.parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - for (; at_index < data.parameters[fss_basic_list_read_parameter_at].additional.used; at_index++) { - if (data.parameters[fss_basic_list_read_parameter_at].additional.array[at_index] > depth_position) { - if (data.parameters[fss_basic_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_basic_list_read_parameter_at].additional.array[at_index] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[1]) { - break; - } - } + for (; position_at < data.parameters[fss_basic_list_read_parameter_at].additional.used; position_at++) { + if (data.parameters[fss_basic_list_read_parameter_at].additional.array[position_at] < position_depth) { + continue; + } - depths->array[0].parameter = fss_basic_list_read_parameter_at; + if (i + 1 < depths->used && data.parameters[fss_basic_list_read_parameter_at].additional.array[position_at] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[i + 1]) { + break; } - } // for - } - if (data.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { - for (; name_index < data.parameters[fss_basic_list_read_parameter_name].additional.used; name_index++) { - if (data.parameters[fss_basic_list_read_parameter_name].additional.array[name_index] > depth_position) { - if (data.parameters[fss_basic_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_basic_list_read_parameter_name].additional.array[name_index] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[1]) { - break; - } - } + depths->array[i].index_at = data.parameters[fss_basic_list_read_parameter_at].additional.array[position_at]; - if (depths->array[0].parameter == fss_basic_list_read_parameter_at) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '--%s' and '--%s' parameters cannot be specified at the same time (specified for depth '%llu').", fss_basic_list_read_long_at, fss_basic_list_read_long_name, depth_current); - return f_status_set_error(f_invalid_parameter); - } + status = fl_console_parameter_to_number_unsigned(arguments.argv[depths->array[i].index_at], &depths->array[i].value_at); - depths->array[0].parameter = fss_basic_list_read_parameter_name; + if (f_status_is_error(status)) { + fss_basic_list_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_list_read_long_at, arguments.argv[depths->array[i].index_at], f_status_set_fine(status)); + return status; } } // for } - for (f_array_length i = 1; i < data.parameters[fss_basic_list_read_parameter_depth].locations.used; i++) { - depth_position = data.parameters[fss_basic_list_read_parameter_depth].additional.array[i]; - depth_current = (f_string_length) atoll(arguments.argv[depth_position]); - - if (depth_current > depth_previous) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The depth '%llu' cannot be specified before the depth '%llu'.", depth_previous, depth_current); - return f_status_set_error(f_invalid_parameter); - } - - if (depth_current == depth_previous) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The depth '%llu' cannot be the same as the depth '%llu'.", depth_previous, depth_current); - return f_status_set_error(f_invalid_parameter); - } - - if (data.parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - for (; at_index < data.parameters[fss_basic_list_read_parameter_at].additional.used; at_index++) { - if (data.parameters[fss_basic_list_read_parameter_at].additional.array[at_index] > depth_position) { - if (data.parameters[fss_basic_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_basic_list_read_parameter_at].additional.array[at_index] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[i+1]) { - break; - } - } + if (data.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { + for (; position_name < data.parameters[fss_basic_list_read_parameter_name].additional.used; position_name++) { + if (data.parameters[fss_basic_list_read_parameter_name].additional.array[position_name] < position_depth) { + continue; + } - depths->array[i].parameter = fss_basic_list_read_parameter_at; - depths->array[i].position = data.parameters[fss_basic_list_read_parameter_at].additional.array[i]; - } - } // for - } + if (i + 1 < depths->used && data.parameters[fss_basic_list_read_parameter_name].additional.array[position_name] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[i + 1]) { + break; + } - if (data.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { - for (; name_index < data.parameters[fss_basic_list_read_parameter_name].additional.used; name_index++) { - if (data.parameters[fss_basic_list_read_parameter_name].additional.array[name_index] > depth_position) { - if (data.parameters[fss_basic_list_read_parameter_depth].additional.used > 1) { - if (data.parameters[fss_basic_list_read_parameter_name].additional.array[name_index] > data.parameters[fss_basic_list_read_parameter_depth].additional.array[i+1]) { - break; - } - } + depths->array[i].index_name = data.parameters[fss_basic_list_read_parameter_name].additional.array[position_name]; + depths->array[i].value_name = arguments.argv[depths->array[i].index_name]; - if (depths->array[i].parameter == fss_basic_list_read_parameter_at) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '--%s' and '--%s' parameters cannot be specified at the same time (specified for depth '%llu').", fss_basic_list_read_long_at, fss_basic_list_read_long_name, depth_current); - return f_status_set_error(f_invalid_parameter); - } + if (depths->array[i].value_name[0] == '\0') { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_name); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' must not be an empty string."); - depths->array[i].parameter = fss_basic_list_read_parameter_name; - depths->array[i].position = data.parameters[fss_basic_list_read_parameter_name].additional.array[i]; - } - } // for - } + return f_status_set_error(f_invalid_parameter); + } + } // for + } + } // for - depths->array[i].depth = (f_string_length) atoll(arguments.argv[depth_position]); - depths->used++; - } // for - } - // when no depth parameter is specified, provide a implicit depth of 0 when depth-sensitive parameters are in use. - else { - if (data.parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - if (data.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "ERROR: The '%s' and '%s' parameters must not be specified at the same time.", fss_basic_list_read_long_name, fss_basic_list_read_long_object); - return f_status_set_error(f_invalid_parameter); - } + for (f_array_length i = 0; i < depths->used; i++) { + for (f_array_length j = i + 1; j < depths->used; j++) { + if (depths->array[i].depth == depths->array[j].depth) { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[i].depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' may only be specified once for the parameter '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_depth); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "'."); - macro_fss_basic_list_read_depths_new(status, (*depths), 1); - if (f_status_is_error(status)) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); return f_status_set_error(f_invalid_parameter); } + else if (depths->array[i].depth > depths->array[j].depth) { + fl_color_print(f_standard_error, data.context.error, data.context.reset, "ERROR: The parameter '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "--%s", fss_basic_list_read_long_depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' may not have the value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[i].depth); + fl_color_print(f_standard_error, data.context.error, data.context.reset, "' before the value '"); + fl_color_print(f_standard_error, data.context.notable, data.context.reset, "%llu", depths->array[j].depth); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "'."); - depths->array[0].depth = (f_string_length) atoll(arguments.argv[data.parameters[fss_basic_list_read_parameter_depth].additional.array[0]]); - depths->array[0].parameter = fss_basic_list_read_parameter_at; - depths->array[0].position = 0; - depths->used = 1; - } - else if (data.parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { - macro_fss_basic_list_read_depths_new(status, (*depths), 1); - if (f_status_is_error(status)) { - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); return f_status_set_error(f_invalid_parameter); } - - depths->array[0].depth = (f_string_length) atoll(arguments.argv[data.parameters[fss_basic_list_read_parameter_depth].additional.array[0]]); - depths->array[0].parameter = fss_basic_list_read_parameter_name; - depths->array[0].position = 0; - depths->used = 1; - } - } + } // for + } // for return f_none; } #endif // _di_fss_basic_list_read_main_preprocess_depth_ #ifndef _di_fss_basic_list_read_main_process_file_ - f_return_status fss_basic_list_read_main_process_file(const f_console_arguments arguments, fss_basic_list_read_data *data, const f_string filename, const f_string_length target) { + f_return_status fss_basic_list_read_main_process_file(const f_console_arguments arguments, fss_basic_list_read_data *data, const f_string filename, const fss_basic_list_read_depths depths) { f_status status = f_none; f_status status2 = f_none; - f_string_length current = 0; - f_string_length found = 0; - { f_string_location input = f_string_location_initialize; input.start = 0; - input.stop = data->buffer.used - 1; + input.stop = data->buffer.used - 1; status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); @@ -236,26 +266,39 @@ extern "C" { status = f_status_set_fine(status); if (status == f_invalid_parameter) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_basic_list_read()"); + fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } else if (status == f_allocation_error || status == f_reallocation_error) { fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory"); } else if (status == f_incomplete_utf_on_stop) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%d", input.start); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, ")."); } else if (status == f_incomplete_utf_on_eos) { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%d", input.start); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, ")."); } else { - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", status, filename); + fl_color_print(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error ("); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%u", status); + fl_color_print(f_standard_error, data->context.error, data->context.reset, ") has occured while calling "); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "fll_fss_basic_list_read()"); + fl_color_print(f_standard_error, data->context.error, data->context.reset, " for the file '"); + fl_color_print(f_standard_error, data->context.notable, data->context.reset, "%s", filename); + fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "'."); } - fss_basic_list_read_delete_data(data); return f_status_set_error(status); } else if (status == f_no_data_on_stop || status == f_no_data_on_eos) { - // clear buffers, then attempt the next file + // Clear buffers, then attempt the next file. f_macro_fss_contents_delete(status2, data->contents); f_macro_fss_objects_delete(status2, data->objects); f_macro_string_dynamic_delete(status2, data->buffer); @@ -264,240 +307,285 @@ extern "C" { } } - // now that all of the files have been read, process the objects and contents - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_none) { - fprintf(f_standard_output, "%llu\n", data->objects.used); + f_string_length select = 0; + + if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) { + status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_basic_list_read_parameter_select].additional.array[data->parameters[fss_basic_list_read_parameter_select].additional.used - 1]], &select); + + if (f_status_is_error(status)) { + fss_basic_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_basic_list_read_long_select, arguments.argv[data->parameters[fss_basic_list_read_parameter_select].additional.array[0]], f_status_set_fine(status)); + return status; + } + + // This standard does not support multiple content groups. + if (select > 0) { + return f_none; + } } - else { - current = 0; - if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_none) { - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none) { - for (; current < data->objects.used; current++) { - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional && found == target)) { + f_string_length line = 0; - /*if (data->parameters[fss_basic_list_read_parameter_size].result == f_console_result_found) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length size = 0; + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_basic_list_read_parameter_line].additional.array[data->parameters[fss_basic_list_read_parameter_line].additional.used - 1]], &line); - for (; counter <= data->contents.array[current].array[0].stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) size++; - } // for + if (f_status_is_error(status)) { + fss_basic_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_basic_list_read_long_line, arguments.argv[data->parameters[fss_basic_list_read_parameter_line].additional.array[0]], f_status_set_fine(status)); + return status; + } + } - // the last newline is never present - size++; + bool names[data->objects.used]; - fprintf(f_standard_output, "%u\n", (unsigned int) size); - } - else { - fprintf(f_standard_output, "0\n"); - } - } - else*/ if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length position = 0; - f_string_length target = (f_string_length) atoll(arguments.argv[data->parameters[fss_basic_list_read_parameter_line].additional.array[0]]); - f_string_location range = f_string_location_initialize; - - // use an invalid range to communicate range not found - range.start = 1; - range.stop = 0; - - for (; counter <= data->contents.array[current].array[0].stop; counter++) { - if (position == target) { - range.start = counter; - - // explicit use of < instead of <= is done here so that the range.stop will always be accurate - for (; counter < data->contents.array[current].array[0].stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) { - break; - } - } // for - - range.stop = counter; - break; - } - - if (data->buffer.string[counter] == f_string_eol) { - position++; - } - } // for - - if (range.start <= range.stop) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, range); - } - } - } - else { - if (data->contents.array[current].used > 0) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); - } - } - } + if (depths.array[0].index_name > 0) { + memset(names, 0, sizeof(bool) * data->objects.used); - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } - } - } // for + f_string_length argv_length = strlen(depths.array[0].value_name); + f_string_length name_length = 0; + + for (f_string_length i = 0; i < data->objects.used; i++) { + name_length = data->objects.array[i].stop - data->objects.array[i].start + 1; + + if (name_length == argv_length) { + if (fl_string_compare(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name, name_length, argv_length) == f_equal_to) { + names[i] = 1; + } } - else { - for (; current < data->objects.used; current++) { - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional && found == target)) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } + } // for + } + else { + memset(names, 1, sizeof(bool) * data->objects.used); + } - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } - } + bool include_empty = 0; + + if (data->parameters[fss_basic_list_read_parameter_empty].result == f_console_result_found) { + include_empty = 1; + } + + if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) { + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (depths.array[0].index_at > 0) { + if (depths.array[0].value_at < data->objects.used && names[depths.array[0].value_at]) { + fprintf(f_standard_output, "1%c", f_string_eol); + } + else { + fprintf(f_standard_output, "0%c", f_string_eol); + } + } + else if (depths.array[0].index_name > 0) { + f_string_length total = 0; + + for (f_string_length i = 0; i < data->objects.used; i++) { + if (names[i] == 0) continue; + + total++; } // for + + fprintf(f_standard_output, "%llu%c", total, f_string_eol); + } + else { + fprintf(f_standard_output, "%llu%c", data->objects.used, f_string_eol); } - } - else { - current = 0; - f_string_length total = 0; - f_string_length name_length = 0; - f_string_length argv_length = 0; + return f_none; + } - if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_additional) { - argv_length = strlen(arguments.argv[data->parameters[fss_basic_list_read_parameter_name].additional.array[0]]); + if (depths.array[0].index_at > 0) { + if (depths.array[0].value_at < data->objects.used && names[depths.array[0].value_at]) { + f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[depths.array[0].value_at]); + fprintf(f_standard_output, "%c", f_string_eol); + } - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_none) { - for (; current < data->objects.used; current++) { - name_length = data->objects.array[current].stop - data->objects.array[current].start + 1; + return f_none; + } - if (name_length == argv_length) { - if (fl_string_compare(data->buffer.string + data->objects.array[current].start, arguments.argv[data->parameters[fss_basic_list_read_parameter_name].additional.array[0]], name_length, argv_length) == f_equal_to) { + for (f_string_length i = 0; i < data->objects.used; i++) { + if (names[i] == 0) continue; - /*if (data->parameters[fss_basic_list_read_parameter_size].result == f_console_result_found) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length size = 0; + f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[i]); + fprintf(f_standard_output, "%c", f_string_eol); + } // for - for (; counter <= data->contents.array[current].array[0].stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) size++; - } // for + return f_none; + } - // the last newline is never present - size++; + if (depths.array[0].index_at > 0) { + if (names[depths.array[0].value_at]) { + if (depths.array[0].value_at >= data->objects.used) { + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + fprintf(f_standard_output, "0%c", f_string_eol); + } - fprintf(f_standard_output, "%u\n", (unsigned int) size); - } - else { - fprintf(f_standard_output, "0\n"); - } - } - else*/ if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { - if (data->contents.array[current].used > 0) { - f_string_length counter = data->contents.array[current].array[0].start; - f_string_length position = 0; - f_string_length target = (f_string_length) atoll(arguments.argv[data->parameters[fss_basic_list_read_parameter_line].additional.array[0]]); - f_string_location range = f_string_location_initialize; - - // use an invalid range to communicate range not found - range.start = 1; - range.stop = 0; - - for (; counter <= data->contents.array[current].array[0].stop; counter++) { - if (position == target) { - range.start = counter; - - // explicit use of < instead of <= is done here so that the range.stop will always be accurate - for (; counter < data->contents.array[current].array[0].stop; counter++) { - if (data->buffer.string[counter] == f_string_eol) { - break; - } - } // for - - range.stop = counter; - break; - } - - if (data->buffer.string[counter] == f_string_eol) { - position++; - } - } // for - - if (range.start <= range.stop) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, range); - } - } - } - else { - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional && found == target)) { - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - total++; - } - else { - if (data->contents.array[current].used > 0) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[current].array[0]); - fprintf(f_standard_output, "\n"); - } - } - } - } + return f_none; + } + else if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (data->contents.array[depths.array[0].value_at].used == 0) { + fprintf(f_standard_output, "0%c", f_string_eol); + } + else { + fprintf(f_standard_output, "1%c", f_string_eol); + } - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { - break; - } - else { - found++; - } - } - } - } - } // for + return f_none; + } - if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found && data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_none) { - fprintf(f_standard_output, f_string_length_printf "\n", total); + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + if (data->contents.array[depths.array[0].value_at].used == 0) { + if (include_empty && line == 0) { + fprintf(f_standard_output, "%c", f_string_eol); } } else { - // when and because the object parameter is specified, the name parameter refers to the content instead of the object - // therefore, make the search on the content and display the object - for (; current < data->contents.used; current++) { - if (data->contents.array[current].used > 0) { - name_length = data->contents.array[current].array[0].stop - data->contents.array[current].array[0].start + 1; - - if (name_length == argv_length) { - if (fl_string_compare(data->buffer.string + data->contents.array[current].array[0].start, arguments.argv[data->parameters[fss_basic_list_read_parameter_name].additional.array[0]], name_length, argv_length) == f_equal_to) { - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_none || (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional && found == target)) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, data->objects.array[current]); - fprintf(f_standard_output, "\n"); - } - - if (data->parameters[fss_basic_list_read_parameter_at].result == f_console_result_additional) { - if (found == target) { + f_string_length i = data->contents.array[depths.array[0].value_at].array[0].start; + + if (line == 0) { + for (; i <= data->contents.array[depths.array[0].value_at].array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + if (data->buffer.string[i] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + fprintf(f_standard_output, "%c", data->buffer.string[i]); + } // for + } + else { + f_string_length line_current = 0; + + for (; i <= data->contents.array[depths.array[0].value_at].array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + + if (data->buffer.string[i] == f_string_eol) { + line_current++; + + if (line_current == line) { + i++; + + for (; i <= data->contents.array[depths.array[0].value_at].array[0].stop; i++) { + if (data->buffer.string[i] == f_string_eos) continue; + if (data->buffer.string[i] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); break; } - else { - found++; - } - } + + fprintf(f_standard_output, "%c", data->buffer.string[i]); + } // for + + break; } } - } - } // for + } // for + } } + + return f_none; + } + + if (data->contents.array[depths.array[0].value_at].used > 0) { + f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[depths.array[0].value_at].array[0]); + } + else if (include_empty) { + fprintf(f_standard_output, "%c", f_string_eol); } } + + return f_none; + } + + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + f_string_length total = 0; + + for (f_string_length i = 0; i < data->objects.used; i++) { + if (!names[i]) { + continue; + } + + if (data->contents.array[i].used == 0 && !include_empty) { + continue; + } + + total++; + } // for + + fprintf(f_standard_output, "%llu%c", total, f_string_eol); + return f_none; + } + + if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + f_string_length line_current = 0; + f_string_length i = 0; + f_string_length j = 0; + + for (; i < data->contents.used; i++) { + if (!names[i]) { + continue; + } + + if (data->contents.array[i].used == 0) { + if (include_empty) { + if (line_current == line) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + line_current++; + } + + continue; + } + + j = data->contents.array[i].array[0].start; + + if (line_current != line) { + for (; j <= data->contents.array[i].array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eol) { + line_current++; + + if (line_current == line) { + j++; + break; + } + } + } // for + } + + if (line_current == line) { + if (j > data->contents.array[i].array[0].stop) continue; + + for (; j <= data->contents.array[i].array[0].stop; j++) { + if (data->buffer.string[j] == f_string_eos) continue; + + if (data->buffer.string[j] == f_string_eol) { + fprintf(f_standard_output, "%c", f_string_eol); + break; + } + + fprintf(f_standard_output, "%c", data->buffer.string[j]); + } // for + + break; + } + } // for + + return f_none; } + for (f_string_length i = 0; i < data->contents.used; i++) { + if (!names[i]) { + continue; + } + + if (data->contents.array[i].used == 0) { + if (include_empty) { + fprintf(f_standard_output, "%c", f_string_eol); + } + + continue; + } + + f_print_string_dynamic_partial(f_standard_output, data->buffer, data->contents.array[i].array[0]); + } // for + return f_none; } #endif // _di_fss_basic_list_read_main_process_file_ diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h index 0d7c72c..6ac9bd3 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h @@ -11,6 +11,7 @@ #ifdef __cplusplus extern "C" { #endif + /** * A structure of parameters applied at some depth. * @@ -22,8 +23,11 @@ extern "C" { typedef struct { f_string_length depth; - f_array_length parameter; - f_array_length position; + f_array_length index_at; + f_array_length index_name; + + f_number_unsigned value_at; + f_string value_name; } fss_basic_list_read_depth; #define fss_basic_list_read_depth_initialize \ @@ -31,6 +35,8 @@ extern "C" { 0, \ 0, \ 0, \ + 0, \ + f_string_initialize, \ } #endif // _di_fss_basic_list_read_depth_ @@ -53,13 +59,13 @@ extern "C" { #define macro_fss_basic_list_read_depths_clear(depths) f_macro_memory_structure_clear(depths) - #define macro_fss_basic_list_read_depths_new(status, depths, length) f_macro_memory_structure_new(status, depths, fss_basic_list_read_depths, length) + #define macro_fss_basic_list_read_depths_new(status, depths, length) f_macro_memory_structure_new(status, depths, fss_basic_list_read_depth, length) - #define macro_fss_basic_list_read_depths_delete(status, depths) f_macro_memory_structure_delete(status, depths, fss_basic_list_read_depths) - #define macro_fss_basic_list_read_depths_destroy(status, depths) f_macro_memory_structure_destroy(status, depths, fss_basic_list_read_depths) + #define macro_fss_basic_list_read_depths_delete(status, depths) f_macro_memory_structure_delete(status, depths, fss_basic_list_read_depth) + #define macro_fss_basic_list_read_depths_destroy(status, depths) f_macro_memory_structure_destroy(status, depths, fss_basic_list_read_depth) - #define macro_fss_basic_list_read_depths_resize(status, depths, new_length) f_macro_memory_structure_resize(status, depths, fss_basic_list_read_depths, new_length) - #define macro_fss_basic_list_read_depths_adjust(status, depths, new_length) f_macro_memory_structure_adjust(status, depths, fss_basic_list_read_depths, new_length) + #define macro_fss_basic_list_read_depths_resize(status, depths, new_length) f_macro_memory_structure_resize(status, depths, fss_basic_list_read_depth, new_length) + #define macro_fss_basic_list_read_depths_adjust(status, depths, new_length) f_macro_memory_structure_adjust(status, depths, fss_basic_list_read_depth, new_length) #endif // _di_fss_basic_list_read_depths_ /** @@ -79,12 +85,32 @@ extern "C" { #endif // _di_fss_basic_list_read_print_file_error_ /** + * Print number parameter argument error messages. + * + * @param context + * The color context information to use when printing. + * @param function_name + * The name of the function responsible for the error. + * @param parameter_name + * The name of the parameter responsible for the error. + * @param argument + * The value of the argument that is invalid. + * @param status + * The status code representing the error. + */ +#ifndef _di_fss_basic_list_read_print_number_argument_error_ + extern void fss_basic_list_read_print_number_argument_error(const fl_color_context context, const f_string function_name, const f_string parameter_name, const f_string argument, const f_status status) f_gcc_attribute_visibility_internal; +#endif // _di_fss_basic_list_read_print_number_argument_error_ + +/** * Pre-process the parameters, parsing out and handling the depth and depth related parameters. * + * Will handle depth-sensitive parameter conflicts, such as --name being used with --at (which is not allowed). + * * @param arguments * The console arguments to pre-process. * @param data - * The Program specific data. + * The program specific data. * @param depths * This stores the pre-processed depth parameters. * @@ -96,8 +122,22 @@ extern "C" { extern f_return_status fss_basic_list_read_main_preprocess_depth(const f_console_arguments arguments, const fss_basic_list_read_data data, fss_basic_list_read_depths *depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_list_read_main_preprocess_depth_ +/** + * Process a given file. + * + * @param arguments + * The console arguments passed to the program. + * @param data + * The program specific data. + * @param file_name + * The name of the file being processed. + * @param depths + * The processed depth parameters. + * + * @see fss_basic_list_read_main_preprocess_depth() + */ #ifndef _di_fss_basic_list_read_main_process_file_ - extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments arguments, fss_basic_list_read_data *data, const f_string filename, const f_string_length target) f_gcc_attribute_visibility_internal; + extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments arguments, fss_basic_list_read_data *data, const f_string file_name, const fss_basic_list_read_depths depths) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_list_read_main_process_file_ #ifdef __cplusplus -- 1.8.3.1