]> Kevux Git Server - fll/commitdiff
Update: Finish program related work for fss_payload_write.
authorKevin Day <thekevinday@gmail.com>
Thu, 17 Nov 2022 03:23:27 +0000 (21:23 -0600)
committerKevin Day <thekevinday@gmail.com>
Thu, 17 Nov 2022 03:36:58 +0000 (21:36 -0600)
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.

level_3/fss_payload_write/c/common.c
level_3/fss_payload_write/c/common.h
level_3/fss_payload_write/c/fss_payload_write.c
level_3/fss_payload_write/c/fss_payload_write.h
level_3/fss_payload_write/c/main.c
level_3/fss_payload_write/c/print.c
level_3/fss_payload_write/c/print.h
level_3/fss_payload_write/c/private-common.h
level_3/fss_payload_write/c/private-write.c
level_3/fss_payload_write/c/private-write.h

index 5c53e90d9a384c8954ce4753c547eb8a719ef6ce..9ab24b3d1cc584fa624778131a971db417f82264 100644 (file)
@@ -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;
     }
   }
index a22a4a051ea195ebf24cd199ac433221116adf01..8d62e02563c1f378a7f476509c631a532150ca19 100644 (file)
@@ -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, \
     }
index 0e5c0f7ed2d3c9beda59f75b3e0b1807e46cc1a6..cd806aaf05b03d4a96542ab69105a9718608859e 100644 (file)
@@ -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_
 
index 3ddeceee6cabb939fba1306f7b93effd6e04faca..00c3ae0f6201b9bf98f19bd3a369f1e5da9d407e 100644 (file)
 #include <fll/level_0/utf.h>
 #include <fll/level_0/color.h>
 #include <fll/level_0/console.h>
+#include <fll/level_0/conversion.h>
 #include <fll/level_0/file.h>
 #include <fll/level_0/pipe.h>
 #include <fll/level_0/print.h>
 #include <fll/level_0/signal.h>
 
 // FLL-1 includes.
+#include <fll/level_1/conversion.h>
 #include <fll/level_1/fss/basic_list.h>
 #include <fll/level_1/print.h>
 #include <fll/level_1/string.h>
index e9649899d165b2ae403247b65d8573ab0c3f1cf9..566c9382ab23c8b5a6b761c6ad601867a4e0f29d 100644 (file)
@@ -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;
 }
index bf6343cf75b197075237df85eec5cacb9df4b880..609e78c7780f26d5f8f7cf5dfbc9b5740292b590 100644 (file)
@@ -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);
index 7f4218117eb91df299f219a24a07cf8df156538f..3cc0ccffd020972edf8329498eb0ed6b6fd81c0d 100644 (file)
@@ -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
index 1262946859427c72e3b1ea604f4f519a207d04cb..f6a495da1feac233404f8ab097ad6f157ec4f0f2 100644 (file)
 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
index e847547d6412ff264bc55a2b6e52879d58239ea1..a5c3b3bf266c63c617ebe4bb2ff132e552ce84aa 100644 (file)
 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_
 
index 50188bf261a77bc5c6c78b98bf0cfa86fd0a27bc..cf73720240d31c252a23fd89165c0845a25164c3 100644 (file)
@@ -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