From: Kevin Day Date: Thu, 15 Oct 2020 02:44:20 +0000 (-0500) Subject: Progress: FSS read and write programs. X-Git-Tag: 0.5.1~32 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=faab7448e194cc893719739409cd60c803a7d9c5;p=fll Progress: FSS read and write programs. Use \b (backspace character) instead of \0 (NULL character). - The bash programs and functions like "echo" automatically strip NULL characters. - This defeats the purpose of providing these functions for manipulating FSS files using these programs. Add an ignore range list. - The pipes represent the start and stop of an ignore range using the \v (vertical tab character). - Only the FSS-0003 (Extended List) utilize the ignore range. - This ignore range list provides a simple way to manage nested lists without having to write complex recursive parsers. - For consistency, all FSS write programs utilize the -I/--ignore parameter, but for the standards that do not support ignore range lists then that parameter is essentially ignored. - The ignore lists only applies to Content. Fix bug in the fll_error where the wrong variable is being used (should be printing a newline). --- diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index b8cfead..a2d0798 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -1133,11 +1133,13 @@ extern "C" { if (F_status_is_error(status)) break; if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) { + if (content.string[range->start] == f_fss_eol) { do_prepend = F_true; } if (ignore && ignore->used) { + for (r = 0; r < ignore->used; r++) { if (start >= ignore->array[r].start && start <= ignore->array[r].stop) break; } // for diff --git a/level_2/fll_error/c/error.c b/level_2/fll_error/c/error.c index 0580bef..fd426fd 100644 --- a/level_2/fll_error/c/error.c +++ b/level_2/fll_error/c/error.c @@ -261,7 +261,7 @@ extern "C" { if (status == F_number) { if (error.verbosity != f_console_verbosity_quiet) { - fprintf(error.to.stream, "%c", argument[0]); + fprintf(error.to.stream, "%c", f_string_eol[0]); fprintf(error.to.stream, "%s%sThe argument '", error.context.before->string, error.prefix ? error.prefix : ""); fprintf(error.to.stream, "%s%s%s%s", error.context.after->string, error.notable.before->string, argument, error.notable.after->string); fprintf(error.to.stream, "%s' is not a valid number for the parameter '", error.context.before->string); @@ -274,7 +274,7 @@ extern "C" { if (status == F_number_negative) { if (error.verbosity != f_console_verbosity_quiet) { - fprintf(error.to.stream, "%c", argument[0]); + fprintf(error.to.stream, "%c", f_string_eol[0]); fprintf(error.to.stream, "%s%sThe argument '", error.context.before->string, error.prefix ? error.prefix : ""); fprintf(error.to.stream, "%s%s%s%s", error.context.after->string, error.notable.before->string, argument, error.notable.after->string); fprintf(error.to.stream, "%s' is negative, which is not allowed for the parameter '", error.context.before->string); @@ -287,7 +287,7 @@ extern "C" { if (status == F_number_overflow) { if (error.verbosity != f_console_verbosity_quiet) { - fprintf(error.to.stream, "%c", argument[0]); + fprintf(error.to.stream, "%c", f_string_eol[0]); fprintf(error.to.stream, "%s%sThe argument '", error.context.before->string, error.prefix ? error.prefix : ""); fprintf(error.to.stream, "%s%s%s%s", error.context.after->string, error.notable.before->string, argument, error.notable.after->string); fprintf(error.to.stream, "%s' is too large for the parameter '", error.context.before->string); @@ -300,7 +300,7 @@ extern "C" { if (status == F_number_positive) { if (error.verbosity != f_console_verbosity_quiet) { - fprintf(error.to.stream, "%c", argument[0]); + fprintf(error.to.stream, "%c", f_string_eol[0]); fprintf(error.to.stream, "%s%sThe argument '", error.context.before->string, error.prefix ? error.prefix : ""); fprintf(error.to.stream, "%s%s%s%s", error.context.after->string, error.notable.before->string, argument, error.notable.after->string); fprintf(error.to.stream, "%s' is positive, which is not allowed for the parameter '", error.context.before->string); @@ -313,7 +313,7 @@ extern "C" { if (status == F_number_underflow) { if (error.verbosity != f_console_verbosity_quiet) { - fprintf(error.to.stream, "%c", argument[0]); + fprintf(error.to.stream, "%c", f_string_eol[0]); fprintf(error.to.stream, "%s%sThe argument '", error.context.before->string, error.prefix ? error.prefix : ""); fprintf(error.to.stream, "%s%s%s%s", error.context.after->string, error.notable.before->string, argument, error.notable.after->string); fprintf(error.to.stream, "%s' is too small for the parameter '", error.context.before->string); 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 c284d4d..1c6028d 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 @@ -62,8 +62,9 @@ extern "C" { #endif // _di_fss_basic_list_read_name_ #ifndef _di_fss_basic_list_read_defines_ - #define fss_basic_list_read_pipe_content_start '\0' - #define fss_basic_list_read_pipe_content_end '\f' + #define fss_basic_list_read_pipe_content_end '\f' + #define fss_basic_list_read_pipe_content_ignore '\v' + #define fss_basic_list_read_pipe_content_start '\b' #define fss_basic_list_read_short_at "a" #define fss_basic_list_read_short_content "c" diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.c b/level_3/fss_basic_list_write/c/fss_basic_list_write.c index e407450..df8c058 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.c @@ -25,6 +25,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_list_write_short_file, fss_basic_list_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); fll_program_print_help_option(file, context, fss_basic_list_write_short_content, fss_basic_list_write_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "The Content to output."); fll_program_print_help_option(file, context, fss_basic_list_write_short_double, fss_basic_list_write_long_double, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use double quotes (default)."); + fll_program_print_help_option(file, context, fss_basic_list_write_short_ignore, fss_basic_list_write_long_ignore, f_console_symbol_short_enable, f_console_symbol_long_enable, " Ignore a given range within a content."); fll_program_print_help_option(file, context, fss_basic_list_write_short_object, fss_basic_list_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " The Object to output."); fll_program_print_help_option(file, context, fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_basic_list_write_short_prepend, fss_basic_list_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); @@ -33,24 +34,34 @@ extern "C" { fll_program_print_help_usage(file, context, fss_basic_list_write_name, ""); - printf(" The pipe uses the NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + printf(" The pipe uses the Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); - printf(") to designate the start of a Content and uses the Form Feed character '"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); + printf(") to designate the start of a Content.%c", f_string_eol[0]); + + printf(" The pipe uses the Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(") to designate the end of the last Content.%c", f_string_eol[0]); - printf(" For the pipe, an Object is terminated by either a NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + + printf(" The pipe uses the Vertical Line character '"); + fl_color_print(f_type_output, context.set.notable, "\\v"); + printf("' ("); + fl_color_print(f_type_output, context.set.notable, "U+000B"); + printf(") is used to ignore a content range, which does nothing in this program.%c", f_string_eol[0]); + + printf(" For the pipe, an Object is terminated by either a Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); printf(") or a Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(").%c", f_string_eol[0]); + printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]); printf("%c", f_string_eol[0]); @@ -63,6 +74,13 @@ extern "C" { printf("%c", f_string_eol[0]); + printf(" This program does not use the parameter '"); + fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_ignore); + printf("', which therefore does nothing.%c", f_string_eol[0]); + printf(" This parameter requires two values.%c", f_string_eol[0]); + + printf("%c", f_string_eol[0]); + return F_none; } #endif // _di_fss_basic_list_write_print_help_ @@ -322,6 +340,32 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_basic_list_write_parameter_ignore].result == f_console_result_found) { + if (data->error.verbosity != f_console_verbosity_quiet) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' was specified, but no values were given.%c", f_string_eol[0]); + } + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_basic_list_write_parameter_ignore].result == f_console_result_additional) { + const f_array_length_t total_locations = data->parameters[fss_basic_list_write_parameter_ignore].locations.used; + const f_array_length_t total_arguments = data->parameters[fss_basic_list_write_parameter_ignore].additional.used; + + if (total_locations * 2 > total_arguments) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires two values.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + } + } + f_fss_quote_t quote = f_fss_delimit_quote_double; if (F_status_is_error_not(status)) { diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.h b/level_3/fss_basic_list_write/c/fss_basic_list_write.h index 7b719db..052ca19 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.h @@ -54,12 +54,14 @@ extern "C" { #endif // _di_fss_basic_list_write_name_ #ifndef _di_fss_basic_list_write_defines_ - #define fss_basic_list_write_pipe_content_start '\0' - #define fss_basic_list_write_pipe_content_end '\f' + #define fss_basic_list_write_pipe_content_end '\f' + #define fss_basic_list_write_pipe_content_ignore '\v' + #define fss_basic_list_write_pipe_content_start '\b' #define fss_basic_list_write_short_file "f" #define fss_basic_list_write_short_content "c" #define fss_basic_list_write_short_double "d" + #define fss_basic_list_write_short_ignore "I" #define fss_basic_list_write_short_object "o" #define fss_basic_list_write_short_partial "p" #define fss_basic_list_write_short_prepend "P" @@ -69,6 +71,7 @@ extern "C" { #define fss_basic_list_write_long_file "file" #define fss_basic_list_write_long_content "content" #define fss_basic_list_write_long_double "double" + #define fss_basic_list_write_long_ignore "ignore" #define fss_basic_list_write_long_object "object" #define fss_basic_list_write_long_partial "partial" #define fss_basic_list_write_long_prepend "prepend" @@ -89,6 +92,7 @@ extern "C" { fss_basic_list_write_parameter_file, fss_basic_list_write_parameter_content, fss_basic_list_write_parameter_double, + fss_basic_list_write_parameter_ignore, fss_basic_list_write_parameter_object, fss_basic_list_write_parameter_partial, fss_basic_list_write_parameter_prepend, @@ -110,6 +114,7 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_list_write_short_file, fss_basic_list_write_long_file, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_content, fss_basic_list_write_long_content, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_double, fss_basic_list_write_long_double, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_list_write_short_ignore, fss_basic_list_write_long_ignore, 0, 2, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_object, fss_basic_list_write_long_object, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_list_write_short_prepend, fss_basic_list_write_long_prepend, 0, 1, f_console_type_normal), \ @@ -117,7 +122,7 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_list_write_short_trim, fss_basic_list_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_list_write_total_parameters 17 + #define fss_basic_list_write_total_parameters 18 #endif // _di_fss_basic_list_write_defines_ #ifndef _di_fss_basic_list_write_data_t_ diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c index 71b8bc9..2f50280 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c @@ -194,6 +194,11 @@ extern "C" { break; } + if (block.string[range.start] == fss_basic_list_write_pipe_content_ignore) { + // this is not used by objects. + continue; + } + object.string[object.used++] = block.string[range.start]; } // for @@ -242,6 +247,11 @@ extern "C" { break; } + if (block.string[range.start] == fss_basic_list_write_pipe_content_ignore) { + // this is not used by this program. + continue; + } + content.string[content.used++] = block.string[range.start]; } // for diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h index 9a9a7eb..8a3a5cb 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h @@ -70,8 +70,10 @@ extern "C" { * This is either single our double quote. * @param object * The object to validate and print. + * Set pointer address to 0 to not use. * @param content * The content to escape and print. + * Set pointer address to 0 to not use. * @param buffer * The buffer array used as a cache to construct the output before printing. * 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 ea35952..ae4a818 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.h +++ b/level_3/fss_basic_read/c/fss_basic_read.h @@ -62,8 +62,9 @@ extern "C" { #endif // _di_fss_basic_read_name_ #ifndef _di_fss_basic_read_defines_ - #define fss_basic_read_pipe_content_start '\0' - #define fss_basic_read_pipe_content_end '\f' + #define fss_basic_read_pipe_content_end '\f' + #define fss_basic_read_pipe_content_ignore '\v' + #define fss_basic_read_pipe_content_start '\b' #define fss_basic_read_short_at "a" #define fss_basic_read_short_content "c" diff --git a/level_3/fss_basic_write/c/fss_basic_write.c b/level_3/fss_basic_write/c/fss_basic_write.c index 172dfaa..88c4b9b 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.c +++ b/level_3/fss_basic_write/c/fss_basic_write.c @@ -25,6 +25,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_basic_write_short_file, fss_basic_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); fll_program_print_help_option(file, context, fss_basic_write_short_content, fss_basic_write_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "The Content to output."); fll_program_print_help_option(file, context, fss_basic_write_short_double, fss_basic_write_long_double, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use double quotes (default)."); + fll_program_print_help_option(file, context, fss_basic_write_short_ignore, fss_basic_write_long_ignore, f_console_symbol_short_enable, f_console_symbol_long_enable, " Ignore a given range within a content."); fll_program_print_help_option(file, context, fss_basic_write_short_object, fss_basic_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " The Object to output."); fll_program_print_help_option(file, context, fss_basic_write_short_partial, fss_basic_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_basic_write_short_prepend, fss_basic_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); @@ -33,24 +34,34 @@ extern "C" { fll_program_print_help_usage(file, context, fss_basic_write_name, ""); - printf(" The pipe uses the NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + printf(" The pipe uses the Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); - printf(") to designate the start of a Content and uses the Form Feed character '"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); + printf(") to designate the start of a Content.%c", f_string_eol[0]); + + printf(" The pipe uses the Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(") to designate the end of the last Content.%c", f_string_eol[0]); - printf(" For the pipe, an Object is terminated by either a NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + + printf(" The pipe uses the Vertical Line character '"); + fl_color_print(f_type_output, context.set.notable, "\\v"); + printf("' ("); + fl_color_print(f_type_output, context.set.notable, "U+000B"); + printf(") is used to ignore a content range, which does nothing in this program.%c", f_string_eol[0]); + + printf(" For the pipe, an Object is terminated by either a Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); printf(") or a Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(").%c", f_string_eol[0]); + printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]); printf("%c", f_string_eol[0]); @@ -61,6 +72,13 @@ extern "C" { printf("%c", f_string_eol[0]); + printf(" This program does not use the parameter '"); + fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_ignore); + printf("', which therefore does nothing.%c", f_string_eol[0]); + printf(" This parameter requires two values.%c", f_string_eol[0]); + + printf("%c", f_string_eol[0]); + return F_none; } #endif // _di_fss_basic_write_print_help_ @@ -318,6 +336,32 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_basic_write_parameter_ignore].result == f_console_result_found) { + if (data->error.verbosity != f_console_verbosity_quiet) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' was specified, but no values were given.%c", f_string_eol[0]); + } + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_basic_write_parameter_ignore].result == f_console_result_additional) { + const f_array_length_t total_locations = data->parameters[fss_basic_write_parameter_ignore].locations.used; + const f_array_length_t total_arguments = data->parameters[fss_basic_write_parameter_ignore].additional.used; + + if (total_locations * 2 > total_arguments) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires two values.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + } + } + f_fss_quote_t quote = f_fss_delimit_quote_double; if (F_status_is_error_not(status)) { diff --git a/level_3/fss_basic_write/c/fss_basic_write.h b/level_3/fss_basic_write/c/fss_basic_write.h index a8f0664..697db51 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.h +++ b/level_3/fss_basic_write/c/fss_basic_write.h @@ -55,12 +55,14 @@ extern "C" { #endif // _di_fss_basic_write_name_ #ifndef _di_fss_basic_write_defines_ - #define fss_basic_write_pipe_content_start '\0' - #define fss_basic_write_pipe_content_end '\f' + #define fss_basic_write_pipe_content_end '\f' + #define fss_basic_write_pipe_content_ignore '\v' + #define fss_basic_write_pipe_content_start '\b' #define fss_basic_write_short_file "f" #define fss_basic_write_short_content "c" #define fss_basic_write_short_double "d" + #define fss_basic_write_short_ignore "I" #define fss_basic_write_short_object "o" #define fss_basic_write_short_partial "p" #define fss_basic_write_short_prepend "P" @@ -70,6 +72,7 @@ extern "C" { #define fss_basic_write_long_file "file" #define fss_basic_write_long_content "content" #define fss_basic_write_long_double "double" + #define fss_basic_write_long_ignore "ignore" #define fss_basic_write_long_object "object" #define fss_basic_write_long_partial "partial" #define fss_basic_write_long_prepend "prepend" @@ -90,6 +93,7 @@ extern "C" { fss_basic_write_parameter_file, fss_basic_write_parameter_content, fss_basic_write_parameter_double, + fss_basic_write_parameter_ignore, fss_basic_write_parameter_object, fss_basic_write_parameter_partial, fss_basic_write_parameter_prepend, @@ -111,6 +115,7 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_write_short_file, fss_basic_write_long_file, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_content, fss_basic_write_long_content, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_double, fss_basic_write_long_double, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_basic_write_short_ignore, fss_basic_write_long_ignore, 0, 2, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_object, fss_basic_write_long_object, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_partial, fss_basic_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_basic_write_short_prepend, fss_basic_write_long_prepend, 0, 1, f_console_type_normal), \ @@ -118,7 +123,7 @@ extern "C" { f_console_parameter_t_initialize(fss_basic_write_short_trim, fss_basic_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_basic_write_total_parameters 17 + #define fss_basic_write_total_parameters 18 #endif // _di_fss_basic_write_defines_ #ifndef _di_fss_basic_write_data_ diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.c b/level_3/fss_basic_write/c/private-fss_basic_write.c index ba33799..46b6989 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.c +++ b/level_3/fss_basic_write/c/private-fss_basic_write.c @@ -206,6 +206,11 @@ extern "C" { break; } + if (block.string[range.start] == fss_basic_write_pipe_content_ignore) { + // this is not used by objects. + continue; + } + object.string[object.used++] = block.string[range.start]; } // for @@ -247,12 +252,19 @@ extern "C" { status = F_status_set_error(F_unsupported); break; } - else if (block.string[range.start] == fss_basic_write_pipe_content_end) { + + if (block.string[range.start] == fss_basic_write_pipe_content_end) { state = 0x3; range.start++; break; } - else if (F_status_set_fine(status) == F_none_eol) { + + if (block.string[range.start] == fss_basic_write_pipe_content_ignore) { + // this is not used by this program. + continue; + } + + if (F_status_set_fine(status) == F_none_eol) { fss_basic_write_error_parameter_unsupported_eol_print(data); status = F_status_set_error(F_unsupported); diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.h b/level_3/fss_basic_write/c/private-fss_basic_write.h index 768479b..7e4ebca 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.h +++ b/level_3/fss_basic_write/c/private-fss_basic_write.h @@ -70,10 +70,10 @@ extern "C" { * This is either single our double quote. * @param object * A pointer to the object to validate and print. - * Set to 0 to disable. + * Set pointer address to 0 to not use. * @param content * A pointer to the content to escape and print. - * Set to 0 to disable. + * Set pointer address to 0 to not use. * @param buffer * The buffer array used as a cache to construct the output before printing. * 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 57942c3..c2840b1 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 @@ -62,8 +62,9 @@ extern "C" { #endif // _di_fss_extended_list_read_name_ #ifndef _di_fss_extended_list_read_defines_ - #define fss_extended_list_read_pipe_content_start '\0' - #define fss_extended_list_read_pipe_content_end '\f' + #define fss_extended_list_read_pipe_content_end '\f' + #define fss_extended_list_read_pipe_content_ignore '\v' + #define fss_extended_list_read_pipe_content_start '\b' #define fss_extended_list_read_short_at "a" #define fss_extended_list_read_short_content "c" diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.c b/level_3/fss_extended_list_write/c/fss_extended_list_write.c index 5225de3..2ff6089 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.c @@ -25,6 +25,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_extended_list_write_short_file, fss_extended_list_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); fll_program_print_help_option(file, context, fss_extended_list_write_short_content, fss_extended_list_write_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "The Content to output."); fll_program_print_help_option(file, context, fss_extended_list_write_short_double, fss_extended_list_write_long_double, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use double quotes (default)."); + fll_program_print_help_option(file, context, fss_extended_list_write_short_ignore, fss_extended_list_write_long_ignore, f_console_symbol_short_enable, f_console_symbol_long_enable, " Ignore a given range within a content."); fll_program_print_help_option(file, context, fss_extended_list_write_short_object, fss_extended_list_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " The Object to output."); fll_program_print_help_option(file, context, fss_extended_list_write_short_partial, fss_extended_list_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_extended_list_write_short_prepend, fss_extended_list_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); @@ -33,29 +34,39 @@ extern "C" { fll_program_print_help_usage(file, context, fss_extended_list_write_name, ""); - printf(" The pipe uses the NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + printf(" The pipe uses the Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); - printf(") to designate the start of a Content and uses the Form Feed character '"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); + printf(") to designate the start of a Content.%c", f_string_eol[0]); + + printf(" The pipe uses the Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(") to designate the end of the last Content.%c", f_string_eol[0]); - printf(" For the pipe, an Object is terminated by either a NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + + printf(" The pipe uses the Vertical Line character '"); + fl_color_print(f_type_output, context.set.notable, "\\v"); + printf("' ("); + fl_color_print(f_type_output, context.set.notable, "U+000B"); + printf(") is used to ignore a content range (use this both before and after the range).%c", f_string_eol[0]); + + printf(" For the pipe, an Object is terminated by either a Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); printf(") or a Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(").%c", f_string_eol[0]); + printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]); printf("%c", f_string_eol[0]); - printf(" The FSS-0002 (Basic List) specification does not support quoted names, therefore the parameters '"); + printf(" The FSS-0003 (Extended List) specification does not support quoted names, therefore the parameters '"); fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_write_long_single); printf("' and '"); fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_write_long_double); @@ -63,6 +74,19 @@ extern "C" { 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_write_long_ignore); + printf("' designates to not escape any valid nested Object or Content within some Content.%c", f_string_eol[0]); + printf(" This parameter requires two values.%c", f_string_eol[0]); + printf(" This is not used for ignoring anything within the input pipe.%c", f_string_eol[0]); + printf(" This parameter must be specified after a '"); + fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_write_long_content); + printf("' parameter and this applies only to the Content represented by that specific '"); + fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_write_long_content); + printf("' parameter.%c", f_string_eol[0]); + + printf("%c", f_string_eol[0]); + return F_none; } #endif // _di_fss_extended_list_write_print_help_ @@ -322,6 +346,32 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_extended_list_write_parameter_ignore].result == f_console_result_found) { + if (data->error.verbosity != f_console_verbosity_quiet) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' was specified, but no values were given.%c", f_string_eol[0]); + } + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_extended_list_write_parameter_ignore].result == f_console_result_additional) { + const f_array_length_t total_locations = data->parameters[fss_extended_list_write_parameter_ignore].locations.used; + const f_array_length_t total_arguments = data->parameters[fss_extended_list_write_parameter_ignore].additional.used; + + if (total_locations * 2 > total_arguments) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires two values.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + } + } + f_fss_quote_t quote = f_fss_delimit_quote_double; if (F_status_is_error_not(status)) { @@ -343,9 +393,10 @@ extern "C" { if (F_status_is_error_not(status)) { f_string_dynamic_t escaped = f_string_dynamic_t_initialize; + f_string_ranges_t ignore = f_string_ranges_t_initialize; if (data->process_pipe) { - status = fss_extended_list_write_process_pipe(*data, output, quote, &buffer); + status = fss_extended_list_write_process_pipe(*data, output, quote, &buffer, &ignore); if (F_status_is_error(status)) { if (data->error.verbosity != f_console_verbosity_quiet) { @@ -355,6 +406,8 @@ extern "C" { fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]); } } + + ignore.used = 0; } if (F_status_is_error_not(status)) { @@ -367,18 +420,21 @@ extern "C" { object.used = strnlen(object.string, f_console_length_size); object.size = object.used; - status = fss_extended_list_write_process(*data, output, quote, &object, 0, &buffer); + status = fss_extended_list_write_process(*data, output, quote, &object, 0, 0, &buffer); if (F_status_is_error(status)) break; } // for } else { for (f_array_length_t i = 0; i < data->parameters[fss_extended_list_write_parameter_content].additional.used; i++) { + status = fss_extended_list_write_process_parameter_ignore(arguments, *data, data->parameters[fss_extended_list_write_parameter_content].locations, i, &ignore); + if (F_status_is_error(status)) break; + content.string = arguments.argv[data->parameters[fss_extended_list_write_parameter_content].additional.array[i]]; content.used = strnlen(content.string, f_console_length_size); content.size = content.used; - status = fss_extended_list_write_process(*data, output, quote, 0, &content, &buffer); + status = fss_extended_list_write_process(*data, output, quote, 0, &content, &ignore, &buffer); if (F_status_is_error(status)) break; } // for } @@ -386,6 +442,9 @@ extern "C" { else { for (f_array_length_t i = 0; i < data->parameters[fss_extended_list_write_parameter_object].additional.used; i++) { + status = fss_extended_list_write_process_parameter_ignore(arguments, *data, data->parameters[fss_extended_list_write_parameter_content].locations, i, &ignore); + if (F_status_is_error(status)) break; + object.string = arguments.argv[data->parameters[fss_extended_list_write_parameter_object].additional.array[i]]; object.used = strnlen(object.string, f_console_length_size); object.size = object.used; @@ -394,7 +453,7 @@ extern "C" { content.used = strnlen(content.string, f_console_length_size); content.size = content.used; - status = fss_extended_list_write_process(*data, output, quote, &object, &content, &buffer); + status = fss_extended_list_write_process(*data, output, quote, &object, &content, &ignore, &buffer); if (F_status_is_error(status)) break; } // for } @@ -414,6 +473,7 @@ extern "C" { } f_macro_string_dynamic_t_delete_simple(escaped); + f_macro_string_ranges_t_delete_simple(ignore); // object and content, though being a "dynamic" type, is being used statically, so clear them up to avoid invalid free(). object.string = 0; diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.h b/level_3/fss_extended_list_write/c/fss_extended_list_write.h index f705074..2946920 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.h +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.h @@ -28,6 +28,7 @@ // fll-1 includes #include #include +#include #include #include #include @@ -54,12 +55,14 @@ extern "C" { #endif // _di_fss_extended_list_write_name_ #ifndef _di_fss_extended_list_write_defines_ - #define fss_extended_list_write_pipe_content_start '\0' - #define fss_extended_list_write_pipe_content_end '\f' + #define fss_extended_list_write_pipe_content_end '\f' + #define fss_extended_list_write_pipe_content_ignore '\v' + #define fss_extended_list_write_pipe_content_start '\b' #define fss_extended_list_write_short_file "f" #define fss_extended_list_write_short_content "c" #define fss_extended_list_write_short_double "d" + #define fss_extended_list_write_short_ignore "I" #define fss_extended_list_write_short_object "o" #define fss_extended_list_write_short_partial "p" #define fss_extended_list_write_short_prepend "P" @@ -69,6 +72,7 @@ extern "C" { #define fss_extended_list_write_long_file "file" #define fss_extended_list_write_long_content "content" #define fss_extended_list_write_long_double "double" + #define fss_extended_list_write_long_ignore "ignore" #define fss_extended_list_write_long_object "object" #define fss_extended_list_write_long_partial "partial" #define fss_extended_list_write_long_prepend "prepend" @@ -89,6 +93,7 @@ extern "C" { fss_extended_list_write_parameter_file, fss_extended_list_write_parameter_content, fss_extended_list_write_parameter_double, + fss_extended_list_write_parameter_ignore, fss_extended_list_write_parameter_object, fss_extended_list_write_parameter_partial, fss_extended_list_write_parameter_prepend, @@ -110,6 +115,7 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_list_write_short_file, fss_extended_list_write_long_file, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_content, fss_extended_list_write_long_content, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_double, fss_extended_list_write_long_double, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_list_write_short_ignore, fss_extended_list_write_long_ignore, 0, 2, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_object, fss_extended_list_write_long_object, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_partial, fss_extended_list_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_list_write_short_prepend, fss_extended_list_write_long_prepend, 0, 1, f_console_type_normal), \ @@ -117,7 +123,7 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_list_write_short_trim, fss_extended_list_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_list_write_total_parameters 17 + #define fss_extended_list_write_total_parameters 18 #endif // _di_fss_extended_list_write_defines_ #ifndef _di_fss_extended_list_write_data_t_ diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c index c6bc35b..171f848 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c @@ -52,7 +52,7 @@ extern "C" { #endif // _di_fss_extended_list_write_error_parameter_value_missing_print_ #ifndef _di_fss_extended_list_write_process_ - f_return_status fss_extended_list_write_process(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) { + f_return_status fss_extended_list_write_process(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, const f_string_ranges_t *ignore, f_string_dynamic_t *buffer) { f_status_t status = F_none; f_string_range_t range = f_string_range_t_initialize; @@ -96,8 +96,7 @@ extern "C" { range.start = 0; range.stop = content->used - 1; - // @todo: add const f_string_ranges_t *ignore parameter. - status = fl_fss_extended_list_content_write_string(*content, object ? f_fss_complete_full : f_fss_complete_none, &data.prepend, 0, &range, buffer); + status = fl_fss_extended_list_content_write_string(*content, object ? f_fss_complete_full : f_fss_complete_none, &data.prepend, ignore, &range, buffer); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_content_write_string", F_true); @@ -122,7 +121,7 @@ extern "C" { #endif // _di_fss_extended_list_write_process_ #ifndef _di_fss_extended_list_write_process_pipe_ - f_return_status fss_extended_list_write_process_pipe(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) { + f_return_status fss_extended_list_write_process_pipe(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer, f_string_ranges_t *ignore) { f_status_t status = F_none; f_status_t status_pipe = F_none; @@ -133,7 +132,9 @@ extern "C" { f_string_length_t total = 0; f_string_length_t previous = 0; + f_string_range_t range = f_string_range_t_initialize; + f_string_range_t range_ignore = f_string_range_t_initialize; f_string_dynamic_t block = f_string_dynamic_t_initialize; f_string_dynamic_t object = f_string_dynamic_t_initialize; @@ -170,6 +171,9 @@ extern "C" { content.used = 0; state = 0x1; + + range_ignore.start = 1; + range_ignore.stop = 0; } if (object.used + block.used > object.size) { @@ -195,6 +199,11 @@ extern "C" { break; } + if (block.string[range.start] == fss_extended_list_write_pipe_content_ignore) { + // this is not used by objects. + continue; + } + object.string[object.used++] = block.string[range.start]; } // for @@ -243,6 +252,45 @@ extern "C" { break; } + if (block.string[range.start] == fss_extended_list_write_pipe_content_ignore) { + if (ignore) { + if (range_ignore.start > range_ignore.stop) { + range_ignore.start = content.used; + range_ignore.stop = content.used; + } + else { + if (ignore->used + 1 > ignore->size) { + if (ignore->size + f_fss_default_allocation_step > f_array_length_t_size) { + if (ignore->size + 1 > f_array_length_t_size) { + fll_error_print(data.error, F_string_too_large, "fss_extended_list_write_process_pipe", F_true); + + status = F_status_set_error(F_string_too_large); + break; + } + + f_macro_string_ranges_t_resize(status, (*ignore), ignore->size + 1); + } + else { + f_macro_string_ranges_t_resize(status, (*ignore), ignore->size + f_fss_default_allocation_step); + } + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_string_too_large, "fss_extended_list_write_process_pipe", F_true); + break; + } + } + + ignore->array[ignore->used].start = range_ignore.start; + ignore->array[ignore->used++].stop = content.used - 1; + + range_ignore.start = 1; + range_ignore.stop = 0; + } + } + + continue; + } + content.string[content.used++] = block.string[range.start]; } // for @@ -254,7 +302,7 @@ extern "C" { } if (state == 0x3) { - status = fss_extended_list_write_process(data, output, quote, &object, &content, buffer); + status = fss_extended_list_write_process(data, output, quote, &object, &content, ignore, buffer); if (F_status_is_error(status)) break; state = 0; @@ -263,7 +311,7 @@ extern "C" { // if the pipe ended before finishing, then attempt to wrap up. if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) { - status = fss_extended_list_write_process(data, output, quote, &object, &content, buffer); + status = fss_extended_list_write_process(data, output, quote, &object, &content, ignore, buffer); } f_macro_string_dynamic_t_delete_simple(block); @@ -273,6 +321,89 @@ extern "C" { } #endif // _di_fss_extended_list_write_process_pipe_ +#ifndef _di_fss_extended_list_write_process_parameter_ignore_ + f_return_status fss_extended_list_write_process_parameter_ignore(const f_console_arguments_t arguments, const fss_extended_list_write_data_t data, const f_array_lengths_t contents, const f_array_length_t location, f_string_ranges_t *ignore) { + f_status_t status = F_none; + + f_array_length_t i = 0; + f_array_length_t l = 0; + f_array_length_t index = 0; + + f_string_range_t range = f_string_range_t_initialize; + + f_number_unsigned_t number = 0; + + range.start = 0; + + for (; i < data.parameters[fss_extended_list_write_parameter_ignore].locations.used; i++) { + + l = data.parameters[fss_extended_list_write_parameter_ignore].locations.array[i]; + + if (l < contents.array[location]) continue; + if (location + 1 < contents.used && l > contents.array[location + 1]) continue; + + if (ignore->used + 1 > ignore->size) { + if (ignore->size + f_fss_default_allocation_step > f_array_length_t_size) { + if (ignore->size + 1 > f_array_length_t_size) { + fll_error_print(data.error, F_string_too_large, "fss_extended_list_write_process_parameter_ignore", F_true); + return F_status_set_error(F_string_too_large); + } + + f_macro_string_ranges_t_resize(status, (*ignore), ignore->size + 1); + } + else { + f_macro_string_ranges_t_resize(status, (*ignore), ignore->size + f_fss_default_allocation_step); + } + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fss_extended_list_write_process_parameter_ignore", F_true); + return status; + } + } + + index = data.parameters[fss_extended_list_write_parameter_ignore].additional.array[i * 2]; + + range.start = 0; + range.stop = strnlen(arguments.argv[index], f_console_length_size); + + // allow and ignore the positive sign. + if (range.stop > 0 && arguments.argv[index][0] == '+') { + range.start = 1; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[index], &number, 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_write_long_ignore, arguments.argv[index]); + return status; + } + + ignore->array[ignore->used].start = number; + + index = data.parameters[fss_extended_list_write_parameter_ignore].additional.array[(i * 2) + 1]; + + range.start = 0; + range.stop = strnlen(arguments.argv[index], f_console_length_size); + + // allow and ignore the positive sign. + if (range.stop > 0 && arguments.argv[index][0] == '+') { + range.start = 1; + } + + status = fl_conversion_string_to_number_unsigned(arguments.argv[index], &number, 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_write_long_ignore, arguments.argv[index]); + return status; + } + + ignore->array[ignore->used++].stop = number; + } // for + + return F_none; + } +#endif // _di_fss_extended_list_write_process_parameter_ignore_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h index ed984b7..5f56773 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h +++ b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h @@ -70,8 +70,13 @@ extern "C" { * This is either single our double quote. * @param object * The object to validate and print. + * Set pointer address to 0 to not use. * @param content * The content to escape and print. + * Set pointer address to 0 to not use. + * @param ignore + * An array of ranges within the Content to ignore. + * Set pointer address to 0 to not use. * @param buffer * The buffer array used as a cache to construct the output before printing. * @@ -80,7 +85,7 @@ extern "C" { * F_failure (with error bit) for any othe failure. */ #ifndef _di_fss_extended_list_write_process_ - extern f_return_status fss_extended_list_write_process(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_write_process(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, const f_string_ranges_t *ignore, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_write_process_ /** @@ -95,15 +100,40 @@ extern "C" { * This is either single our double quote. * @param buffer * The buffer array used as a cache to construct the output before printing. + * @param ignore + * An array of ranges within the Content to ignore. + * Set pointer address to 0 to not use. * * @return * F_none on success. * F_failure (with error bit) for any othe failure. */ #ifndef _di_fss_extended_list_write_process_pipe_ - extern f_return_status fss_extended_list_write_process_pipe(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_write_process_pipe(const fss_extended_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer, f_string_ranges_t *ignore) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_write_process_pipe_ +/** + * Process the ignore parameter associated with a specific content parameter. + * + * @param arguments + * The parameters passed to the process. + * @param data + * The program data. + * @param contents + * The console parameter locations array for the content parameter. + * @param location + * The specific location within the contents locations array. + * @param ignore + * An array of ranges within the Content to ignore. + * + * @return + * F_none on success. + * F_failure (with error bit) for any othe failure. + */ +#ifndef _di_fss_extended_list_write_process_parameter_ignore_ + extern f_return_status fss_extended_list_write_process_parameter_ignore(const f_console_arguments_t arguments, const fss_extended_list_write_data_t data, const f_array_lengths_t contents, const f_array_length_t location, f_string_ranges_t *ignore) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_write_process_parameter_ignore_ + #ifdef __cplusplus } // extern "C" #endif 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 71d4ae0..7c3d1db 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.h +++ b/level_3/fss_extended_read/c/fss_extended_read.h @@ -62,8 +62,9 @@ extern "C" { #endif // _di_fss_extended_read_name_ #ifndef _di_fss_extended_read_defines_ - #define fss_extended_read_pipe_content_start '\0' - #define fss_extended_read_pipe_content_end '\f' + #define fss_extended_read_pipe_content_end '\f' + #define fss_extended_read_pipe_content_ignore '\v' + #define fss_extended_read_pipe_content_start '\b' #define fss_extended_read_short_at "a" #define fss_extended_read_short_content "c" diff --git a/level_3/fss_extended_write/c/fss_extended_write.c b/level_3/fss_extended_write/c/fss_extended_write.c index 6cb9453..cbed51d 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -25,6 +25,7 @@ extern "C" { fll_program_print_help_option(file, context, fss_extended_write_short_file, fss_extended_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); fll_program_print_help_option(file, context, fss_extended_write_short_content, fss_extended_write_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "The Content to output."); fll_program_print_help_option(file, context, fss_extended_write_short_double, fss_extended_write_long_double, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use double quotes (default)."); + fll_program_print_help_option(file, context, fss_extended_write_short_ignore, fss_extended_write_long_ignore, f_console_symbol_short_enable, f_console_symbol_long_enable, " Ignore a given range within a content."); fll_program_print_help_option(file, context, fss_extended_write_short_object, fss_extended_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " The Object to output."); fll_program_print_help_option(file, context, fss_extended_write_short_partial, fss_extended_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output end of Object/Content character."); fll_program_print_help_option(file, context, fss_extended_write_short_prepend, fss_extended_write_long_prepend, f_console_symbol_short_enable, f_console_symbol_long_enable, "Prepend the given whitespace characters to the start of each multi-line Content."); @@ -33,24 +34,34 @@ extern "C" { fll_program_print_help_usage(file, context, fss_extended_write_name, ""); - printf(" The pipe uses the NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + printf(" The pipe uses the Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); - printf(") to designate the start of a Content and uses the Form Feed character '"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); + printf(") to designate the start of a Content.%c", f_string_eol[0]); + + printf(" The pipe uses the Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(") to designate the end of the last Content.%c", f_string_eol[0]); - printf(" For the pipe, an Object is terminated by either a NULL character '"); - fl_color_print(f_type_output, context.set.notable, "\\0"); + + printf(" The pipe uses the Vertical Line character '"); + fl_color_print(f_type_output, context.set.notable, "\\v"); + printf("' ("); + fl_color_print(f_type_output, context.set.notable, "U+000B"); + printf(") is used to ignore a content range, which does nothing in this program.%c", f_string_eol[0]); + + printf(" For the pipe, an Object is terminated by either a Backspace character '"); + fl_color_print(f_type_output, context.set.notable, "\\b"); printf("' ("); - fl_color_print(f_type_output, context.set.notable, "U+0000"); + fl_color_print(f_type_output, context.set.notable, "U+0008"); printf(") or a Form Feed character '"); fl_color_print(f_type_output, context.set.notable, "\\f"); printf("' ("); fl_color_print(f_type_output, context.set.notable, "U+000C"); printf(").%c", f_string_eol[0]); + printf(" The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]); printf("%c", f_string_eol[0]); @@ -61,6 +72,13 @@ extern "C" { printf("%c", f_string_eol[0]); + printf(" This program does not use the parameter '"); + fl_color_print(f_type_output, context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_ignore); + printf("', which therefore does nothing.%c", f_string_eol[0]); + printf(" This parameter requires two values.%c", f_string_eol[0]); + + printf("%c", f_string_eol[0]); + return F_none; } #endif // _di_fss_extended_write_print_help_ @@ -329,6 +347,32 @@ extern "C" { } } + if (F_status_is_error_not(status)) { + if (data->parameters[fss_extended_write_parameter_ignore].result == f_console_result_found) { + if (data->error.verbosity != f_console_verbosity_quiet) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' was specified, but no values were given.%c", f_string_eol[0]); + } + + status = F_status_set_error(F_parameter); + } + else if (data->parameters[fss_extended_write_parameter_ignore].result == f_console_result_additional) { + const f_array_length_t total_locations = data->parameters[fss_extended_write_parameter_ignore].locations.used; + const f_array_length_t total_arguments = data->parameters[fss_extended_write_parameter_ignore].additional.used; + + if (total_locations * 2 > total_arguments) { + fprintf(data->error.to.stream, "%c", f_string_eol[0]); + 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_write_long_ignore); + fl_color_print(data->error.to.stream, data->context.set.error, "' requires two values.%c", f_string_eol[0]); + + status = F_status_set_error(F_parameter); + } + } + } + f_fss_quote_t quote = f_fss_delimit_quote_double; if (F_status_is_error_not(status)) { diff --git a/level_3/fss_extended_write/c/fss_extended_write.h b/level_3/fss_extended_write/c/fss_extended_write.h index 0e9b235..d32667f 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.h +++ b/level_3/fss_extended_write/c/fss_extended_write.h @@ -54,12 +54,14 @@ extern "C" { #endif // _di_fss_extended_write_name_ #ifndef _di_fss_extended_write_defines_ - #define fss_extended_write_pipe_content_start '\0' - #define fss_extended_write_pipe_content_end '\f' + #define fss_extended_write_pipe_content_end '\f' + #define fss_extended_write_pipe_content_ignore '\v' + #define fss_extended_write_pipe_content_start '\b' #define fss_extended_write_short_file "f" #define fss_extended_write_short_content "c" #define fss_extended_write_short_double "d" + #define fss_extended_write_short_ignore "I" #define fss_extended_write_short_object "o" #define fss_extended_write_short_partial "p" #define fss_extended_write_short_prepend "P" @@ -69,6 +71,7 @@ extern "C" { #define fss_extended_write_long_file "file" #define fss_extended_write_long_content "content" #define fss_extended_write_long_double "double" + #define fss_extended_write_long_ignore "ignore" #define fss_extended_write_long_object "object" #define fss_extended_write_long_partial "partial" #define fss_extended_write_long_prepend "prepend" @@ -89,6 +92,7 @@ extern "C" { fss_extended_write_parameter_file, fss_extended_write_parameter_content, fss_extended_write_parameter_double, + fss_extended_write_parameter_ignore, fss_extended_write_parameter_object, fss_extended_write_parameter_partial, fss_extended_write_parameter_prepend, @@ -110,6 +114,7 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_write_short_file, fss_extended_write_long_file, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_content, fss_extended_write_long_content, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_double, fss_extended_write_long_double, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(fss_extended_write_short_ignore, fss_extended_write_long_ignore, 0, 2, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_object, fss_extended_write_long_object, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_partial, fss_extended_write_long_partial, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(fss_extended_write_short_prepend, fss_extended_write_long_prepend, 0, 1, f_console_type_normal), \ @@ -117,7 +122,7 @@ extern "C" { f_console_parameter_t_initialize(fss_extended_write_short_trim, fss_extended_write_long_trim, 0, 0, f_console_type_normal), \ } - #define fss_extended_write_total_parameters 17 + #define fss_extended_write_total_parameters 18 #endif // _di_fss_extended_write_defines_ #ifndef _di_fss_extended_write_data_t_ diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.c b/level_3/fss_extended_write/c/private-fss_extended_write.c index b95a86b..7e8dc4d 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.c +++ b/level_3/fss_extended_write/c/private-fss_extended_write.c @@ -218,6 +218,11 @@ extern "C" { break; } + if (block.string[range.start] == fss_extended_write_pipe_content_ignore) { + // this is not used by objects. + continue; + } + object.string[object.used++] = block.string[range.start]; } // for @@ -268,12 +273,19 @@ extern "C" { contents.used++; continue; } - else if (block.string[range.start] == fss_extended_write_pipe_content_end) { + + if (block.string[range.start] == fss_extended_write_pipe_content_end) { state = 0x4; range.start++; break; } - else if (F_status_set_fine(status) == F_none_eol) { + + if (block.string[range.start] == fss_extended_write_pipe_content_ignore) { + // this is not used by this program. + continue; + } + + if (F_status_set_fine(status) == F_none_eol) { fss_extended_write_error_parameter_unsupported_eol_print(data); status = F_status_set_error(F_unsupported); diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.h b/level_3/fss_extended_write/c/private-fss_extended_write.h index 49522b4..d12b25c 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.h +++ b/level_3/fss_extended_write/c/private-fss_extended_write.h @@ -70,10 +70,10 @@ extern "C" { * This is either single our double quote. * @param object * A pointer to the object to validate and print. - * Set to 0 to disable. + * Set pointer address to 0 to not use. * @param content * A pointer to the content to escape and print. - * Set to 0 to disable. + * Set pointer address to 0 to not use. * @param buffer * The buffer array used as a cache to construct the output before printing. *