]> Kevux Git Server - fll/commitdiff
Progress: fss write functions and programs.
authorKevin Day <thekevinday@gmail.com>
Tue, 6 Oct 2020 04:22:11 +0000 (23:22 -0500)
committerKevin Day <thekevinday@gmail.com>
Tue, 6 Oct 2020 04:39:23 +0000 (23:39 -0500)
I reviewed, fixed, and cleaned up the write functions.
I have only partially gotten to the basic list and have not so much as glanced at the extended list.
These two I will start working on later.

Several bugs and problems have been identified and resolved.

Add back the UTF-8 processing.
- This time check the width and add each 8-byte sequence until width is reached to correctly process the UTF-8 character.

21 files changed:
level_1/fl_fss/c/fss_basic.c
level_1/fl_fss/c/fss_basic.h
level_1/fl_fss/c/fss_basic_list.c
level_1/fl_fss/c/fss_basic_list.h
level_1/fl_fss/c/fss_extended.c
level_1/fl_fss/c/fss_extended.h
level_1/fl_fss/c/fss_macro.h
level_1/fl_fss/c/private-fss.c
level_1/fl_fss/c/private-fss.h
level_2/fll_fss/c/fss_basic.c
level_2/fll_fss/c/fss_basic_list.c
level_2/fll_fss/c/fss_basic_list.h
level_2/fll_fss/c/fss_extended.c
level_3/fss_basic_list_write/c/fss_basic_list_write.c
level_3/fss_basic_list_write/c/private-fss_basic_list_write.c
level_3/fss_basic_write/c/fss_basic_write.c
level_3/fss_basic_write/c/private-fss_basic_write.c
level_3/fss_basic_write/c/private-fss_basic_write.h
level_3/fss_extended_write/c/fss_extended_write.c
level_3/fss_extended_write/c/private-fss_extended_write.c
level_3/fss_extended_write/c/private-fss_extended_write.h

index 220c9b7e1dc2ff25db8607e8c108a981732d78c5..969cf3b0ddafe99cdd2381447a6e645bdf8ac44e 100644 (file)
@@ -98,7 +98,7 @@ extern "C" {
       if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    const f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination);
