From: Kevin Day Date: Sun, 2 May 2021 22:09:43 +0000 (-0500) Subject: Update: Implement data structure in FSS Read. X-Git-Tag: 0.5.4~68 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=1801132e1b0a5e04eaa58d1341d4f762a1050518;p=fll Update: Implement data structure in FSS Read. This is the designated follow up commit for resolving the need for a "data" structure. The parameters are now extracted into a bitwise "option" property on the "data" structure. The process is now broken up into multiple functions. --- 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 c9209de..645dd6e 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -160,7 +160,7 @@ extern "C" { #endif // _di_fss_basic_read_print_help_ #ifndef _di_fss_basic_read_main_ - f_status_t fss_basic_read_main(const f_console_arguments_t arguments, fss_basic_read_main_t *main) { + f_status_t fss_basic_read_main(f_console_arguments_t * const arguments, fss_basic_read_main_t *main) { f_status_t status = F_none; { @@ -170,7 +170,7 @@ extern "C" { f_console_parameter_id_t ids[3] = { fss_basic_read_parameter_no_color, fss_basic_read_parameter_light, fss_basic_read_parameter_dark }; const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 3); - status = fll_program_parameter_process(arguments, parameters, choices, F_true, &main->remaining, &main->context); + status = fll_program_parameter_process(*arguments, parameters, choices, F_true, &main->remaining, &main->context); if (main->context.set.error.before) { main->error.context = main->context.set.error; @@ -232,6 +232,14 @@ extern "C" { return status; } + // Provide a range designating where within the buffer a particular file exists, using a statically allocated array. + fss_basic_read_file_t files_array[main->remaining.used + 1]; + fss_basic_read_data_t data = fss_basic_read_data_t_initialize; + + data.files.array = files_array; + data.files.used = 1; + data.files.size = main->remaining.used + 1; + if (main->remaining.used > 0 || main->process_pipe) { if (main->parameters[fss_basic_read_parameter_at].result == f_console_result_found) { f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); @@ -295,7 +303,7 @@ extern "C" { } else if (main->parameters[fss_basic_read_parameter_delimit].result == f_console_result_additional) { const f_array_length_t location = main->parameters[fss_basic_read_parameter_delimit].values.array[0]; - f_array_length_t length = strnlen(arguments.argv[location], f_console_parameter_size); + f_array_length_t length = strnlen(arguments->argv[location], f_console_parameter_size); if (length == 0) { f_color_print(main->error.to.stream, main->context.set.error, "%sThe value for the parameter '", fll_error_print_error); @@ -304,23 +312,23 @@ extern "C" { status = F_status_set_error(F_parameter); } - else if (fl_string_compare(arguments.argv[location], fss_basic_read_delimit_mode_name_none, length, fss_basic_read_delimit_mode_name_none_length) == F_equal_to) { - main->delimit_mode = fss_basic_read_delimit_mode_none; + else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_none, length, fss_basic_read_delimit_mode_name_none_length) == F_equal_to) { + data.delimit_mode = fss_basic_read_delimit_mode_none; } - else if (fl_string_compare(arguments.argv[location], fss_basic_read_delimit_mode_name_all, length, fss_basic_read_delimit_mode_name_all_length) == F_equal_to) { - main->delimit_mode = fss_basic_read_delimit_mode_all; + else if (fl_string_compare(arguments->argv[location], fss_basic_read_delimit_mode_name_all, length, fss_basic_read_delimit_mode_name_all_length) == F_equal_to) { + data.delimit_mode = fss_basic_read_delimit_mode_all; } else { - main->delimit_mode = fss_basic_read_delimit_mode_depth; + data.delimit_mode = fss_basic_read_delimit_mode_depth; - if (arguments.argv[location][length - 1] == fss_basic_read_delimit_mode_name_greater[0]) { - main->delimit_mode = fss_basic_read_delimit_mode_depth_greater; + if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_greater[0]) { + data.delimit_mode = fss_basic_read_delimit_mode_depth_greater; // shorten the length to better convert the remainder to a number. length--; } - else if (arguments.argv[location][length - 1] == fss_basic_read_delimit_mode_name_lesser[0]) { - main->delimit_mode = fss_basic_read_delimit_mode_depth_lesser; + else if (arguments->argv[location][length - 1] == fss_basic_read_delimit_mode_name_lesser[0]) { + data.delimit_mode = fss_basic_read_delimit_mode_depth_lesser; // shorten the length to better convert the remainder to a number. length--; @@ -329,35 +337,32 @@ extern "C" { f_string_range_t range = macro_f_string_range_t_initialize(length); // ignore leading plus sign. - if (arguments.argv[location][0] == '+') { + if (arguments->argv[location][0] == '+') { range.start++; } - status = fl_conversion_string_to_number_unsigned(arguments.argv[location], range, &main->delimit_depth); + status = fl_conversion_string_to_number_unsigned(arguments->argv[location], range, &data.delimit_depth); if (F_status_is_error(status)) { - fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_delimit, arguments.argv[location]); + fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_delimit, arguments->argv[location]); } } } } f_file_t file = f_file_t_initialize; - fss_basic_read_depths_t depths = fss_basic_read_depths_t_initialize; - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; if (F_status_is_error_not(status)) { - status = fss_basic_read_depth_process(arguments, *main, &depths); + status = fss_basic_read_depth_process(arguments, main, &data); } // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. - if (F_status_is_error_not(status) && depths.array[0].depth > 0) { + if (F_status_is_error_not(status) && data.depths.array[0].depth > 0) { if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fprintf(main->output.stream, "0%c", f_string_eol_s[0]); } - fss_basic_read_depths_resize(0, &depths); - macro_f_fss_delimits_t_delete_simple(delimits); + fss_basic_read_data_delete_simple(&data); fss_basic_read_main_delete(main); return F_none; @@ -368,21 +373,14 @@ extern "C" { f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_select); f_color_print(main->error.to.stream, main->context.set.error, "' parameter requires a positive number.%c", f_string_eol_s[0]); - fss_basic_read_depths_resize(0, &depths); + fss_basic_read_depths_resize(0, &data.depths); status = F_status_set_error(F_parameter); } - // Provide a range designating where within the buffer a particular file exists, using a statically allocated array. @fixme make this a structure with - fss_basic_read_file_t files_array[main->remaining.used + 1]; - fss_basic_read_files_t files = fss_basic_read_files_t_initialize; - if (F_status_is_error_not(status)) { - files.array = files_array; - files.size += main->remaining.used; - - for (f_array_length_t i = 0; i < files.used; ++i) { - macro_f_string_range_t_clear(files.array[i].range); + for (f_array_length_t i = 0; i < data.files.used; ++i) { + macro_f_string_range_t_clear(data.files.array[i].range); } // for } @@ -390,90 +388,110 @@ extern "C" { file.id = f_type_descriptor_input; file.stream = f_type_input; - files.array[0].name = 0; - files.array[0].range.start = 0; + data.files.array[0].name = 0; + data.files.array[0].range.start = 0; - status = f_file_stream_read(file, &main->buffer); + status = f_file_stream_read(file, &data.buffer); if (F_status_is_error(status)) { fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_read", F_true, "-", "read", fll_error_file_type_pipe); } - else if (main->buffer.used) { - files.array[0].range.stop = main->buffer.used - 1; + else if (data.buffer.used) { + data.files.array[0].range.stop = data.buffer.used - 1; // This standard is newline sensitive, when appending files to the buffer if the file lacks a final newline then this could break the format for files appended thereafter. // Guarantee that a newline exists at the end of the buffer. - status = f_string_append_assure(f_string_eol_s, 1, &main->buffer); + status = f_string_append_assure(f_string_eol_s, 1, &data.buffer); if (F_status_is_error(status)) { fll_error_file_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true, "-", "read", fll_error_file_type_pipe); } } else { - files.array[0].range.start = 1; + data.files.array[0].range.start = 1; } } if (F_status_is_error_not(status) && main->remaining.used > 0) { - for (f_array_length_t i = 0; i < main->remaining.used; i++) { + f_array_length_t size_file = 0; + + for (f_array_length_t i = 0; i < main->remaining.used; ++i) { - files.array[files.used].range.start = main->buffer.used; + data.files.array[data.files.used].range.start = data.buffer.used; file.stream = 0; file.id = -1; - status = f_file_stream_open(arguments.argv[main->remaining.array[i]], 0, &file); + status = f_file_stream_open(arguments->argv[main->remaining.array[i]], 0, &file); if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_open", F_true, arguments.argv[main->remaining.array[i]], "open", fll_error_file_type_file); + fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_open", F_true, arguments->argv[main->remaining.array[i]], "open", fll_error_file_type_file); f_file_stream_close(F_true, &file); break; } - status = f_file_stream_read(file, &main->buffer); - - f_file_stream_close(F_true, &file); + size_file = 0; + status = f_file_size_by_id(file.id, &size_file); if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_read", F_true, arguments.argv[main->remaining.array[i]], "read", fll_error_file_type_file); + fll_error_file_print(main->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file); + f_file_stream_close(F_true, &file); break; } - else if (main->buffer.used > files.array[files.used].range.start) { - files.array[files.used].name = arguments.argv[main->remaining.array[i]]; - files.array[files.used++].range.stop = main->buffer.used - 1; - // This standard is newline sensitive, when appending files to the buffer if the file lacks a final newline then this could break the format for files appended thereafter. - // Guarantee that a newline exists at the end of the buffer. - status = f_string_append_assure(f_string_eol_s, 1, &main->buffer); + if (size_file) { + status = f_string_dynamic_resize(data.buffer.size + size_file, &data.buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), "f_string_dynamic_resize", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file); + + f_file_stream_close(F_true, &file); + break; + } + + status = f_file_stream_read(file, &data.buffer); + + f_file_stream_close(F_true, &file); if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true, "-", "read", fll_error_file_type_pipe); + fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_read", F_true, arguments->argv[main->remaining.array[i]], "read", fll_error_file_type_file); + + break; + } + else if (data.buffer.used > data.files.array[data.files.used].range.start) { + data.files.array[data.files.used].name = arguments->argv[main->remaining.array[i]]; + data.files.array[data.files.used++].range.stop = data.buffer.used - 1; + + // This standard is newline sensitive, when appending files to the buffer if the file lacks a final newline then this could break the format for files appended thereafter. + // Guarantee that a newline exists at the end of the buffer. + status = f_string_append_assure(f_string_eol_s, 1, &data.buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true, "-", "read", fll_error_file_type_pipe); + } } } else { - files.array[files.used].range.start = 1; + data.files.array[data.files.used].range.start = 1; } } // for } if (F_status_is_error_not(status)) { - status = fss_basic_read_process(arguments, files, depths, main, &delimits); + status = fss_basic_read_process(arguments, main, &data); } - macro_f_fss_contents_t_delete_simple(main->contents); - macro_f_fss_objects_t_delete_simple(main->objects); - macro_f_string_dynamic_t_delete_simple(main->buffer); - - fss_basic_read_depths_resize(0, &depths); - macro_f_fss_delimits_t_delete_simple(delimits); + fss_basic_read_data_delete_simple(&data); } else { f_color_print(main->error.to.stream, main->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol_s[0]); status = F_status_set_error(F_parameter); } + fss_basic_read_data_delete_simple(&data); fss_basic_read_main_delete(main); + return status; } #endif // _di_fss_basic_read_main_ @@ -487,9 +505,6 @@ extern "C" { macro_f_array_lengths_t_delete_simple(main->parameters[i].values); } // for - macro_f_fss_contents_t_delete_simple(main->contents); - macro_f_fss_objects_t_delete_simple(main->objects); - macro_f_string_dynamic_t_delete_simple(main->buffer); macro_f_array_lengths_t_delete_simple(main->remaining); macro_f_color_context_t_delete_simple(main->context); 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 e43c565..785893d 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -175,13 +175,6 @@ extern "C" { f_file_t output; fll_error_print_t error; - f_string_dynamic_t buffer; - f_fss_objects_t objects; - f_fss_contents_t contents; - - uint8_t delimit_mode; - f_array_length_t delimit_depth; - f_color_context_t context; } fss_basic_read_main_t; @@ -192,11 +185,6 @@ extern "C" { F_false, \ macro_f_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ - f_string_dynamic_t_initialize, \ - f_fss_objects_t_initialize, \ - f_fss_contents_t_initialize, \ - fss_basic_read_delimit_mode_all, \ - 0, \ f_color_context_t_initialize, \ } #endif // _di_fss_basic_read_main_t_ @@ -234,7 +222,7 @@ extern "C" { * @see fss_basic_read_main_delete() */ #ifndef _di_fss_basic_read_main_ - extern f_status_t fss_basic_read_main(const f_console_arguments_t arguments, fss_basic_read_main_t *main); + extern f_status_t fss_basic_read_main(f_console_arguments_t * const arguments, fss_basic_read_main_t *main); #endif // _di_fss_basic_read_main_ /** diff --git a/level_3/fss_basic_read/c/main.c b/level_3/fss_basic_read/c/main.c index 2af2ce9..efe4f0c 100644 --- a/level_3/fss_basic_read/c/main.c +++ b/level_3/fss_basic_read/c/main.c @@ -1,14 +1,15 @@ #include "fss_basic_read.h" int main(const int argc, const f_string_t *argv) { - const f_console_arguments_t arguments = { argc, argv }; + + f_console_arguments_t arguments = { argc, argv }; fss_basic_read_main_t main = fss_basic_read_main_t_initialize; if (f_pipe_input_exists()) { main.process_pipe = F_true; } - const f_status_t status = fss_basic_read_main(arguments, &main); + const f_status_t status = fss_basic_read_main(&arguments, &main); // flush output pipes before closing. fflush(f_type_output); diff --git a/level_3/fss_basic_read/c/private-common.c b/level_3/fss_basic_read/c/private-common.c index eba3728..0409bb6 100644 --- a/level_3/fss_basic_read/c/private-common.c +++ b/level_3/fss_basic_read/c/private-common.c @@ -5,6 +5,22 @@ extern "C" { #endif +#ifndef _di_fss_basic_read_data_delete_simple_ + void fss_basic_read_data_delete_simple(fss_basic_read_data_t *data) { + + if (!data) return; + + // data->files is expected to be statically loaded and cannot be deallocated. + + fss_basic_read_depths_resize(0, &data->depths); + macro_f_fss_delimits_t_delete_simple(data->delimits); + + macro_f_fss_contents_t_delete_simple(data->contents); + macro_f_fss_objects_t_delete_simple(data->objects); + macro_f_string_dynamic_t_delete_simple(data->buffer); + } +#endif // _di_fss_basic_read_data_delete_simple_ + #ifndef _di_fss_basic_read_depth_delete_simple_ void fss_basic_read_depth_delete_simple(fss_basic_read_depth_t *depth) { @@ -14,11 +30,12 @@ extern "C" { } #endif // _di_fss_basic_read_depth_delete_simple_ - #ifndef _di_fss_basic_read_depths_resize_ f_status_t fss_basic_read_depths_resize(const f_array_length_t length, fss_basic_read_depths_t *depths) { - if (!depths) return F_status_set_error(F_parameter); + if (!depths) { + return F_status_set_error(F_parameter); + } for (f_array_length_t i = length; i < depths->size; ++i) { fss_basic_read_depth_delete_simple(&depths->array[i]); diff --git a/level_3/fss_basic_read/c/private-common.h b/level_3/fss_basic_read/c/private-common.h index ab5c403..4c22775 100644 --- a/level_3/fss_basic_read/c/private-common.h +++ b/level_3/fss_basic_read/c/private-common.h @@ -90,7 +90,7 @@ extern "C" { #endif // _di_fss_basic_read_file_t_ /** - * An array of depth parameters. + * An array of files. * * This is intended to be defined and used statically allocated and as such no dynamic allocation or dynamic deallocation methods are provided. * @@ -112,6 +112,88 @@ extern "C" { #endif // _di_fss_basic_read_files_t_ /** + * The data structure for FSS Basic Read. + * + * fss_basic_read_data_option_*: + * - at: The object at the given position is being selected (Think of this as select a row for some Object). + * - content: The Content is to be printed. + * - delimit: The Content delimits will be applied on print. + * - empty: Empty Content will be printed (Objects that have no Content will have their empty Content printed). + * - line: A specific Content at a given line is to be selected (Think of this as select a row for some Content). + * - name: A specific Object name has been requested. + * - object: The Object is to be printed. + * - select: A specific Content at a given position is to be selected (Think of this as select a column for some Content). + * - total: The total lines found and selected is printed instead of the Content. + * - trim: Empty space before and after Objects and Content will not be printed (They will be trimmed). + * + * options: Bitwise flags representing parameters. + * delimit_mode: The delimit mode. + * delimit_depth: The delimit depth. + * select: The Content to select (column number). + * line: The Content to select (row number). + * files: A statically allocated array of files for designating where in the buffer a file is represented. + * depths: The array of parameters for each given depth. + * buffer: The buffer containing all loaded files (and STDIN pipe). + * objects: The positions within the buffer representing Objects. + * contents: The positions within the buffer representing Contents. + * delimits: The positions within the buffer representing character delimits. + */ +#ifndef _di_fss_basic_read_data_t_ + + #define fss_basic_read_data_option_at 0x1 + #define fss_basic_read_data_option_content 0x2 + #define fss_basic_read_data_option_delimit 0x4 + #define fss_basic_read_data_option_empty 0x8 + #define fss_basic_read_data_option_line 0x10 + #define fss_basic_read_data_option_name 0x20 + #define fss_basic_read_data_option_object 0x40 + #define fss_basic_read_data_option_select 0x80 + #define fss_basic_read_data_option_total 0x100 + #define fss_basic_read_data_option_trim 0x200 + + typedef struct { + uint16_t option; + uint8_t delimit_mode; + f_array_length_t delimit_depth; + f_number_unsigned_t select; + f_number_unsigned_t line; + + fss_basic_read_files_t files; + fss_basic_read_depths_t depths; + + f_string_dynamic_t buffer; + f_fss_objects_t objects; + f_fss_contents_t contents; + f_fss_delimits_t delimits; + } fss_basic_read_data_t; + + #define fss_basic_read_data_t_initialize \ + { \ + 0, \ + fss_basic_read_delimit_mode_all, \ + 0, \ + 0, \ + 0, \ + fss_basic_read_files_t_initialize, \ + fss_basic_read_depths_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_fss_objects_t_initialize, \ + f_fss_contents_t_initialize, \ + f_fss_delimits_t_initialize, \ + } +#endif // _di_fss_basic_read_data_t_ + +/** + * Fully deallocate all memory for the given data without caring about return status. + * + * @param data + * The data to deallocate. + */ +#ifndef _di_fss_basic_read_data_delete_simple_ + extern void fss_basic_read_data_delete_simple(fss_basic_read_data_t *daa) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_data_delete_simple_ + +/** * Fully deallocate all memory for the given depth without caring about return status. * * @param depth 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 3260d47..52a0407 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 @@ -7,116 +7,116 @@ extern "C" { #endif #ifndef _di_fss_basic_read_depth_process_ - f_status_t fss_basic_read_depth_process(const f_console_arguments_t arguments, const fss_basic_read_main_t main, fss_basic_read_depths_t *depths) { + f_status_t fss_basic_read_depth_process(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) { f_status_t status = F_none; { f_array_length_t depth_size = 1; - if (main.parameters[fss_basic_read_parameter_depth].result == f_console_result_additional) { - depth_size = main.parameters[fss_basic_read_parameter_depth].values.used; + if (main->parameters[fss_basic_read_parameter_depth].result == f_console_result_additional) { + depth_size = main->parameters[fss_basic_read_parameter_depth].values.used; } - if (depth_size > depths->size) { - status = fss_basic_read_depths_resize(depth_size, depths); + if (depth_size > data->depths.size) { + status = fss_basic_read_depths_resize(depth_size, &data->depths); if (F_status_is_error(status)) { - fll_error_print(main.error, F_status_set_fine(status), "fss_basic_read_depths_resize", F_true); + fll_error_print(main->error, F_status_set_fine(status), "fss_basic_read_depths_resize", F_true); return status; } } - depths->used = depth_size; + data->depths.used = depth_size; } f_array_length_t position_depth = 0; f_array_length_t position_at = 0; f_array_length_t position_name = 0; - for (f_array_length_t i = 0; i < depths->used; i++) { + for (f_array_length_t i = 0; i < data->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; + data->depths.array[i].depth = 0; + data->depths.array[i].index_at = 0; + data->depths.array[i].index_name = 0; + data->depths.array[i].value_at = 0; - macro_f_string_dynamic_t_clear(depths->array[i].value_name); + macro_f_string_dynamic_t_clear(data->depths.array[i].value_name); - if (!main.parameters[fss_basic_read_parameter_depth].values.used) { + if (!main->parameters[fss_basic_read_parameter_depth].values.used) { position_depth = 0; } else { - position_depth = main.parameters[fss_basic_read_parameter_depth].values.array[i]; + position_depth = main->parameters[fss_basic_read_parameter_depth].values.array[i]; - const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[position_depth])); + const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments->argv[position_depth])); - status = fl_conversion_string_to_number_unsigned(arguments.argv[position_depth], range, &depths->array[i].depth); + status = fl_conversion_string_to_number_unsigned(arguments->argv[position_depth], range, &data->depths.array[i].depth); if (F_status_is_error(status)) { - fll_error_parameter_integer_print(main.error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_depth, arguments.argv[position_depth]); + fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_depth, arguments->argv[position_depth]); return status; } } - if (main.parameters[fss_basic_read_parameter_at].result == f_console_result_additional) { - for (; position_at < main.parameters[fss_basic_read_parameter_at].values.used; position_at++) { + if (main->parameters[fss_basic_read_parameter_at].result == f_console_result_additional) { + for (; position_at < main->parameters[fss_basic_read_parameter_at].values.used; ++position_at) { - if (main.parameters[fss_basic_read_parameter_at].values.array[position_at] < position_depth) { + if (main->parameters[fss_basic_read_parameter_at].values.array[position_at] < position_depth) { continue; } - if (i + 1 < depths->used && main.parameters[fss_basic_read_parameter_at].values.array[position_at] > main.parameters[fss_basic_read_parameter_depth].values.array[i + 1]) { + if (i + 1 < data->depths.used && main->parameters[fss_basic_read_parameter_at].values.array[position_at] > main->parameters[fss_basic_read_parameter_depth].values.array[i + 1]) { break; } - depths->array[i].index_at = main.parameters[fss_basic_read_parameter_at].values.array[position_at]; + data->depths.array[i].index_at = main->parameters[fss_basic_read_parameter_at].values.array[position_at]; - const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments.argv[depths->array[i].index_at])); + const f_string_range_t range = macro_f_string_range_t_initialize(strlen(arguments->argv[data->depths.array[i].index_at])); - status = fl_conversion_string_to_number_unsigned(arguments.argv[depths->array[i].index_at], range, &depths->array[i].value_at); + status = fl_conversion_string_to_number_unsigned(arguments->argv[data->depths.array[i].index_at], range, &data->depths.array[i].value_at); if (F_status_is_error(status)) { - fll_error_parameter_integer_print(main.error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_at, arguments.argv[depths->array[i].index_at]); + fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_at, arguments->argv[data->depths.array[i].index_at]); return status; } } // for } - if (main.parameters[fss_basic_read_parameter_name].result == f_console_result_additional) { - for (; position_name < main.parameters[fss_basic_read_parameter_name].values.used; position_name++) { + if (main->parameters[fss_basic_read_parameter_name].result == f_console_result_additional) { + for (; position_name < main->parameters[fss_basic_read_parameter_name].values.used; position_name++) { - if (main.parameters[fss_basic_read_parameter_name].values.array[position_name] < position_depth) { + if (main->parameters[fss_basic_read_parameter_name].values.array[position_name] < position_depth) { continue; } - if (i + 1 < depths->used && main.parameters[fss_basic_read_parameter_name].values.array[position_name] > main.parameters[fss_basic_read_parameter_depth].values.array[i + 1]) { + if (i + 1 < data->depths.used && main->parameters[fss_basic_read_parameter_name].values.array[position_name] > main->parameters[fss_basic_read_parameter_depth].values.array[i + 1]) { break; } - depths->array[i].index_name = main.parameters[fss_basic_read_parameter_name].values.array[position_name]; + data->depths.array[i].index_name = main->parameters[fss_basic_read_parameter_name].values.array[position_name]; - if (main.parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { - status = fl_string_rip(arguments.argv[depths->array[i].index_name], strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + if (main->parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { + status = fl_string_rip(arguments->argv[data->depths.array[i].index_name], strlen(arguments->argv[data->depths.array[i].index_name]), &data->depths.array[i].value_name); } else { - status = f_string_append(arguments.argv[depths->array[i].index_name], strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + status = f_string_append(arguments->argv[data->depths.array[i].index_name], strlen(arguments->argv[data->depths.array[i].index_name]), &data->depths.array[i].value_name); } if (F_status_is_error(status)) { - fll_error_print(main.error, F_status_set_fine(status), main.parameters[fss_basic_read_parameter_trim].result == f_console_result_found ? "fl_string_rip" : "f_string_append", F_true); + fll_error_print(main->error, F_status_set_fine(status), main->parameters[fss_basic_read_parameter_trim].result == f_console_result_found ? "fl_string_rip" : "f_string_append", F_true); return status; } - if (!depths->array[i].value_name.used) { - if (main.error.verbosity != f_console_verbosity_quiet) { - f_color_print(main.error.to.stream, main.context.set.error, "%sThe '", fll_error_print_error); - f_color_print(main.error.to.stream, main.context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_name); - f_color_print(main.error.to.stream, main.context.set.error, "' must not be an empty string.%c", f_string_eol_s[0]); + if (!data->depths.array[i].value_name.used) { + if (main->error.verbosity != f_console_verbosity_quiet) { + f_color_print(main->error.to.stream, main->context.set.error, "%sThe '", fll_error_print_error); + f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_name); + f_color_print(main->error.to.stream, main->context.set.error, "' must not be an empty string.%c", f_string_eol_s[0]); } return F_status_set_error(F_parameter); @@ -125,30 +125,30 @@ extern "C" { } } // for - for (f_array_length_t i = 0; i < depths->used; i++) { + for (f_array_length_t i = 0; i < data->depths.used; ++i) { - for (f_array_length_t j = i + 1; j < depths->used; j++) { + for (f_array_length_t j = i + 1; j < data->depths.used; ++j) { - if (depths->array[i].depth == depths->array[j].depth) { - if (main.error.verbosity != f_console_verbosity_quiet) { - f_color_print(main.error.to.stream, main.context.set.error, "%sThe value '", fll_error_print_error); - f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[i].depth); - f_color_print(main.error.to.stream, main.context.set.error, "' may only be specified once for the parameter '"); - f_color_print(main.error.to.stream, main.context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_depth); - f_color_print(main.error.to.stream, main.context.set.error, "'.%c", f_string_eol_s[0]); + if (data->depths.array[i].depth == data->depths.array[j].depth) { + if (main->error.verbosity != f_console_verbosity_quiet) { + f_color_print(main->error.to.stream, main->context.set.error, "%sThe value '", fll_error_print_error); + f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[i].depth); + f_color_print(main->error.to.stream, main->context.set.error, "' may only be specified once for the parameter '"); + f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_depth); + f_color_print(main->error.to.stream, main->context.set.error, "'.%c", f_string_eol_s[0]); } return F_status_set_error(F_parameter); } - else if (depths->array[i].depth > depths->array[j].depth) { - if (main.error.verbosity != f_console_verbosity_quiet) { - f_color_print(main.error.to.stream, main.context.set.error, "%sThe parameter '", fll_error_print_error); - f_color_print(main.error.to.stream, main.context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_depth); - f_color_print(main.error.to.stream, main.context.set.error, "' may not have the value '"); - f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[i].depth); - f_color_print(main.error.to.stream, main.context.set.error, "' before the value '"); - f_color_print(main.error.to.stream, main.context.set.notable, "%llu", depths->array[j].depth); - f_color_print(main.error.to.stream, main.context.set.error, "'.%c", f_string_eol_s[0]); + else if (data->depths.array[i].depth > data->depths.array[j].depth) { + if (main->error.verbosity != f_console_verbosity_quiet) { + f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); + f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, fss_basic_read_long_depth); + f_color_print(main->error.to.stream, main->context.set.error, "' may not have the value '"); + f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[i].depth); + f_color_print(main->error.to.stream, main->context.set.error, "' before the value '"); + f_color_print(main->error.to.stream, main->context.set.notable, "%llu", data->depths.array[j].depth); + f_color_print(main->error.to.stream, main->context.set.error, "'.%c", f_string_eol_s[0]); } return F_status_set_error(F_parameter); @@ -175,55 +175,55 @@ extern "C" { #endif // _di_fss_basic_read_file_identify_ #ifndef _di_fss_basic_read_load_number_ - f_status_t fss_basic_read_load_number(const f_console_arguments_t arguments, const fss_basic_read_main_t main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) { + f_status_t fss_basic_read_load_number(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) { - if (main.parameters[parameter].result == f_console_result_additional) { - const f_array_length_t index = main.parameters[parameter].values.array[main.parameters[parameter].values.used - 1]; - const f_string_range_t range = macro_f_string_range_t_initialize(strnlen(arguments.argv[index], f_console_parameter_size)); + if (main->parameters[parameter].result == f_console_result_additional) { + const f_array_length_t index = main->parameters[parameter].values.array[main->parameters[parameter].values.used - 1]; + const f_string_range_t range = macro_f_string_range_t_initialize(strnlen(arguments->argv[index], f_console_parameter_size)); - const f_status_t status = fl_conversion_string_to_number_unsigned(arguments.argv[index], range, number); + const f_status_t status = fl_conversion_string_to_number_unsigned(arguments->argv[index], range, number); if (F_status_is_error(status)) { - fll_error_parameter_integer_print(main.error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, name, arguments.argv[index]); + fll_error_parameter_integer_print(main->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, name, arguments->argv[index]); return status; } + + return F_true; } - return F_none; + return F_false; } #endif // _di_fss_basic_read_load_number_ #ifndef _di_fss_basic_read_print_at_ - void fss_basic_read_print_at(const fss_basic_read_main_t main, const f_array_length_t at, const bool include_empty, const f_fss_delimits_t delimits, const uint8_t print_this) { + void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits) { - if (at >= main.contents.used) { + if (at >= data->contents.used) { return; } - if (main.contents.array[at].used || include_empty) { + if (data->contents.array[at].used || (data->option & fss_basic_read_data_option_empty)) { f_status_t (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_array_lengths_t) = &f_print_except_dynamic_partial; - if (main.parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { + if (data->option & fss_basic_read_data_option_trim) { print_object = &fl_print_trim_except_dynamic_partial; } - const f_array_lengths_t except_none = f_array_lengths_t_initialize; - - if (main.parameters[fss_basic_read_parameter_object].result == f_console_result_found) { - print_object(main.output.stream, main.buffer, main.objects.array[at], delimits); + if (data->option & fss_basic_read_data_option_object) { + print_object(main->output.stream, data->buffer, data->objects.array[at], delimits); - if (print_this & 0x2) { + if (data->option & fss_basic_read_data_option_content) { fss_basic_read_print_object_end(main); } } - if ((print_this & 0x2) && main.contents.array[at].used) { - f_print_except_dynamic_partial(main.output.stream, main.buffer, main.contents.array[at].array[0], delimits); + if ((data->option & fss_basic_read_data_option_content) && data->contents.array[at].used) { + f_print_except_dynamic_partial(main->output.stream, data->buffer, data->contents.array[at].array[0], delimits); } - if ((print_this & 0x1) || (print_this & 0x2) && (main.contents.array[at].used || include_empty)) { + if ((data->option & fss_basic_read_data_option_object) || (data->option & fss_basic_read_data_option_content) && (data->contents.array[at].used || (data->option & fss_basic_read_data_option_empty))) { fss_basic_read_print_set_end(main); } } @@ -231,270 +231,343 @@ extern "C" { #endif // _di_fss_basic_read_print_at_ #ifndef _di_fss_basic_read_print_object_end_ - void fss_basic_read_print_object_end(const fss_basic_read_main_t main) { + void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) { - if (main.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { - fprintf(main.output.stream, "%c", fss_basic_read_pipe_content_start); + if (main->parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { + fprintf(main->output.stream, "%c", fss_basic_read_pipe_content_start); } else { - fprintf(main.output.stream, "%c", f_fss_space); + fprintf(main->output.stream, "%c", f_fss_space); } } #endif // _di_fss_basic_read_print_object_end_ #ifndef _di_fss_basic_read_print_one_ - void fss_basic_read_print_one(const fss_basic_read_main_t main) { - fprintf(main.output.stream, "1%c", f_string_eol_s[0]); + void fss_basic_read_print_one(fss_basic_read_main_t * const main) { + fprintf(main->output.stream, "1%c", f_string_eol_s[0]); } #endif // _di_fss_basic_read_print_one_ #ifndef _di_fss_basic_read_print_set_end_ - void fss_basic_read_print_set_end(const fss_basic_read_main_t main) { + void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) { - if (main.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { - fprintf(main.output.stream, "%c", fss_basic_read_pipe_content_end); + if (main->parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) { + fprintf(main->output.stream, "%c", fss_basic_read_pipe_content_end); } else { - fprintf(main.output.stream, "%c", f_fss_eol); + fprintf(main->output.stream, "%c", f_fss_eol); } } #endif // _di_fss_basic_read_print_set_end_ #ifndef _di_fss_basic_read_print_zero_ - void fss_basic_read_print_zero(const fss_basic_read_main_t main) { - fprintf(main.output.stream, "0%c", f_string_eol_s[0]); + void fss_basic_read_print_zero(fss_basic_read_main_t * const main) { + fprintf(main->output.stream, "0%c", f_string_eol_s[0]); } #endif // _di_fss_basic_read_print_zero_ -#ifndef _di_fss_basic_read_process_ - f_status_t fss_basic_read_process(const f_console_arguments_t arguments, const fss_basic_read_files_t files, const fss_basic_read_depths_t depths, fss_basic_read_main_t *main, f_fss_delimits_t *delimits) { +#ifndef _di_fss_basic_read_load_ + f_status_t fss_basic_read_load(fss_basic_read_main_t * const main, fss_basic_read_data_t *data) { - f_status_t status = F_none; + f_string_range_t input = macro_f_string_range_t_initialize(data->buffer.used); - const f_array_lengths_t except_none = f_array_lengths_t_initialize; - bool delimited = F_true; - bool include_empty = F_false; - f_number_unsigned_t select = 0; - f_number_unsigned_t line = 0; + data->delimits.used = 0; - // @todo after changes to main, create a private main object for processing and using this and similar. - // 0x1 = print object, 0x2 = print content. - uint8_t print_this = main->parameters[fss_basic_read_parameter_object].result == f_console_result_found; + const f_status_t status = fll_fss_basic_read(data->buffer, &input, &data->objects, &data->contents, 0, &data->delimits, 0); - if (!print_this || main->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { - print_this |= 0x2; - } + if (F_status_is_error(status)) { + const f_string_t file_name = fss_basic_read_file_identify(input.start, data->files); - if (main->delimit_mode == fss_basic_read_delimit_mode_none || (main->delimit_depth && (main->delimit_mode == fss_basic_read_delimit_mode_depth || main->delimit_mode == fss_basic_read_delimit_mode_depth_greater))) { - delimited = F_false; - } + fll_error_file_print(main->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, file_name ? file_name : "-", "process", fll_error_file_type_file); - if (main->parameters[fss_basic_read_parameter_empty].result == f_console_result_found) { - include_empty = F_true; + return status; } + else if (status == F_data_not_stop || status == F_data_not_eos) { + if (data->option & fss_basic_read_data_option_total) { + fss_basic_read_print_zero(main); - status = fss_basic_read_load_number(arguments, *main, fss_basic_read_parameter_select, fss_basic_read_long_select, &select); - if (F_status_is_error(status)) return status; + return F_none; + } - status = fss_basic_read_load_number(arguments, *main, fss_basic_read_parameter_line, fss_basic_read_long_line, &line); - if (F_status_is_error(status)) return status; + return F_status_set_warning(status); + } - if (main->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) { + return F_none; + } +#endif // _di_fss_basic_read_load_ - // This standard does not support multiple content groups. - if (select) { - if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fss_basic_read_print_zero(*main); - } +#ifndef _di_fss_basic_read_process_ + f_status_t fss_basic_read_process(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) { - return F_none; + f_status_t status = fss_basic_read_process_option(arguments, main, data); + if (F_status_is_error(status)) return status; + + // This standard does not support multiple content groups. + if (data->option & fss_basic_read_data_option_select) { + if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { + fss_basic_read_print_zero(main); } + + return F_none; } - { - f_string_range_t input = macro_f_string_range_t_initialize(main->buffer.used); + status = fss_basic_read_load(main, data); + if (F_status_is_error(status)) return status; - delimits->used = 0; + bool names[data->objects.used]; - status = fll_fss_basic_read(main->buffer, &input, &main->objects, &main->contents, 0, delimits, 0); + status = fss_basic_read_process_name(data, names); + if (F_status_is_error(status)) return status; - if (F_status_is_error(status)) { - const f_string_t file_name = fss_basic_read_file_identify(input.start, files); + if (data->depths.array[0].index_at) { + return fss_basic_read_process_at(main, data, names); + } - fll_error_file_print(main->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, file_name ? file_name : "-", "process", fll_error_file_type_file); - } - else if (status == F_data_not_stop || status == F_data_not_eos) { - if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fss_basic_read_print_zero(*main); + if (data->option & fss_basic_read_data_option_total) { + return fss_basic_read_process_total(main, data, names); + } - return F_none; - } + if (data->option & fss_basic_read_data_option_line) { + return fss_basic_read_process_line(main, data, names); + } - return F_status_set_warning(status); - } + f_array_lengths_t except_none = f_array_lengths_t_initialize; + f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none; - if (F_status_is_error(status)) { - return status; - } - } + for (f_array_length_t i = 0; i < data->contents.used; ++i) { - bool names[main->objects.used]; + if (!names[i]) continue; - f_array_length_t i = 0; + fss_basic_read_print_at(main, data, i, *delimits); + } // for - if (depths.array[0].index_name > 0) { - memset(names, 0, sizeof(bool) * main->objects.used); + return F_none; + } +#endif // _di_fss_basic_read_process_ - if (main->parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { - for (i = 0; i < main->objects.used; i++) { +#ifndef _di_fss_basic_read_process_at_ + f_status_t fss_basic_read_process_at(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) { - if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[0].value_name, main->buffer, main->objects.array[i], except_none, *delimits) == F_equal_to) { - names[i] = 1; - } - } // for + if (data->depths.array[0].value_at >= data->objects.used) { + if (names[data->depths.array[0].value_at] && (data->option & fss_basic_read_data_option_total)) { + fss_basic_read_print_zero(main); } - else { - for (i = 0; i < main->objects.used; i++) { - if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[0].value_name, main->buffer, main->objects.array[i], except_none, *delimits) == F_equal_to) { - names[i] = 1; - } - } // for - } - } - else { - memset(names, 1, sizeof(bool) * main->objects.used); + return F_none; } - if (depths.array[0].index_at) { - if (depths.array[0].value_at >= main->objects.used) { - if (names[depths.array[0].value_at] && main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fss_basic_read_print_zero(*main); - } - + if (data->option & fss_basic_read_data_option_line) { + if (data->line) { return F_none; } + } - if (main->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { - if (line > 0) { - return F_none; - } - } + f_array_lengths_t except_none = f_array_lengths_t_initialize; + f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none; - f_array_length_t at = 0; + f_array_length_t at = 0; - for (; i < main->objects.used; i++) { + for (f_array_length_t i = 0; i < data->objects.used; ++i) { - if (!names[i]) continue; + if (!names[i]) continue; - if (at == depths.array[0].value_at) { - if (main->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { + if (at == data->depths.array[0].value_at) { + if (data->option & fss_basic_read_data_option_line) { - // This standard only supports one Content per Object so when using "--at", the only valid line is line 0. - if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - if (line) { - fss_basic_read_print_one(*main); - } - else { - fss_basic_read_print_zero(*main); - } - } - else if (!line) { - fss_basic_read_print_at(*main, i, include_empty, delimited ? *delimits : except_none, print_this); - } - } - else if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - if (!main->contents.array[i].used) { - fss_basic_read_print_zero(*main); + // This standard only supports one Content per Object so when using "--at", the only valid line is line 0. + if (data->option & fss_basic_read_data_option_total) { + if (data->line) { + fss_basic_read_print_one(main); } else { - fss_basic_read_print_one(*main); + fss_basic_read_print_zero(main); } } + else if (!data->line) { + fss_basic_read_print_at(main, data, i, *delimits); + } + } + else if (data->option & fss_basic_read_data_option_total) { + if (!data->contents.array[i].used) { + fss_basic_read_print_zero(main); + } else { - fss_basic_read_print_at(*main, i, include_empty, delimited ? *delimits : except_none, print_this); + fss_basic_read_print_one(main); } - - break; + } + else { + fss_basic_read_print_at(main, data, i, *delimits); } - at++; - } // for + break; + } - return F_none; - } + ++at; + } // for - if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - f_array_length_t total = 0; + return F_none; + } +#endif // _di_fss_basic_read_process_at_ - for (i = 0; i < main->objects.used; i++) { +#ifndef _di_fss_basic_read_process_line_ + f_status_t fss_basic_read_process_line(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) { - if (!names[i]) continue; + f_array_lengths_t except_none = f_array_lengths_t_initialize; + f_array_lengths_t *delimits = (data->option & fss_basic_read_data_option_delimit) ? &data->delimits : &except_none; - if (!(main->contents.array[i].used || include_empty)) { - continue; - } + f_array_length_t line_current = 0; - total++; - } // for + for (f_array_length_t i = 0; i < data->contents.used; ++i) { - if (main->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { - if (line < total) { - fss_basic_read_print_one(*main); - } - else { - fss_basic_read_print_zero(*main); + if (!names[i]) continue; + + if (!data->contents.array[i].used) { + if (data->option & fss_basic_read_data_option_empty) { + if (line_current == data->line) { + fss_basic_read_print_set_end(main); + break; + } + + ++line_current; } + + continue; + } + + if (line_current == data->line) { + fss_basic_read_print_at(main, data, i, *delimits); + + break; + } + + ++line_current; + } // for + + return F_none; + } +#endif // _di_fss_basic_read_process_line_ + +#ifndef _di_fss_basic_read_process_name_ + f_status_t fss_basic_read_process_name(fss_basic_read_data_t *data, bool names[]) { + + f_array_lengths_t except_none = f_array_lengths_t_initialize; + + if (data->depths.array[0].index_name > 0) { + f_array_length_t i = 0; + + memset(names, F_false, sizeof(bool) * data->objects.used); + + if (data->option & fss_basic_read_data_option_trim) { + for (i = 0; i < data->objects.used; ++i) { + + if (fl_string_dynamic_partial_compare_except_trim_dynamic(data->depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, data->delimits) == F_equal_to) { + names[i] = F_true; + } + } // for } else { - fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]); + for (i = 0; i < data->objects.used; ++i) { + + if (fl_string_dynamic_partial_compare_except_dynamic(data->depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, data->delimits) == F_equal_to) { + names[i] = F_true; + } + } // for } + } + else { + memset(names, F_true, sizeof(bool) * data->objects.used); + } - return F_none; + return F_none; + } +#endif // _di_fss_basic_read_process_name_ + +#ifndef _di_fss_basic_read_process_option_ + f_status_t fss_basic_read_process_option(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) { + + f_status_t status = F_none; + + if (main->parameters[fss_basic_read_parameter_at].result == f_console_result_additional) { + data->option |= fss_basic_read_data_option_at; } - if (main->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { - f_array_length_t line_current = 0; + if (main->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { + data->option |= fss_basic_read_data_option_content; + } - for (i = 0; i < main->contents.used; i++) { + if (!(data->delimit_mode == fss_basic_read_delimit_mode_none || (data->delimit_depth && (data->delimit_mode == fss_basic_read_delimit_mode_depth || data->delimit_mode == fss_basic_read_delimit_mode_depth_greater)))) { + data->option |= fss_basic_read_data_option_delimit; + } - if (!names[i]) continue; + if (main->parameters[fss_basic_read_parameter_empty].result == f_console_result_found) { + data->option |= fss_basic_read_data_option_empty; + } - if (!main->contents.array[i].used) { - if (include_empty) { - if (line_current == line) { - fss_basic_read_print_set_end(*main); - break; - } + if (main->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { + data->option |= fss_basic_read_data_option_line; - line_current++; - } + status = fss_basic_read_load_number(arguments, main, fss_basic_read_parameter_line, fss_basic_read_long_line, &data->line); + if (F_status_is_error(status)) return status; + } - continue; - } + if (main->parameters[fss_basic_read_parameter_name].result == f_console_result_additional) { + data->option |= fss_basic_read_data_option_name; + } - if (line_current == line) { - fss_basic_read_print_at(*main, i, include_empty, delimited ? *delimits : except_none, print_this); + if (main->parameters[fss_basic_read_parameter_object].result == f_console_result_found) { + data->option |= fss_basic_read_data_option_object; + } - break; - } + if (main->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) { + data->option |= fss_basic_read_data_option_select; - line_current++; - } // for + status = fss_basic_read_load_number(arguments, main, fss_basic_read_parameter_select, fss_basic_read_long_select, &data->select); + if (F_status_is_error(status)) return status; + } - return F_none; + if (main->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { + data->option |= fss_basic_read_data_option_total; + } + + if (main->parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { + data->option |= fss_basic_read_data_option_trim; } - for (i = 0; i < main->contents.used; i++) { + return F_none; + } +#endif // _di_fss_basic_read_process_option_ + +#ifndef _di_fss_basic_read_process_total_ + f_status_t fss_basic_read_process_total(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) { + + f_array_length_t total = 0; + + for (f_array_length_t i = 0; i < data->objects.used; ++i) { if (!names[i]) continue; - fss_basic_read_print_at(*main, i, include_empty, delimited ? *delimits : except_none, print_this); + if (!(data->contents.array[i].used || (data->option & fss_basic_read_data_option_empty))) { + continue; + } + + ++total; } // for + if (data->option & fss_basic_read_data_option_line) { + if (data->line < total) { + fss_basic_read_print_one(main); + } + else { + fss_basic_read_print_zero(main); + } + } + else { + fprintf(main->output.stream, "%llu%c", total, f_string_eol_s[0]); + } + return F_none; } -#endif // _di_fss_basic_read_process_ +#endif // _di_fss_basic_read_process_total_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.h b/level_3/fss_basic_read/c/private-fss_basic_read.h index fd196e6..eeda2c5 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.h +++ b/level_3/fss_basic_read/c/private-fss_basic_read.h @@ -18,11 +18,11 @@ extern "C" { * 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. + * The parameters passed to the process. * @param main - * The program specific main. - * @param depths - * This stores the pre-processed depth parameters. + * The main data. + * @param data + * The program data. * * @return * F_none on success. @@ -40,7 +40,7 @@ extern "C" { * @see fss_basic_read_depths_resize() */ #ifndef _di_fss_basic_read_depth_process_ - extern f_status_t fss_basic_read_depth_process(const f_console_arguments_t arguments, const fss_basic_read_main_t main, fss_basic_read_depths_t *depths) f_attribute_visibility_internal; + extern f_status_t fss_basic_read_depth_process(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) f_attribute_visibility_internal; #endif // _di_fss_basic_read_depth_process_ /** @@ -78,7 +78,8 @@ extern "C" { * The location to store the loaded number. * * @return - * F_none on success. + * F_true on success and the parameter was found (and is valid). + * F_false on success and the parameter was not found. * * Errors (with error bit) from: fl_conversion_string_to_number_unsigned(). * @@ -87,7 +88,7 @@ extern "C" { * @see fss_basic_read_depths_resize() */ #ifndef _di_fss_basic_read_load_number_ - extern f_status_t fss_basic_read_load_number(const f_console_arguments_t arguments, const fss_basic_read_main_t main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) f_attribute_visibility_internal; + extern f_status_t fss_basic_read_load_number(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, const f_array_length_t parameter, const f_string_t name, f_number_unsigned_t *number) f_attribute_visibility_internal; #endif // _di_fss_basic_read_load_number_ /** @@ -96,22 +97,18 @@ extern "C" { * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. * * @param main - * The program specific main. + * The main data. + * @param data + * The program data. * @param at * The index in the Objects and Contents to print. - * @param include_empty - * If TRUE, empty Content is printed. - * If FALSE, empty Content is ignored. * @param delimits * The delimits in the objects and contents. - * @param print_this - * Set bit 0x1 for printing Object. - * Set bit 0x2 for printing Content. * * This is a temporary parameter to be used until other structural changes are made and completed. */ #ifndef _di_fss_basic_read_print_at_ - extern void fss_basic_read_print_at(const fss_basic_read_main_t main, const f_array_length_t at, const bool include_empty, const f_fss_delimits_t delimits, const uint8_t print_this) f_attribute_visibility_internal; + extern void fss_basic_read_print_at(fss_basic_read_main_t * const main, fss_basic_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits) f_attribute_visibility_internal; #endif // _di_fss_basic_read_print_at_ /** @@ -121,7 +118,7 @@ extern "C" { * The program specific main. */ #ifndef _di_fss_basic_read_print_object_end_ - extern void fss_basic_read_print_object_end(const fss_basic_read_main_t main) f_attribute_visibility_internal; + extern void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) f_attribute_visibility_internal; #endif // _di_fss_basic_read_print_object_end_ /** @@ -131,7 +128,7 @@ extern "C" { * The program specific main. */ #ifndef _di_fss_basic_read_print_one_ - extern void fss_basic_read_print_one(const fss_basic_read_main_t main) f_attribute_visibility_internal; + extern void fss_basic_read_print_one(fss_basic_read_main_t * const main) f_attribute_visibility_internal; #endif // _di_fss_basic_read_print_one_ /** @@ -141,7 +138,7 @@ extern "C" { * The program specific main. */ #ifndef _di_fss_basic_read_print_set_end_ - extern void fss_basic_read_print_set_end(const fss_basic_read_main_t main) f_attribute_visibility_internal; + extern void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) f_attribute_visibility_internal; #endif // _di_fss_basic_read_print_set_end_ /** @@ -151,29 +148,126 @@ extern "C" { * The program specific main. */ #ifndef _di_fss_basic_read_print_zero_ - extern void fss_basic_read_print_zero(const fss_basic_read_main_t main) f_attribute_visibility_internal; + extern void fss_basic_read_print_zero(fss_basic_read_main_t * const main) f_attribute_visibility_internal; #endif // _di_fss_basic_read_print_zero_ /** + * Process the buffer, loading the FSS data. + * + * This will print an error message on error. + * + * @param main + * The main data. + * @param data + * The program data. + * + * @return + * F_none on success. + * + * F_data_not_stop (with warning bit) on no valid FSS data found and reached stopping point. + * F_data_not_eos (with warning bit) on no valid FSS data found and reached end of string. + * + * Errors (with error bit) from: fll_fss_basic_read() + * + * @see fll_fss_basic_read() + * + * @see fss_basic_read_process_option() + */ +#ifndef _di_fss_basic_read_load_ + extern f_status_t fss_basic_read_load(fss_basic_read_main_t * const main, fss_basic_read_data_t *data) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_load_ + +/** * Perform the basic read processing on the buffer. * * This will print an error message on error. * * @param arguments - * The console arguments passed to the program. - * @param files - * An array representing the ranges in which a given file exists in the buffer. - * @param depths - * The processed depth parameters. + * The parameters passed to the process. * @param main - * The program specific main. - * @param delimits - * An array of delimits detected during processing. + * The main data. + * @param data + * The program data. * * @return * F_none on success. * - * Errors (with error bit) from: fll_fss_basic_read() + * Errors (with error bit) from: fss_basic_read_load() + * Errors (with error bit) from: fss_basic_read_process_option() + * + * @see fss_basic_read_load() + * @see fss_basic_read_process_option() + */ +#ifndef _di_fss_basic_read_process_ + extern f_status_t fss_basic_read_process(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_ + +/** + * Process based on at parameter. + * + * @param main + * The main data. + * @param data + * The program data. + * @param names + * An array of booleans representing whether or not some Object name is to be used. + * (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.) + * + * @return + * F_none on success. + */ +#ifndef _di_fss_basic_read_process_at_ + extern f_status_t fss_basic_read_process_at(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_at_ + +/** + * Process based on line parameter. + * + * @param main + * The main data. + * @param data + * The program data. + * @param names + * An array of booleans representing whether or not some Object name is to be used. + * (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.) + * + * @return + * F_none on success. + */ +#ifndef _di_fss_basic_read_process_line_ + extern f_status_t fss_basic_read_process_line(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_line_ + +/** + * Process the Objects in the buffer, determining if the Object name is to be used or not. + * + * How an Object name is determined to be used or not is dependent on several parameters, such as --name, --depth, --at, and --line. + * + * @param data + * The program data. + * @param names + * An array of booleans representing whether or not some Object name is to be used. + * (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.) + * + * @return + * F_none on success. + */ +#ifndef _di_fss_basic_read_process_name_ + extern f_status_t fss_basic_read_process_name(fss_basic_read_data_t *data, bool names[]) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_name_ + +/** + * Process the parameters, populating the option property of the program data. + * + * @param arguments + * The parameters passed to the process. + * @param main + * The main data. + * @param data + * The program data. + * + * @return + * F_none on success. * * Errors (with error bit) from: fss_basic_read_load_setting() * @@ -181,9 +275,27 @@ extern "C" { * * @see fss_basic_read_load_setting() */ -#ifndef _di_fss_basic_read_process_ - extern f_status_t fss_basic_read_process(const f_console_arguments_t arguments, const fss_basic_read_files_t files, const fss_basic_read_depths_t depths, fss_basic_read_main_t *main, f_fss_delimits_t *delimits) f_attribute_visibility_internal; -#endif // _di_fss_basic_read_process_ +#ifndef _di_fss_basic_read_process_option_ + extern f_status_t fss_basic_read_process_option(f_console_arguments_t * const arguments, fss_basic_read_main_t * const main, fss_basic_read_data_t *data) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_option_ + +/** + * Process based on total parameter. + * + * @param main + * The main data. + * @param data + * The program data. + * @param names + * An array of booleans representing whether or not some Object name is to be used. + * (If TRUE, then the name is to be used and if FALSE, then the name is not to be used.) + * + * @return + * F_none on success. + */ +#ifndef _di_fss_basic_read_process_total_ + extern f_status_t fss_basic_read_process_total(fss_basic_read_main_t * const main, fss_basic_read_data_t *data, bool names[]) f_attribute_visibility_internal; +#endif // _di_fss_basic_read_process_total_ #ifdef __cplusplus } // extern "C"