From: Kevin Day Date: Thu, 17 Nov 2022 03:23:27 +0000 (-0600) Subject: Update: Finish program related work for fss_payload_write. X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=ef89fafafe125e0afbf83476f255f52e176a9c72;p=fll Update: Finish program related work for fss_payload_write. This appears to be done now. The next step for fss_payload_write is to use it as the starting point for the fss_write program that is intended to provide all of the fss_*_write programs. I will likely make improvements to the lazy approach I took regarding loading the entire file when processing. I found two bugs regarding the pipe processing. 1) The first character never gets printed for payload Content. 2) An end-of-content character must be printed after the Content if printing partial Objects or if the "payload" Content is not yet printed. --- diff --git a/level_3/fss_payload_write/c/common.c b/level_3/fss_payload_write/c/common.c index 5c53e90..9ab24b3 100644 --- a/level_3/fss_payload_write/c/common.c +++ b/level_3/fss_payload_write/c/common.c @@ -19,6 +19,10 @@ extern "C" { const f_string_static_t fss_payload_write_pipe_content_start_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_pipe_content_start_s, 0, FSS_PAYLOAD_WRITE_pipe_content_start_s_length); #endif // _di_fss_payload_write_defines_ +#ifndef _di_fss_payload_write_strings_ + const f_string_static_t fss_payload_write_string_two_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_string_two_s, 0, FSS_PAYLOAD_WRITE_string_two_s_length); +#endif // _di_fss_payload_write_strings_ + #ifndef _di_fss_payload_write_parameters_ const f_string_static_t fss_payload_write_short_file_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_short_file_s, 0, FSS_PAYLOAD_WRITE_short_file_s_length); const f_string_static_t fss_payload_write_short_content_s = macro_f_string_static_t_initialize(FSS_PAYLOAD_WRITE_short_content_s, 0, FSS_PAYLOAD_WRITE_short_content_s_length); @@ -47,11 +51,13 @@ extern "C" { if (!setting) return F_status_set_error(F_parameter); f_string_dynamic_resize(0, &setting->escaped); + f_string_dynamic_resize(0, &setting->block); f_string_dynamic_resize(0, &setting->buffer); f_string_dynamic_resize(0, &setting->object); f_string_dynamic_resize(0, &setting->content); f_string_dynamic_resize(0, &setting->prepend); + f_string_ranges_resize(0, &setting->ignores); f_string_dynamics_resize(0, &setting->objects); f_string_dynamics_resize(0, &setting->contents); @@ -275,7 +281,7 @@ extern "C" { return; } - if (status == F_false) { + if (setting->status == F_false) { setting->status = F_status_set_error(F_parameter); fss_payload_write_print_error_prepend_only_whitespace(setting, main->error); @@ -297,6 +303,81 @@ extern "C" { return; } + if (main->parameters.array[fss_payload_write_parameter_ignore_e].result == f_console_result_additional_e && main->parameters.array[fss_payload_write_parameter_ignore_e].values.used) { + + if (main->parameters.array[fss_payload_write_parameter_ignore_e].values.used % 2 != 0) { + setting->status = F_status_set_error(F_parameter); + + fss_payload_write_print_line_first_locked(setting, main->error); + fll_program_print_error_parameter_missing_value_requires_amount(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, fss_payload_write_string_two_s); + fss_payload_write_print_line_last_locked(setting, main->error); + + return; + } + + setting->ignores.used = 0; + + setting->status = f_string_ranges_increase_by(main->parameters.array[fss_payload_write_parameter_ignore_e].values.used / 2, &setting->ignores); + + if (F_status_is_error(setting->status)) { + fss_payload_write_print_error(setting, main->error, "f_string_ranges_increase_by"); + + return; + } + + f_array_length_t index = 0; + + for (f_array_length_t i = 0; i < main->parameters.array[fss_payload_write_parameter_ignore_e].values.used; i += 2) { + + index = main->parameters.array[fss_payload_write_parameter_ignore_e].values.array[i]; + + setting->status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, main->parameters.arguments.array[index], &setting->ignores.array[setting->ignores.used].start); + + if (F_status_is_error(setting->status)) { + fss_payload_write_print_line_first_locked(setting, main->error); + fll_program_print_error_parameter_integer_not(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, main->parameters.arguments.array[index]); + fss_payload_write_print_line_last_locked(setting, main->error); + + return; + } + + index = main->parameters.array[fss_payload_write_parameter_ignore_e].values.array[i + 1]; + + setting->status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, main->parameters.arguments.array[index], &setting->ignores.array[setting->ignores.used].stop); + + if (F_status_is_error(setting->status)) { + fss_payload_write_print_line_first_locked(setting, main->error); + fll_program_print_error_parameter_integer_not(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, main->parameters.arguments.array[index]); + fss_payload_write_print_line_last_locked(setting, main->error); + + return; + } + + if (setting->ignores.array[setting->ignores.used].stop > setting->ignores.array[setting->ignores.used].start) { + setting->status = F_status_set_error(F_parameter); + + fss_payload_write_print_line_first_locked(setting, main->error); + fll_program_print_error_parameter_range_start_before_stop(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, main->parameters.arguments.array[main->parameters.array[fss_payload_write_parameter_ignore_e].values.array[i]], main->parameters.arguments.array[index]); + fss_payload_write_print_line_last_locked(setting, main->error); + + return; + } + + ++setting->ignores.used; + } // for + + setting->flag |= fss_payload_write_main_flag_ignore_e; + } + else if (main->parameters.array[fss_payload_write_parameter_ignore_e].result == f_console_result_found_e) { + setting->status = F_status_set_error(F_parameter); + + fss_payload_write_print_line_first_locked(setting, main->error); + fll_program_print_error_parameter_missing_value(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s); + fss_payload_write_print_line_last_locked(setting, main->error); + + return; + } + if (main->parameters.array[fss_payload_write_parameter_partial_e].result == f_console_result_found_e) { setting->flag |= fss_payload_write_main_flag_partial_e; } @@ -307,7 +388,7 @@ extern "C" { setting->status = F_status_set_error(F_parameter); fss_payload_write_print_line_first_locked(setting, main->error); - fss_payload_write_error_parameter_value_missing_print(main, f_console_symbol_long_enable_s, fss_payload_write_long_object_s); + fll_program_print_error_parameter_missing_value(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_object_s); fss_payload_write_print_line_last_locked(setting, main->error); return; @@ -317,7 +398,7 @@ extern "C" { setting->status = F_status_set_error(F_parameter); fss_payload_write_print_line_first_locked(setting, main->error); - fss_payload_write_error_parameter_value_missing_print(main, f_console_symbol_long_enable_s, fss_payload_write_long_content_s); + fll_program_print_error_parameter_missing_value(main->error, f_console_symbol_long_enable_s, fss_payload_write_long_content_s); fss_payload_write_print_line_last_locked(setting, main->error); return; @@ -327,7 +408,7 @@ extern "C" { setting->status = F_status_set_error(F_parameter); fss_payload_write_print_line_first_locked(setting, main->error); - fss_payload_write_error_parameter_same_times_print(main); + fll_program_print_error_parameter_both_specified_same_amount_without(main->error, f_console_symbol_long_enable_s, f_console_symbol_long_enable_s, f_console_symbol_long_enable_s, fss_payload_write_long_object_s, fss_payload_write_long_content_s, fss_payload_write_long_partial_s); fss_payload_write_print_line_last_locked(setting, main->error); return; @@ -372,36 +453,24 @@ extern "C" { } } - setting->quote = f_iki_syntax_quote_double_s; + setting->quote = f_fss_quote_double_s; if (main->parameters.array[fss_payload_write_parameter_double_e].result == f_console_result_found_e) { if (main->parameters.array[fss_payload_write_parameter_single_e].result == f_console_result_found_e) { if (main->parameters.array[fss_payload_write_parameter_double_e].location < main->parameters.array[fss_payload_write_parameter_single_e].location) { - setting->quote = f_iki_syntax_quote_single_s; + setting->quote = f_fss_quote_single_s; } } } else if (main->parameters.array[fss_payload_write_parameter_single_e].result == f_console_result_found_e) { - setting->quote = f_iki_syntax_quote_single_s; + setting->quote = f_fss_quote_single_s; } if (main->parameters.array[fss_payload_write_parameter_trim_e].result == f_console_result_found_e) { setting->flag |= fss_payload_write_main_flag_trim_e; } - if (main->pipe & fll_program_data_pipe_input_e) { - // @fixme why is this not allowed? - if (setting->flag & fss_payload_write_main_flag_partial_e) { - setting->status = F_status_set_error(F_parameter); - - fss_payload_write_print_line_first_locked(setting, main->error); - fll_program_print_error_parameter_cannot_use_with_pipe(setting, main->error); - fss_payload_write_print_line_last_locked(setting, main->error); - - return; - } - } - else if (!(setting->flag & (fss_payload_write_main_flag_content_e | fss_payload_write_parameter_object_e))) { + if (!(setting->flag & (fll_program_data_pipe_input_e | fss_payload_write_main_flag_content_e | fss_payload_write_parameter_object_e))) { setting->status = F_data_not; } } diff --git a/level_3/fss_payload_write/c/common.h b/level_3/fss_payload_write/c/common.h index a22a4a0..8d62e02 100644 --- a/level_3/fss_payload_write/c/common.h +++ b/level_3/fss_payload_write/c/common.h @@ -61,10 +61,17 @@ extern "C" { /** * The program defines. + * + * payload_write_common_allocation_*: + * - large: An allocation step used for buffers that are anticipated to have large buffers. + * - small: An allocation step used for buffers that are anticipated to have small buffers. */ #ifndef _di_fss_payload_write_defines_ #define fss_payload_write_signal_check_d 20000 + #define fss_payload_write_common_allocation_large_d 2048 + #define fss_payload_write_common_allocation_small_d 128 + #define FSS_PAYLOAD_WRITE_pipe_content_end_s "\f" #define FSS_PAYLOAD_WRITE_pipe_content_ignore_s "\v" #define FSS_PAYLOAD_WRITE_pipe_content_start_s "\b" @@ -79,6 +86,17 @@ extern "C" { #endif // _di_fss_payload_write_defines_ /** + * A collection of static strings associated with FSS Payload Write. + */ +#ifndef _di_fss_payload_write_strings_ + #define FSS_PAYLOAD_WRITE_string_two_s "two" + + #define FSS_PAYLOAD_WRITE_string_two_s_length 3 + + extern const f_string_static_t fss_payload_write_string_two_s; +#endif // _di_fss_payload_write_strings_ + +/** * The main program parameters. */ #ifndef _di_fss_payload_write_parameters_ @@ -240,17 +258,22 @@ extern "C" { * * status: The main status code, generally used by the load settings and main functions. * + * state: The state data used when processing the FSS data. + * range: A range used as a buffer during processing. + * * line_first: A string expected to represent either "\n" or NULL to allow for easy handling of when to print first new line or not. * line_last: A string expected to represent either "\n" or NULL to allow for easy handling of when to print last new line or not. * * quote: This holds the quote used during processing. * * escaped: A buffer used for escaping strings during processing. + * block: A buffer used to storing one or more blocks while processing a file line by line. * buffer: A buffer used during processing the file. * object: A buffer used to hold an Object during processing. * content: A buffer used to hold a Content during processing. * prepend: A string to prepend to each multi-line Content. * + * ignores: An array of ranges passed as values to the "--ignore" parameter. * objects: An array of objects passed as values to the "--object" parameter. * contents: An array of objects passed as values to the "--content" parameter and must match the length of objects. */ @@ -260,17 +283,22 @@ extern "C" { f_status_t status; + f_state_t state; + f_string_range_t range; + f_string_static_t line_first; f_string_static_t line_last; f_string_static_t quote; f_string_dynamic_t escaped; + f_string_dynamic_t block; f_string_dynamic_t buffer; f_string_dynamic_t object; f_string_dynamic_t content; f_string_dynamic_t prepend; + f_string_ranges_t ignores; f_string_dynamics_t objects; f_string_dynamics_t contents; } fss_payload_write_setting_t; @@ -279,6 +307,8 @@ extern "C" { { \ fss_payload_write_main_flag_none_e, \ F_none, \ + macro_f_state_t_initialize(fss_payload_write_common_allocation_large_d, fss_payload_write_common_allocation_small_d, 0, 0, &fll_program_standard_signal_state, 0, 0, 0), \ + f_string_range_t_initialize, \ f_string_static_t_initialize, \ f_string_static_t_initialize, \ f_string_dynamic_t_initialize, \ @@ -286,6 +316,8 @@ extern "C" { f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_ranges_t_initialize, \ f_string_dynamics_t_initialize, \ f_string_dynamics_t_initialize, \ } diff --git a/level_3/fss_payload_write/c/fss_payload_write.c b/level_3/fss_payload_write/c/fss_payload_write.c index 0e5c0f7..cd806aa 100644 --- a/level_3/fss_payload_write/c/fss_payload_write.c +++ b/level_3/fss_payload_write/c/fss_payload_write.c @@ -28,374 +28,54 @@ extern "C" { setting->escaped.used = 0; if (main->pipe & fll_program_data_pipe_input_e) { - bool object_ended = F_false; - - f_array_length_t previous = 0; - f_string_range_t range = f_string_range_t_initialize; - f_status_t status = F_none; - f_file_t pipe = f_file_t_initialize; - - pipe.id = F_type_descriptor_input_d; - pipe.size_read = 1; - - setting->buffer.used = 0; - setting->object.used = 0; - setting->content.used = 0; - - range.start = 0; - - do { - if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { - if (fll_program_standard_signal_received(main)) { - setting->status = F_status_set_error(F_interrupt); - - return; - } - - main->signal_check = 0; - } - - if (status != F_none_eof) { - status = f_file_read(pipe, &setting->buffer); - - if (F_status_is_error(status)) { - setting->status = F_status_set_error(F_pipe); - - fss_payload_write_print_error_file(setting, main->error, "f_file_read", f_string_ascii_minus_s, f_file_operation_read_s, fll_error_file_type_pipe_e); - - return; - } - - if (!setting->buffer.used) { - setting->status = F_status_set_error(F_parameter); - - fss_payload_write_print_line_first_locked(setting, main->error); - fll_program_print_error_pipe_missing_content(main->error); - fss_payload_write_print_line_last_locked(setting, main->error); - - return; - } - - range.stop = setting->buffer.used - 1; - } - - previous = range.start; - setting->status = f_string_dynamic_seek_to(setting->buffer, f_string_ascii_feed_form_s.string[0], &range); - - if (setting->status == F_data_not_stop) { - setting->status = F_status_set_error(F_parameter); - } - - if (F_status_is_error(setting->status)) { - fss_payload_write_print_error(setting, main->error, "f_string_dynamic_seek_to"); - - return; - } - - if (object_ended && previous == range.start) { - setting->status = F_status_set_error(F_parameter); - - fss_payload_write_print_line_first_locked(setting, main->error); - fll_program_print_error_pipe_invalid_form_feed(main->error); - fss_payload_write_print_line_last_locked(setting, main->error); - - return; - } - - range.stop = range.start - 1; - range.start = previous; - - if (object_ended) { - setting->content.used = 0; - - if (setting->buffer.used) { - setting->status = f_string_dynamic_partial_append_nulless(setting->buffer, range, &setting->content); - - if (F_status_is_error(setting->status)) { - fss_payload_write_print_error(setting, main->error, "f_string_dynamic_partial_append_nulless"); - - return; - } - } - - setting->status = fss_payload_write_process(main, setting, setting->object, setting->content); - if (F_status_is_error(setting->status)) return; - - fll_print_dynamic_raw(f_string_eol_s, main->output.to); - - object_ended = F_false; - } - else { - setting->object.used = 0; - - setting->status = f_string_dynamic_partial_append_nulless(setting->buffer, range, &setting->object); - - if (F_status_is_error(setting->status)) { - fss_payload_write_print_error(setting, main->error, "f_string_dynamic_partial_append_nulless"); - - return; - } - - object_ended = F_true; - } - - // Restore the range, positioned after the new line. - range.start = range.stop + 2; - range.stop = setting->buffer.used - 1; - - // Only clear the buffer and reset the start when the entire buffer has been processed. - if (range.start > range.stop) { - range.start = 0; - setting->buffer.used = 0; - } - - } while (status != F_none_eof || setting->buffer.used || object_ended); - - if (object_ended) { - setting->status = F_status_set_error(F_parameter); - - fss_payload_write_print_line_first_locked(setting, main->error); - fll_program_print_error_pipe_object_without_content(main->error); - fss_payload_write_print_line_last_locked(setting, main->error); - - return; - } - } - - for (f_array_length_t i = 0; i < setting->objects.used; ++i) { - - if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { - if (fll_program_standard_signal_received(main)) { - setting->status = F_status_set_error(F_interrupt); - - return; - } - - main->signal_check = 0; - } - - setting->status = fss_payload_write_process(main, setting, setting->objects.array[i], setting->contents.array[i]); + fss_payload_write_process_pipe(main, setting); if (F_status_is_error(setting->status)) return; - fll_print_dynamic_raw(f_string_eol_s, main->output.to); - } // for - - // Ensure a new line is always put at the end of the program execution, unless in quiet mode. - fss_payload_write_print_line_last_locked(setting, main->message); - - - // xxxxxxxxxxx - - if (F_status_is_error_not(status)) { - if (main->parameters.array[fss_payload_write_parameter_prepend_e].result == f_console_result_additional_e) { - const f_array_length_t index = main->parameters.array[fss_payload_write_parameter_prepend_e].values.array[main->parameters.array[fss_payload_write_parameter_prepend_e].values.used - 1]; - - if (argv[index].used) { - f_string_range_t range = macro_f_string_range_t_initialize2(argv[index].used); - f_state_t state = f_state_t_initialize; - - for (; range.start < argv[index].used; range.start++) { - - status = f_fss_is_space(state, argv[index], range); - if (F_status_is_error(status)) break; - - if (status == F_false) { - if (main->error.verbosity > f_console_verbosity_quiet_e) { - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe value for the parameter '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_prepend_s, main->error.notable); - fl_print_format("%[' must only contain white space.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - } - - status = F_status_set_error(F_parameter); - - break; - } - } // for - } - else { - if (main->error.verbosity > f_console_verbosity_quiet_e) { - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe value for the parameter '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_prepend_s, main->error.notable); - fl_print_format("%[' must not be an empty string.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - } - - status = F_status_set_error(F_parameter); - } - } - } - - if (F_status_is_error_not(status)) { - if (main->parameters.array[fss_payload_write_parameter_ignore_e].result == f_console_result_found_e) { - if (main->error.verbosity > f_console_verbosity_quiet_e) { - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe parameter '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, main->error.notable); - fl_print_format("%[' was specified, but no values were given.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); + // Print newline character to separate data printed from pipe. + if (setting->status == F_none) { + if ((setting->flag & fss_payload_write_main_flag_partial_e) && setting->objects.used) { + fll_print_dynamic(f_string_eol_s, main->output.to); } - - status = F_status_set_error(F_parameter); - } - else if (main->parameters.array[fss_payload_write_parameter_ignore_e].result == f_console_result_additional_e) { - const f_array_length_t total_locations = main->parameters.array[fss_payload_write_parameter_ignore_e].locations.used; - const f_array_length_t total_arguments = main->parameters.array[fss_payload_write_parameter_ignore_e].values.used; - - if (total_locations * 2 > total_arguments) { - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe parameter '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_ignore_s, main->error.notable); - fl_print_format("%[' requires two values.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - - status = F_status_set_error(F_parameter); + else if (setting->contents.used) { + fll_print_dynamic(f_fss_payload_header_close_s, main->output.to); } } } - f_fss_quote_t quote = f_fss_quote_type_double_e; - - if (F_status_is_error_not(status)) { - if (main->parameters.array[fss_payload_write_parameter_double_e].result == f_console_result_found_e) { - if (main->parameters.array[fss_payload_write_parameter_single_e].result == f_console_result_found_e) { - if (main->parameters.array[fss_payload_write_parameter_double_e].location < main->parameters.array[fss_payload_write_parameter_single_e].location) { - quote = f_fss_quote_type_single_e; - } - } - } - else if (main->parameters.array[fss_payload_write_parameter_single_e].result == f_console_result_found_e) { - quote = f_fss_quote_type_single_e; - } - } - - f_string_dynamic_t buffer = f_string_dynamic_t_initialize; - - if (F_status_is_error_not(status)) { - f_string_dynamic_t escaped = f_string_dynamic_t_initialize; - - if (main->pipe & fll_program_data_pipe_input_e) { - status = fss_payload_write_process_pipe(main, output, quote, &buffer); - - if (F_status_is_error(status)) { - if (main->error.verbosity > f_console_verbosity_quiet_e) { - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QWhile processing the '%]%[input pipe%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context, main->error.notable, main->error.notable); - fl_print_format("%['.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); + if (setting->flag & (fss_payload_write_main_flag_object_e | fss_payload_write_main_flag_content_e)) { + f_string_statics_t *objects = &setting->objects; + f_string_statics_t *contents = &setting->contents; + f_string_statics_t *data = &setting->objects; - f_file_stream_unlock(main->error.to); - } - } - } - - if (F_status_is_error_not(status)) { - if (main->parameters.array[fss_payload_write_parameter_partial_e].result == f_console_result_found_e) { - - if (main->parameters.array[fss_payload_write_parameter_object_e].result == f_console_result_additional_e) { - for (f_array_length_t i = 0; i < main->parameters.array[fss_payload_write_parameter_object_e].values.used; ++i) { - - if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { - if (fll_program_standard_signal_received(main)) { - fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received); - - status = F_status_set_error(F_interrupt); - - break; - } - - main->signal_check = 0; - } - - status = fss_payload_write_process(main, output, quote, &argv[main->parameters.array[fss_payload_write_parameter_object_e].values.array[i]], 0, &buffer); - if (F_status_is_error(status)) break; - } // for - } - else { - for (f_array_length_t i = 0; i < main->parameters.array[fss_payload_write_parameter_content_e].values.used; ++i) { - - if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { - if (fll_program_standard_signal_received(main)) { - fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received); - - status = F_status_set_error(F_interrupt); - - break; - } - - main->signal_check = 0; - } - - status = fss_payload_write_process(main, output, quote, 0, &argv[main->parameters.array[fss_payload_write_parameter_content_e].values.array[i]], &buffer); - if (F_status_is_error(status)) break; - } // for - } + if (setting->flag & fss_payload_write_main_flag_partial_e) { + if (setting->flag & fss_payload_write_main_flag_content_e) { + data = &setting->contents; + objects = 0; } else { - for (f_array_length_t i = 0; i < main->parameters.array[fss_payload_write_parameter_object_e].values.used; ++i) { - - if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { - if (fll_program_standard_signal_received(main)) { - fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received); - - status = F_status_set_error(F_interrupt); - - break; - } - - main->signal_check = 0; - } - - status = fss_payload_write_process(main, output, quote, &argv[main->parameters.array[fss_payload_write_parameter_object_e].values.array[i]], &argv[main->parameters.array[fss_payload_write_parameter_content_e].values.array[i]], &buffer); - if (F_status_is_error(status)) break; - } // for + contents = 0; } + } - if (F_status_is_error(status)) { - if (main->error.verbosity > f_console_verbosity_quiet_e) { - f_file_stream_lock(main->error.to); + for (f_array_length_t i = 0; i < data->used; ++i) { - fl_print_format("%r%[%QWhile processing the '%]%[input arguments%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context, main->error.notable, main->error.notable); - fl_print_format("%['.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); + if (!((++main->signal_check) % fss_payload_write_signal_check_d)) { + if (fll_program_standard_signal_received(main)) { + setting->status = F_status_set_error(F_interrupt); - f_file_stream_unlock(main->error.to); + return; } - } - else if (main->error.verbosity > f_console_verbosity_quiet_e && main->error.verbosity != f_console_verbosity_error_e && main->parameters.array[fss_payload_write_parameter_file_e].result == f_console_result_none_e) { - // Ensure there is always a newline at the end, unless in quiet mode. - fll_print_dynamic_raw(f_string_eol_s, main->output.to); + main->signal_check = 0; } - } - - f_string_dynamic_resize(0, &escaped); - } - if (main->parameters.array[fss_payload_write_parameter_file_e].result == f_console_result_additional_e) { - f_file_stream_flush(output); - f_file_stream_close(&output); + fss_payload_write_process(main, setting, objects ? &objects->array[i] : 0, contents ? &contents->array[i] : 0); + if (F_status_is_error(setting->status)) return; + } // for } - // Ensure a newline is always put at the end of the program execution, unless in quiet mode. - if (main->error.verbosity > f_console_verbosity_quiet_e) { - if (F_status_is_error(status)) { - fll_print_dynamic_raw(f_string_eol_s, main->error.to); - } - } - - f_string_dynamic_resize(0, &buffer); - - return status; + // Ensure a new line is always put at the end of the program execution, unless in quiet mode. + fss_payload_write_print_line_last_locked(setting, main->message); } #endif // _di_fss_payload_write_main_ diff --git a/level_3/fss_payload_write/c/fss_payload_write.h b/level_3/fss_payload_write/c/fss_payload_write.h index 3ddecee..00c3ae0 100644 --- a/level_3/fss_payload_write/c/fss_payload_write.h +++ b/level_3/fss_payload_write/c/fss_payload_write.h @@ -24,12 +24,14 @@ #include #include #include +#include #include #include #include #include // FLL-1 includes. +#include #include #include #include diff --git a/level_3/fss_payload_write/c/main.c b/level_3/fss_payload_write/c/main.c index e964989..566c938 100644 --- a/level_3/fss_payload_write/c/main.c +++ b/level_3/fss_payload_write/c/main.c @@ -4,6 +4,7 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { fll_program_data_t data = fll_program_data_t_initialize; fss_payload_write_setting_t setting = fss_payload_write_setting_t_initialize; + setting.state.data = (void *) &data; f_console_parameter_t parameters[] = fss_payload_write_console_parameter_t_initialize; data.parameters.array = parameters; @@ -30,5 +31,5 @@ int main(const int argc, const f_string_t *argv, const f_string_t *envp) { fll_program_standard_set_down(&data); - return F_status_is_error(status) ? 1 : 0; + return F_status_is_error(setting.status) ? 1 : 0; } diff --git a/level_3/fss_payload_write/c/print.c b/level_3/fss_payload_write/c/print.c index bf6343c..609e78c 100644 --- a/level_3/fss_payload_write/c/print.c +++ b/level_3/fss_payload_write/c/print.c @@ -50,6 +50,17 @@ extern "C" { } #endif // _di_fss_payload_write_print_error_object_not_before_content_ +#ifndef _di_fss_payload_write_print_error_one_content_only_ + f_status_t fss_payload_write_print_error_one_content_only(fss_payload_write_setting_t * const setting, const fl_print_t print) { + + if (print.verbosity == f_console_verbosity_quiet_e) return F_output_not; + + fll_print_format("%r%[%QThe FSS-000E (Payload) standard only supports one content per object.%]%r", print.to, f_string_eol_s, print.set->error, print.prefix, print.set->error, f_string_eol_s); + + return F_none; + } +#endif // _di_fss_payload_write_print_error_one_content_only_ + #ifndef _fss_payload_write_print_error_prepend_only_whitespace_ f_status_t fss_payload_write_print_error_prepend_only_whitespace(fss_payload_write_setting_t * const setting, const fl_print_t print) { @@ -67,6 +78,25 @@ extern "C" { } #endif // _fss_payload_write_print_error_prepend_only_whitespace_ +#ifndef _di_fss_payload_write_print_error_unsupported_eol_ + f_status_t fss_payload_write_print_error_unsupported_eol(fss_payload_write_setting_t * const setting, const fl_print_t print) { + + if (print.verbosity == f_console_verbosity_quiet_e) return F_output_not; + + f_file_stream_lock(print.to); + + fl_print_format("%r%[%QThe FSS-000E (Payload) standard does not support end of line character '%]", print.to, f_string_eol_s, print.set->error, print.prefix, print.set->error); + fl_print_format("%[\\n%]", print.to, print.set->notable, print.set->notable); + fl_print_format("%[' (%]", print.to, print.set->error, print.set->error); + fl_print_format("%[U+000A%]", print.to, print.set->notable, print.set->notable); + fl_print_format("%[) in objects.%]%r", print.to, print.set->error, print.set->error, f_string_eol_s); + + f_file_stream_unlock(print.to); + + return F_none; + } +#endif // _di_fss_payload_write_print_error_unsupported_eol_ + #ifndef _di_fss_payload_write_print_help_ f_status_t fss_payload_write_print_help(fss_payload_write_setting_t * const setting, const fl_print_t print) { @@ -154,7 +184,7 @@ extern "C" { if (!F_status_is_error(setting->status)) { if (print.verbosity == f_console_verbosity_error_e) return F_output_not; - if (setting->flag & (fss_payload_write_main_flag_verify_e | fss_payload_write_main_flag_file_to_e)) return F_output_not; + if (setting->flag & fss_payload_write_main_flag_file_to_e) return F_output_not; } fll_print_dynamic_raw(setting->line_last, print.to); @@ -170,7 +200,7 @@ extern "C" { if (!F_status_is_error(setting->status)) { if (print.verbosity == f_console_verbosity_error_e) return F_output_not; - if (setting->flag & (fss_payload_write_main_flag_verify_e | fss_payload_write_main_flag_file_to_e)) return F_output_not; + if (setting->flag & fss_payload_write_main_flag_file_to_e) return F_output_not; } f_print_dynamic_raw(setting->line_last, print.to); diff --git a/level_3/fss_payload_write/c/print.h b/level_3/fss_payload_write/c/print.h index 7f42181..3cc0ccf 100644 --- a/level_3/fss_payload_write/c/print.h +++ b/level_3/fss_payload_write/c/print.h @@ -80,6 +80,24 @@ extern "C" { #endif // _di_fss_payload_write_print_error_object_not_before_content_ /** + * Print an message about a multiple Content being unsupported. + * + * @param setting + * The main program settings. + * + * This does not alter setting.status. + * @param print + * Designates the how and where to print. + * + * @return + * F_none on success. + * F_output_not on success, but no printing is performed. + */ +#ifndef _di_fss_payload_write_print_error_one_content_only_ + extern f_status_t fss_payload_write_print_error_one_content_only(fss_payload_write_setting_t * const setting, const fl_print_t print); +#endif // _di_fss_payload_write_print_error_one_content_only_ + +/** * Print error when prepend parameter has something other than white space. * * @param setting @@ -98,6 +116,24 @@ extern "C" { #endif // _fss_payload_write_print_error_prepend_only_whitespace_ /** + * Print an message about a parameter New Line character '\n' (U+000A) being unsupported. + * + * @param setting + * The main program settings. + * + * This does not alter setting.status. + * @param print + * Designates the how and where to print. + * + * @return + * F_none on success. + * F_output_not on success, but no printing is performed. + */ +#ifndef _di_fss_payload_write_print_error_unsupported_eol_ + extern f_status_t fss_payload_write_print_error_unsupported_eol(fss_payload_write_setting_t * const setting, const fl_print_t print); +#endif // _di_fss_payload_write_print_error_unsupported_eol_ + +/** * Print help. * * @param setting diff --git a/level_3/fss_payload_write/c/private-common.h b/level_3/fss_payload_write/c/private-common.h index 1262946..f6a495d 100644 --- a/level_3/fss_payload_write/c/private-common.h +++ b/level_3/fss_payload_write/c/private-common.h @@ -12,18 +12,6 @@ extern "C" { #endif -/** - * Provide common/generic definitions. - * - * payload_write_common_allocation_*: - * - large: An allocation step used for buffers that are anticipated to have large buffers. - * - small: An allocation step used for buffers that are anticipated to have small buffers. - */ -#ifndef _di_fss_payload_write_common_ - #define fss_payload_write_common_allocation_large_d 2048 - #define fss_payload_write_common_allocation_small_d 128 -#endif // _di_fss_payload_write_common_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/fss_payload_write/c/private-write.c b/level_3/fss_payload_write/c/private-write.c index e847547..a5c3b3b 100644 --- a/level_3/fss_payload_write/c/private-write.c +++ b/level_3/fss_payload_write/c/private-write.c @@ -6,113 +6,48 @@ extern "C" { #endif -#ifndef _di_fss_payload_write_error_parameter_same_times_print_ - void fss_payload_write_error_parameter_same_times_print(fll_program_data_t * const main) { - - if (main->error.verbosity == f_console_verbosity_quiet_e) return; - - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QMust specify the '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_object_s, main->error.notable); - fl_print_format("%[' parameter and the '%]", main->error.to, main->error.context, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_content_s, main->error.notable); - fl_print_format("%[' parameter the same number of times when not specifying the '%]", main->error.to, main->error.context, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, f_console_symbol_long_enable_s, fss_payload_write_long_partial_s, main->error.notable); - fl_print_format("%[' parameter.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - } -#endif // _di_fss_payload_write_error_parameter_same_times_print_ - -#ifndef _di_fss_payload_write_error_parameter_unsupported_eol_print_ - void fss_payload_write_error_parameter_unsupported_eol_print(fll_program_data_t * const main) { - - if (main->error.verbosity == f_console_verbosity_quiet_e) return; - - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe FSS-000E (Payload) standard does not support end of line character '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[\\n%]", main->error.to, main->error.notable, main->error.notable); - fl_print_format("%[' (%]", main->error.to, main->error.context, main->error.context); - fl_print_format("%[U+000A%]", main->error.to, main->error.notable, main->error.notable); - fl_print_format("%[) in objects.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - } -#endif // _di_fss_payload_write_error_parameter_unsupported_eol_print_ - -#ifndef _di_fss_payload_write_error_parameter_value_missing_print_ - void fss_payload_write_error_parameter_value_missing_print(fll_program_data_t * const main, const f_string_static_t symbol, const f_string_static_t parameter) { - - if (main->error.verbosity == f_console_verbosity_quiet_e) return; - - f_file_stream_lock(main->error.to); - - fl_print_format("%r%[%QThe parameter '%]", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%r%r%]", main->error.to, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' is specified, but no value is given.%]%r", main->error.to, main->error.context, main->error.context, f_string_eol_s); - - f_file_stream_unlock(main->error.to); - } -#endif // _di_fss_payload_write_error_parameter_value_missing_print_ - #ifndef _di_fss_payload_write_process_ - f_status_t fss_payload_write_process(fll_program_data_t * const main, 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_status_t status = F_none; - f_state_t state = macro_f_state_t_initialize(fss_payload_write_common_allocation_large_d, fss_payload_write_common_allocation_small_d, 0, 0, &fll_program_standard_signal_state, 0, (void *) main, 0); - f_string_range_t range = f_string_range_t_initialize; + void fss_payload_write_process(fll_program_data_t * const main, fss_payload_write_setting_t * const setting, const f_string_static_t *object, const f_string_static_t *content) { if (object) { if (content) { - bool trim = F_false; - - if (main->parameters.array[fss_payload_write_parameter_trim_e].result == f_console_result_found_e) { - trim = F_true; - } - if (object->used) { - range.start = 0; - range.stop = object->used - 1; + setting->range.start = 0; + setting->range.stop = object->used - 1; } else { - range.start = 1; - range.stop = 0; + setting->range.start = 1; + setting->range.stop = 0; } - const f_string_static_t *prepend = 0; + setting->status = fll_fss_payload_write(*object, *content, setting->flag & fss_payload_write_main_flag_trim_e, setting->flag & fss_payload_write_main_flag_prepend_e ? &setting->prepend : 0, setting->state, &setting->buffer); - if (main->parameters.array[fss_payload_write_parameter_prepend_e].result == f_console_result_additional_e) { - const f_array_length_t index = main->parameters.array[fss_payload_write_parameter_prepend_e].values.array[main->parameters.array[fss_payload_write_parameter_prepend_e].values.used - 1]; - - prepend = &main->parameters.arguments.array[index]; - } + if (F_status_set_fine(setting->status) == F_none_eol) { + setting->status = F_status_set_error(F_supported_not); - status = fll_fss_payload_write(*object, *content, trim, prepend, state, buffer); + fss_payload_write_print_line_first_locked(setting, main->error); + fss_payload_write_print_error_unsupported_eol(setting, main->error); + fss_payload_write_print_line_last_locked(setting, main->error); - if (F_status_set_fine(status) == F_none_eol) { - fss_payload_write_error_parameter_unsupported_eol_print(main); - - return F_status_set_error(F_supported_not); + return; } - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "fll_fss_payload_write"); - return status; + return; } } else { - uint8_t complete = f_fss_complete_none_e; + bool complete = f_fss_complete_none_e; if (object->used) { - range.start = 0; - range.stop = object->used - 1; + setting->range.start = 0; + setting->range.stop = object->used - 1; } else { - range.start = 1; - range.stop = 0; + setting->range.start = 1; + setting->range.stop = 0; } if (content) { @@ -124,79 +59,82 @@ extern "C" { } } - status = fl_fss_basic_list_object_write(*object, complete, state, &range, buffer); + setting->status = fl_fss_basic_list_object_write(*object, complete, setting->state, &setting->range, &setting->buffer); + + if (F_status_set_fine(setting->status) == F_none_eol) { + setting->status = F_status_set_error(F_supported_not); - if (F_status_set_fine(status) == F_none_eol) { - fss_payload_write_error_parameter_unsupported_eol_print(main); + fss_payload_write_print_line_first_locked(setting, main->error); + fss_payload_write_print_error_unsupported_eol(setting, main->error); + fss_payload_write_print_line_last_locked(setting, main->error); - return F_status_set_error(F_supported_not); + return; } - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "fl_fss_basic_list_object_write"); - return status; + return; } } } - else { - if (content && content->used) { - range.start = 0; - range.stop = content->used - 1; + else if (content && content->used) { + setting->range.start = 0; + setting->range.stop = content->used - 1; - const f_string_static_t *prepend = 0; + const f_string_static_t *prepend = 0; - if (main->parameters.array[fss_payload_write_parameter_prepend_e].result == f_console_result_additional_e) { - const f_array_length_t index = main->parameters.array[fss_payload_write_parameter_prepend_e].values.array[main->parameters.array[fss_payload_write_parameter_prepend_e].values.used - 1]; + if (setting->flag & fss_payload_write_main_flag_prepend_e) { + const f_array_length_t index = main->parameters.array[fss_payload_write_parameter_prepend_e].values.array[main->parameters.array[fss_payload_write_parameter_prepend_e].values.used - 1]; - prepend = &main->parameters.arguments.array[index]; - } + prepend = &main->parameters.arguments.array[index]; + } - status = fl_fss_basic_list_content_write(*content, object ? f_fss_complete_full_e : f_fss_complete_none_e, prepend, state, &range, buffer); + setting->status = fl_fss_basic_list_content_write(*content, object ? f_fss_complete_full_e : f_fss_complete_none_e, prepend, setting->state, &setting->range, &setting->buffer); - if (F_status_is_error(status)) { - fss_payload_write_print_error(setting, main->error, "fl_fss_payload_content_write"); + if (F_status_is_error(setting->status)) { + fss_payload_write_print_error(setting, main->error, "fl_fss_payload_content_write"); - return status; - } + return; } } if (!object || !content) { - status = f_string_dynamic_append(f_string_eol_s, buffer); + setting->status = f_string_dynamic_append(f_string_eol_s, &setting->buffer); - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "f_string_dynamic_append"); - return status; + return; } } - fll_print_dynamic(*buffer, output); + fll_print_dynamic(setting->buffer, main->output.to); - buffer->used = 0; - - return status; + setting->buffer.used = 0; + setting->status = F_none; } #endif // _di_fss_payload_write_process_ +#ifndef _di_fss_payload_write_process_parameters_ + void fss_payload_write_process_parameters(fll_program_data_t * const main, fss_payload_write_setting_t * const setting) { + } +#endif // _di_fss_payload_write_process_parameters_ + #ifndef _di_fss_payload_write_process_pipe_ - f_status_t fss_payload_write_process_pipe(fll_program_data_t * const main, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) { + void fss_payload_write_process_pipe(fll_program_data_t * const main, fss_payload_write_setting_t * const setting) { - f_status_t status = F_none; f_status_t status_pipe = F_none; - f_file_t input = f_file_t_initialize; - input.id = F_type_descriptor_input_d; - input.size_read = 2048; + input.size_read = fss_payload_write_common_allocation_large_d; f_array_length_t total = 0; + f_array_length_t length = 0; f_string_range_t range = 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; - f_string_dynamic_t content = f_string_dynamic_t_initialize; + // 0x0 = nothing printed, 0x1 = something printed, 0x2 = "payload" matched. + uint8_t printed = 0; // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set, 0x4 = processing payload content. uint8_t state = 0; @@ -207,7 +145,7 @@ extern "C" { if (fll_program_standard_signal_received(main)) { fll_program_print_signal_received(main->warning, setting->line_first, main->signal_received); - status = F_status_set_error(F_interrupt); + setting->status = F_status_set_error(F_interrupt); break; } @@ -218,9 +156,9 @@ extern "C" { if (range.start > range.stop) { if (status_pipe == F_none_eof) break; - block.used = 0; + setting->block.used = 0; - status_pipe = f_file_read_block(input, &block); + status_pipe = f_file_read_block(input, &setting->block); if (F_status_is_error(status_pipe)) { fss_payload_write_print_error(setting, main->error, "f_file_read_block"); @@ -230,24 +168,24 @@ extern "C" { break; } - if (!block.used) break; + if (!setting->block.used) break; range.start = 0; - range.stop = block.used - 1; + range.stop = setting->block.used - 1; } if (!state || state == 0x1) { if (!state) { - object.used = 0; - content.used = 0; + setting->object.used = 0; + setting->content.used = 0; state = 0x1; } - if (object.used + block.used > object.size) { - status = f_string_dynamic_increase_by(block.used, &object); + if (setting->object.used + setting->block.used > setting->object.size) { + setting->status = f_string_dynamic_increase_by(setting->block.used, &setting->object); - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "f_string_dynamic_increase_by"); break; @@ -256,30 +194,30 @@ extern "C" { for (; range.start <= range.stop; ++range.start) { - if (block.string[range.start] == fss_payload_write_pipe_content_start_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_start_s.string[0]) { state = 0x2; ++range.start; break; } - if (block.string[range.start] == fss_payload_write_pipe_content_end_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_end_s.string[0]) { state = 0x3; ++range.start; break; } - if (block.string[range.start] == fss_payload_write_pipe_content_ignore_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_ignore_s.string[0]) { // This is not used by objects. continue; } - object.string[object.used++] = block.string[range.start]; + setting->object.string[setting->object.used++] = setting->block.string[range.start]; } // for - if (F_status_is_error(status)) break; + if (F_status_is_error(setting->status)) break; // If the start of content was not found, then fetch the next block. if (state == 0x1) continue; @@ -297,27 +235,23 @@ extern "C" { } // When payload is provided, all data at this point is part of the payload until the end of the pipe. - if (fl_string_dynamic_compare(f_fss_string_payload_s, object) == F_equal_to) { + if (fl_string_dynamic_compare(f_fss_string_payload_s, setting->object) == F_equal_to) { if (total > 1) { + setting->status = f_string_dynamic_increase_by(total, &setting->content); - // The first character is the terminating new line, which is not part of the payload. - ++range.start; - --total; - - status = f_string_dynamic_increase_by(total, &content); - - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "f_string_dynamic_increase_by"); break; } - memcpy(content.string, block.string + range.start, sizeof(f_char_t) * total); + memcpy(setting->content.string, setting->block.string + range.start, sizeof(f_char_t) * total); - content.used += total; + setting->content.used += total; } state = 0x4; + printed |= 0x2; // Designate to read next block from pipe. range.start = 1; @@ -327,9 +261,9 @@ extern "C" { } if (total) { - status = f_string_dynamic_increase_by(total, &content); + setting->status = f_string_dynamic_increase_by(total, &setting->content); - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "f_string_dynamic_increase_by"); break; @@ -337,33 +271,35 @@ extern "C" { for (; range.start <= range.stop; ++range.start) { - if (block.string[range.start] == fss_payload_write_pipe_content_start_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_start_s.string[0]) { + setting->status = F_status_set_error(F_supported_not); + if (main->error.verbosity > f_console_verbosity_quiet_e) { - fll_print_format("%r%[%QThe FSS-000E (Payload) standard only supports one content per object.%]%r", main->error.to, f_string_eol_s, main->error.context, main->error.prefix, main->error.context, f_string_eol_s); + fss_payload_write_print_line_first_locked(setting, main->error); + fss_payload_write_print_error_one_content_only(setting, main->error); + fss_payload_write_print_line_last_locked(setting, main->error); } - status = F_status_set_error(F_supported_not); - break; } - if (block.string[range.start] == fss_payload_write_pipe_content_end_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_end_s.string[0]) { state = 0x3; ++range.start; break; } - if (block.string[range.start] == fss_payload_write_pipe_content_ignore_s.string[0]) { + if (setting->block.string[range.start] == fss_payload_write_pipe_content_ignore_s.string[0]) { // This is not used by this program. continue; } - content.string[content.used++] = block.string[range.start]; + setting->content.string[setting->content.used++] = setting->block.string[range.start]; } // for - if (F_status_is_error(status)) break; + if (F_status_is_error(setting->status)) break; } else { state = 0x3; @@ -371,25 +307,41 @@ extern "C" { } if (state == 0x3) { - status = fss_payload_write_process(main, output, quote, &object, &content, buffer); - if (F_status_is_error(status)) break; + if (setting->flag & fss_payload_write_main_flag_partial_e) { + if (setting->flag & fss_payload_write_main_flag_content_e) { + fss_payload_write_process(main, setting, 0, &setting->content); + } + else { + fss_payload_write_process(main, setting, &setting->object, 0); + } + } + else { + fss_payload_write_process(main, setting, &setting->object, &setting->content); + } + + if (F_status_is_error(setting->status)) break; state = 0; + printed |= 0x1; + + continue; } if (state == 0x4) { - if (block.used) { - status = f_string_dynamic_increase_by(block.used, &content); + if (setting->block.used && range.start <= range.stop) { + length = (range.stop - range.start) + 1; + + setting->status = f_string_dynamic_increase_by(length + 1, &setting->content); - if (F_status_is_error(status)) { + if (F_status_is_error(setting->status)) { fss_payload_write_print_error(setting, main->error, "f_string_dynamic_increase_by"); break; } - memcpy(content.string, block.string, sizeof(f_char_t) * block.used); + memcpy(setting->content.string + range.start, setting->block.string, sizeof(f_char_t) * length); - content.used += block.used; + setting->content.used += length; } // Designate to read next block from pipe. @@ -399,15 +351,41 @@ extern "C" { } // for // 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_payload_write_process(main, output, quote, &object, &content, buffer); + if (F_status_is_error_not(setting->status) && status_pipe == F_none_eof && state) { + if (setting->flag & fss_payload_write_main_flag_partial_e) { + if (setting->flag & fss_payload_write_main_flag_content_e) { + fss_payload_write_process(main, setting, 0, &setting->content); + } + else { + fss_payload_write_process(main, setting, &setting->object, 0); + } + } + else { + fss_payload_write_process(main, setting, &setting->object, &setting->content); + } + + printed |= 0x1; } - f_string_dynamic_resize(0, &block); - f_string_dynamic_resize(0, &object); - f_string_dynamic_resize(0, &content); + setting->block.used = 0; + setting->object.used = 0; + setting->content.used = 0; + setting->buffer.used = 0; - return status; + if (F_status_is_error_not(setting->status)) { + + if (printed | 0x1) { + if (printed | 0x2) { + setting->status = F_payload; + } + else { + setting->status = F_none; + } + } + else { + setting->status = F_data_not; + } + } } #endif // _di_fss_payload_write_process_pipe_ diff --git a/level_3/fss_payload_write/c/private-write.h b/level_3/fss_payload_write/c/private-write.h index 50188bf..cf73720 100644 --- a/level_3/fss_payload_write/c/private-write.h +++ b/level_3/fss_payload_write/c/private-write.h @@ -13,64 +13,31 @@ extern "C" { #endif /** - * Print an message about the object and content parameters not being specified the same number of times. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_write_error_parameter_same_times_print_ - void fss_payload_write_error_parameter_same_times_print(fll_program_data_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_write_error_parameter_same_times_print_ - -/** - * Print an message about a parameter New Line character '\n' (U+000A) being unsupported. + * Process a given object and content, printing the FSS if valid or an error if invalid. * * @param main * The main program data. - */ -#ifndef _di_fss_payload_write_error_parameter_unsupported_eol_print_ - void fss_payload_write_error_parameter_unsupported_eol_print(fll_program_data_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_write_error_parameter_unsupported_eol_print_ - -/** - * Print an message about a parameter missing a value. + * @param setting + * The main program settings. * - * @param main - * The main program data. - * @param symbol - * The console symbol, such as "--" in "--help". - * @param parameter - * The parameter name, such as "help" in "--help". - */ -#ifndef _di_fss_payload_write_error_parameter_value_missing_print_ - void fss_payload_write_error_parameter_value_missing_print(fll_program_data_t * const main, const f_string_static_t symbol, const f_string_static_t parameter) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_write_error_parameter_value_missing_print_ - -/** - * Process a given object and content, printing the FSS if valid or an error if invalid. + * This alters setting.status: + * F_none on success. + * F_interrupt on (exit) signal received. * - * @param main - * The main program data. - * @param output - * The file to output to. - * @param quote - * The quote character to use. - * This is either single our double quote. + * F_parameter (with error bit) if main is NULL or setting is NULL. * @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. * * @return * F_none on success. * F_failure (with error bit) for any other failure. */ #ifndef _di_fss_payload_write_process_ - extern f_status_t fss_payload_write_process(fll_program_data_t * const main, 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_attribute_visibility_internal_d; + extern void fss_payload_write_process(fll_program_data_t * const main, fss_payload_write_setting_t * const setting, const f_string_static_t *object, const f_string_static_t *content) F_attribute_visibility_internal_d; #endif // _di_fss_payload_write_process_ /** @@ -78,20 +45,23 @@ extern "C" { * * @param main * The main program data. - * @param output - * The file to output to. - * @param quote - * The quote character to use. - * This is either single our double quote. - * @param buffer - * The buffer array used as a cache to construct the output before printing. + * @param setting + * The main program settings. + * + * This alters setting.status: + * F_none on success. + * F_data_not on success but pipe contained no relevant data. + * F_payload on success and the payload has been printed. + * F_interrupt on (exit) signal received. + * + * F_parameter (with error bit) if main is NULL or setting is NULL. * * @return * F_none on success. * F_failure (with error bit) for any other failure. */ #ifndef _di_fss_payload_write_process_pipe_ - extern f_status_t fss_payload_write_process_pipe(fll_program_data_t * const main, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) F_attribute_visibility_internal_d; + extern void fss_payload_write_process_pipe(fll_program_data_t * const main, fss_payload_write_setting_t * const setting) F_attribute_visibility_internal_d; #endif // _di_fss_payload_write_process_pipe_ #ifdef __cplusplus