+    f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination);
 
     if (status == F_data_not_stop || status == F_data_not_eos) {
 
@@ -108,16 +108,10 @@ extern "C" {
 
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
-
-      if (status == F_data_not_stop) {
-        return F_none_stop;
-      }
-
-      return F_none_eos;
     }
 
     if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
-      if (status == F_none_stop || status == F_none_eos) {
+      if (status == F_none_stop || status == F_none_eos || status == F_data_not_stop || status == F_data_not_eos) {
         const f_status_t status_allocation = private_fl_fss_destination_increase(destination);
         if (F_status_is_error(status_allocation)) return status_allocation;
 
@@ -165,7 +159,7 @@ extern "C" {
 
     for (; range->start <= range->stop && range->start < content.used; range->start++) {
 
-      if (content.string[range->start] == f_string_eol[0]) {
+      if (content.string[range->start] == f_fss_eol) {
         destination->used = used_start;
         return F_status_set_error(F_none_eol);
       }
index e19a35cf98c20be729d77d7c7bf04e0d818e0155..99ac0ae5fa60bdfc2efd86cf0e37dbffc3859c9e 100644 (file)
@@ -149,12 +149,15 @@ extern "C" {
  *   F_none_stop on success after reaching the range stop.
  *   F_data_not_stop no data to write due start location being greater than stop location.
  *   F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ *   F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
  *   F_memory_reallocation (with error bit) on reallocation error.
  *   F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ *   F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
  *
  *   Errors (with error bit) from: f_fss_is_space().
+ *   Errors (with error bit) from: f_utf_buffer_increment().
  */
 #ifndef _di_fl_fss_basic_object_write_
   extern f_return_status fl_fss_basic_object_write(const f_string_static_t object, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
index 0a3bfe24e6db1d69ae21c720d3810283b991d468..da5700149e92172d68dca22db1352c550c78b5c9 100644 (file)
@@ -395,141 +395,160 @@ extern "C" {
 #endif // _di_fl_fss_basic_list_content_read_
 
 #ifndef _di_fl_fss_basic_list_object_write_
-  f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination) {
+  f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination) {
     #ifndef _di_level_1_parameter_checking_
       if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
     f_status_t status = F_none;
 
-    f_string_range_t buffer_position = f_string_range_t_initialize;
-    f_string_length_t start_position = f_string_t_initialize;
-    f_string_length_t start_buffer = 0;
-
     fl_macro_fss_skip_past_delimit_placeholders(object, (*range))
 
-    if (range->start > range->stop) return F_data_not_stop;
-    else if (range->start >= object.used) return F_data_not_eos;
+    if (range->start > range->stop) {
+      status = F_data_not_stop;
+    }
+    else if (range->start >= object.used) {
+      status = F_data_not_eos;
+    }
 
-    start_position = range->start;
+    if (status == F_data_not_stop || status == F_data_not_eos) {
+      if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
+        const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination);
+        if (F_status_is_error(status_allocation)) return status_allocation;
 
-    // ensure that there is room for the start and stop quotes or a slash delimit and the object open character.
-    f_string_length_t size_allocate = destination->used + (range->stop - range->start) + 3 + f_fss_default_allocation_step;
+        destination->string[destination->used++] = f_fss_basic_list_open;
 
-    if (size_allocate > destination->size) {
-      f_macro_string_dynamic_t_resize(status, (*destination), size_allocate);
-      if (F_status_is_error(status)) return status;
+        if (complete == f_fss_complete_full) {
+          destination->string[destination->used++] = f_fss_eol;
+        }
+      }
+
+      return status;
     }
 
-    buffer_position.start = destination->used;
-    buffer_position.stop = destination->used;
+    // ensure that there is room for a slash delimit, the object open character, and the end of line character.
+    status = private_fl_fss_destination_increase_by(destination->used + (range->stop - range->start) + 3, destination);
+    if (F_status_is_error(status)) return status;
 
-    bool quote = quoted ? F_true : F_false;
+    const f_string_length_t input_start = range->start;
+    const f_string_length_t used_start = destination->used;
 
-    if (quoted) {
-      if (quoted == f_fss_quote_type_single) {
-        destination->string[destination->used] = f_fss_delimit_quote_single;
-      }
-      else {
-        destination->string[destination->used] = f_fss_delimit_quote_double;
-      }
+    f_string_length_t i = 0;
 
-      destination->used++;
-    }
+    uint8_t width = 0;
 
+    // find the first graph character.
     while (range->start <= range->stop && range->start < object.used) {
 
       if (object.string[range->start] == f_fss_comment) {
+        // @todo the standard may be updated to allow escaping comments.
         // comments are not allowed and this format has no way of "wrapping" a comment.
-        return F_status_set_error(FL_fss_found_comment);
-      }
-      else if ((status = f_fss_is_graph(object, *range)) == F_true) {
+        status = F_status_set_error(FL_fss_found_comment);
         break;
       }
-      else if (F_status_is_error(status)) {
-        return status;
-      }
+
+      status = f_fss_is_graph(object, *range);
+      if (F_status_is_error(status)) break;
+
+      if (status == F_true) break;
 
       if (object.string[range->start] != f_fss_delimit_placeholder) {
-        destination->string[buffer_position.stop] = object.string[range->start];
-        buffer_position.stop++;
+        width = f_macro_utf_byte_width(object.string[range->start]);
+
+        status = private_fl_fss_destination_increase_by(width, destination);
+        if (F_status_is_error(status)) break;
+
+        for (i = 0; i < width; i++) {
+          destination->string[destination->used++] = object.string[range->start + i];
+        } // for
       }
 
       status = f_utf_buffer_increment(object, range, 1);
-      if (F_status_is_error(status)) return status;
+      if (F_status_is_error(status)) break;
     } // while
 
+    if (F_status_is_error(status)) {
+      destination->used = used_start;
+      return status;
+    }
+
     while (range->start <= range->stop && range->start < object.used) {
 
       if (object.string[range->start] == f_fss_delimit_slash) {
         f_string_length_t slash_count = 1;
 
-        destination->string[buffer_position.stop] = object.string[range->start];
-        buffer_position.stop++;
-
-        status = f_utf_buffer_increment(object, range, 1);
-        if (F_status_is_error(status)) return status;
+        destination->string[destination->used++] = object.string[range->start];
+        range->start++;
 
         while (range->start <= range->stop && range->start < object.used) {
 
           if (object.string[range->start] == f_fss_delimit_placeholder) {
-            status = f_utf_buffer_increment(object, range, 1);
-            if (F_status_is_error(status)) return status;
-
+            range->start++;
             continue;
           } else if (object.string[range->start] != f_fss_delimit_slash) {
             break;
           }
 
-          destination->string[buffer_position.stop] = object.string[range->start];
-          buffer_position.stop++;
-
-          status = f_utf_buffer_increment(object, range, 1);
-          if (F_status_is_error(status)) return status;
+          destination->string[destination->used++] = object.string[range->start];
 
+          range->start++;
           slash_count++;
         } // while
 
-        if (range->start > range->stop || range->start >= object.used) {
-          size_allocate += slash_count;
+        if (F_status_is_error(status)) break;
 
-          if (size_allocate > destination->size) {
-            f_macro_string_dynamic_t_resize(status, (*destination), size_allocate + f_fss_default_allocation_step);
-            if (F_status_is_error(status)) return status;
-          }
+        if (range->start > range->stop || range->start >= object.used) {
+          status = private_fl_fss_destination_increase_by(slash_count, destination);
+          if (F_status_is_error(status)) break;
 
           while (slash_count > 0) {
-            destination->string[buffer_position.stop] = f_fss_delimit_slash;
-            buffer_position.stop++;
+            destination->string[destination->used++] = f_fss_delimit_slash;
             slash_count--;
           } // while
 
           break;
         }
       }
-      else if (object.string[range->start] == f_string_eol[0]) {
-        if (buffer_position.stop == buffer_position.start) {
+      else if (object.string[range->start] == f_fss_eol) {
+        if (destination->used == used_start) {
           return F_data_not_eol;
         }
 
-        break;
+        return F_none_eol;
       }
 
       if (object.string[range->start] != f_fss_delimit_placeholder) {
-        destination->string[buffer_position.stop] = object.string[range->start];
-        buffer_position.stop++;
+        width = f_macro_utf_byte_width(object.string[range->start]);
+
+        status = private_fl_fss_destination_increase_by(width, destination);
+        if (F_status_is_error(status)) break;
+
+        for (i = 0; i < width; i++) {
+          destination->string[destination->used++] = object.string[range->start + i];
+        } // for
       }
 
       status = f_utf_buffer_increment(object, range, 1);
-      if (F_status_is_error(status)) return status;
+      if (F_status_is_error(status)) break;
     } // while
 
-    destination->string[buffer_position.stop] = f_fss_basic_list_open;
-    destination->string[buffer_position.stop + 1] = f_string_eol[0];
-    destination->used = buffer_position.stop + 2;
+    if (F_status_is_error(status)) {
+      destination->used = used_start;
+      return status;
+    }
 
-    if (range->start > range->stop) return F_none_stop;
-    else if (range->start >= object.used) return F_none_eos;
+    if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
+      destination->string[destination->used++] = f_fss_basic_list_open;
+      destination->string[destination->used++] = f_fss_eol;
+    }
+
+    if (range->start > range->stop) {
+      return F_none_stop;
+    }
+
+    if (range->start >= object.used) {
+      return F_none_eos;
+    }
 
     return F_none;
   }
@@ -538,6 +557,7 @@ extern "C" {
 #ifndef _di_fl_fss_basic_list_content_write_
   f_return_status fl_fss_basic_list_content_write(const f_string_static_t content, f_string_range_t *range, f_string_dynamic_t *destination) {
     #ifndef _di_level_1_parameter_checking_
+      if (!range) return F_status_set_error(F_parameter);
       if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
index c327547b261721580b276e3ea7dde1909dfde40f..c061fd8e879cd5e07637b5c54c9309eb00ef1532 100644 (file)
@@ -129,9 +129,10 @@ extern "C" {
  *
  * @param object
  *   The string to write as (does not stop at NULLS, they are ignored and not written).
- * @param quoted
- *   If 0, then double quotes are auto-inserted, when required.
- *   Otherwise, this is the type of quote to wrap the object in when writing.
+ * @param complete
+ *   If f_fss_complete_none, then only the object name is written.
+ *   If f_fss_complete_partial, this will write any appropriate open and close aspects of this object.
+ *   If f_fss_complete_full, this will write any appropriate open and close aspects of this object.
  * @param range
  *   The start/stop location within the object string to write as an object.
  * @param destination
@@ -151,7 +152,7 @@ extern "C" {
  *   Errors (with error bit) from: f_utf_buffer_increment().
  */
 #ifndef _di_fl_fss_basic_list_object_write_
-  extern f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination);
+  extern f_return_status fl_fss_basic_list_object_write(const f_string_static_t object, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
 #endif // _di_fl_fss_basic_list_object_write_
 
 /**
@@ -171,6 +172,7 @@ extern "C" {
  *
  * @return
  *   F_none on success.
+ *   F_none_eol on success after reaching the end of the line.
  *   F_none_eos on success after reaching the end of the buffer.
  *   F_data_not_stop no data to write due start location being greater than stop location.
  *   F_data_not_eos no data to write due start location being greater than or equal to buffer size.
index edd1da32e8b40c980a0c6c9cfd6315b8fe5b2d3b..f93a0f97fc73f99559698afb5750907b4d79d764 100644 (file)
@@ -163,26 +163,20 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con
       if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    const f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination);
+    f_status_t status = private_fl_fss_basic_object_write(object, quote ? quote : f_fss_delimit_quote_double, range, destination);
 
     if (status == F_data_not_stop || status == F_data_not_eos) {
 
       // Objects cannot be empty, so write a quoted empty string.
-      const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination);
+      const f_status_t status_allocation = private_fl_fss_destination_increase_by(3, destination);
       if (F_status_is_error(status_allocation)) return status_allocation;
 
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
-
-      if (status == F_data_not_stop) {
-        return F_none_stop;
-      }
-
-      return F_none_eos;
     }
 
     if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
-      if (status == F_none_stop || status == F_none_eos) {
+      if (status == F_none_stop || status == F_none_eos || status == F_data_not_stop || status == F_data_not_eos) {
         const f_status_t status_allocation = private_fl_fss_destination_increase(destination);
         if (F_status_is_error(status_allocation)) return status_allocation;
 
@@ -207,6 +201,13 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con
     if (status == F_data_not_stop || status == F_data_not_eos) {
       f_status_t status_allocation = F_none;
 
+      // content that is empty must be represented by a quoted empty string.
+      status_allocation = private_fl_fss_destination_increase_by(3, destination);
+      if (F_status_is_error(status_allocation)) return status_allocation;
+
+      destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
+      destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
+
       // content should be terminated, even if empty.
       if (complete == f_fss_complete_partial || complete == f_fss_complete_full || complete == f_fss_complete_next) {
         status_allocation = private_fl_fss_destination_increase(destination);
index 49aa5f29ae4a4efa27138af8fadbc64a432c2537..4976456387d1f43ae05d5cfc2cc10b181874335f 100644 (file)
@@ -152,12 +152,15 @@ extern "C" {
  *   F_none_stop on success after reaching the range stop.
  *   F_data_not_stop no data to write due start location being greater than stop location.
  *   F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ *   F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
  *   F_memory_reallocation (with error bit) on reallocation error.
  *   F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ *   F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
  *
  *   Errors (with error bit) from: f_fss_is_space().
+ *   Errors (with error bit) from: f_utf_buffer_increment().
  */
 #ifndef _di_fl_fss_extended_object_write_
   extern f_return_status fl_fss_extended_object_write(const f_string_static_t object, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
@@ -191,12 +194,15 @@ extern "C" {
  *   F_none_stop on success after reaching the range stop.
  *   F_data_not_stop no data to write due start location being greater than stop location.
  *   F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ *   F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
  *   F_memory_reallocation (with error bit) on reallocation error.
  *   F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ *   F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
  *
  *   Errors (with error bit) from: f_fss_is_space().
+ *   Errors (with error bit) from: f_utf_buffer_increment().
  */
 #ifndef _di_fl_fss_extended_content_write_
   extern f_return_status fl_fss_extended_content_write(const f_string_static_t content, const f_fss_quote_t quote, const uint8_t complete, f_string_range_t *range, f_string_dynamic_t *destination);
index 69e356011e56fce922f3cba423c75f4fd63926a4..8364c636ed82f686f09a3d527bbf494a78d690c4 100644 (file)
@@ -26,12 +26,14 @@ extern "C" {
 
 #ifndef _di_fl_macro_fss_skip_past_delimit_placeholders_
   #define fl_macro_fss_skip_past_delimit_placeholders(buffer, range) \
-    while (buffer.string[range.start] == f_fss_delimit_placeholder) { \
-      range.start++;\
-      \
-      if (range.start >= buffer.used) break; \
-      if (range.start  > range.stop) break; \
-    } // while
+    if (buffer.used) { \
+      while (buffer.string[range.start] == f_fss_delimit_placeholder) { \
+        range.start++;\
+        \
+        if (range.start >= buffer.used) break; \
+        if (range.start > range.stop) break; \
+      } \
+    }
 #endif // _di_fl_macro_fss_skip_past_delimit_placeholders_
 
 #ifndef _di_fl_macro_fss_object_return_on_overflow_
index 290dec8600a7ddc5ee6ffbcc3925b479b53f6f71..94ba99e0d0c912210d4b44d48ccfc5837c19cce9 100644 (file)
@@ -532,7 +532,9 @@ extern "C" {
       quoted = F_true;
     }
 
-    for (; range->start <= range->stop && range->start < object.used; range->start++) {
+    uint8_t width = 0;
+
+    for (; range->start <= range->stop && range->start < object.used; ) {
 
       if (object.string[range->start] == f_fss_delimit_slash) {
         item_first = range->start++;
@@ -614,7 +616,15 @@ extern "C" {
           } // for
 
           destination->string[destination->used++] = quote;
-          destination->string[destination->used++] = object.string[range->start];
+
+          width = f_macro_utf_byte_width(object.string[range->start]);
+
+          status = private_fl_fss_destination_increase_by(width, destination);
+          if (F_status_is_error(status)) break;
+
+          for (i = 0; i < width; i++) {
+            destination->string[destination->used++] = object.string[range->start + i];
+          } // for
         }
         else {
 
@@ -631,7 +641,14 @@ extern "C" {
             destination->string[destination->used++] = f_fss_delimit_slash;
           } // for
 
-          destination->string[destination->used++] = object.string[range->start];
+          width = f_macro_utf_byte_width(object.string[range->start]);
+
+          status = private_fl_fss_destination_increase_by(width, destination);
+          if (F_status_is_error(status)) break;
+
+          for (i = 0; i < width; i++) {
+            destination->string[destination->used++] = object.string[range->start + i];
+          } // for
         }
       }
       else if (object.string[range->start] == quote) {
@@ -652,8 +669,7 @@ extern "C" {
         if (object.string[range->start] == quote) {
           destination->string[destination->used++] = quote;
 
-          // the next quote must also be checked.
-          range->start--;
+          // the next quote must also be checked, so do not increment.
           continue;
         }
 
@@ -673,7 +689,15 @@ extern "C" {
         }
 
         destination->string[destination->used++] = quote;
-        destination->string[destination->used++] = object.string[range->start];
+
+        width = f_macro_utf_byte_width(object.string[range->start]);
+
+        status = private_fl_fss_destination_increase_by(width, destination);
+        if (F_status_is_error(status)) break;
+
+        for (i = 0; i < width; i++) {
+          destination->string[destination->used++] = object.string[range->start + i];
+        } // for
       }
       else if (object.string[range->start] == f_fss_eol) {
         status = F_status_set_error(F_none_eol);
@@ -690,8 +714,18 @@ extern "C" {
           }
         }
 
-        destination->string[destination->used++] = object.string[range->start];
+        width = f_macro_utf_byte_width(object.string[range->start]);
+
+        status = private_fl_fss_destination_increase_by(width, destination);
+        if (F_status_is_error(status)) break;
+
+        for (i = 0; i < width; i++) {
+          destination->string[destination->used++] = object.string[range->start + i];
+        } // for
       }
+
+      status = f_utf_buffer_increment(object, range, 1);
+      if (F_status_is_error(status)) break;
     } // for
 
     if (F_status_is_error(status)) {
@@ -737,7 +771,7 @@ extern "C" {
   }
 #endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
 
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
   f_return_status private_fl_fss_destination_increase(f_string_dynamic_t *destination) {
     f_status_t status = F_none;
 
@@ -756,9 +790,9 @@ extern "C" {
 
     return status;
   }
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
 
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
   f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination) {
     f_status_t status = F_none;
 
@@ -772,7 +806,7 @@ extern "C" {
 
     return status;
   }
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
 
 #ifdef __cplusplus
 } // extern "C"
index 6f62640ad79626ba7b6f44b31b7f9451a43bd899..94a47c86044b00c32c8239fdc3d1fc0850ba5a1d 100644 (file)
@@ -89,10 +89,14 @@ extern "C" {
  *   F_none_stop on success after reaching the range stop.
  *   F_data_not_stop no data to write due start location being greater than stop location.
  *   F_data_not_eos no data to write due start location being greater than or equal to buffer size.
+ *   F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete.
  *   F_memory_reallocation (with error bit) on reallocation error.
  *   F_none_eol (with error bit) after reaching an EOL, which is not supported by the standard.
  *   F_parameter (with error bit) if a parameter is invalid.
  *   F_string_too_large (with error bit) if appended string length is too large to store in the destination.
+ *   F_utf (with error bit) is returned on failure to read/process a UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_buffer_increment().
  *
  * @see fl_fss_basic_object_write()
  * @see fl_fss_extended_object_write()
@@ -115,12 +119,13 @@ extern "C" {
  *
  * @see fl_fss_basic_object_write()
  * @see fl_fss_basic_content_write()
+ * @see fl_fss_basic_list_object_write()
  * @see fl_fss_extended_object_write()
  * @see fl_fss_extended_content_write()
  */
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
   extern f_return_status private_fl_fss_destination_increase(f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal;
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
 
 /**
  * Increase the size of destination buffer by the given amount, but only if necessary.
@@ -137,12 +142,13 @@ extern "C" {
  *
  * @see fl_fss_basic_object_write()
  * @see fl_fss_basic_content_write()
+ * @see fl_fss_basic_list_object_write()
  * @see fl_fss_extended_object_write()
  * @see fl_fss_extended_content_write()
  */
-#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
+#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
   f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination);
-#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_extended_object_write_)  || !defined(_di_fl_fss_extended_content_write_)
+#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_basic_content_write_) || !defined(_di_fl_fss_basic_list_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
 
 #ifdef __cplusplus
 } // extern "C"
index 1b75d7ca76ef901b6afc9952bdc0c08da6c4819a..9ba467d76f1501cbeb814a7c7a45eff208ad5c28 100644 (file)
@@ -187,7 +187,7 @@ extern "C" {
       }
     }
 
-    return F_none;
+    return status;
   }
 #endif // _di_fll_fss_basic_write_
 
index 0158aa379ec932b1c700d5652c5bfbf1975127fc..eee66b3833c1d7416d2f5f8242f7d9bac52b5cfc 100644 (file)
@@ -134,48 +134,30 @@ extern "C" {
 #endif // _di_fll_fss_basic_list_read_
 
 #ifndef _di_fll_fss_basic_list_write_
-  f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quoted, f_string_dynamic_t *buffer) {
+  f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, f_string_dynamic_t *destination) {
     #ifndef _di_level_2_parameter_checking_
-      if (!buffer) return F_status_set_error(F_parameter);
-      if (contents.used > contents.size) return F_status_set_error(F_parameter);
+      if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_2_parameter_checking_
 
     f_status_t status = 0;
-    f_array_length_t current = 0;
-    f_string_range_t range = f_string_range_t_initialize;
-
-    range.start = 0;
-    range.stop = object.used - 1;
+    f_string_range_t range = f_macro_string_range_t_initialize(object.used);
 
-    status = fl_fss_basic_list_object_write(object, quoted, &range, buffer);
+    status = fl_fss_basic_list_object_write(object, f_fss_complete_full, &range, destination);
 
     if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) {
       return status;
     }
 
     if (status == F_none || status == F_none_stop || status == F_none_eos || status == F_none_eol) {
-      if (contents.used > 0) {
+      if (contents.used && contents.array[0].used) {
         range.start = 0;
         range.stop = contents.array[0].used - 1;
 
-        status = fl_fss_basic_list_content_write(contents.array[0], &range, buffer);
-
-        if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) {
-          return status;
-        }
-      }
-      else {
-        if (buffer->used == buffer->size) {
-          status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, buffer);
-          if (F_status_is_error(status)) return status;
-        }
-
-        buffer->string[buffer->used] = f_string_eol[0];
-        buffer->used++;
+        status = fl_fss_basic_list_content_write(contents.array[0], &range, destination);
       }
     }
 
-    return F_none;
+    return status;
   }
 #endif // _di_fll_fss_basic_list_write_
 
index 9742bff936cceec57c37f1604cfed72a0911b1b9..7e600b8fa9f5c7ff39514daf2861537861c79945 100644 (file)
@@ -67,9 +67,6 @@ extern "C" {
  *   A string representing the object.
  * @param contents
  *   An array of strings representing multiple content to write.
- * @param quoted
- *   If 0, then double quotes are auto-inserted, when required.
- *   Otherwise, this is the type of quote to wrap the object in when writing.
  * @param buffer
  *   The buffer to write to.
  *
@@ -89,7 +86,7 @@ extern "C" {
  *   Errors (with error bit) from: fl_string_dynamic_size_increase().
  */
 #ifndef _di_fll_fss_basic_list_write_
-  extern f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quoted, f_string_dynamic_t *buffer);
+  extern f_return_status fll_fss_basic_list_write(const f_string_static_t object, const f_string_statics_t contents, f_string_dynamic_t *buffer);
 #endif // _di_fll_fss_basic_list_write_
 
 #ifdef __cplusplus
index ce1b93a78c41f3608463f27be11a4a4f0da137b9..98765e495ace9ddf5676a3310e9f1beb3fdcf8d8 100644 (file)
@@ -214,8 +214,14 @@ extern "C" {
           complete = f_fss_complete_end;
         }
 
-        range.start = 0;
-        range.stop = contents.array[i].used - 1;
+        if (contents.array[i].used) {
+          range.start = 0;
+          range.stop = contents.array[i].used - 1;
+        }
+        else {
+          range.start = 1;
+          range.stop = 0;
+        }
 
         status = fl_fss_extended_content_write(contents.array[i], quote, complete, &range, destination);
 
@@ -225,7 +231,7 @@ extern "C" {
       } // for
     }
 
-    return F_none;
+    return status;
   }
 #endif // _di_fll_fss_extended_write_
 
index 9a2678166258d8ca249cae48c2900e277a559d73..4bff84ce49bd54e7202d5d7e97bf7bed4a3d9d43 100644 (file)
@@ -31,6 +31,28 @@ extern "C" {
 
     fll_program_print_help_usage(file, context, fss_basic_list_write_name, "");
 
+    printf("  The pipe uses the NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") to designate the start of a Content and uses the Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+    printf("  For the pipe, an Object is terminated by either a NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") or a Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(").%c", f_string_eol[0]);
+    printf("  The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+    printf("%c", f_string_eol[0]);
+
     return F_none;
   }
 #endif // _di_fss_basic_list_write_print_help_
@@ -111,6 +133,7 @@ extern "C" {
       if (data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_additional) {
         if (data->parameters[fss_basic_list_write_parameter_file].additional.used > 1) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_file);
             fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
@@ -154,6 +177,7 @@ extern "C" {
           else if (data->parameters[fss_basic_list_write_parameter_content].locations.used && data->parameters[fss_basic_list_write_parameter_partial].locations.used) {
             if (data->parameters[fss_basic_list_write_parameter_content].result == f_console_result_additional) {
               if (data->error.verbosity != f_console_verbosity_quiet) {
+                fprintf(data->error.to.stream, "%c", f_string_eol[0]);
                 fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
                 fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_partial);
                 fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
@@ -181,11 +205,14 @@ extern "C" {
                 location_sub_content = data->parameters[fss_basic_list_write_parameter_content].locations_sub.array[i];
 
                 if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_object);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_content);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  if (data->error.verbosity != f_console_verbosity_quiet) {
+                    fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_object);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_content);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  }
 
                   status = F_status_set_error(F_parameter);
                   break;
@@ -207,6 +234,7 @@ extern "C" {
       }
       else if (!data->process_pipe) {
         if (data->error.verbosity != f_console_verbosity_quiet) {
+          fprintf(data->error.to.stream, "%c", f_string_eol[0]);
           fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
@@ -220,6 +248,7 @@ extern "C" {
       if (F_status_is_error_not(status) && data->process_pipe) {
         if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_partial);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
@@ -256,9 +285,12 @@ extern "C" {
         status = fss_basic_list_write_process_pipe(*data, output, quote, &buffer);
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
       }
 
@@ -305,9 +337,12 @@ extern "C" {
         }
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
         else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_none) {
           // ensure there is always a newline at the end, unless in quiet mode.
index a189661119ad7b2785f7a03ac61d89111d4ef030..95324eea312cb8c54f43c519cdf5438ea8a919a7 100644 (file)
@@ -12,6 +12,7 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sMust specify both the '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_object);
     fl_color_print(data.error.to.stream, data.context.set.error, "' parameter and the '");
@@ -29,6 +30,7 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sThe parameter '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", symbol, parameter);
     fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
@@ -51,27 +53,17 @@ extern "C" {
         range.stop = 0;
       }
 
-      status = fl_fss_basic_list_object_write(*object, quote, &range, buffer);
+      status = fl_fss_basic_list_object_write(*object, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
-      if (status == F_data_not_stop || status == F_data_not_eos) {
-        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
-        return F_status_set_error(status);
-      }
-      else if (F_status_is_error(status)) {
+      if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
         return status;
       }
     }
 
-    if (content) {
-      if (content->used) {
-        range.start = 0;
-        range.stop = content->used - 1;
-      }
-      else {
-        range.start = 1;
-        range.stop = 0;
-      }
+    if (content && content->used) {
+      range.start = 0;
+      range.stop = content->used - 1;
 
       status = fl_fss_basic_list_content_write(*content, &range, buffer);
 
@@ -125,6 +117,8 @@ extern "C" {
           break;
         }
 
+        if (!block.used) break;
+
         range.start = 0;
         range.stop = block.used - 1;
       }
@@ -154,20 +148,26 @@ extern "C" {
             break;
           }
 
+          if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
+            state = 0x3;
+            range.start++;
+            break;
+          }
+
           object.string[object.used++] = block.string[range.start];
         } // for
 
         if (F_status_is_error(status)) break;
 
         // if the start of content was not found, then fetch the next block.
-        if (state != 0x2) continue;
+        if (state == 0x1) continue;
 
         // if the end of the current block is reached, fetch the next block.
         if (range.start > range.stop) continue;
       }
 
       if (state == 0x2) {
-        if (block.used && range.start <= range.stop) {
+        if (range.start <= range.stop) {
           total = (range.stop - range.start) + 1;
         }
         else {
@@ -187,12 +187,16 @@ extern "C" {
           for (; range.start <= range.stop; range.start++) {
 
             if (block.string[range.start] == fss_basic_list_write_pipe_content_start) {
-              fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+              if (data.error.verbosity != f_console_verbosity_quiet) {
+                fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+                fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+              }
 
               status = F_status_set_error(F_unsupported);
               break;
             }
-            else if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
+
+            if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
               state = 0x3;
               range.start++;
               break;
@@ -217,7 +221,7 @@ extern "C" {
     } // for
 
     // if the pipe ended before finishing, then attempt to wrap up.
-    if (status_pipe == F_none_eof && state) {
+    if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
       status = fss_basic_list_write_process(data, output, quote, &object, &content, buffer);
     }
 
index a0e7889cd7c4ac8fce050a4af0b03df0bf6522fe..fc170ba7c72f1719286723f6465f2849d5767c04 100644 (file)
@@ -31,6 +31,28 @@ extern "C" {
 
     fll_program_print_help_usage(file, context, fss_basic_write_name, "");
 
+    printf("  The pipe uses the NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") to designate the start of a Content and uses the Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+    printf("  For the pipe, an Object is terminated by either a NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") or a Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(").%c", f_string_eol[0]);
+    printf("  The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+    printf("%c", f_string_eol[0]);
+
     return F_none;
   }
 #endif // _di_fss_basic_write_print_help_
@@ -111,6 +133,7 @@ extern "C" {
       if (data->parameters[fss_basic_write_parameter_file].result == f_console_result_additional) {
         if (data->parameters[fss_basic_write_parameter_file].additional.used > 1) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_file);
             fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
@@ -154,6 +177,7 @@ extern "C" {
           else if (data->parameters[fss_basic_write_parameter_content].locations.used && data->parameters[fss_basic_write_parameter_partial].locations.used) {
             if (data->parameters[fss_basic_write_parameter_content].result == f_console_result_additional) {
               if (data->error.verbosity != f_console_verbosity_quiet) {
+                fprintf(data->error.to.stream, "%c", f_string_eol[0]);
                 fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
                 fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_partial);
                 fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
@@ -181,11 +205,14 @@ extern "C" {
                 location_sub_content = data->parameters[fss_basic_write_parameter_content].locations_sub.array[i];
 
                 if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_content);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  if (data->error.verbosity != f_console_verbosity_quiet) {
+                    fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_content);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  }
 
                   status = F_status_set_error(F_parameter);
                   break;
@@ -207,6 +234,7 @@ extern "C" {
       }
       else if (!data->process_pipe) {
         if (data->error.verbosity != f_console_verbosity_quiet) {
+          fprintf(data->error.to.stream, "%c", f_string_eol[0]);
           fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
@@ -220,6 +248,7 @@ extern "C" {
       if (F_status_is_error_not(status) && data->process_pipe) {
         if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_partial);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
@@ -256,9 +285,12 @@ extern "C" {
         status = fss_basic_write_process_pipe(*data, output, quote, &buffer);
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
       }
 
@@ -308,9 +340,12 @@ extern "C" {
         }
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
         else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_write_parameter_file].result == f_console_result_none) {
           // ensure there is always a newline at the end, unless in quiet mode.
index e05b2d17efeb895b6e4bd7a37c23d5be8d413c7d..6005c6f29c66b76cd817865b447c5fc9d942b4d4 100644 (file)
@@ -12,6 +12,7 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sMust specify both the '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
     fl_color_print(data.error.to.stream, data.context.set.error, "' parameter and the '");
@@ -29,12 +30,27 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sThe parameter '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", symbol, parameter);
     fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
   }
 #endif // _di_fss_basic_write_error_parameter_value_missing_print_
 
+#ifndef _di_fss_basic_write_error_parameter_unsupported_eol_print_
+  void fss_basic_write_error_parameter_unsupported_eol_print(const fss_basic_write_data_t data) {
+
+    if (data.error.verbosity == f_console_verbosity_quiet) {
+      return;
+    }
+
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+    fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+    fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+    fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+  }
+#endif // _di_fss_basic_write_error_parameter_unsupported_eol_print_
+
 #ifndef _di_fss_basic_write_process_
   f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) {
     f_status_t status = F_none;
@@ -54,19 +70,13 @@ extern "C" {
       status = fl_fss_basic_object_write(*object, quote, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
       if (F_status_set_fine(status) == F_none_eol) {
-        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
-        fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
-        fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+        fss_basic_write_error_parameter_unsupported_eol_print(data);
 
         return F_status_set_error(F_unsupported);
       }
 
-      if (status == F_data_not_stop || status == F_data_not_eos) {
-        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
-        return F_status_set_error(status);
-      }
-      else if (F_status_is_error(status)) {
-        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_object_write", F_true);
         return status;
       }
     }
@@ -83,6 +93,12 @@ extern "C" {
 
       status = fl_fss_basic_content_write(*content, object ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
+      if (F_status_set_fine(status) == F_none_eol) {
+        fss_basic_write_error_parameter_unsupported_eol_print(data);
+
+        return F_status_set_error(F_unsupported);
+      }
+
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
         return status;
@@ -93,7 +109,7 @@ extern "C" {
       status = fl_string_append(f_string_eol, 1, buffer);
 
       if (F_status_is_error(status)) {
-        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
+        fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
         return status;
       }
     }
@@ -142,6 +158,8 @@ extern "C" {
           break;
         }
 
+        if (!block.used) break;
+
         range.start = 0;
         range.stop = block.used - 1;
       }
@@ -171,20 +189,26 @@ extern "C" {
             break;
           }
 
+          if (block.string[range.start] == fss_basic_write_pipe_content_end) {
+            state = 0x3;
+            range.start++;
+            break;
+          }
+
           object.string[object.used++] = block.string[range.start];
         } // for
 
         if (F_status_is_error(status)) break;
 
         // if the start of content was not found, then fetch the next block.
-        if (state != 0x2) continue;
+        if (state == 0x1) continue;
 
         // if the end of the current block is reached, fetch the next block.
         if (range.start > range.stop) continue;
       }
 
       if (state == 0x2) {
-        if (block.used && range.start <= range.stop) {
+        if (range.start <= range.stop) {
           total = (range.stop - range.start) + 1;
         }
         else {
@@ -204,7 +228,10 @@ extern "C" {
           for (; range.start <= range.stop; range.start++) {
 
             if (block.string[range.start] == fss_basic_write_pipe_content_start) {
-              fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+              if (data.error.verbosity != f_console_verbosity_quiet) {
+                fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+                fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+              }
 
               status = F_status_set_error(F_unsupported);
               break;
@@ -214,6 +241,12 @@ extern "C" {
               range.start++;
               break;
             }
+            else if (F_status_set_fine(status) == F_none_eol) {
+              fss_basic_write_error_parameter_unsupported_eol_print(data);
+
+              status = F_status_set_error(F_unsupported);
+              break;
+            }
 
             content.string[content.used++] = block.string[range.start];
           } // for
@@ -234,7 +267,7 @@ extern "C" {
     } // for
 
     // if the pipe ended before finishing, then attempt to wrap up.
-    if (status_pipe == F_none_eof && state) {
+    if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
       status = fss_basic_write_process(data, output, quote, &object, &content, buffer);
     }
 
index ad3f60dd3179297f46858b6918992332c6805211..768479b157c008070b3ff63d394ee1cd9636f258 100644 (file)
@@ -45,6 +45,20 @@ extern "C" {
 #endif // _di_fss_basic_write_error_parameter_value_missing_print_
 
 /**
+ * Print an message about a parameter EOL being unsupported.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_basic_write_error_parameter_unsupported_eol_print_
+  void fss_basic_write_error_parameter_unsupported_eol_print(const fss_basic_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_write_error_parameter_unsupported_eol_print_
+
+/**
  * Process a given object and content, printing the FSS if valid or an error if invalid.
  *
  * @param data
index e7efbf5cdd36c46f182fbec69bf327cc80d92875..7c4a2e709de6b24f82f58a172afbf1b9730db650 100644 (file)
@@ -31,6 +31,28 @@ extern "C" {
 
     fll_program_print_help_usage(file, context, fss_extended_write_name, "");
 
+    printf("  The pipe uses the NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") to designate the start of a Content and uses the Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(") to designate the end of the last Content.%c", f_string_eol[0]);
+    printf("  For the pipe, an Object is terminated by either a NULL character '");
+    fl_color_print(f_type_output, context.set.notable, "\\0");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+0000");
+    printf(") or a Form Feed character '");
+    fl_color_print(f_type_output, context.set.notable, "\\f");
+    printf("' (");
+    fl_color_print(f_type_output, context.set.notable, "U+000C");
+    printf(").%c", f_string_eol[0]);
+    printf("  The end of the pipe represents the end of any Object or Content.%c", f_string_eol[0]);
+
+    printf("%c", f_string_eol[0]);
+
     return F_none;
   }
 #endif // _di_fss_extended_write_print_help_
@@ -111,6 +133,7 @@ extern "C" {
       if (data->parameters[fss_extended_write_parameter_file].result == f_console_result_additional) {
         if (data->parameters[fss_extended_write_parameter_file].additional.used > 1) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_file);
             fl_color_print(data->error.to.stream, data->context.set.error, "' may only be specified once.%c", f_string_eol[0]);
@@ -154,6 +177,7 @@ extern "C" {
           else if (data->parameters[fss_extended_write_parameter_content].locations.used && data->parameters[fss_extended_write_parameter_partial].locations.used) {
             if (data->parameters[fss_extended_write_parameter_content].result == f_console_result_additional) {
               if (data->error.verbosity != f_console_verbosity_quiet) {
+                fprintf(data->error.to.stream, "%c", f_string_eol[0]);
                 fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
                 fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_partial);
                 fl_color_print(data->error.to.stream, data->context.set.error, "' parameter only allows either the '");
@@ -175,11 +199,14 @@ extern "C" {
               f_array_length_t location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[0];
 
               if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
-                fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
-                fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
-                fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
-                fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
-                fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                if (data->error.verbosity != f_console_verbosity_quiet) {
+                  fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                }
 
                 status = F_status_set_error(F_parameter);
               }
@@ -190,11 +217,14 @@ extern "C" {
                 location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[data->parameters[fss_extended_write_parameter_content].locations_sub.used - 1];
 
                 if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must have at least one '");
-                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
-                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  if (data->error.verbosity != f_console_verbosity_quiet) {
+                    fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must have at least one '");
+                    fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+                    fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+                  }
 
                   status = F_status_set_error(F_parameter);
                 }
@@ -215,6 +245,7 @@ extern "C" {
       }
       else if (!data->process_pipe) {
         if (data->error.verbosity != f_console_verbosity_quiet) {
+          fprintf(data->error.to.stream, "%c", f_string_eol[0]);
           fl_color_print(data->error.to.stream, data->context.set.error, "%sThis requires either piped data or the use of the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
@@ -228,6 +259,7 @@ extern "C" {
       if (F_status_is_error_not(status) && data->process_pipe) {
         if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) {
           if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
             fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_partial);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
@@ -264,9 +296,12 @@ extern "C" {
         status = fss_extended_write_process_pipe(*data, output, quote, &buffer);
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
       }
 
@@ -368,9 +403,12 @@ extern "C" {
         }
 
         if (F_status_is_error(status)) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
-          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fprintf(data->error.to.stream, "%c", f_string_eol[0]);
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+            fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+          }
         }
         else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_extended_write_parameter_file].result == f_console_result_none) {
           // ensure there is always a newline at the end, unless in quiet mode.
index d03d49c3bcd155d7ce2f330eaaad8ee160b7c081..425b8f9b1feea882572144159ea9b9b0db2178dc 100644 (file)
@@ -12,6 +12,7 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sMust specify the '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
     fl_color_print(data.error.to.stream, data.context.set.error, "' parameter at least once and the '");
@@ -29,12 +30,27 @@ extern "C" {
       return;
     }
 
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
     fl_color_print(data.error.to.stream, data.context.set.error, "%sThe parameter '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", symbol, parameter);
     fl_color_print(data.error.to.stream, data.context.set.error, "' was specified, but no value was given.%c", f_string_eol[0]);
   }
 #endif // _di_fss_extended_write_error_parameter_value_missing_print_
 
+#ifndef _di_fss_extended_write_error_parameter_unsupported_eol_print_
+  void fss_extended_write_error_parameter_unsupported_eol_print(const fss_extended_write_data_t data) {
+
+    if (data.error.verbosity == f_console_verbosity_quiet) {
+      return;
+    }
+
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+    fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+    fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+    fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
+  }
+#endif // _di_fss_extended_write_error_parameter_unsupported_eol_print_
+
 #ifndef _di_fss_extended_write_process_
   f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_statics_t *contents, f_string_dynamic_t *buffer) {
     f_status_t status = F_none;
@@ -51,37 +67,56 @@ extern "C" {
         range.stop = 0;
       }
 
-      status = fl_fss_extended_object_write(*object, quote, contents ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
+      status = fl_fss_extended_object_write(*object, quote, contents && contents->used ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
-      if (status == F_data_not_stop || status == F_data_not_eos) {
-        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
-        return F_status_set_error(status);
+      if (F_status_set_fine(status) == F_none_eol) {
+        fss_extended_write_error_parameter_unsupported_eol_print(data);
+
+        return F_status_set_error(F_unsupported);
       }
-      else if (F_status_is_error(status)) {
+
+      if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_object_write", F_true);
         return F_status_set_error(status);
       }
     }
 
     if (contents) {
-      for (f_array_length_t i = 0; i < contents->used; i++) {
+      if (contents->used) {
+        for (f_array_length_t i = 0; i < contents->used; i++) {
 
-        if (contents->used) {
-          range.start = 0;
-          range.stop = contents->array[i].used - 1;
-        }
-        else {
-          range.start = 1;
-          range.stop = 0;
-        }
+          if (contents->array[i].used) {
+            range.start = 0;
+            range.stop = contents->array[i].used - 1;
+          }
+          else {
+            range.start = 1;
+            range.stop = 0;
+          }
+
+          status = fl_fss_extended_content_write(contents->array[i], quote, i + 1 < contents->used ? f_fss_complete_next : f_fss_complete_end, &range, buffer);
+
+          if (F_status_set_fine(status) == F_none_eol) {
+            fss_extended_write_error_parameter_unsupported_eol_print(data);
+
+            return F_status_set_error(F_unsupported);
+          }
 
-        status = fl_fss_extended_content_write(contents->array[i], quote, i + 1 < contents->used ? f_fss_complete_next : f_fss_complete_end, &range, buffer);
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_content_write", F_true);
+            return F_status_set_error(status);
+          }
+        } // for
+      }
+      else {
+        // objects in this standard do not have EOL, so add an EOL for printing purposes when there is no desired content.
+        status = fl_string_append(f_string_eol, 1, buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_content_write", F_true);
-          return F_status_set_error(status);
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
+          return status;
         }
-      } // for
+      }
     }
 
     f_print_dynamic(output.stream, *buffer);
@@ -101,6 +136,8 @@ extern "C" {
     input.id = f_type_descriptor_input;
     input.size_read = 2048;
 
+    f_array_length_t i = 0;
+
     f_string_length_t total = 0;
     f_string_length_t previous = 0;
     f_string_range_t range = f_string_range_t_initialize;
@@ -109,7 +146,7 @@ extern "C" {
     f_string_dynamic_t object = f_string_dynamic_t_initialize;
     f_string_dynamics_t contents = f_string_dynamics_t_initialize;
 
-    // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set.
+    // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = new individual content, 0x3 = processing content, 0x4 = end object/content set.
     uint8_t state = 0;
 
     for (;;) {
@@ -128,12 +165,20 @@ extern "C" {
           break;
         }
 
+        if (!block.used) break;
+
         range.start = 0;
         range.stop = block.used - 1;
       }
 
       if (!state || state == 0x1) {
         if (!state) {
+          if (contents.used) {
+            for (i = 0; i < contents.used; i++) {
+              contents.array[i].used = 0;
+            } // for
+          }
+
           object.used = 0;
           contents.used = 0;
 
@@ -157,20 +202,40 @@ extern "C" {
             break;
           }
 
+          if (block.string[range.start] == fss_extended_write_pipe_content_end) {
+            state = 0x4;
+            range.start++;
+            break;
+          }
+
           object.string[object.used++] = block.string[range.start];
         } // for
 
         if (F_status_is_error(status)) break;
 
         // if the start of content was not found, then fetch the next block.
-        if (state != 0x2) continue;
+        if (state == 0x1) continue;
 
         // if the end of the current block is reached, fetch the next block.
         if (range.start > range.stop) continue;
       }
 
       if (state == 0x2) {
-        if (block.used && range.start <= range.stop) {
+        if (contents.used + 1 > contents.size) {
+          status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+            break;
+          }
+        }
+
+        state = 0x3;
+        contents.used++;
+      }
+
+      if (state == 0x3) {
+        if (range.start <= range.stop) {
           total = (range.stop - range.start) + 1;
         }
         else {
@@ -181,31 +246,32 @@ extern "C" {
           for (; range.start <= range.stop; range.start++) {
 
             if (block.string[range.start] == fss_extended_write_pipe_content_start) {
-              contents.used++;
+              if (contents.used + 1 > contents.size) {
+                status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
 
-              if (contents.used < contents.size && contents.array[contents.used].used) {
-                contents.array[contents.used].used = 0;
+                if (F_status_is_error(status)) {
+                  fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+                  break;
+                }
               }
 
+              contents.used++;
               continue;
             }
             else if (block.string[range.start] == fss_extended_write_pipe_content_end) {
-              state = 0x3;
+              state = 0x4;
               range.start++;
               break;
             }
+            else if (F_status_set_fine(status) == F_none_eol) {
+              fss_extended_write_error_parameter_unsupported_eol_print(data);
 
-            if (contents.used + 1 > contents.size) {
-              status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
-
-              if (F_status_is_error(status)) {
-                fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
-                break;
-              }
+              status = F_status_set_error(F_unsupported);
+              break;
             }
 
-            if (contents.array[contents.used].used + 1 > contents.array[contents.used].size) {
-              status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, &contents.array[contents.used]);
+            if (contents.array[contents.used - 1].used + 1 > contents.array[contents.used - 1].size) {
+              status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, &contents.array[contents.used - 1]);
 
               if (F_status_is_error(status)) {
                 fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
@@ -213,17 +279,17 @@ extern "C" {
               }
             }
 
-            contents.array[contents.used].string[contents.array[contents.used].used++] = block.string[range.start];
+            contents.array[contents.used - 1].string[contents.array[contents.used - 1].used++] = block.string[range.start];
           } // for
 
           if (F_status_is_error(status)) break;
         }
         else {
-          state = 0x3;
+          state = 0x4;
         }
       }
 
-      if (state == 0x3) {
+      if (state == 0x4) {
         status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
         if (F_status_is_error(status)) break;
 
@@ -232,7 +298,7 @@ extern "C" {
     } // for
 
     // if the pipe ended before finishing, then attempt to wrap up.
-    if (status_pipe == F_none_eof && state) {
+    if (F_status_is_error_not(status) && status_pipe == F_none_eof && state) {
       status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
     }
 
index d884210260a3525a8991c1df0dc9b75ad5684596..49522b455072cd1c3768d12bfaefd87c70128707 100644 (file)
@@ -45,6 +45,20 @@ extern "C" {
 #endif // _di_fss_extended_write_error_parameter_value_missing_print_
 
 /**
+ * Print an message about a parameter EOL being unsupported.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_extended_write_error_parameter_unsupported_eol_print_
+  void fss_extended_write_error_parameter_unsupported_eol_print(const fss_extended_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_write_error_parameter_unsupported_eol_print_
+
+/**
  * Process a given object and content, printing the FSS if valid or an error if invalid.
  *
  * @param data