From afd2c0fd7774b0e55509493b10840c5cc4bd08bc Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 13 Nov 2019 20:44:53 -0600 Subject: [PATCH] Update: finish implementing fss_basic_read --- level_3/fss_basic_read/c/fss_basic_read.c | 31 ++---- level_3/fss_basic_read/c/fss_basic_read.h | 2 +- level_3/fss_basic_read/c/private-fss_basic_read.c | 123 +++++++++++++++------- 3 files changed, 93 insertions(+), 63 deletions(-) diff --git a/level_3/fss_basic_read/c/fss_basic_read.c b/level_3/fss_basic_read/c/fss_basic_read.c index 136f770..102ec5b 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -27,6 +27,10 @@ extern "C" { fll_program_print_help_usage(data.context, fss_basic_read_name, "filename(s)"); + 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 +57,13 @@ extern "C" { printf(" The parameter "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_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_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_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_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); @@ -77,7 +73,7 @@ extern "C" { printf(" Specify both "); fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_read_long_object); printf(" and the "); - fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_read_long_line); + fl_color_print(f_standard_output, data.context.notable, data.context.reset, "--%s", fss_basic_read_long_total); printf(" parameters to get the total objects.%c", f_string_eol); printf("%c", f_string_eol); @@ -236,21 +232,6 @@ extern "C" { return f_status_set_error(f_invalid_parameter); } - // 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_read_parameter_total].result == f_console_result_found) { - if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_found && data->parameters[fss_basic_read_parameter_name].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_read_parameter_total); - fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter, the '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_read_long_object); - fl_color_print(f_standard_error, data->context.error, data->context.reset, "' parameter, and the '"); - fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_basic_read_long_line); - fl_color_print_line(f_standard_error, data->context.error, data->context.reset, "' parameter together."); - - return f_status_set_error(f_invalid_parameter); - } - } - if (data->process_pipe) { f_file file = f_file_initialize; diff --git a/level_3/fss_basic_read/c/fss_basic_read.h b/level_3/fss_basic_read/c/fss_basic_read.h index b3d6ca5..34bc25f 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -104,7 +104,7 @@ extern "C" { f_console_parameter_initialize(fss_basic_read_short_total, fss_basic_read_long_total, 0, f_false, f_console_type_normal), \ } - #define fss_basic_read_total_parameters 13 + #define fss_basic_read_total_parameters 12 #endif // _di_fss_basic_read_defines_ #ifndef _di_fss_basic_read_data_ diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c index a8c02c3..6045522 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-fss_basic_read.c @@ -134,62 +134,111 @@ extern "C" { f_return_status fss_basic_read_main_preprocess_depth(const f_console_arguments arguments, const fss_basic_read_data data, fss_basic_read_depths *depths) { f_status status = f_none; - macro_fss_basic_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 status; + { + f_array_length depth_size = 1; + + if (data.parameters[fss_basic_read_parameter_depth].result == f_console_result_additional) { + depth_size = data.parameters[fss_basic_read_parameter_depth].additional.used; + } + + macro_fss_basic_read_depths_new(status, (*depths), depth_size); + 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 status; + } } - depths->array[0].depth = 0; - depths->array[0].index_at = 0; - depths->array[0].index_name = 0; - depths->array[0].value_at = 0; - depths->array[0].value_name = f_string_eos; - depths->used = 1; + depths->used = data.parameters[fss_basic_read_parameter_depth].additional.used; + + 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; - // @todo: walk through all depth parameters and build the loop, get and validate all --at and --name parameters on a per depth basis. - if (data.parameters[fss_basic_read_parameter_depth].result == f_console_result_additional) { - f_array_length depth_position = data.parameters[fss_basic_read_parameter_depth].additional.array[data.parameters[fss_basic_read_parameter_depth].additional.used - 1]; + position_depth = data.parameters[fss_basic_read_parameter_depth].additional.array[i]; - status = fl_console_parameter_to_number_unsigned(arguments.argv[depth_position], &depths->array[0].depth); + status = fl_console_parameter_to_number_unsigned(arguments.argv[position_depth], &depths->array[i].depth); if (f_status_is_error(status)) { - fss_basic_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_read_long_depth, arguments.argv[depth_position], f_status_set_fine(status)); + fss_basic_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_read_long_depth, arguments.argv[position_depth], f_status_set_fine(status)); return status; } - } - else { - // @todo: walk though each --at and --name parameter, validating them (consider warning for multiple values because only the last one will be used). + if (data.parameters[fss_basic_read_parameter_at].result == f_console_result_additional) { - depths->array[0].index_at = data.parameters[fss_basic_read_parameter_at].additional.array[data.parameters[fss_basic_read_parameter_at].additional.used - 1]; + for (; position_at < data.parameters[fss_basic_read_parameter_at].additional.used; position_at++) { + if (data.parameters[fss_basic_read_parameter_at].additional.array[position_at] < position_depth) { + continue; + } - status = fl_console_parameter_to_number_unsigned(arguments.argv[depths->array[0].index_at], &depths->array[0].value_at); + if (i + 1 < depths->used && data.parameters[fss_basic_read_parameter_at].additional.array[position_at] > data.parameters[fss_basic_read_parameter_depth].additional.array[i + 1]) { + break; + } - if (f_status_is_error(status)) { - fss_basic_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_read_long_at, arguments.argv[depths->array[0].index_at], f_status_set_fine(status)); - return status; - } + depths->array[i].index_at = data.parameters[fss_basic_read_parameter_at].additional.array[position_at]; + + status = fl_console_parameter_to_number_unsigned(arguments.argv[depths->array[i].index_at], &depths->array[i].value_at); + + if (f_status_is_error(status)) { + fss_basic_read_print_number_argument_error(data.context, "fl_console_parameter_to_number_unsigned", fss_basic_read_long_at, arguments.argv[depths->array[i].index_at], f_status_set_fine(status)); + return status; + } + } // for } if (data.parameters[fss_basic_read_parameter_name].result == f_console_result_additional) { - macro_fss_basic_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 status; - } + for (; position_name < data.parameters[fss_basic_read_parameter_name].additional.used; position_name++) { + if (data.parameters[fss_basic_read_parameter_name].additional.array[position_name] < position_depth) { + continue; + } + + if (i + 1 < depths->used && data.parameters[fss_basic_read_parameter_name].additional.array[position_name] > data.parameters[fss_basic_read_parameter_depth].additional.array[i + 1]) { + break; + } - depths->array[0].index_name = data.parameters[fss_basic_read_parameter_name].additional.array[data.parameters[fss_basic_read_parameter_name].additional.used - 1]; - depths->array[0].value_name = arguments.argv[depths->array[0].index_name]; + depths->array[i].index_name = data.parameters[fss_basic_read_parameter_name].additional.array[position_name]; + depths->array[i].value_name = arguments.argv[depths->array[i].index_name]; - if (depths->array[0].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_read_long_name); - fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' must not be an empty string."); + 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_read_long_name); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "' must not be an empty string."); + + return f_status_set_error(f_invalid_parameter); + } + } // for + } + } // for + + 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_read_long_depth); + fl_color_print_line(f_standard_error, data.context.error, data.context.reset, "'."); 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_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, "'."); + + return f_status_set_error(f_invalid_parameter); + } + } // for + } // for return f_none; } -- 1.8.3.1