From 478c6aafc77f6748447a865355fedabda1c3bf2a Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 24 Oct 2020 11:55:14 -0500 Subject: [PATCH] Feature: add suppot for specifying delimits via -D/--delimit to FSS read programs. The -D/--delimit parameter accepts multiple types of values: - "all": apply all delimits. - "none": do not apply delimits. - 1: apply limits at depth 1 (this can be any supported whole number and not just 1). - 1-: apply limits at depth 1 or lesser (this can be any supported whole number and not just 1). - 1+: apply limits at depth 1 or greater (this can be any supported whole number and not just 1). The appropriate FSS functions need to be updated to not auto-apply delimits. Instead, these now pass the delimits array back to the caller. The FSS Extended List Read program delimits support is currently incomplete. - A considerable amount of changes are needed to adequately support this. - A follow up commit will address this issue. --- level_2/fll_fss/c/fss_basic.c | 8 +- level_2/fll_fss/c/fss_basic.h | 10 +- level_2/fll_fss/c/fss_basic_list.c | 8 +- level_2/fll_fss/c/fss_basic_list.h | 10 +- level_2/fll_fss/c/fss_extended.c | 8 +- level_2/fll_fss/c/fss_extended.h | 10 +- level_2/fll_fss/c/fss_extended_list.c | 8 +- level_2/fll_fss/c/fss_extended_list.h | 10 +- .../fss_basic_list_read/c/fss_basic_list_read.c | 327 ++++++++++++-------- .../fss_basic_list_read/c/fss_basic_list_read.h | 35 ++- .../c/private-fss_basic_list_read.c | 100 +++---- level_3/fss_basic_read/c/fss_basic_read.c | 315 ++++++++++++-------- level_3/fss_basic_read/c/fss_basic_read.h | 35 ++- level_3/fss_basic_read/c/private-fss_basic_read.c | 83 +++--- .../c/fss_extended_list_read.c | 323 ++++++++++++-------- .../c/fss_extended_list_read.h | 35 ++- .../c/private-fss_extended_list_read.c | 121 ++++---- .../c/private-fss_extended_list_read.h | 30 +- level_3/fss_extended_read/c/fss_extended_read.c | 328 +++++++++++++-------- level_3/fss_extended_read/c/fss_extended_read.h | 35 ++- .../c/private-fss_extended_read.c | 147 +++++---- .../c/private-fss_extended_read.h | 24 +- 22 files changed, 1258 insertions(+), 752 deletions(-) diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index c0c5a5c..4c23006 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -5,13 +5,13 @@ extern "C" { #endif #ifndef _di_fll_fss_basic_read_ - f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *delimits) { + f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); - if (!delimits) return F_status_set_error(F_parameter); + if (!objects_delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; @@ -41,7 +41,7 @@ extern "C" { quoted_object = "ed_objects->array[quoted_objects->used]; } - status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used], quoted_object, delimits); + status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used], quoted_object, objects_delimits); if (F_status_is_error(status)) { return status; @@ -84,7 +84,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_basic_content_read(buffer, range, &contents->array[contents->used], delimits); + status = fl_fss_basic_content_read(buffer, range, &contents->array[contents->used], contents_delimits ? contents_delimits : objects_delimits); if (F_status_is_error(status)) return status; break; diff --git a/level_2/fll_fss/c/fss_basic.h b/level_2/fll_fss/c/fss_basic.h index 93c6808..351ddac 100644 --- a/level_2/fll_fss/c/fss_basic.h +++ b/level_2/fll_fss/c/fss_basic.h @@ -43,9 +43,13 @@ extern "C" { * @param quoted_objects * An array of all objects discovered with quotes and the quote discovered. * Set the pointer address to 0 to disable. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits for objects detected during processing. * The caller is expected to decide if and when to process them. + * @param contents_delimits + * (optional) An array of delimits for contents detected during processing. + * The caller is expected to decide if and when to process them. + * Set pointer address to 0 and all delimits will instead utilize objects_delimits. * * @return * F_none on success. @@ -64,7 +68,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_basic_object_read(). */ #ifndef _di_fll_fss_basic_read_ - extern f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *delimits); + extern f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits); #endif // _di_fll_fss_basic_read_ /** diff --git a/level_2/fll_fss/c/fss_basic_list.c b/level_2/fll_fss/c/fss_basic_list.c index 3c129e7..d84d1c7 100644 --- a/level_2/fll_fss/c/fss_basic_list.c +++ b/level_2/fll_fss/c/fss_basic_list.c @@ -5,13 +5,13 @@ extern "C" { #endif #ifndef _di_fll_fss_basic_list_read_ - f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *delimits) { + f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); - if (!delimits) return F_status_set_error(F_parameter); + if (!objects_delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; @@ -30,7 +30,7 @@ extern "C" { } do { - status = fl_fss_basic_list_object_read(buffer, range, &objects->array[objects->used], delimits); + status = fl_fss_basic_list_object_read(buffer, range, &objects->array[objects->used], objects_delimits); if (F_status_is_error(status)) return status; if (range->start >= range->stop || range->start >= buffer->used) { @@ -65,7 +65,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_basic_list_content_read(buffer, range, &contents->array[contents->used], delimits); + status = fl_fss_basic_list_content_read(buffer, range, &contents->array[contents->used], contents_delimits ? contents_delimits : objects_delimits); if (F_status_is_error(status)) { return status; diff --git a/level_2/fll_fss/c/fss_basic_list.h b/level_2/fll_fss/c/fss_basic_list.h index 86abeb9..1cd4cfa 100644 --- a/level_2/fll_fss/c/fss_basic_list.h +++ b/level_2/fll_fss/c/fss_basic_list.h @@ -39,9 +39,13 @@ extern "C" { * This will be populated with all valid objects found. * @param contents * This will be populated with all valid contents found. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits for objects detected during processing. * The caller is expected to decide if and when to process them. + * @param contents_delimits + * (optional) An array of delimits for contents detected during processing. + * The caller is expected to decide if and when to process them. + * Set pointer address to 0 and all delimits will instead utilize objects_delimits. * * @return * F_none on success. @@ -60,7 +64,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_basic_list_object_read(). */ #ifndef _di_fll_fss_basic_list_read_ - extern f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *delimits); + extern f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits); #endif // _di_fll_fss_basic_list_read_ /** diff --git a/level_2/fll_fss/c/fss_extended.c b/level_2/fll_fss/c/fss_extended.c index 480ced1..45d1969 100644 --- a/level_2/fll_fss/c/fss_extended.c +++ b/level_2/fll_fss/c/fss_extended.c @@ -5,13 +5,13 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_read_ - f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *delimits) { + f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); - if (!delimits) return F_status_set_error(F_parameter); + if (!objects_delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; @@ -47,7 +47,7 @@ extern "C" { quoted_object = "ed_objects->array[quoted_objects->used]; } - status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used], quoted_object, delimits); + status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used], quoted_object, objects_delimits); if (F_status_is_error(status)) { return status; @@ -98,7 +98,7 @@ extern "C" { quoted_content = "ed_contents->array[quoted_contents->used]; } - status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used], quoted_content, delimits); + status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used], quoted_content, contents_delimits ? contents_delimits : objects_delimits); if (F_status_is_error(status)) { return status; diff --git a/level_2/fll_fss/c/fss_extended.h b/level_2/fll_fss/c/fss_extended.h index 158b753..12ccb4b 100644 --- a/level_2/fll_fss/c/fss_extended.h +++ b/level_2/fll_fss/c/fss_extended.h @@ -44,9 +44,13 @@ extern "C" { * @param quoted_contents * An array of all contents discovered with quotes and the quote discovered. * Set the pointer address to 0 to disable. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits for objects detected during processing. * The caller is expected to decide if and when to process them. + * @param contents_delimits + * (optional) An array of delimits for contents detected during processing. + * The caller is expected to decide if and when to process them. + * Set pointer address to 0 and all delimits will instead utilize objects_delimits. * * @return * F_none on success. @@ -65,7 +69,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_extended_object_read(). */ #ifndef _di_fll_fss_extended_read_ - extern f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *delimits); + extern f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits); #endif // _di_fll_fss_extended_read_ /** diff --git a/level_2/fll_fss/c/fss_extended_list.c b/level_2/fll_fss/c/fss_extended_list.c index 0cca1f5..64316f5 100644 --- a/level_2/fll_fss/c/fss_extended_list.c +++ b/level_2/fll_fss/c/fss_extended_list.c @@ -5,12 +5,12 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_list_read_ - f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *delimits) { + f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { #ifndef _di_level_3_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!nest) return F_status_set_error(F_parameter); - if (!delimits) return F_status_set_error(F_parameter); + if (!objects_delimits) return F_status_set_error(F_parameter); #endif // _di_level_3_parameter_checking_ f_status_t status = F_none; @@ -34,7 +34,7 @@ extern "C" { if (F_status_is_error(status)) return status; } - status = fl_fss_extended_list_object_read(buffer, range, &nest->depth[0].array[nest->depth[0].used].object, delimits); + status = fl_fss_extended_list_object_read(buffer, range, &nest->depth[0].array[nest->depth[0].used].object, objects_delimits); if (F_status_is_error(status)) return status; if (range->start >= range->stop || range->start >= buffer->used) { @@ -63,7 +63,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_extended_list_content_read(buffer, range, nest, delimits); + status = fl_fss_extended_list_content_read(buffer, range, nest, contents_delimits ? contents_delimits : objects_delimits); break; } diff --git a/level_2/fll_fss/c/fss_extended_list.h b/level_2/fll_fss/c/fss_extended_list.h index d8153bf..5510a22 100644 --- a/level_2/fll_fss/c/fss_extended_list.h +++ b/level_2/fll_fss/c/fss_extended_list.h @@ -36,9 +36,13 @@ extern "C" { * The range within the buffer that is currently being read. * @param nest * An nested set of all objects and content. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits for objects detected during processing. * The caller is expected to decide if and when to process them. + * @param contents_delimits + * (optional) An array of delimits for contents detected during processing. + * The caller is expected to decide if and when to process them. + * Set pointer address to 0 and all delimits will instead utilize objects_delimits. * * @return * F_none on success (both valid object and valid content found with start location is at end of content). @@ -64,7 +68,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_extended_list_object_read(). */ #ifndef _di_fll_fss_extended_list_read_ - extern f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *delimits); + extern f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits); #endif // _di_fll_fss_extended_list_read_ /** 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 811d814..b24b3c5 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 @@ -6,133 +6,153 @@ extern "C" { #endif #ifndef _di_fss_basic_list_read_print_help_ - f_return_status fss_basic_list_read_print_help(const f_file_t file, const f_color_context_t context) { + f_return_status fss_basic_list_read_print_help(const f_file_t output, const f_color_context_t context) { - fll_program_print_help_header(file, context, fss_basic_list_read_name_long, fss_basic_list_read_version); + fll_program_print_help_header(output, context, fss_basic_list_read_name_long, fss_basic_list_read_version); - fll_program_print_help_option(file, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); - fll_program_print_help_option(file, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); - fll_program_print_help_option(file, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); + fll_program_print_help_option(output, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); + fll_program_print_help_option(output, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); + fll_program_print_help_option(output, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - fll_program_print_help_option(file, 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(file, context, fss_basic_list_read_short_content, fss_basic_list_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); - fll_program_print_help_option(file, 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(file, 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(file, 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(file, 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(file, 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."); - fll_program_print_help_option(file, context, fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); - fll_program_print_help_option(file, 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(file, 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_option(file, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); + fll_program_print_help_option(output, 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(output, context, fss_basic_list_read_short_content, fss_basic_list_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); + fll_program_print_help_option(output, context, fss_basic_list_read_short_delimit, fss_basic_list_read_long_delimit, f_console_symbol_short_enable, f_console_symbol_long_enable, " Designate how to handle applying delimits."); + fll_program_print_help_option(output, 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(output, 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(output, 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(output, 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(output, 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."); + fll_program_print_help_option(output, context, fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); + fll_program_print_help_option(output, 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(output, 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_option(output, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); - fll_program_print_help_usage(file, context, fss_basic_list_read_name, "filename(s)"); + fll_program_print_help_usage(output, context, fss_basic_list_read_name, "filename(s)"); - fl_color_print(f_type_output, context.set.important, " Notes:"); + fl_color_print(output.stream, context.set.important, " Notes:"); - printf("%c", f_string_eol[0], f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0], f_string_eol[0]); - 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[0]); + fprintf(output.stream, " 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[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When using the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); + fprintf(output.stream, " option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); + + fprintf(output.stream, " When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); + fprintf(output.stream, ": An object index at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); + fprintf(output.stream, ": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); + fprintf(output.stream, ": An object name at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); + fprintf(output.stream, " must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); + fprintf(output.stream, " ('-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[0]); + fprintf(output.stream, " ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); + fprintf(output.stream, " selects a content index at a given depth.%c", f_string_eol[0]); + fprintf(output.stream, " (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " Specify both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); + fprintf(output.stream, " and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total); + fprintf(output.stream, " parameters to get the total objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); + fprintf(output.stream, " and "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); + fprintf(output.stream, " parameters are specified (at the same depth), the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); + fprintf(output.stream, " parameter value will be treated as a position relative to the specified "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); + fprintf(output.stream, " parameter value.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " This program may support parameters, such as "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); + fprintf(output.stream, " or "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); + fprintf(output.stream, ", even if not supported by the standard.%c", f_string_eol[0]); + fprintf(output.stream, " This is done to help ensure consistency for scripting.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); + fprintf(output.stream, ", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); + fprintf(output.stream, ", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_trim); + fprintf(output.stream, " will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When specifying both the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); + fprintf(output.stream, " parameter and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_content); + fprintf(output.stream, " parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content printed are already escaped.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content are separated by an EOL.%c", f_string_eol[0]); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - printf(" When using the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); - printf(" option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); - - printf(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); - printf(": An object index at the specified depth.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); - printf(": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); - printf(": An object name at the specified depth.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); - printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); - 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[0]); - printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); - printf(" selects a content index at a given depth.%c", f_string_eol[0]); - printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" Specify both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); - printf(" and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total); - printf(" parameters to get the total objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); - printf(" and "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); - printf(" parameters are specified (at the same depth), the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at); - printf(" parameter value will be treated as a position relative to the specified "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name); - printf(" parameter value.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" This program may support parameters, such as "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); - printf(" or "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); - printf(", even if not supported by the standard.%c", f_string_eol[0]); - printf(" This is done to help ensure consistency for scripting.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth); - printf(", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select); - printf(", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_trim); - printf(" will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When specifying both the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); - printf(" parameter and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_content); - printf(" parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); - printf(" Both the object and content printed are already escaped.%c", f_string_eol[0]); - printf(" Both the object and content are separated by an EOL.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_delimit); + fprintf(output.stream, " accepts the following:%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_list_read_delimit_mode_name_none); + fprintf(output.stream, ": Do not apply delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_list_read_delimit_mode_name_all); + fprintf(output.stream, ": (default) apply all delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater: apply delimits for the specified depth.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_list_read_delimit_mode_name_greater); + fprintf(output.stream, ": (such as '1+') apply delimits for the specified depth and any greater depth (numerically).%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_list_read_delimit_mode_name_lesser); + fprintf(output.stream, ": (such as '1-') apply delimits for the specified depth and any lesser depth (numerically).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); return F_none; } @@ -245,8 +265,8 @@ extern "C" { status = F_status_set_error(F_parameter); } - if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) { - if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { + if (F_status_is_error_not(status) && 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_additional) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); @@ -281,8 +301,8 @@ extern "C" { } } - if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { - if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && 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(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); @@ -293,8 +313,8 @@ extern "C" { } } - if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { - if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { + if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error); fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_pipe); fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '"); @@ -305,6 +325,63 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_basic_list_read_parameter_delimit].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires a value.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_basic_list_read_parameter_delimit].result == f_console_result_additional) { + const f_string_length_t location = data->parameters[fss_basic_list_read_parameter_delimit].additional.array[0]; + f_string_length_t length = strnlen(arguments.argv[location], f_console_length_size); + + if (length == 0) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe value for the parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' must not be empty.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (fl_string_compare(arguments.argv[location], fss_basic_list_read_delimit_mode_name_none, length, fss_basic_list_read_delimit_mode_name_none_length) == F_equal_to) { + data->delimit_mode = fss_basic_list_read_delimit_mode_none; + } + else if (fl_string_compare(arguments.argv[location], fss_basic_list_read_delimit_mode_name_all, length, fss_basic_list_read_delimit_mode_name_all_length) == F_equal_to) { + data->delimit_mode = fss_basic_list_read_delimit_mode_all; + } + else { + data->delimit_mode = fss_basic_list_read_delimit_mode_depth; + + if (arguments.argv[location][length - 1] == fss_basic_list_read_delimit_mode_name_greater[0]) { + data->delimit_mode = fss_basic_list_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_list_read_delimit_mode_name_lesser[0]) { + data->delimit_mode = fss_basic_list_read_delimit_mode_depth_lesser; + + // shorten the length to better convert the remainder to a number. + length--; + } + + f_string_range_t range = f_macro_string_range_t_initialize(length); + + // ignore leading plus sign. + if (arguments.argv[location][0] == '+') { + range.start++; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[location], &data->delimit_depth, range); + + if (F_status_is_error(status)) { + fll_error_parameter_integer_print(data->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_list_read_long_delimit, arguments.argv[location]); + } + } + } + } + fss_basic_list_read_depths_t depths = fss_basic_list_read_depths_t_initialize; f_fss_delimits_t delimits = f_fss_delimits_t_initialize; @@ -325,7 +402,7 @@ extern "C" { f_macro_fss_delimits_t_delete_simple(delimits); if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } fss_basic_list_read_delete_data(data); @@ -390,7 +467,7 @@ extern "C" { // Skip past empty files. if (!data->quantity.total) { if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } f_file_stream_close(F_true, &file); 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 1c6028d..fc49c1a 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 @@ -68,6 +68,7 @@ extern "C" { #define fss_basic_list_read_short_at "a" #define fss_basic_list_read_short_content "c" + #define fss_basic_list_read_short_delimit "D" #define fss_basic_list_read_short_depth "d" #define fss_basic_list_read_short_empty "e" #define fss_basic_list_read_short_line "l" @@ -80,6 +81,7 @@ extern "C" { #define fss_basic_list_read_long_at "at" #define fss_basic_list_read_long_content "content" + #define fss_basic_list_read_long_delimit "delimit" #define fss_basic_list_read_long_depth "depth" #define fss_basic_list_read_long_empty "empty" #define fss_basic_list_read_long_line "line" @@ -103,6 +105,7 @@ extern "C" { fss_basic_list_read_parameter_at, fss_basic_list_read_parameter_content, + fss_basic_list_read_parameter_delimit, fss_basic_list_read_parameter_depth, fss_basic_list_read_parameter_empty, fss_basic_list_read_parameter_line, @@ -127,6 +130,7 @@ extern "C" { f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \ f_console_parameter_t_initialize(fss_basic_list_read_short_at, fss_basic_list_read_long_at, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_content, fss_basic_list_read_long_content, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_list_read_short_delimit, fss_basic_list_read_long_delimit, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_depth, fss_basic_list_read_long_depth, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_empty, fss_basic_list_read_long_empty, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_read_short_line, fss_basic_list_read_long_line, 0, 1, f_console_type_normal), \ @@ -138,9 +142,29 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_list_read_total_parameters 20 + #define fss_basic_list_read_total_parameters 21 #endif // _di_fss_basic_list_read_defines_ +#ifndef _di_fss_basic_list_read_delimit_mode_ + #define fss_basic_list_read_delimit_mode_name_none "none" + #define fss_basic_list_read_delimit_mode_name_all "all" + #define fss_basic_list_read_delimit_mode_name_greater "+" + #define fss_basic_list_read_delimit_mode_name_lesser "-" + + #define fss_basic_list_read_delimit_mode_name_none_length 4 + #define fss_basic_list_read_delimit_mode_name_all_length 3 + #define fss_basic_list_read_delimit_mode_name_greater_length 1 + #define fss_basic_list_read_delimit_mode_name_lesser_length 1 + + enum { + fss_basic_list_read_delimit_mode_none = 1, + fss_basic_list_read_delimit_mode_all, + fss_basic_list_read_delimit_mode_depth, + fss_basic_list_read_delimit_mode_depth_greater, + fss_basic_list_read_delimit_mode_depth_lesser, + }; +#endif // _di_fss_basic_list_read_delimit_modes_ + #ifndef _di_fss_basic_list_read_data_t_ typedef struct { f_console_parameter_t parameters[fss_basic_list_read_total_parameters]; @@ -156,6 +180,9 @@ extern "C" { f_fss_contents_t contents; f_string_quantity_t quantity; + uint8_t delimit_mode; + f_string_length_t delimit_depth; + f_color_context_t context; } fss_basic_list_read_data_t; @@ -170,6 +197,8 @@ extern "C" { f_fss_objects_t_initialize, \ f_fss_contents_t_initialize, \ f_string_quantity_t_initialize, \ + fss_basic_list_read_delimit_mode_all, \ + 0, \ f_color_context_t_initialize, \ } #endif // _di_fss_basic_list_read_data_t_ @@ -177,7 +206,7 @@ extern "C" { /** * Print help. * - * @param file + * @param output * The file to print to. * @param context * The color context settings. @@ -186,7 +215,7 @@ extern "C" { * F_none on success. */ #ifndef _di_fss_basic_list_read_print_help_ - extern f_return_status fss_basic_list_read_print_help(const f_file_t file, const f_color_context_t context); + extern f_return_status fss_basic_list_read_print_help(const f_file_t output, const f_color_context_t context); #endif // _di_fss_basic_list_read_print_help_ /** 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 fb6b115..1e1783a 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 @@ -173,46 +173,39 @@ extern "C" { f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t filename, const fss_basic_list_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; + const f_string_lengths_t except_none = f_string_lengths_t_initialize; + bool delimited = F_true; + + // for this standard, delimits would always be applied, except for when delimit_depth is greater than 0. + if (data->delimit_mode == fss_basic_list_read_delimit_mode_none || (data->delimit_depth && (data->delimit_mode == fss_basic_list_read_delimit_mode_depth || data->delimit_mode == fss_basic_list_read_delimit_mode_depth_greater))) { + delimited = F_false; + } + { f_string_range_t input = f_macro_string_range_t_initialize(data->buffer.used); delimits->used = 0; - status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents, delimits); + status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents, delimits, 0); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. - f_macro_fss_contents_t_delete_simple(data->contents); - f_macro_fss_objects_t_delete_simple(data->objects); - f_macro_string_dynamic_t_delete_simple(data->buffer); - - return status; } - - if (status == F_data_not_stop || status == F_data_not_eos) { - - // Clear buffers, then attempt the next file. + else if (status == F_data_not_stop || status == F_data_not_eos) { f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); return F_none; } return F_status_set_warning(status); } - status = fl_fss_apply_delimit(*delimits, &data->buffer); - if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); @@ -262,28 +255,18 @@ extern "C" { if (depths.array[0].index_name > 0) { memset(names, 0, sizeof(bool) * data->objects.used); - f_string_length_t name_length = 0; - if (data->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare_trim(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *delimits) == F_equal_to) { + names[i] = 1; } } // for } else { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *delimits) == F_equal_to) { + names[i] = 1; } } // for } @@ -302,10 +285,10 @@ extern "C" { 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_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } else { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } } else if (depths.array[0].index_name > 0) { @@ -317,19 +300,19 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); } else { - fprintf(f_type_output, "%llu%c", data->objects.used, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", data->objects.used, f_string_eol[0]); } return F_none; } - f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t) = &f_print_dynamic_partial; + f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_string_lengths_t) = &f_print_except_dynamic_partial; if (data->parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) { - print_object = &fl_print_trim_string_dynamic_partial; + print_object = &fl_print_trim_except_dynamic_partial; } if (depths.array[0].index_at > 0) { @@ -340,13 +323,13 @@ extern "C" { if (names[i]) { if (at == depths.array[0].value_at) { - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], delimited ? *delimits : except_none); fss_basic_list_read_print_object_end(*data); if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); } } @@ -362,15 +345,16 @@ extern "C" { } for (i = 0; i < data->objects.used; i++) { + if (!names[i]) continue; - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], delimited ? *delimits : except_none); fss_basic_list_read_print_object_end(*data); if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); } } @@ -383,7 +367,7 @@ extern "C" { if (depths.array[0].index_at > 0) { if (depths.array[0].value_at >= data->objects.used) { if (names[depths.array[0].value_at] && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } return F_none; @@ -397,7 +381,7 @@ extern "C" { if (at == depths.array[0].value_at) { if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { if (!data->contents.array[i].used) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } else { f_array_length_t total = 1; @@ -410,7 +394,7 @@ extern "C" { } } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); } return F_none; @@ -419,7 +403,7 @@ extern "C" { if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) { if (!data->contents.array[i].used) { if (include_empty && !line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); fss_basic_list_read_print_set_end(*data); } } @@ -430,11 +414,11 @@ extern "C" { for (; i <= data->contents.array[i].array[0].stop; i++) { if (!data->buffer.string[i]) continue; if (data->buffer.string[i] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[i]); + fprintf(data->output.stream, "%c", data->buffer.string[i]); } // for } else { @@ -453,11 +437,11 @@ extern "C" { if (!data->buffer.string[i]) continue; if (data->buffer.string[i] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[i]); + fprintf(data->output.stream, "%c", data->buffer.string[i]); } // for break; @@ -471,14 +455,14 @@ extern "C" { } if (data->contents.array[i].used > 0) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end); } } else if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); fss_basic_list_read_print_set_end(*data); } @@ -515,7 +499,7 @@ extern "C" { } // for } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); return F_none; } @@ -526,7 +510,7 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { if (line_current == line) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); fss_basic_list_read_print_set_end(*data); break; } @@ -560,11 +544,11 @@ extern "C" { if (!data->buffer.string[j]) continue; if (data->buffer.string[j] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[j]); + fprintf(data->output.stream, "%c", data->buffer.string[j]); } // for break; @@ -579,14 +563,14 @@ extern "C" { if (!data->contents.array[i].used) { if (include_empty) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); fss_basic_list_read_print_set_end(*data); } continue; } - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) { fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end); 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 6e80642..8eb7db5 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -6,133 +6,153 @@ extern "C" { #endif #ifndef _di_fss_basic_read_print_help_ - f_return_status fss_basic_read_print_help(const f_file_t file, const f_color_context_t context) { + f_return_status fss_basic_read_print_help(const f_file_t output, const f_color_context_t context) { - fll_program_print_help_header(file, context, fss_basic_read_name_long, fss_basic_read_version); + fll_program_print_help_header(output, context, fss_basic_read_name_long, fss_basic_read_version); - fll_program_print_help_option(file, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); - fll_program_print_help_option(file, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); - fll_program_print_help_option(file, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); + fll_program_print_help_option(output, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); + fll_program_print_help_option(output, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); + fll_program_print_help_option(output, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - fll_program_print_help_option(file, context, fss_basic_read_short_at, fss_basic_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); - fll_program_print_help_option(file, context, fss_basic_read_short_content, fss_basic_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); - fll_program_print_help_option(file, context, fss_basic_read_short_depth, fss_basic_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); - fll_program_print_help_option(file, context, fss_basic_read_short_empty, fss_basic_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); - fll_program_print_help_option(file, context, fss_basic_read_short_line, fss_basic_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(file, context, fss_basic_read_short_name, fss_basic_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); - fll_program_print_help_option(file, context, fss_basic_read_short_object, fss_basic_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); - fll_program_print_help_option(file, context, fss_basic_read_short_pipe, fss_basic_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); - fll_program_print_help_option(file, context, fss_basic_read_short_select, fss_basic_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); - fll_program_print_help_option(file, context, fss_basic_read_short_total, fss_basic_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); - fll_program_print_help_option(file, context, fss_basic_read_short_trim, fss_basic_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); + fll_program_print_help_option(output, context, fss_basic_read_short_at, fss_basic_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); + fll_program_print_help_option(output, context, fss_basic_read_short_content, fss_basic_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); + fll_program_print_help_option(output, context, fss_basic_read_short_delimit, fss_basic_read_long_delimit, f_console_symbol_short_enable, f_console_symbol_long_enable, " Designate how to handle applying delimits."); + fll_program_print_help_option(output, context, fss_basic_read_short_depth, fss_basic_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); + fll_program_print_help_option(output, context, fss_basic_read_short_empty, fss_basic_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); + fll_program_print_help_option(output, context, fss_basic_read_short_line, fss_basic_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(output, context, fss_basic_read_short_name, fss_basic_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); + fll_program_print_help_option(output, context, fss_basic_read_short_object, fss_basic_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(output, context, fss_basic_read_short_pipe, fss_basic_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); + fll_program_print_help_option(output, context, fss_basic_read_short_select, fss_basic_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); + fll_program_print_help_option(output, context, fss_basic_read_short_total, fss_basic_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); + fll_program_print_help_option(output, context, fss_basic_read_short_trim, fss_basic_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); - fll_program_print_help_usage(file, context, fss_basic_read_name, "filename(s)"); + fll_program_print_help_usage(output, context, fss_basic_read_name, "filename(s)"); - fl_color_print(f_type_output, context.set.important, " Notes:"); + fl_color_print(output.stream, context.set.important, " Notes:"); - printf("%c", f_string_eol[0], f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0], f_string_eol[0]); - 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[0]); + fprintf(output.stream, " 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[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When using the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); + fprintf(output.stream, " option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); + + fprintf(output.stream, " When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); + fprintf(output.stream, ": An object index at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); + fprintf(output.stream, ": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); + fprintf(output.stream, ": An object name at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); + fprintf(output.stream, " must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); + fprintf(output.stream, " ('-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[0]); + fprintf(output.stream, " ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); + fprintf(output.stream, " selects a content index at a given depth.%c", f_string_eol[0]); + fprintf(output.stream, " (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " Specify both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); + fprintf(output.stream, " and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total); + fprintf(output.stream, " parameters to get the total objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); + fprintf(output.stream, " and "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); + fprintf(output.stream, " parameters are specified (at the same depth), the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); + fprintf(output.stream, " parameter value will be treated as a position relative to the specified "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); + fprintf(output.stream, " parameter value.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " This program may support parameters, such as "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); + fprintf(output.stream, " or "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); + fprintf(output.stream, ", even if not supported by the standard.%c", f_string_eol[0]); + fprintf(output.stream, " This is done to help ensure consistency for scripting.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); + fprintf(output.stream, ", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); + fprintf(output.stream, ", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_trim); + fprintf(output.stream, " will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When specifying both the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); + fprintf(output.stream, " parameter and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_content); + fprintf(output.stream, " parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content printed are already escaped.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content are separated by a space.%c", f_string_eol[0]); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - printf(" When using the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); - printf(" option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); - - printf(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); - printf(": An object index at the specified depth.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); - printf(": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); - printf(": An object name at the specified depth.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); - printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); - 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[0]); - printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); - printf(" selects a content index at a given depth.%c", f_string_eol[0]); - printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" Specify both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); - printf(" and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total); - printf(" parameters to get the total objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); - printf(" and "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); - printf(" parameters are specified (at the same depth), the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at); - printf(" parameter value will be treated as a position relative to the specified "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name); - printf(" parameter value.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" This program may support parameters, such as "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); - printf(" or "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); - printf(", even if not supported by the standard.%c", f_string_eol[0]); - printf(" This is done to help ensure consistency for scripting.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth); - printf(", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select); - printf(", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_trim); - printf(" will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When specifying both the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object); - printf(" parameter and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_content); - printf(" parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); - printf(" Both the object and content printed are already escaped.%c", f_string_eol[0]); - printf(" Both the object and content are separated by a space.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_delimit); + fprintf(output.stream, " accepts the following:%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_none); + fprintf(output.stream, ": Do not apply delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_all); + fprintf(output.stream, ": (default) apply all delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater: apply delimits for the specified depth.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_greater); + fprintf(output.stream, ": (such as '1+') apply delimits for the specified depth and any greater depth (numerically).%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_basic_read_delimit_mode_name_lesser); + fprintf(output.stream, ": (such as '1-') apply delimits for the specified depth and any lesser depth (numerically).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); return F_none; } @@ -305,6 +325,63 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_basic_read_parameter_delimit].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires a value.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_basic_read_parameter_delimit].result == f_console_result_additional) { + const f_string_length_t location = data->parameters[fss_basic_read_parameter_delimit].additional.array[0]; + f_string_length_t length = strnlen(arguments.argv[location], f_console_length_size); + + if (length == 0) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe value for the parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' must not be empty.%c", f_string_eol[0]); + + 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) { + 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) { + data->delimit_mode = fss_basic_read_delimit_mode_all; + } + else { + data->delimit_mode = fss_basic_read_delimit_mode_depth; + + 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]) { + data->delimit_mode = fss_basic_read_delimit_mode_depth_lesser; + + // shorten the length to better convert the remainder to a number. + length--; + } + + f_string_range_t range = f_macro_string_range_t_initialize(length); + + // ignore leading plus sign. + if (arguments.argv[location][0] == '+') { + range.start++; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[location], &data->delimit_depth, range); + + if (F_status_is_error(status)) { + fll_error_parameter_integer_print(data->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_basic_read_long_delimit, arguments.argv[location]); + } + } + } + } + fss_basic_read_depths_t depths = fss_basic_read_depths_t_initialize; f_fss_delimits_t delimits = f_fss_delimits_t_initialize; @@ -325,7 +402,7 @@ extern "C" { f_macro_fss_delimits_t_delete_simple(delimits); if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } fss_basic_read_delete_data(data); @@ -391,7 +468,7 @@ extern "C" { // Skip past empty files. if (!data->quantity.total) { if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } f_file_stream_close(F_true, &file); 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 ae4a818..df5e123 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -68,6 +68,7 @@ extern "C" { #define fss_basic_read_short_at "a" #define fss_basic_read_short_content "c" + #define fss_basic_read_short_delimit "D" #define fss_basic_read_short_depth "d" #define fss_basic_read_short_empty "e" #define fss_basic_read_short_line "l" @@ -80,6 +81,7 @@ extern "C" { #define fss_basic_read_long_at "at" #define fss_basic_read_long_content "content" + #define fss_basic_read_long_delimit "delimit" #define fss_basic_read_long_depth "depth" #define fss_basic_read_long_empty "empty" #define fss_basic_read_long_line "line" @@ -103,6 +105,7 @@ extern "C" { fss_basic_read_parameter_at, fss_basic_read_parameter_content, + fss_basic_read_parameter_delimit, fss_basic_read_parameter_depth, fss_basic_read_parameter_empty, fss_basic_read_parameter_line, @@ -127,6 +130,7 @@ extern "C" { f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \ f_console_parameter_t_initialize(fss_basic_read_short_at, fss_basic_read_long_at, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_content, fss_basic_read_long_content, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_read_short_delimit, fss_basic_read_long_delimit, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_depth, fss_basic_read_long_depth, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_empty, fss_basic_read_long_empty, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_read_short_line, fss_basic_read_long_line, 0, 1, f_console_type_normal), \ @@ -138,9 +142,29 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_read_short_trim, fss_basic_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_read_total_parameters 20 + #define fss_basic_read_total_parameters 21 #endif // _di_fss_basic_read_defines_ +#ifndef _di_fss_basic_read_delimit_mode_ + #define fss_basic_read_delimit_mode_name_none "none" + #define fss_basic_read_delimit_mode_name_all "all" + #define fss_basic_read_delimit_mode_name_greater "+" + #define fss_basic_read_delimit_mode_name_lesser "-" + + #define fss_basic_read_delimit_mode_name_none_length 4 + #define fss_basic_read_delimit_mode_name_all_length 3 + #define fss_basic_read_delimit_mode_name_greater_length 1 + #define fss_basic_read_delimit_mode_name_lesser_length 1 + + enum { + fss_basic_read_delimit_mode_none = 1, + fss_basic_read_delimit_mode_all, + fss_basic_read_delimit_mode_depth, + fss_basic_read_delimit_mode_depth_greater, + fss_basic_read_delimit_mode_depth_lesser, + }; +#endif // _di_fss_basic_read_delimit_modes_ + #ifndef _di_fss_basic_read_data_t_ typedef struct { f_console_parameter_t parameters[fss_basic_read_total_parameters]; @@ -156,6 +180,9 @@ extern "C" { f_fss_contents_t contents; f_string_quantity_t quantity; + uint8_t delimit_mode; + f_string_length_t delimit_depth; + f_color_context_t context; } fss_basic_read_data_t; @@ -170,6 +197,8 @@ extern "C" { f_fss_objects_t_initialize, \ f_fss_contents_t_initialize, \ f_string_quantity_t_initialize, \ + fss_basic_read_delimit_mode_all, \ + 0, \ f_color_context_t_initialize, \ } #endif // _di_fss_basic_read_data_t_ @@ -177,7 +206,7 @@ extern "C" { /** * Print help. * - * @param file + * @param output * The file to print to. * @param context * The color context settings. @@ -186,7 +215,7 @@ extern "C" { * F_none on success. */ #ifndef _di_fss_basic_read_print_help_ - extern f_return_status fss_basic_read_print_help(const f_file_t file, const f_color_context_t context); + extern f_return_status fss_basic_read_print_help(const f_file_t output, const f_color_context_t context); #endif // _di_fss_basic_read_print_help_ /** 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 e7a08b4..ef2e461 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 @@ -173,46 +173,39 @@ extern "C" { f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t filename, const fss_basic_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; + const f_string_lengths_t except_none = f_string_lengths_t_initialize; + bool delimited = F_true; + + // for this standard, delimits would always be applied, except for when delimit_depth is greater than 0. + 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))) { + delimited = F_false; + } + { f_string_range_t input = f_macro_string_range_t_initialize(data->buffer.used); delimits->used = 0; - status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0, delimits); + status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0, delimits, 0); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. - f_macro_fss_contents_t_delete_simple(data->contents); - f_macro_fss_objects_t_delete_simple(data->objects); - f_macro_string_dynamic_t_delete_simple(data->buffer); - - return status; } - - if (status == F_data_not_stop || status == F_data_not_eos) { - - // Clear buffers, then attempt the next file. + else if (status == F_data_not_stop || status == F_data_not_eos) { f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); return F_none; } return F_status_set_warning(status); } - status = fl_fss_apply_delimit(*delimits, &data->buffer); - if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); @@ -261,29 +254,19 @@ extern "C" { if (depths.array[0].index_name > 0) { memset(names, 0, sizeof(bool) * data->objects.used); - f_string_length_t name_length = 0; - if (data->parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare_trim(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *delimits) == F_equal_to) { + names[i] = 1; } } // for } else { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *delimits) == F_equal_to) { + names[i] = 1; } } // for } @@ -302,10 +285,10 @@ extern "C" { if (data->parameters[fss_basic_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_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } else { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } } else if (depths.array[0].index_name > 0) { @@ -317,19 +300,19 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); } else { - fprintf(f_type_output, "%llu%c", data->objects.used, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", data->objects.used, f_string_eol[0]); } return F_none; } - f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t) = &f_print_dynamic_partial; + f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_string_lengths_t) = &f_print_except_dynamic_partial; if (data->parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { - print_object = &fl_print_trim_string_dynamic_partial; + print_object = &fl_print_trim_except_dynamic_partial; } if (depths.array[0].index_at > 0) { @@ -339,12 +322,12 @@ extern "C" { if (names[i]) { if (at == depths.array[0].value_at) { - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], delimited ? *delimits : except_none); if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { fss_basic_read_print_object_end(*data); - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); } } @@ -362,12 +345,12 @@ extern "C" { for (i = 0; i < data->objects.used; i++) { if (!names[i]) continue; - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], delimited ? *delimits : except_none); if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { fss_basic_read_print_object_end(*data); - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); } } @@ -380,7 +363,7 @@ extern "C" { if (depths.array[0].index_at > 0) { if (depths.array[0].value_at >= data->objects.used) { if (names[depths.array[0].value_at] && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } return F_none; @@ -400,15 +383,15 @@ extern "C" { if (at == depths.array[0].value_at) { if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { if (!data->contents.array[i].used) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } else { - fprintf(f_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } } else if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) { if (data->contents.array[i].used > 0) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); fss_basic_read_print_set_end(*data); } else if (include_empty) { @@ -417,7 +400,7 @@ extern "C" { } else { if (data->contents.array[i].used > 0) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); fss_basic_read_print_set_end(*data); } else if (include_empty) { @@ -448,7 +431,7 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); return F_none; } @@ -472,7 +455,7 @@ extern "C" { } if (line_current == line) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); fss_basic_read_print_set_end(*data); break; @@ -495,7 +478,7 @@ extern "C" { continue; } - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[0], delimited ? *delimits : except_none); fss_basic_read_print_set_end(*data); } // for diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 5467ddb..61abc15 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -6,133 +6,153 @@ extern "C" { #endif #ifndef _di_fss_extended_list_read_print_help_ - f_return_status fss_extended_list_read_print_help(const f_file_t file, const f_color_context_t context) { + f_return_status fss_extended_list_read_print_help(const f_file_t output, const f_color_context_t context) { - fll_program_print_help_header(file, context, fss_extended_list_read_name_long, fss_extended_list_read_version); + fll_program_print_help_header(output, context, fss_extended_list_read_name_long, fss_extended_list_read_version); - fll_program_print_help_option(file, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); - fll_program_print_help_option(file, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); - fll_program_print_help_option(file, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); + fll_program_print_help_option(output, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); + fll_program_print_help_option(output, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); + fll_program_print_help_option(output, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - fll_program_print_help_option(file, context, fss_extended_list_read_short_at, fss_extended_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(file, context, fss_extended_list_read_short_content, fss_extended_list_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_depth, fss_extended_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(file, context, fss_extended_list_read_short_empty, fss_extended_list_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_line, fss_extended_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(file, context, fss_extended_list_read_short_name, fss_extended_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_object, fss_extended_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_select, fss_extended_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(file, context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); - fll_program_print_help_option(file, context, fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_at, fss_extended_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(output, context, fss_extended_list_read_short_content, fss_extended_list_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_delimit, fss_extended_list_read_long_delimit, f_console_symbol_short_enable, f_console_symbol_long_enable, " Designate how to handle applying delimits."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_depth, fss_extended_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(output, context, fss_extended_list_read_short_empty, fss_extended_list_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_line, fss_extended_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(output, context, fss_extended_list_read_short_name, fss_extended_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_object, fss_extended_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_select, fss_extended_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(output, context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); + fll_program_print_help_option(output, context, fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); - fll_program_print_help_usage(file, context, fss_extended_list_read_name, "filename(s)"); + fll_program_print_help_usage(output, context, fss_extended_list_read_name, "filename(s)"); - fl_color_print(f_type_output, context.set.important, " Notes:"); + fl_color_print(output.stream, context.set.important, " Notes:"); - printf("%c", f_string_eol[0], f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0], f_string_eol[0]); - 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[0]); + fprintf(output.stream, " 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[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When using the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); + fprintf(output.stream, " option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); + + fprintf(output.stream, " When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); + fprintf(output.stream, ": An object index at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); + fprintf(output.stream, ": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); + fprintf(output.stream, ": An object name at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); + fprintf(output.stream, " must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); + fprintf(output.stream, " ('-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[0]); + fprintf(output.stream, " ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); + fprintf(output.stream, " selects a content index at a given depth.%c", f_string_eol[0]); + fprintf(output.stream, " (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " Specify both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); + fprintf(output.stream, " and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total); + fprintf(output.stream, " parameters to get the total objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); + fprintf(output.stream, " and "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); + fprintf(output.stream, " parameters are specified (at the same depth), the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); + fprintf(output.stream, " parameter value will be treated as a position relative to the specified "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); + fprintf(output.stream, " parameter value.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " This program may support parameters, such as "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); + fprintf(output.stream, " or "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); + fprintf(output.stream, ", even if not supported by the standard.%c", f_string_eol[0]); + fprintf(output.stream, " This is done to help ensure consistency for scripting.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); + fprintf(output.stream, ", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); + fprintf(output.stream, ", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_trim); + fprintf(output.stream, " will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When specifying both the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); + fprintf(output.stream, " parameter and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_content); + fprintf(output.stream, " parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content printed are already escaped.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content are separated by an EOL.%c", f_string_eol[0]); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - printf(" When using the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); - printf(" option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); - - printf(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); - printf(": An object index at the specified depth.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); - printf(": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); - printf(": An object name at the specified depth.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); - printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); - 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[0]); - printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); - printf(" selects a content index at a given depth.%c", f_string_eol[0]); - printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" Specify both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); - printf(" and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total); - printf(" parameters to get the total objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); - printf(" and "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); - printf(" parameters are specified (at the same depth), the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at); - printf(" parameter value will be treated as a position relative to the specified "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name); - printf(" parameter value.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" This program may support parameters, such as "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); - printf(" or "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); - printf(", even if not supported by the standard.%c", f_string_eol[0]); - printf(" This is done to help ensure consistency for scripting.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth); - printf(", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select); - printf(", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_trim); - printf(" will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When specifying both the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object); - printf(" parameter and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_content); - printf(" parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); - printf(" Both the object and content printed are already escaped.%c", f_string_eol[0]); - printf(" Both the object and content are separated by an EOL.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_delimit); + fprintf(output.stream, " accepts the following:%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_list_read_delimit_mode_name_none); + fprintf(output.stream, ": Do not apply delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_list_read_delimit_mode_name_all); + fprintf(output.stream, ": (default) apply all delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater: apply delimits for the specified depth.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_list_read_delimit_mode_name_greater); + fprintf(output.stream, ": (such as '1+') apply delimits for the specified depth and any greater depth (numerically).%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_list_read_delimit_mode_name_lesser); + fprintf(output.stream, ": (such as '1-') apply delimits for the specified depth and any lesser depth (numerically).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); return F_none; } @@ -305,9 +325,67 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_extended_list_read_parameter_delimit].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires a value.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_extended_list_read_parameter_delimit].result == f_console_result_additional) { + const f_string_length_t location = data->parameters[fss_extended_list_read_parameter_delimit].additional.array[0]; + f_string_length_t length = strnlen(arguments.argv[location], f_console_length_size); + + if (length == 0) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe value for the parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' must not be empty.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (fl_string_compare(arguments.argv[location], fss_extended_list_read_delimit_mode_name_none, length, fss_extended_list_read_delimit_mode_name_none_length) == F_equal_to) { + data->delimit_mode = fss_extended_list_read_delimit_mode_none; + } + else if (fl_string_compare(arguments.argv[location], fss_extended_list_read_delimit_mode_name_all, length, fss_extended_list_read_delimit_mode_name_all_length) == F_equal_to) { + data->delimit_mode = fss_extended_list_read_delimit_mode_all; + } + else { + data->delimit_mode = fss_extended_list_read_delimit_mode_depth; + + if (arguments.argv[location][length - 1] == fss_extended_list_read_delimit_mode_name_greater[0]) { + data->delimit_mode = fss_extended_list_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_extended_list_read_delimit_mode_name_lesser[0]) { + data->delimit_mode = fss_extended_list_read_delimit_mode_depth_lesser; + + // shorten the length to better convert the remainder to a number. + length--; + } + + f_string_range_t range = f_macro_string_range_t_initialize(length); + + // ignore leading plus sign. + if (arguments.argv[location][0] == '+') { + range.start++; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[location], &data->delimit_depth, range); + + if (F_status_is_error(status)) { + fll_error_parameter_integer_print(data->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_extended_list_read_long_delimit, arguments.argv[location]); + } + } + } + } + fss_extended_list_read_depths_t depths = fss_extended_list_read_depths_t_initialize; - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_fss_delimits_t objects_delimits = f_fss_delimits_t_initialize; + f_fss_delimits_t contents_delimits = f_fss_delimits_t_initialize; f_string_length_t original_size = data->quantity.total; @@ -338,7 +416,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_extended_list_read_main_process_file(arguments, data, "-", depths, &delimits); + status = fss_extended_list_read_main_process_file(arguments, data, "-", depths, &objects_delimits, &contents_delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -375,7 +453,7 @@ extern "C" { // Skip past empty files. if (!data->quantity.total) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } f_file_stream_close(F_true, &file); @@ -392,7 +470,7 @@ extern "C" { break; } - status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); + status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &objects_delimits, &contents_delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -411,7 +489,8 @@ extern "C" { } macro_fss_extended_list_read_depths_t_delete_simple(depths); - f_macro_fss_delimits_t_delete_simple(delimits); + f_macro_fss_delimits_t_delete_simple(objects_delimits); + f_macro_fss_delimits_t_delete_simple(contents_delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.h b/level_3/fss_extended_list_read/c/fss_extended_list_read.h index c2840b1..fc1fe70 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.h @@ -68,6 +68,7 @@ extern "C" { #define fss_extended_list_read_short_at "a" #define fss_extended_list_read_short_content "c" + #define fss_extended_list_read_short_delimit "D" #define fss_extended_list_read_short_depth "d" #define fss_extended_list_read_short_empty "e" #define fss_extended_list_read_short_line "l" @@ -80,6 +81,7 @@ extern "C" { #define fss_extended_list_read_long_at "at" #define fss_extended_list_read_long_content "content" + #define fss_extended_list_read_long_delimit "delimit" #define fss_extended_list_read_long_depth "depth" #define fss_extended_list_read_long_empty "empty" #define fss_extended_list_read_long_line "line" @@ -103,6 +105,7 @@ extern "C" { fss_extended_list_read_parameter_at, fss_extended_list_read_parameter_content, + fss_extended_list_read_parameter_delimit, fss_extended_list_read_parameter_depth, fss_extended_list_read_parameter_empty, fss_extended_list_read_parameter_line, @@ -127,6 +130,7 @@ extern "C" { f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \ f_console_parameter_t_initialize(fss_extended_list_read_short_at, fss_extended_list_read_long_at, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_content, fss_extended_list_read_long_content, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_list_read_short_delimit, fss_extended_list_read_long_delimit, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_depth, fss_extended_list_read_long_depth, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_empty, fss_extended_list_read_long_empty, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_read_short_line, fss_extended_list_read_long_line, 0, 1, f_console_type_normal), \ @@ -138,9 +142,29 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_list_read_total_parameters 20 + #define fss_extended_list_read_total_parameters 21 #endif // _di_fss_extended_list_read_defines_ +#ifndef _di_fss_extended_list_read_delimit_mode_ + #define fss_extended_list_read_delimit_mode_name_none "none" + #define fss_extended_list_read_delimit_mode_name_all "all" + #define fss_extended_list_read_delimit_mode_name_greater "+" + #define fss_extended_list_read_delimit_mode_name_lesser "-" + + #define fss_extended_list_read_delimit_mode_name_none_length 4 + #define fss_extended_list_read_delimit_mode_name_all_length 3 + #define fss_extended_list_read_delimit_mode_name_greater_length 1 + #define fss_extended_list_read_delimit_mode_name_lesser_length 1 + + enum { + fss_extended_list_read_delimit_mode_none = 1, + fss_extended_list_read_delimit_mode_all, + fss_extended_list_read_delimit_mode_depth, + fss_extended_list_read_delimit_mode_depth_greater, + fss_extended_list_read_delimit_mode_depth_lesser, + }; +#endif // _di_fss_extended_list_read_delimit_modes_ + #ifndef _di_fss_extended_list_read_data_t_ typedef struct { f_console_parameter_t parameters[fss_extended_list_read_total_parameters]; @@ -155,6 +179,9 @@ extern "C" { f_fss_nest_t nest; f_string_quantity_t quantity; + uint8_t delimit_mode; + f_string_length_t delimit_depth; + f_color_context_t context; } fss_extended_list_read_data_t; @@ -168,6 +195,8 @@ extern "C" { f_string_dynamic_t_initialize, \ f_fss_nest_t_initialize, \ f_string_quantity_t_initialize, \ + fss_extended_list_read_delimit_mode_all, \ + 0, \ f_color_context_t_initialize, \ } #endif // _di_fss_extended_list_read_data_t_ @@ -175,7 +204,7 @@ extern "C" { /** * Print help. * - * @param file + * @param output * The file to print to. * @param context * The color context settings. @@ -184,7 +213,7 @@ extern "C" { * F_none on success. */ #ifndef _di_fss_extended_list_read_print_help_ - extern f_return_status fss_extended_list_read_print_help(const f_file_t file, const f_color_context_t context); + extern f_return_status fss_extended_list_read_print_help(const f_file_t output, const f_color_context_t context); #endif // _di_fss_extended_list_read_print_help_ /** diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index a91fa91..25b9264 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -5,6 +5,33 @@ extern "C" { #endif +#ifndef _di_fss_extended_list_read_is_delimited_at_depth_ + f_return_status fss_extended_list_read_is_delimited_at_depth(const fss_extended_list_read_data_t data, const f_string_length_t depth) { + + if (data.delimit_mode == fss_extended_list_read_delimit_mode_none) { + return F_false; + } + + if (data.delimit_mode == fss_extended_list_read_delimit_mode_all) { + return F_true; + } + + if (data.delimit_mode == fss_extended_list_read_delimit_mode_depth) { + return depth == data.delimit_depth; + } + + if (data.delimit_mode == fss_extended_list_read_delimit_mode_depth_lesser) { + return depth <= data.delimit_depth; + } + + if (data.delimit_mode == fss_extended_list_read_delimit_mode_depth_greater) { + return depth >= data.delimit_depth; + } + + return F_true; + } +#endif // _di_fss_extended_list_read_is_delimited_at_depth_ + #ifndef _di_fss_extended_list_read_main_preprocess_depth_ f_return_status fss_extended_list_read_main_preprocess_depth(const f_console_arguments_t arguments, const fss_extended_list_read_data_t data, fss_extended_list_read_depths_t *depths) { f_status_t status = F_none; @@ -170,47 +197,34 @@ extern "C" { #endif // _di_fss_extended_list_read_main_preprocess_depth_ #ifndef _di_fss_extended_list_read_main_process_file_ - f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *delimits) { + f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { f_status_t status = F_none; { f_string_range_t input = f_macro_string_range_t_initialize(data->buffer.used); - delimits->used = 0; + objects_delimits->used = 0; + contents_delimits->used = 0; - status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest, delimits); + status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest, objects_delimits, contents_delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_list_read", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. - f_macro_fss_nest_t_delete_simple(data->nest); - f_macro_string_dynamic_t_delete_simple(data->buffer); - - return status; } - - if (status == F_data_not_stop || status == F_data_not_eos) { - - // Clear buffers, then attempt the next file. + else if (status == F_data_not_stop || status == F_data_not_eos) { f_macro_fss_nest_t_delete_simple(data->nest); f_macro_string_dynamic_t_delete_simple(data->buffer); if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); return F_none; } return F_status_set_warning(status); } - status = fl_fss_apply_delimit(*delimits, &data->buffer); - if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. f_macro_fss_nest_t_delete_simple(data->nest); f_macro_string_dynamic_t_delete_simple(data->buffer); @@ -221,7 +235,7 @@ extern "C" { // Requested depths cannot be greater than contents depth. if (depths.used > data->nest.used) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); return F_none; } @@ -263,18 +277,21 @@ extern "C" { } } + // @fixme: this function currently prints the entire content without handling individual parts. + // this is well and good, except that there is no way to determine when any given depth should or should not be delimited. + // consider doing something like pre-processing the depths when depth mode is some specific depth (as opposed to "all" or "none"). + // this pre-process will build a new objects_delimits and contents_delimits that only contain the expected delimits. + // futhermore, when set to "none" just pass something like "except_none" for both objects_delimits and contents_delimits. if (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_none || (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_additional && depths.used == 1)) { - return fss_extended_list_read_main_process_for_depth(arguments, data, filename, depths.array[0], line); + return fss_extended_list_read_main_process_for_depth(arguments, data, filename, depths.array[0], line, objects_delimits, contents_delimits); } - // @todo: handle recursive situations, possibly calling the above block as a separate private function. - return F_none; } #endif // _di_fss_extended_list_read_main_process_file_ #ifndef _di_fss_extended_list_read_main_process_for_depth_ - f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line) { + f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { f_status_t status = F_none; f_fss_items_t *items = &data->nest.depth[depth_setting.depth]; @@ -283,22 +300,24 @@ extern "C" { f_array_length_t i = 0; f_array_length_t j = 0; + const f_string_lengths_t except_none = f_string_lengths_t_initialize; + bool delimited = fss_extended_list_read_is_delimited_at_depth(*data, depth_setting.depth); + if (depth_setting.index_name > 0) { memset(names, 0, sizeof(bool) * items->used); - f_string_range_t value_range = f_string_range_t_initialize; - value_range.stop = depth_setting.value_name.used - 1; - if (data->parameters[fss_extended_list_read_parameter_trim].result == f_console_result_found) { for (i = 0; i < items->used; i++) { - if (fl_string_dynamic_partial_compare_trim(data->buffer, depth_setting.value_name, items->array[i].object, value_range) == F_equal_to) { + + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depth_setting.value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) == F_equal_to) { names[i] = 1; } } // for } else { for (i = 0; i < items->used; i++) { - if (fl_string_dynamic_partial_compare(data->buffer, depth_setting.value_name, items->array[i].object, value_range) == F_equal_to) { + + if (fl_string_dynamic_partial_compare_except_dynamic(depth_setting.value_name, data->buffer, items->array[i].object, except_none, *objects_delimits) == F_equal_to) { names[i] = 1; } } // for @@ -319,10 +338,10 @@ extern "C" { if (depth_setting.index_at > 0) { if (depth_setting.value_at < items->used && names[depth_setting.value_at]) { - fprintf(f_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } else { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } return F_none; @@ -336,31 +355,31 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); return F_none; } - fprintf(f_type_output, "%llu%c", items->used, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", items->used, f_string_eol[0]); return F_none; } - f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t) = &f_print_dynamic_partial; + f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_string_lengths_t) = &f_print_except_dynamic_partial; if (data->parameters[fss_extended_list_read_parameter_trim].result == f_console_result_found) { - print_object = &fl_print_trim_string_dynamic_partial; + print_object = &fl_print_trim_except_dynamic_partial; } if (depth_setting.index_at > 0) { if (depth_setting.value_at < items->used && names[depth_setting.value_at]) { - print_object(f_type_output, data->buffer, items->array[depth_setting.value_at].object); + print_object(data->output.stream, data->buffer, items->array[depth_setting.value_at].object, delimited ? *objects_delimits : except_none); if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) { fss_extended_list_read_print_object_end(*data); if (items->array[depth_setting.value_at].content.used) { - f_print_dynamic_partial(f_type_output, data->buffer, items->array[depth_setting.value_at].content.array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, items->array[depth_setting.value_at].content.array[0], delimited ? *contents_delimits : except_none); } } @@ -373,13 +392,13 @@ extern "C" { for (i = 0; i < items->used; i++) { if (names[i]) { - print_object(f_type_output, data->buffer, items->array[i].object); + print_object(data->output.stream, data->buffer, items->array[i].object, delimited ? *objects_delimits : except_none); if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) { fss_extended_list_read_print_object_end(*data); if (items->array[i].content.used) { - f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, items->array[i].content.array[0], delimited ? *contents_delimits : except_none); } } @@ -393,7 +412,7 @@ extern "C" { if (depth_setting.index_at > 0) { if (depth_setting.value_at >= items->used) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } return F_none; @@ -407,7 +426,7 @@ extern "C" { if (at == depth_setting.value_at) { if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { if (!items->array[i].content.used) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } else { f_array_length_t total = 1; @@ -420,7 +439,7 @@ extern "C" { } } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); } return F_none; @@ -440,11 +459,11 @@ extern "C" { if (!data->buffer.string[i]) continue; if (data->buffer.string[i] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[i]); + fprintf(data->output.stream, "%c", data->buffer.string[i]); } // for } else { @@ -463,11 +482,11 @@ extern "C" { if (!data->buffer.string[i]) continue; if (data->buffer.string[i] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[i]); + fprintf(data->output.stream, "%c", data->buffer.string[i]); } // for break; @@ -481,7 +500,7 @@ extern "C" { } if (items->array[i].content.used > 0) { - f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, items->array[i].content.array[0], delimited ? *contents_delimits : except_none); if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end); @@ -524,7 +543,7 @@ extern "C" { } // for } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); return F_none; } @@ -569,11 +588,11 @@ extern "C" { if (!data->buffer.string[j]) continue; if (data->buffer.string[j] == f_string_eol[0]) { - fprintf(f_type_output, "%c", f_string_eol[0]); + fprintf(data->output.stream, "%c", f_string_eol[0]); break; } - fprintf(f_type_output, "%c", data->buffer.string[j]); + fprintf(data->output.stream, "%c", data->buffer.string[j]); } // for break; @@ -594,7 +613,7 @@ extern "C" { continue; } - f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]); + f_print_except_dynamic_partial(data->output.stream, data->buffer, items->array[i].content.array[0], delimited ? *contents_delimits : except_none); if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end); diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h index c9e15cf..bf702ea 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h @@ -158,6 +158,22 @@ extern "C" { #endif // _di_fss_extended_list_read_depths_t_ /** + * Determine if the given depth is to be delimited or not. + * + * @param data + * The program specific data. + * @param depth + * The depth to check. + * + * @return + * F_true if delimited. + * F_false if not delimited. + */ +#ifndef _di_fss_extended_list_read_is_delimited_at_depth_ + extern f_return_status fss_extended_list_read_is_delimited_at_depth(const fss_extended_list_read_data_t data, const f_string_length_t depth) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_is_delimited_at_depth_ + +/** * 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). @@ -188,14 +204,16 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits detected during processing, for top-level objects. + * @param contents_delimits + * An array of delimits detected during processing, for contents. * * @see fss_extended_list_read_main_preprocess_depth() * @see fss_extended_list_read_main_process_for_depth() */ #ifndef _di_fss_extended_list_read_main_process_file_ - extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t file_name, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t file_name, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_file_ /** @@ -214,11 +232,15 @@ extern "C" { * The depth settings specific to the desired depth. * @param line * The line number parameter value, used for printing a specific line number for content. + * @param objects_delimits + * An array of delimits detected during processing, for top-level objects. + * @param contents_delimits + * An array of delimits detected during processing, for contents. * * @see fss_extended_list_read_main_process_file() */ #ifndef _di_fss_extended_list_read_main_process_for_depth_ - extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_for_depth_ /** diff --git a/level_3/fss_extended_read/c/fss_extended_read.c b/level_3/fss_extended_read/c/fss_extended_read.c index 7c69b80..67f35aa 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -6,133 +6,153 @@ extern "C" { #endif #ifndef _di_fss_extended_read_print_help_ - f_return_status fss_extended_read_print_help(const f_file_t file, const f_color_context_t context) { + f_return_status fss_extended_read_print_help(const f_file_t output, const f_color_context_t context) { - fll_program_print_help_header(file, context, fss_extended_read_name_long, fss_extended_read_version); + fll_program_print_help_header(output, context, fss_extended_read_name_long, fss_extended_read_version); - fll_program_print_help_option(file, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); - fll_program_print_help_option(file, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); - fll_program_print_help_option(file, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); - fll_program_print_help_option(file, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); - fll_program_print_help_option(file, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); + fll_program_print_help_option(output, context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message."); + fll_program_print_help_option(output, context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds."); + fll_program_print_help_option(output, context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color."); + fll_program_print_help_option(output, context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_normal, f_console_standard_long_normal, f_console_symbol_short_disable, f_console_symbol_long_disable, " Set verbosity to normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_debug, f_console_standard_long_debug, f_console_symbol_short_disable, f_console_symbol_long_disable, " Enable debugging, inceasing verbosity beyond normal output."); + fll_program_print_help_option(output, context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number."); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - fll_program_print_help_option(file, context, fss_extended_read_short_at, fss_extended_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); - fll_program_print_help_option(file, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); - fll_program_print_help_option(file, context, fss_extended_read_short_depth, fss_extended_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); - fll_program_print_help_option(file, context, fss_extended_read_short_empty, fss_extended_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); - fll_program_print_help_option(file, context, fss_extended_read_short_line, fss_extended_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(file, context, fss_extended_read_short_name, fss_extended_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); - fll_program_print_help_option(file, context, fss_extended_read_short_object, fss_extended_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); - fll_program_print_help_option(file, context, fss_extended_read_short_pipe, fss_extended_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); - fll_program_print_help_option(file, context, fss_extended_read_short_select, fss_extended_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); - fll_program_print_help_option(file, context, fss_extended_read_short_total, fss_extended_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); - fll_program_print_help_option(file, context, fss_extended_read_short_trim, fss_extended_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); + fll_program_print_help_option(output, context, fss_extended_read_short_at, fss_extended_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric index."); + fll_program_print_help_option(output, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default)."); + fll_program_print_help_option(output, context, fss_extended_read_short_delimit, fss_extended_read_long_delimit, f_console_symbol_short_enable, f_console_symbol_long_enable, " Designate how to handle applying delimits."); + fll_program_print_help_option(output, context, fss_extended_read_short_depth, fss_extended_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object at this numeric depth."); + fll_program_print_help_option(output, context, fss_extended_read_short_empty, fss_extended_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, " Include empty content when processing."); + fll_program_print_help_option(output, context, fss_extended_read_short_line, fss_extended_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(output, context, fss_extended_read_short_name, fss_extended_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select object with this name."); + fll_program_print_help_option(output, context, fss_extended_read_short_object, fss_extended_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the object."); + fll_program_print_help_option(output, context, fss_extended_read_short_pipe, fss_extended_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print using the special pipe format."); + fll_program_print_help_option(output, context, fss_extended_read_short_select, fss_extended_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, " Select sub-content at this index."); + fll_program_print_help_option(output, context, fss_extended_read_short_total, fss_extended_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the total number of lines."); + fll_program_print_help_option(output, context, fss_extended_read_short_trim, fss_extended_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, " Trim object names on select or print."); - fll_program_print_help_usage(file, context, fss_extended_read_name, "filename(s)"); + fll_program_print_help_usage(output, context, fss_extended_read_name, "filename(s)"); - fl_color_print(f_type_output, context.set.important, " Notes:"); + fl_color_print(output.stream, context.set.important, " Notes:"); - printf("%c", f_string_eol[0], f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0], f_string_eol[0]); - printf(" This program will print the content associated with the given object and content data based on the FSS-0001 Extended standard.%c", f_string_eol[0]); + fprintf(output.stream, " This program will print the content associated with the given object and content data based on the FSS-0001 Extended standard.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When using the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); + fprintf(output.stream, " option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); + + fprintf(output.stream, " When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); + fprintf(output.stream, ": An object index at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); + fprintf(output.stream, ": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); + + fprintf(output.stream, " "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); + fprintf(output.stream, ": An object name at the specified depth.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); + fprintf(output.stream, " must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); + fprintf(output.stream, " ('-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[0]); + fprintf(output.stream, " ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); + fprintf(output.stream, " selects a content index at a given depth.%c", f_string_eol[0]); + fprintf(output.stream, " (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " Specify both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); + fprintf(output.stream, " and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total); + fprintf(output.stream, " parameters to get the total objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When both "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); + fprintf(output.stream, " and "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); + fprintf(output.stream, " parameters are specified (at the same depth), the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); + fprintf(output.stream, " parameter value will be treated as a position relative to the specified "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); + fprintf(output.stream, " parameter value.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " This program may support parameters, such as "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); + fprintf(output.stream, " or "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); + fprintf(output.stream, ", even if not supported by the standard.%c", f_string_eol[0]); + fprintf(output.stream, " This is done to help ensure consistency for scripting.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); + fprintf(output.stream, ", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, " For parameters like "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); + fprintf(output.stream, ", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_trim); + fprintf(output.stream, " will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); + + fprintf(output.stream, " When specifying both the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); + fprintf(output.stream, " parameter and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_content); + fprintf(output.stream, " parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content printed are already escaped.%c", f_string_eol[0]); + fprintf(output.stream, " Both the object and content are separated by a space.%c", f_string_eol[0]); - printf("%c", f_string_eol[0]); + fprintf(output.stream, "%c", f_string_eol[0]); - printf(" When using the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); - printf(" option, an order of operations is enforced on the parameters.%c", f_string_eol[0]); - - printf(" When this order of operations is in effect, parameters to the right of a depth parameter are influenced by that depth parameter:%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); - printf(": An object index at the specified depth.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); - printf(": A new depth within the specified depth, indexed from the root.%c", f_string_eol[0]); - - printf(" "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); - printf(": An object name at the specified depth.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); - printf(" must be in numeric order, but values in between may be skipped.%c", f_string_eol[0]); - 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[0]); - printf(" ('-d 2 -a 1 -d 0 -a 2' would be invalid because depth 2 is before depth 1.)%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); - printf(" selects a content index at a given depth.%c", f_string_eol[0]); - printf(" (This parameter is not synonymous with the depth parameter and does not relate to nested content).%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" Specify both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); - printf(" and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total); - printf(" parameters to get the total objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When both "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); - printf(" and "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); - printf(" parameters are specified (at the same depth), the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at); - printf(" parameter value will be treated as a position relative to the specified "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name); - printf(" parameter value.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" This program may support parameters, such as "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); - printf(" or "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); - printf(", even if not supported by the standard.%c", f_string_eol[0]); - printf(" This is done to help ensure consistency for scripting.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth); - printf(", if the standard doesn't support nested content, then only a depth of 0 would be valid.%c", f_string_eol[0]); - - printf(" For parameters like "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select); - printf(", if the standard doesn't support multiple content groups, then only a select of 0 would be valid.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" The parameter "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_trim); - printf(" will remove leading and trailing whitespaces when selecting objects or when printing objects.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); - - printf(" When specifying both the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object); - printf(" parameter and the "); - fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_content); - printf(" parameter, the entire object and content are printed, including the formatting.%c", f_string_eol[0]); - printf(" Both the object and content printed are already escaped.%c", f_string_eol[0]); - printf(" Both the object and content are separated by a space.%c", f_string_eol[0]); - - printf("%c", f_string_eol[0]); + fprintf(output.stream, " The parameter "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_delimit); + fprintf(output.stream, " accepts the following:%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_read_delimit_mode_name_none); + fprintf(output.stream, ": Do not apply delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_read_delimit_mode_name_all); + fprintf(output.stream, ": (default) apply all delimits.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater: apply delimits for the specified depth.%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_read_delimit_mode_name_greater); + fprintf(output.stream, ": (such as '1+') apply delimits for the specified depth and any greater depth (numerically).%c", f_string_eol[0]); + fprintf(output.stream, " - a number, 0 or greater, followed by a "); + fl_color_print(output.stream, context.set.notable, "%s", fss_extended_read_delimit_mode_name_lesser); + fprintf(output.stream, ": (such as '1-') apply delimits for the specified depth and any lesser depth (numerically).%c", f_string_eol[0]); + + fprintf(output.stream, "%c", f_string_eol[0]); return F_none; } @@ -305,9 +325,67 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_extended_read_parameter_delimit].result == f_console_result_found) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires a value.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_extended_read_parameter_delimit].result == f_console_result_additional) { + const f_string_length_t location = data->parameters[fss_extended_read_parameter_delimit].additional.array[0]; + f_string_length_t length = strnlen(arguments.argv[location], f_console_length_size); + + if (length == 0) { + fl_color_print(data->error.to.stream, data->context.set.error, "%sThe value for the parameter '", fll_error_print_error); + fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_delimit); + fl_color_print(data->error.to.stream, data->context.set.error, "' must not be empty.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + else if (fl_string_compare(arguments.argv[location], fss_extended_read_delimit_mode_name_none, length, fss_extended_read_delimit_mode_name_none_length) == F_equal_to) { + data->delimit_mode = fss_extended_read_delimit_mode_none; + } + else if (fl_string_compare(arguments.argv[location], fss_extended_read_delimit_mode_name_all, length, fss_extended_read_delimit_mode_name_all_length) == F_equal_to) { + data->delimit_mode = fss_extended_read_delimit_mode_all; + } + else { + data->delimit_mode = fss_extended_read_delimit_mode_depth; + + if (arguments.argv[location][length - 1] == fss_extended_read_delimit_mode_name_greater[0]) { + data->delimit_mode = fss_extended_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_extended_read_delimit_mode_name_lesser[0]) { + data->delimit_mode = fss_extended_read_delimit_mode_depth_lesser; + + // shorten the length to better convert the remainder to a number. + length--; + } + + f_string_range_t range = f_macro_string_range_t_initialize(length); + + // ignore leading plus sign. + if (arguments.argv[location][0] == '+') { + range.start++; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[location], &data->delimit_depth, range); + + if (F_status_is_error(status)) { + fll_error_parameter_integer_print(data->error, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, fss_extended_read_long_delimit, arguments.argv[location]); + } + } + } + } + fss_extended_read_depths_t depths = fss_extended_read_depths_t_initialize; - f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_fss_delimits_t objects_delimits = f_fss_delimits_t_initialize; + f_fss_delimits_t contents_delimits = f_fss_delimits_t_initialize; f_string_length_t original_size = data->quantity.total; @@ -322,10 +400,11 @@ extern "C" { // 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) { macro_fss_extended_read_depths_t_delete_simple(depths); - f_macro_fss_delimits_t_delete_simple(delimits); + f_macro_fss_delimits_t_delete_simple(objects_delimits); + f_macro_fss_delimits_t_delete_simple(contents_delimits); if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } fss_extended_read_delete_data(data); @@ -351,7 +430,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_extended_read_main_process_file(arguments, data, "-", depths, &delimits); + status = fss_extended_read_main_process_file(arguments, data, "-", depths, &objects_delimits, &contents_delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -390,7 +469,7 @@ extern "C" { // Skip past empty files. if (!data->quantity.total) { if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } f_file_stream_close(F_true, &file); @@ -407,7 +486,7 @@ extern "C" { break; } - status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); + status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &objects_delimits, &contents_delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -428,7 +507,8 @@ extern "C" { } macro_fss_extended_read_depths_t_delete_simple(depths); - f_macro_fss_delimits_t_delete_simple(delimits); + f_macro_fss_delimits_t_delete_simple(objects_delimits); + f_macro_fss_delimits_t_delete_simple(contents_delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_extended_read/c/fss_extended_read.h b/level_3/fss_extended_read/c/fss_extended_read.h index 7c3d1db..f29fd57 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.h +++ b/level_3/fss_extended_read/c/fss_extended_read.h @@ -68,6 +68,7 @@ extern "C" { #define fss_extended_read_short_at "a" #define fss_extended_read_short_content "c" + #define fss_extended_read_short_delimit "D" #define fss_extended_read_short_depth "d" #define fss_extended_read_short_empty "e" #define fss_extended_read_short_line "l" @@ -80,6 +81,7 @@ extern "C" { #define fss_extended_read_long_at "at" #define fss_extended_read_long_content "content" + #define fss_extended_read_long_delimit "delimit" #define fss_extended_read_long_depth "depth" #define fss_extended_read_long_empty "empty" #define fss_extended_read_long_line "line" @@ -103,6 +105,7 @@ extern "C" { fss_extended_read_parameter_at, fss_extended_read_parameter_content, + fss_extended_read_parameter_delimit, fss_extended_read_parameter_depth, fss_extended_read_parameter_empty, fss_extended_read_parameter_line, @@ -127,6 +130,7 @@ extern "C" { f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \ f_console_parameter_t_initialize(fss_extended_read_short_at, fss_extended_read_long_at, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_content, fss_extended_read_long_content, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_read_short_delimit, fss_extended_read_long_delimit, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_depth, fss_extended_read_long_depth, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_empty, fss_extended_read_long_empty, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_read_short_line, fss_extended_read_long_line, 0, 1, f_console_type_normal), \ @@ -138,9 +142,29 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_read_short_trim, fss_extended_read_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_read_total_parameters 20 + #define fss_extended_read_total_parameters 21 #endif // _di_fss_extended_read_defines_ +#ifndef _di_fss_extended_read_delimit_mode_ + #define fss_extended_read_delimit_mode_name_none "none" + #define fss_extended_read_delimit_mode_name_all "all" + #define fss_extended_read_delimit_mode_name_greater "+" + #define fss_extended_read_delimit_mode_name_lesser "-" + + #define fss_extended_read_delimit_mode_name_none_length 4 + #define fss_extended_read_delimit_mode_name_all_length 3 + #define fss_extended_read_delimit_mode_name_greater_length 1 + #define fss_extended_read_delimit_mode_name_lesser_length 1 + + enum { + fss_extended_read_delimit_mode_none = 1, + fss_extended_read_delimit_mode_all, + fss_extended_read_delimit_mode_depth, + fss_extended_read_delimit_mode_depth_greater, + fss_extended_read_delimit_mode_depth_lesser, + }; +#endif // _di_fss_extended_read_delimit_modes_ + #ifndef _di_fss_extended_read_data_t_ typedef struct { f_console_parameter_t parameters[fss_extended_read_total_parameters]; @@ -156,6 +180,9 @@ extern "C" { f_fss_contents_t contents; f_string_quantity_t quantity; + uint8_t delimit_mode; + f_string_length_t delimit_depth; + f_color_context_t context; } fss_extended_read_data_t; @@ -170,6 +197,8 @@ extern "C" { f_fss_objects_t_initialize, \ f_fss_contents_t_initialize, \ f_string_quantity_t_initialize, \ + fss_extended_read_delimit_mode_all, \ + 0, \ f_color_context_t_initialize, \ } #endif // _di_fss_extended_read_data_t_ @@ -177,7 +206,7 @@ extern "C" { /** * Print help. * - * @param file + * @param output * The file to print to. * @param context * The color context settings. @@ -186,7 +215,7 @@ extern "C" { * F_none on success. */ #ifndef _di_fss_extended_read_print_help_ - extern f_return_status fss_extended_read_print_help(const f_file_t file, const f_color_context_t context); + extern f_return_status fss_extended_read_print_help(const f_file_t output, const f_color_context_t context); #endif // _di_fss_extended_read_print_help_ /** diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c index 8116cf7..e56772f 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-fss_extended_read.c @@ -5,6 +5,33 @@ extern "C" { #endif +#ifndef _di_fss_extended_read_is_delimited_at_depth_ + f_return_status fss_extended_read_is_delimited_at_depth(const fss_extended_read_data_t data, const f_string_length_t depth) { + + if (data.delimit_mode == fss_extended_read_delimit_mode_none) { + return F_false; + } + + if (data.delimit_mode == fss_extended_read_delimit_mode_all) { + return F_true; + } + + if (data.delimit_mode == fss_extended_read_delimit_mode_depth) { + return depth == data.delimit_depth; + } + + if (data.delimit_mode == fss_extended_read_delimit_mode_depth_lesser) { + return depth <= data.delimit_depth; + } + + if (data.delimit_mode == fss_extended_read_delimit_mode_depth_greater) { + return depth >= data.delimit_depth; + } + + return F_true; + } +#endif // _di_fss_extended_read_is_delimited_at_depth_ + #ifndef _di_fss_extended_read_main_preprocess_depth_ f_return_status fss_extended_read_main_preprocess_depth(const f_console_arguments_t arguments, const fss_extended_read_data_t data, fss_extended_read_depths_t *depths) { f_status_t status = F_none; @@ -170,49 +197,43 @@ extern "C" { #endif // _di_fss_extended_read_main_preprocess_depth_ #ifndef _di_fss_extended_read_main_process_file_ - f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t filename, const fss_extended_read_depths_t depths, f_fss_delimits_t *delimits) { + f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t filename, const fss_extended_read_depths_t depths, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { f_status_t status = F_none; + const f_string_lengths_t except_none = f_string_lengths_t_initialize; + bool object_delimited = F_true; + bool content_delimited = F_true; + + if (data->delimit_mode == fss_extended_read_delimit_mode_none || (data->delimit_depth && (data->delimit_mode == fss_extended_read_delimit_mode_depth || data->delimit_mode == fss_extended_read_delimit_mode_depth_greater))) { + object_delimited = F_false; + } + { f_string_range_t input = f_macro_string_range_t_initialize(data->buffer.used); - delimits->used = 0; + objects_delimits->used = 0; + contents_delimits->used = 0; - status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0, delimits); + status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0, objects_delimits, contents_delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. - f_macro_fss_contents_t_delete_simple(data->contents); - f_macro_fss_objects_t_delete_simple(data->objects); - f_macro_string_dynamic_t_delete_simple(data->buffer); - - return status; } - - if (status == F_data_not_stop || status == F_data_not_eos) { - - // Clear buffers, then attempt the next file. + else if (status == F_data_not_stop || status == F_data_not_eos) { f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); return F_none; } return F_status_set_warning(status); } - status = fl_fss_apply_delimit(*delimits, &data->buffer); - if (F_status_is_error(status)) { - fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); - - // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); @@ -257,29 +278,19 @@ extern "C" { if (depths.array[0].index_name > 0) { memset(names, 0, sizeof(bool) * data->objects.used); - f_string_length_t name_length = 0; - if (data->parameters[fss_extended_read_parameter_trim].result == f_console_result_found) { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare_trim(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_trim_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *objects_delimits) == F_equal_to) { + names[i] = 1; } } // for } else { for (i = 0; i < data->objects.used; i++) { - name_length = (data->objects.array[i].stop - data->objects.array[i].start) + 1; - - if (name_length == depths.array[0].value_name.used) { - if (fl_string_compare(data->buffer.string + data->objects.array[i].start, depths.array[0].value_name.string, name_length, depths.array[0].value_name.used) == F_equal_to) { - names[i] = 1; - } + if (fl_string_dynamic_partial_compare_except_dynamic(depths.array[0].value_name, data->buffer, data->objects.array[i], except_none, *objects_delimits) == F_equal_to) { + names[i] = 1; } } // for } @@ -298,10 +309,10 @@ extern "C" { if (data->parameters[fss_extended_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_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } else { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } } else if (depths.array[0].index_name > 0) { @@ -313,19 +324,19 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); } else { - fprintf(f_type_output, "%llu%c", data->objects.used, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", data->objects.used, f_string_eol[0]); } return F_none; } - f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t) = &f_print_dynamic_partial; + f_return_status (*print_object)(FILE *, const f_string_static_t, const f_string_range_t, const f_string_lengths_t) = &f_print_except_dynamic_partial; if (data->parameters[fss_extended_read_parameter_trim].result == f_console_result_found) { - print_object = &fl_print_trim_string_dynamic_partial; + print_object = &fl_print_trim_except_dynamic_partial; } if (depths.array[0].index_at > 0) { @@ -335,7 +346,7 @@ extern "C" { if (names[i]) { if (at == depths.array[0].value_at) { - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], object_delimited ? *objects_delimits : except_none); if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { @@ -343,7 +354,9 @@ extern "C" { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); @@ -366,7 +379,7 @@ extern "C" { for (i = 0; i < data->objects.used; i++) { if (!names[i]) continue; - print_object(f_type_output, data->buffer, data->objects.array[i]); + print_object(data->output.stream, data->buffer, data->objects.array[i], object_delimited ? *objects_delimits : except_none); if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) { if (data->contents.array[i].used) { @@ -374,7 +387,9 @@ extern "C" { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); @@ -392,7 +407,7 @@ extern "C" { if (depths.array[0].index_at > 0) { if (depths.array[0].value_at >= data->objects.used) { if (names[depths.array[0].value_at] && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } return F_none; @@ -406,10 +421,10 @@ extern "C" { if (at == depths.array[0].value_at) { if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { if (!data->contents.array[i].used) { - fprintf(f_type_output, "0%c", f_string_eol[0]); + fprintf(data->output.stream, "0%c", f_string_eol[0]); } else { - fprintf(f_type_output, "1%c", f_string_eol[0]); + fprintf(data->output.stream, "1%c", f_string_eol[0]); } return F_none; @@ -422,13 +437,18 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, select); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[select], content_delimited ? *contents_delimits : except_none); fss_extended_read_print_set_end(*data); } } else { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); @@ -458,13 +478,18 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, select); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[select], content_delimited ? *contents_delimits : except_none); fss_extended_read_print_set_end(*data); } } else { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); @@ -510,7 +535,7 @@ extern "C" { total++; } // for - fprintf(f_type_output, "%llu%c", total, f_string_eol[0]); + fprintf(data->output.stream, "%llu%c", total, f_string_eol[0]); return F_none; } @@ -536,13 +561,18 @@ extern "C" { if (line_current == line) { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, select); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[select], content_delimited ? *contents_delimits : except_none); fss_extended_read_print_set_end(*data); } } else { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); @@ -574,13 +604,18 @@ extern "C" { if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) { if (select < data->contents.array[i].used) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]); + content_delimited = fss_extended_read_is_delimited_at_depth(*data, select); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[select], content_delimited ? *contents_delimits : except_none); fss_extended_read_print_set_end(*data); } } else { for (j = 0; j < data->contents.array[i].used; j++) { - f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]); + + content_delimited = fss_extended_read_is_delimited_at_depth(*data, j); + + f_print_except_dynamic_partial(data->output.stream, data->buffer, data->contents.array[i].array[j], content_delimited ? *contents_delimits : except_none); if (j + 1 < data->contents.array[i].used) { fss_extended_read_print_content_end(*data); diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.h b/level_3/fss_extended_read/c/private-fss_extended_read.h index 1acb416..a006257 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.h +++ b/level_3/fss_extended_read/c/private-fss_extended_read.h @@ -158,6 +158,22 @@ extern "C" { #endif // _di_fss_extended_read_depths_t_ /** + * Determine if the given depth is to be delimited or not. + * + * @param data + * The program specific data. + * @param depth + * The depth to check. + * + * @return + * F_true if delimited. + * F_false if not delimited. + */ +#ifndef _di_fss_extended_read_is_delimited_at_depth_ + extern f_return_status fss_extended_read_is_delimited_at_depth(const fss_extended_read_data_t data, const f_string_length_t depth) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_read_is_delimited_at_depth_ + +/** * 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). @@ -188,13 +204,15 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. - * @param delimits - * An array of delimits detected during processing. + * @param objects_delimits + * An array of delimits detected during processing, for top-level objects. + * @param contents_delimits + * An array of delimits detected during processing, for contents. * * @see fss_extended_read_main_preprocess_depth() */ #ifndef _di_fss_extended_read_main_process_file_ - extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_read_main_process_file_ /** -- 1.8.3.1