]> Kevux Git Server - fll/commitdiff
Progress: continue working on FSS read/write programs and related.
authorKevin Day <thekevinday@gmail.com>
Wed, 7 Oct 2020 04:11:16 +0000 (23:11 -0500)
committerKevin Day <thekevinday@gmail.com>
Wed, 7 Oct 2020 04:18:06 +0000 (23:18 -0500)
Get comment delimitation working in FSS read/write functions.
- Comments are now escaped on read/write as appropriate.
- Rename appropriate private fl_fss functions.
- Add object_as boolean to designate whether or not this function is meant to read an object or content.
  - This ends up fixing a bug in the fl_fss_extended read function where a comment character before a content is incorrectly treated as an actual comment (this behavior is not allowed).
- Add similar behavior to the write functions.
  - The basic list and especially the extended list may not be complete in this regard.

Do some cleanup in the fss read programs that is related to the changes in this commit.
- There is still room for cleanups but that is not my focus at this time.

Add a -p/--pipe parameter to the FSS read functions to provide a way of returning data in the pipe-friendly format used by the FSS write programs.

22 files changed:
level_1/fl_fss/c/fss_basic.c
level_1/fl_fss/c/fss_basic_list.c
level_1/fl_fss/c/fss_extended.c
level_1/fl_fss/c/private-fss.c
level_1/fl_fss/c/private-fss.h
level_3/fss_basic_list_read/c/fss_basic_list_read.c
level_3/fss_basic_list_read/c/fss_basic_list_read.h
level_3/fss_basic_list_read/c/private-fss_basic_list_read.c
level_3/fss_basic_list_read/c/private-fss_basic_list_read.h
level_3/fss_basic_read/c/fss_basic_read.c
level_3/fss_basic_read/c/fss_basic_read.h
level_3/fss_basic_read/c/private-fss_basic_read.c
level_3/fss_basic_read/c/private-fss_basic_read.h
level_3/fss_extended_list_read/c/fss_extended_list_read.c
level_3/fss_extended_list_read/c/fss_extended_list_read.h
level_3/fss_extended_list_read/c/private-fss_extended_list_read.c
level_3/fss_extended_list_read/c/private-fss_extended_list_read.h
level_3/fss_extended_read/c/fss_extended_read.c
level_3/fss_extended_read/c/fss_extended_read.h
level_3/fss_extended_read/c/private-fss_extended_read.c
level_3/fss_extended_read/c/private-fss_extended_read.h
specifications/fss.txt

index 969cf3b0ddafe99cdd2381447a6e645bdf8ac44e..af633f8fe844ec30a13cb7bc0e5089d41be16129 100644 (file)
@@ -19,7 +19,7 @@ extern "C" {
     f_status_t status = F_none;
     f_string_lengths_t delimits = f_string_lengths_t_initialize;
 
-    status = private_fl_fss_basic_object_read(buffer, range, found, quote, &delimits);
+    status = private_fl_fss_basic_read(F_true, buffer, range, found, quote, &delimits);
 
     if (F_status_is_error(status)) {
       f_macro_string_lengths_t_delete_simple(delimits);
@@ -98,7 +98,7 @@ extern "C" {
       if (!destination) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    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_write(F_true, object, quote ? quote : f_fss_delimit_quote_double, range, destination);
 
     if (status == F_data_not_stop || status == F_data_not_eos) {
 
index da5700149e92172d68dca22db1352c550c78b5c9..2573e859d030b75b0d03acf35d8f8c56785d334f 100644 (file)
@@ -441,9 +441,12 @@ extern "C" {
     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.
-        status = F_status_set_error(FL_fss_found_comment);
+
+        // when a comment is found, escape it.
+        status = private_fl_fss_destination_increase(destination);
+        if (F_status_is_error(status)) break;
+
+        destination->string[destination->used++] = f_fss_delimit_slash;
         break;
       }
 
index f93a0f97fc73f99559698afb5750907b4d79d764..6ce2e60eb1825ff5a7d48ea70f50e7007f4e358d 100644 (file)
@@ -19,7 +19,7 @@ extern "C" {
     f_status_t status = F_none;
     f_string_lengths_t delimits = f_string_lengths_t_initialize;
 
-    status = private_fl_fss_basic_object_read(buffer, range, found, quoted, &delimits);
+    status = private_fl_fss_basic_read(F_true, buffer, range, found, quoted, &delimits);
 
     if (F_status_is_error(status)) {
       f_macro_string_lengths_t_delete_simple(delimits);
@@ -74,7 +74,7 @@ extern "C" {
       f_string_range_t content_partial = f_string_range_t_initialize;
       f_fss_quote_t quoted = 0;
 
-      status = private_fl_fss_basic_object_read(buffer, range, &content_partial, &quoted, &delimits);
+      status = private_fl_fss_basic_read(F_false, buffer, range, &content_partial, &quoted, &delimits);
 
       if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) {
         if (found->used == found->size) {
@@ -163,12 +163,12 @@ 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_
 
-    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_write(F_true, 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(3, destination);
+      const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination);
       if (F_status_is_error(status_allocation)) return status_allocation;
 
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
@@ -196,13 +196,12 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con
     #endif // _di_level_1_parameter_checking_
 
     // this operates exactly like an object, syntax-wise.
-    const f_status_t status = private_fl_fss_basic_object_write(content, quote ? quote : f_fss_delimit_quote_double, range, destination);
+    const f_status_t status = private_fl_fss_basic_write(F_false, content, quote ? quote : f_fss_delimit_quote_double, range, destination);
 
     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);
+      const f_status_t status_allocation = private_fl_fss_destination_increase_by(4, destination);
       if (F_status_is_error(status_allocation)) return status_allocation;
 
       destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double;
@@ -210,16 +209,10 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con
 
       // 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);
-        if (F_status_is_error(status_allocation)) return status_allocation;
-
         destination->string[destination->used++] = f_fss_extended_next;
       }
 
       if (complete == f_fss_complete_full || complete == f_fss_complete_end) {
-        status_allocation = private_fl_fss_destination_increase(destination);
-        if (F_status_is_error(status_allocation)) return status_allocation;
-
         destination->string[destination->used++] = f_fss_extended_close;
       }
 
@@ -231,19 +224,14 @@ f_return_status fl_fss_extended_object_write(const f_string_static_t object, con
     }
 
     if (F_status_is_error_not(status)) {
-      f_status_t status_allocation = F_none;
+      const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination);
+      if (F_status_is_error(status_allocation)) return status_allocation;
 
       if (complete == f_fss_complete_partial || complete == f_fss_complete_full || complete == f_fss_complete_next) {
-        status_allocation = private_fl_fss_destination_increase(destination);
-        if (F_status_is_error(status_allocation)) return status_allocation;
-
         destination->string[destination->used++] = f_fss_extended_next;
       }
 
       if (complete == f_fss_complete_full || complete == f_fss_complete_end) {
-        status_allocation = private_fl_fss_destination_increase(destination);
-        if (F_status_is_error(status_allocation)) return status_allocation;
-
         destination->string[destination->used++] = f_fss_extended_close;
       }
     }
index 94ba99e0d0c912210d4b44d48ccfc5837c19cce9..6d8caf2d7aa1132f5e9e48d59f5b3694b7b1cfa8 100644 (file)
@@ -6,7 +6,7 @@ extern "C" {
 #endif
 
 #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_)
-  f_return_status private_fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) {
+  f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_string_lengths_t *delimits) {
     f_status_t status = F_none;
 
     status = f_fss_skip_past_space(*buffer, range);
@@ -28,7 +28,7 @@ extern "C" {
     found->start = range->start;
 
     // ignore all comment lines.
-    if (buffer->string[range->start] == f_fss_comment) {
+    if (object_as && buffer->string[range->start] == f_fss_comment) {
       while (buffer->string[range->start] != f_string_eol[0]) {
         range->start++;
 
@@ -46,10 +46,10 @@ extern "C" {
     const f_string_length_t delimit_initial = delimits->used;
 
     // handle quoted support.
-    int8_t quote = 0;
+    int8_t quote_found = 0;
 
-    if (quoted) {
-      *quoted = 0;
+    if (quote) {
+      *quote = 0;
     }
 
     // identify where the object begins.
@@ -112,7 +112,7 @@ extern "C" {
         return F_none_stop;
       }
 
-      if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) {
+      if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double || (object_as && buffer->string[range->start] == f_fss_comment)) {
 
         // only the first slash before a quoted needs to be escaped (or not) as once there is a slash before a quoted, this cannot ever be a quote object.
         // this simplifies the number of slashes needed.
@@ -139,7 +139,7 @@ extern "C" {
       }
     }
     else if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) {
-      quote = buffer->string[range->start];
+      quote_found = buffer->string[range->start];
 
       status = f_utf_buffer_increment(*buffer, range, 1);
       if (F_status_is_error(status)) return status;
@@ -148,7 +148,7 @@ extern "C" {
     }
 
     // identify where the object ends.
-    if (!quote) {
+    if (!quote_found) {
       status = F_none;
 
       while (range->start <= range->stop && range->start < buffer->used) {
@@ -213,7 +213,7 @@ extern "C" {
             return F_unterminated_group_stop;
           }
 
-          if (buffer->string[range->start] == quote) {
+          if (buffer->string[range->start] == quote_found) {
             f_string_length_t location = range->start;
 
             // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted and delimits do not apply.
@@ -239,12 +239,12 @@ extern "C" {
             }
 
             if (status == F_true) {
-              if (quoted) {
-                if (quote == f_fss_delimit_quote_single) {
-                  *quoted = f_fss_quote_type_single;
+              if (quote) {
+                if (quote_found == f_fss_delimit_quote_single) {
+                  *quote = f_fss_quote_type_single;
                 }
-                else if (quote == f_fss_delimit_quote_double) {
-                  *quoted = f_fss_quote_type_double;
+                else if (quote_found == f_fss_delimit_quote_double) {
+                  *quote = f_fss_quote_type_double;
                 }
               }
 
@@ -355,7 +355,7 @@ extern "C" {
             }
           }
         }
-        else if (buffer->string[range->start] == quote) {
+        else if (buffer->string[range->start] == quote_found) {
           // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted.
           {
             f_string_length_t location = range->start;
@@ -385,12 +385,12 @@ extern "C" {
           }
 
           if (status == F_true) {
-            if (quoted) {
-              if (quote == f_fss_delimit_quote_single) {
-                *quoted = f_fss_quote_type_single;
+            if (quote) {
+              if (quote_found == f_fss_delimit_quote_single) {
+                *quote = f_fss_quote_type_single;
               }
-              else if (quote == f_fss_delimit_quote_double) {
-                *quoted = f_fss_quote_type_double;
+              else if (quote_found == f_fss_delimit_quote_double) {
+                *quote = f_fss_quote_type_double;
               }
             }
 
@@ -496,7 +496,7 @@ extern "C" {
 #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_)
 
 #if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) || !defined(_di_fl_fss_extended_content_write_)
-  f_return_status private_fl_fss_basic_object_write(const f_string_static_t object, const f_fss_quote_t quote, f_string_range_t *range, f_string_dynamic_t *destination) {
+  f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quote, f_string_range_t *range, f_string_dynamic_t *destination) {
     f_status_t status = F_none;
 
     fl_macro_fss_skip_past_delimit_placeholders(object, (*range));
@@ -517,6 +517,7 @@ extern "C" {
     const f_string_length_t used_start = destination->used;
 
     bool quoted = F_false;
+    bool commented = F_false;
 
     f_string_length_t item_first = 0;
     f_string_length_t item_total = 0;
@@ -531,6 +532,9 @@ extern "C" {
     if (object.string[input_start] == quote) {
       quoted = F_true;
     }
+    else if (object_as && object.string[input_start] == f_fss_comment) {
+      commented = F_true;
+    }
 
     uint8_t width = 0;
 
@@ -551,19 +555,30 @@ extern "C" {
         } // for
 
         if (range->start > range->stop || range->start >= object.used) {
+
+          // slashes before the final quote must be escaped when quoted, add the delimit slashes.
           if (quoted) {
 
-            // slashes before the final quote must be escaped when quoted, add the delimit slashes.
+            // if this is the first quote, then only a single delimit slash is needed.
             if (item_first == input_start) {
+              status = private_fl_fss_destination_increase(destination);
+              if (F_status_is_error(status)) break;
+
               destination->string[destination->used++] = f_fss_delimit_slash;
             }
             else {
+              status = private_fl_fss_destination_increase_by(item_total, destination);
+              if (F_status_is_error(status)) break;
+
               for (i = 0; i < item_total; i++) {
                 destination->string[destination->used++] = f_fss_delimit_slash;
               } // for
             }
           }
 
+          status = private_fl_fss_destination_increase_by(item_total, destination);
+          if (F_status_is_error(status)) break;
+
           for (i = 0; i < item_total; i++) {
             destination->string[destination->used++] = f_fss_delimit_slash;
           } // for
@@ -581,6 +596,9 @@ extern "C" {
           fl_macro_fss_skip_past_delimit_placeholders(object, (*range));
 
           if (range->start > range->stop || range->start >= object.used) {
+            status = private_fl_fss_destination_increase_by(item_total + 1, destination);
+            if (F_status_is_error(status)) break;
+
             for (i = 0; i < item_total; i++) {
               destination->string[destination->used++] = f_fss_delimit_slash;
             } // for
@@ -602,29 +620,53 @@ extern "C" {
 
             // add the slashes that delimit the slashes.
             if (item_first == input_start) {
+              status = private_fl_fss_destination_increase(destination);
+              if (F_status_is_error(status)) break;
+
               destination->string[destination->used++] = f_fss_delimit_slash;
             }
             else {
+              status = private_fl_fss_destination_increase_by(item_total, destination);
+              if (F_status_is_error(status)) break;
+
               for (i = 0; i < item_total; i++) {
                 destination->string[destination->used++] = f_fss_delimit_slash;
               } // for
             }
           }
 
+          width = f_macro_utf_byte_width(object.string[range->start]);
+
+          status = private_fl_fss_destination_increase_by(item_total + width + 1, destination);
+          if (F_status_is_error(status)) break;
+
           for (i = 0; i < item_total; i++) {
             destination->string[destination->used++] = f_fss_delimit_slash;
           } // for
 
           destination->string[destination->used++] = quote;
 
-          width = f_macro_utf_byte_width(object.string[range->start]);
+          for (i = 0; i < width; i++) {
+            destination->string[destination->used++] = object.string[range->start + i];
+          } // for
+        }
+        else if (object_as && object.string[range->start] == f_fss_comment) {
 
-          status = private_fl_fss_destination_increase_by(width, destination);
+          // only the first slash needs to be escaped for a comment, and then only if not quoted.
+          if (item_first == input_start) {
+            commented = F_true;
+          }
+
+          status = private_fl_fss_destination_increase_by(item_total + 1, destination);
           if (F_status_is_error(status)) break;
 
-          for (i = 0; i < width; i++) {
-            destination->string[destination->used++] = object.string[range->start + i];
+          for (i = 0; i < item_total; i++) {
+            destination->string[destination->used++] = f_fss_delimit_slash;
           } // for
+
+          destination->string[destination->used++] = object.string[range->start];
+          range->start++;
+          continue;
         }
         else {
 
@@ -636,13 +678,16 @@ extern "C" {
             quoted = F_true;
           }
 
+          width = f_macro_utf_byte_width(object.string[range->start]);
+
+          status = private_fl_fss_destination_increase_by(item_total + width, destination);
+          if (F_status_is_error(status)) break;
+
           // there is nothing to delimit, so all slashes should be printed as is.
           for (i = 0; i < item_total; i++) {
             destination->string[destination->used++] = f_fss_delimit_slash;
           } // for
 
-          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;
 
@@ -656,17 +701,26 @@ extern "C" {
 
         // the very first quote, must be escaped, when quoting is disabled.
         if (item_first == input_start) {
+          status = private_fl_fss_destination_increase(destination);
+          if (F_status_is_error(status)) break;
+
           destination->string[used_start + 1] = f_fss_delimit_slash;
         }
 
         fl_macro_fss_skip_past_delimit_placeholders(object, (*range));
 
         if (range->start > range->stop || range->start >= object.used) {
+          status = private_fl_fss_destination_increase(destination);
+          if (F_status_is_error(status)) break;
+
           destination->string[destination->used++] = quote;
           break;
         }
 
         if (object.string[range->start] == quote) {
+          status = private_fl_fss_destination_increase(destination);
+          if (F_status_is_error(status)) break;
+
           destination->string[destination->used++] = quote;
 
           // the next quote must also be checked, so do not increment.
@@ -678,23 +732,23 @@ extern "C" {
         if (F_status_is_error(status)) break;
 
         if (status == F_true) {
-          status = private_fl_fss_destination_increase(destination);
-          if (F_status_is_error(status)) break;
-
           if (item_first != input_start) {
+            status = private_fl_fss_destination_increase(destination);
+            if (F_status_is_error(status)) break;
+
             destination->string[destination->used++] = f_fss_delimit_slash;
           }
 
           quoted = F_true;
         }
 
-        destination->string[destination->used++] = quote;
-
         width = f_macro_utf_byte_width(object.string[range->start]);
 
-        status = private_fl_fss_destination_increase_by(width, destination);
+        status = private_fl_fss_destination_increase_by(1 + width, destination);
         if (F_status_is_error(status)) break;
 
+        destination->string[destination->used++] = quote;
+
         for (i = 0; i < width; i++) {
           destination->string[destination->used++] = object.string[range->start + i];
         } // for
@@ -704,7 +758,6 @@ extern "C" {
         break;
       }
       else if (object.string[range->start] != f_fss_delimit_placeholder) {
-
         if (!quoted) {
           status = f_fss_is_space(object, *range);
           if (F_status_is_error(status)) break;
@@ -734,6 +787,13 @@ extern "C" {
     }
 
     if (quoted) {
+      status = private_fl_fss_destination_increase(destination);
+
+      if (F_status_is_error(status)) {
+        destination->used = used_start;
+        return status;
+      }
+
       destination->string[used_start] = quote;
       destination->string[destination->used++] = quote;
 
@@ -762,6 +822,9 @@ extern "C" {
         }
       }
     }
+    else if (commented) {
+      destination->string[used_start] = f_fss_delimit_slash;
+    }
 
     if (range->start > range->stop) {
       return F_none_stop;
index 94a47c86044b00c32c8239fdc3d1fc0850ba5a1d..b42c3caa70dd3637576f9a579bda15d50561a916 100644 (file)
@@ -20,6 +20,12 @@ extern "C" {
  *
  * Intended to be shared to each of the different implementation variations.
  *
+ * @param object_as
+ *   If TRUE, then this operate as an Object.
+ *   IF FALSE, then this operates as a Content.
+ *
+ *   As Object, this checks if the first graph character is a comment character '#', or an escaped comment character '#'.
+ *   As Content, this does nothing special in regards to a leading '#'.
  * @param buffer
  *   The buffer to read from.
  *   This will be updated with delimit placeholders as it is being processed.
@@ -63,7 +69,7 @@ extern "C" {
  * @see fl_fss_extended_object_read()
  */
 #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_)
-  extern f_return_status private_fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) f_gcc_attribute_visibility_internal;
+  extern f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) f_gcc_attribute_visibility_internal;
 #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_)
 
 /**
@@ -73,6 +79,12 @@ extern "C" {
  *
  * Note: this does not attempt to "complete" the object.
  *
+ * @param object_as
+ *   If TRUE, then this operate as an Object.
+ *   IF FALSE, then this operates as a Content.
+ *
+ *   As Object, this checks if the first graph character is a comment character '#', or an escaped comment character '#'.
+ *   As Content, this does nothing special in regards to a leading '#'.
  * @param object
  *   The string to write as (does not stop at NULLS, they are ignored and not written).
  * @param quoted
@@ -103,7 +115,7 @@ extern "C" {
  * @see fl_fss_extended_content_write()
  */
 #if !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) || !defined(_di_fl_fss_extended_content_write_)
-  extern f_return_status private_fl_fss_basic_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_gcc_attribute_visibility_internal;
+  extern f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal;
 #endif // !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) || !defined(_di_fl_fss_extended_content_write_)
 
 /**
index 27a819aea2a1a461ff29ef12aa62c79f1a44b4fc..4c1310cc3fd148f07c1c8d2cd7b3a79dca90613d 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
     fll_program_print_help_option(file, context, fss_basic_list_read_short_line, fss_basic_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print only the content at the given line.");
     fll_program_print_help_option(file, context, fss_basic_list_read_short_name, fss_basic_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Select object with this name.");
     fll_program_print_help_option(file, context, fss_basic_list_read_short_object, fss_basic_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Print the object.");
+    fll_program_print_help_option(file, context, fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print using the special pipe format.");
     fll_program_print_help_option(file, context, fss_basic_list_read_short_select, fss_basic_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Select sub-content at this index.");
     fll_program_print_help_option(file, context, fss_basic_list_read_short_total, fss_basic_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Print the total number of lines.");
     fll_program_print_help_option(file, context, fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Trim object names on select or print.");
@@ -209,71 +210,64 @@ extern "C" {
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_at);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_depth].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_depth);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_name].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_name);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]);
 
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
       if (data->parameters[fss_basic_list_read_parameter_object].result == f_console_result_found) {
-        if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_basic_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
-        if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_select);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_basic_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
         if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
-          if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+          if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
             fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot 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_read_long_object);
             fl_color_print(data->error.to.stream, data->context.set.error, "' and the '");
@@ -282,64 +276,68 @@ extern "C" {
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-            fss_basic_list_read_delete_data(data);
-            return F_status_set_error(F_parameter);
+            status = F_status_set_error(F_parameter);
           }
         }
       }
 
       if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
-        if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_basic_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
+        }
+      }
+
+      if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_pipe);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_read_long_total);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+          status = F_status_set_error(F_parameter);
         }
       }
 
       fss_basic_list_read_depths_t depths = fss_basic_list_read_depths_t_initialize;
 
-      f_string_length_t counter = 0;
       f_string_length_t original_size = data->quantity.total;
 
-      status = fss_basic_list_read_main_preprocess_depth(arguments, *data, &depths);
+      if (F_status_is_error_not(status)) {
+        status = fss_basic_list_read_main_preprocess_depth(arguments, *data, &depths);
 
-      if (F_status_is_error(status)) {
-        macro_fss_basic_list_read_depths_t_delete_simple(depths);
-        fss_basic_list_read_delete_data(data);
-        return status;
+        if (F_status_is_error(status)) {
+          fll_error_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_preprocess_depth", F_true);
+        }
       }
 
       // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file.
-      if (depths.array[0].depth > 0) {
+      if (F_status_is_error_not(status) && depths.array[0].depth > 0) {
         macro_fss_basic_list_read_depths_t_delete_simple(depths);
 
         if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
           fprintf(f_type_output, "0%c", f_string_eol[0]);
-
-          fss_basic_list_read_delete_data(data);
-          return F_none;
         }
 
         fss_basic_list_read_delete_data(data);
         return F_none;
       }
 
-      if (data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_list_read_parameter_select].result == f_console_result_found) {
         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_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]);
 
-        macro_fss_basic_list_read_depths_t_delete_simple(depths);
-        fss_basic_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->process_pipe) {
+      if (F_status_is_error_not(status) && data->process_pipe) {
         f_file_t file = f_file_t_initialize;
 
         file.id = f_type_descriptor_input;
@@ -347,19 +345,14 @@ extern "C" {
         status = f_file_read(file, &data->buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file);
-
-          macro_fss_basic_list_read_depths_t_delete_simple(depths);
-          fss_basic_list_read_delete_data(data);
-          return status;
+          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe);
         }
+        else {
+          status = fss_basic_list_read_main_process_file(arguments, data, "-", depths);
 
-        status = fss_basic_list_read_main_process_file(arguments, data, "-", depths);
-
-        if (F_status_is_error(status)) {
-          macro_fss_basic_list_read_depths_t_delete_simple(depths);
-          fss_basic_list_read_delete_data(data);
-          return status;
+          if (F_status_is_error(status)) {
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe);
+          }
         }
 
         // Clear buffers before continuing.
@@ -368,32 +361,27 @@ extern "C" {
         f_macro_string_dynamic_t_delete_simple(data->buffer);
       }
 
-      if (data->remaining.used > 0) {
-        for (; counter < data->remaining.used; counter++) {
+      if (F_status_is_error_not(status) && data->remaining.used > 0) {
+        for (f_array_length_t i = 0; i < data->remaining.used; i++) {
           f_file_t file = f_file_t_initialize;
 
-          status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file);
+          status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file);
 
           data->quantity.total = original_size;
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file);
-
-            macro_fss_basic_list_read_depths_t_delete_simple(depths);
-            fss_basic_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file);
+            break;
           }
 
           if (!data->quantity.total) {
             status = f_file_size_by_id(file.id, &data->quantity.total);
+
             if (F_status_is_error(status)) {
-              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
+              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
 
               f_file_stream_close(F_true, &file);
-
-              macro_fss_basic_list_read_depths_t_delete_simple(depths);
-              fss_basic_list_read_delete_data(data);
-              return status;
+              break;
             }
 
             // Skip past empty files.
@@ -412,19 +400,15 @@ extern "C" {
           f_file_stream_close(F_true, &file);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
-
-            macro_fss_basic_list_read_depths_t_delete_simple(depths);
-            fss_basic_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
-          status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths);
+          status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths);
 
           if (F_status_is_error(status)) {
-            macro_fss_basic_list_read_depths_t_delete_simple(depths);
-            fss_basic_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
           // Clear buffers before repeating the loop.
@@ -432,6 +416,12 @@ extern "C" {
           f_macro_fss_objects_t_delete_simple(data->objects);
           f_macro_string_dynamic_t_delete_simple(data->buffer);
         } // for
+
+        if (F_status_is_error(status)) {
+          f_macro_fss_contents_t_delete_simple(data->contents);
+          f_macro_fss_objects_t_delete_simple(data->objects);
+          f_macro_string_dynamic_t_delete_simple(data->buffer);
+        }
       }
 
       macro_fss_basic_list_read_depths_t_delete_simple(depths);
index 192db763446679d69be67745910e2e15ea63a978..c284d4d8dd080d8e524fc957a8a46d1fb63983a8 100644 (file)
@@ -62,6 +62,9 @@ extern "C" {
 #endif // _di_fss_basic_list_read_name_
 
 #ifndef _di_fss_basic_list_read_defines_
+  #define fss_basic_list_read_pipe_content_start '\0'
+  #define fss_basic_list_read_pipe_content_end   '\f'
+
   #define fss_basic_list_read_short_at      "a"
   #define fss_basic_list_read_short_content "c"
   #define fss_basic_list_read_short_depth   "d"
@@ -69,6 +72,7 @@ extern "C" {
   #define fss_basic_list_read_short_line    "l"
   #define fss_basic_list_read_short_name    "n"
   #define fss_basic_list_read_short_object  "o"
+  #define fss_basic_list_read_short_pipe    "p"
   #define fss_basic_list_read_short_select  "s"
   #define fss_basic_list_read_short_total   "t"
   #define fss_basic_list_read_short_trim    "T"
@@ -80,6 +84,7 @@ extern "C" {
   #define fss_basic_list_read_long_line    "line"
   #define fss_basic_list_read_long_name    "name"
   #define fss_basic_list_read_long_object  "object"
+  #define fss_basic_list_read_long_pipe    "pipe"
   #define fss_basic_list_read_long_select  "select"
   #define fss_basic_list_read_long_total   "total"
   #define fss_basic_list_read_long_trim    "trim"
@@ -102,6 +107,7 @@ extern "C" {
     fss_basic_list_read_parameter_line,
     fss_basic_list_read_parameter_name,
     fss_basic_list_read_parameter_object,
+    fss_basic_list_read_parameter_pipe,
     fss_basic_list_read_parameter_select,
     fss_basic_list_read_parameter_total,
     fss_basic_list_read_parameter_trim,
@@ -125,12 +131,13 @@ extern "C" {
       f_console_parameter_t_initialize(fss_basic_list_read_short_line, fss_basic_list_read_long_line, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_list_read_short_name, fss_basic_list_read_long_name, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_list_read_short_object, fss_basic_list_read_long_object, 0, 0, f_console_type_normal), \
+      f_console_parameter_t_initialize(fss_basic_list_read_short_pipe, fss_basic_list_read_long_pipe, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_list_read_short_select, fss_basic_list_read_long_select, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_list_read_short_total, fss_basic_list_read_long_total, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_list_read_short_trim, fss_basic_list_read_long_trim, 0, 0, f_console_type_normal), \
     }
 
-  #define fss_basic_list_read_total_parameters 19
+  #define fss_basic_list_read_total_parameters 20
 #endif // _di_fss_basic_list_read_defines_
 
 #ifndef _di_fss_basic_list_read_data_t_
index 2d0d1a2c2f5f818282e0078f27efa9ca88ffb007..9f1e8125c03206fb413408af8250d4a0c15f8970 100644 (file)
@@ -182,39 +182,10 @@ extern "C" {
       status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents);
 
       if (F_status_is_error(status)) {
-        status = F_status_set_fine(status);
-
-        if (status == F_parameter) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
-        else if (status == F_memory_allocation || status == F_memory_reallocation) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_stop) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_eos) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status);
-          fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling ");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
+        // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate.
+        fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, filename, "process", fll_error_file_type_file);
 
-        return F_status_set_error(status);
+        return status;
       }
       else if (status == F_data_not_stop || status == F_data_not_eos) {
         if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) {
@@ -353,16 +324,14 @@ extern "C" {
               print_object(f_type_output, data->buffer, data->objects.array[i]);
 
               if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
+                fss_basic_list_read_print_object_end(*data);
+
                 if (data->contents.array[i].used) {
-                  fprintf(f_type_output, "%c", f_fss_eol);
                   f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
                 }
-                else {
-                  fprintf(f_type_output, "%c", f_fss_eol);
-                }
               }
 
-              fprintf(f_type_output, "%c", f_fss_eol);
+              fss_basic_list_read_print_set_end(*data);
               break;
             }
 
@@ -379,16 +348,14 @@ extern "C" {
         print_object(f_type_output, data->buffer, data->objects.array[i]);
 
         if (data->parameters[fss_basic_list_read_parameter_content].result == f_console_result_found) {
+          fss_basic_list_read_print_object_end(*data);
+
           if (data->contents.array[i].used) {
-            fprintf(f_type_output, "%c", f_fss_eol);
             f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
           }
-          else {
-            fprintf(f_type_output, "%c", f_fss_eol);
-          }
         }
 
-        fprintf(f_type_output, "%c", f_fss_eol);
+        fss_basic_list_read_print_set_end(*data);
       } // for
 
       return F_none;
@@ -433,7 +400,7 @@ extern "C" {
             if (data->parameters[fss_basic_list_read_parameter_line].result == f_console_result_additional) {
               if (!data->contents.array[i].used) {
                 if (include_empty && !line) {
-                  fprintf(f_type_output, "%c", f_string_eol[0]);
+                  fss_basic_list_read_print_set_end(*data);
                 }
               }
               else {
@@ -485,9 +452,13 @@ extern "C" {
 
             if (data->contents.array[i].used > 0) {
               f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
+
+              if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+                fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end);
+              }
             }
             else if (include_empty) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_basic_list_read_print_set_end(*data);
             }
 
             break;
@@ -534,7 +505,7 @@ extern "C" {
         if (!data->contents.array[i].used) {
           if (include_empty) {
             if (line_current == line) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_basic_list_read_print_set_end(*data);
               break;
             }
 
@@ -586,19 +557,59 @@ extern "C" {
 
       if (!data->contents.array[i].used) {
         if (include_empty) {
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_basic_list_read_print_set_end(*data);
         }
 
         continue;
       }
 
       f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
+
+      if (data->parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+        fprintf(data->output.stream, "%c", fss_basic_list_read_pipe_content_end);
+      }
     } // for
 
     return F_none;
   }
 #endif // _di_fss_basic_list_read_main_process_file_
 
+#ifndef _di_fss_basic_list_read_print_object_end_
+  void fss_basic_list_read_print_object_end(const fss_basic_list_read_data_t data) {
+
+    if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_object_end_
+
+#ifndef _di_fss_basic_list_read_print_content_end_
+  void fss_basic_list_read_print_content_end(const fss_basic_list_read_data_t data) {
+
+    if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_content_end_
+
+#ifndef _di_fss_basic_list_read_print_set_end_
+  void fss_basic_list_read_print_set_end(const fss_basic_list_read_data_t data) {
+
+    if (data.parameters[fss_basic_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_basic_list_read_pipe_content_end);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_basic_list_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 53163026f32c9cf2e5b6708036e4f013cddfbd0c..7981f939e0ddef0e3755e549c167329977269952 100644 (file)
@@ -199,6 +199,36 @@ extern "C" {
   extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t file_name, const fss_basic_list_read_depths_t depths) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_basic_list_read_main_process_file_
 
+/**
+ * Print the end of an object (which is essentially the start of a content).
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_basic_list_read_print_object_end_
+  extern void fss_basic_list_read_print_object_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_object_end_
+
+/**
+ * Print the end of an content.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_basic_list_read_print_content_end_
+  extern void fss_basic_list_read_print_content_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_content_end_
+
+/**
+ * Print the end of an object/content set.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_basic_list_read_print_set_end_
+  extern void fss_basic_list_read_print_set_end(const fss_basic_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_list_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index c660853793dbbb5de8ac15eefe8e970ee6538e3e..a2c051151321550374263231cd23d789ff69e1ad 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
     fll_program_print_help_option(file, context, fss_basic_read_short_line, fss_basic_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print only the content at the given line.");
     fll_program_print_help_option(file, context, fss_basic_read_short_name, fss_basic_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Select object with this name.");
     fll_program_print_help_option(file, context, fss_basic_read_short_object, fss_basic_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Print the object.");
+    fll_program_print_help_option(file, context, fss_basic_read_short_pipe, fss_basic_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print using the special pipe format.");
     fll_program_print_help_option(file, context, fss_basic_read_short_select, fss_basic_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Select sub-content at this index.");
     fll_program_print_help_option(file, context, fss_basic_read_short_total, fss_basic_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Print the total number of lines.");
     fll_program_print_help_option(file, context, fss_basic_read_short_trim, fss_basic_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Trim object names on select or print.");
@@ -209,71 +210,64 @@ extern "C" {
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_at);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_read_parameter_depth].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_depth].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_depth);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_line].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_read_parameter_name].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_name].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_name);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]);
 
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
       if (data->parameters[fss_basic_read_parameter_object].result == f_console_result_found) {
-        if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.");
 
-          fss_basic_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
-        if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_select);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_basic_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
         if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) {
-          if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
+          if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
             fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot 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_read_long_object);
             fl_color_print(data->error.to.stream, data->context.set.error, "' and the '");
@@ -282,63 +276,69 @@ extern "C" {
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-            fss_basic_read_delete_data(data);
-            return F_status_set_error(F_parameter);
+            status = F_status_set_error(F_parameter);
           }
         }
       }
 
       if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) {
-        if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_basic_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
+        }
+      }
+
+      if (data->parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_pipe);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_read_long_total);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+          status = F_status_set_error(F_parameter);
         }
       }
 
       fss_basic_read_depths_t depths = fss_basic_read_depths_t_initialize;
 
-      f_string_length_t counter = 0;
       f_string_length_t original_size = data->quantity.total;
 
-      status = fss_basic_read_main_preprocess_depth(arguments, *data, &depths);
-      if (F_status_is_error(status)) {
-        macro_fss_basic_read_depths_t_delete_simple(depths);
-        fss_basic_read_delete_data(data);
-        return status;
+      if (F_status_is_error_not(status)) {
+        status = fss_basic_read_main_preprocess_depth(arguments, *data, &depths);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data->error, F_status_set_fine(status), "fss_basic_read_main_preprocess_depth", F_true);
+        }
       }
 
       // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file.
-      if (depths.array[0].depth > 0) {
+      if (F_status_is_error_not(status) && depths.array[0].depth > 0) {
         macro_fss_basic_read_depths_t_delete_simple(depths);
 
         if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
           fprintf(f_type_output, "0%c", f_string_eol[0]);
-
-          fss_basic_read_delete_data(data);
-          return F_none;
         }
 
         fss_basic_read_delete_data(data);
         return F_none;
       }
 
-      if (data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_basic_read_parameter_select].result == f_console_result_found) {
         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_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]);
 
         macro_fss_basic_read_depths_t_delete_simple(depths);
-        fss_basic_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->process_pipe) {
+      if (F_status_is_error_not(status) && data->process_pipe) {
         f_file_t file = f_file_t_initialize;
 
         file.id = f_type_descriptor_input;
@@ -346,19 +346,14 @@ extern "C" {
         status = f_file_read(file, &data->buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file);
-
-          macro_fss_basic_read_depths_t_delete_simple(depths);
-          fss_basic_read_delete_data(data);
-          return status;
+          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe);
         }
+        else {
+          status = fss_basic_read_main_process_file(arguments, data, "-", depths);
 
-        status = fss_basic_read_main_process_file(arguments, data, "-", depths);
-
-        if (F_status_is_error(status)) {
-          macro_fss_basic_read_depths_t_delete_simple(depths);
-          fss_basic_read_delete_data(data);
-          return status;
+          if (F_status_is_error(status)) {
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe);
+          }
         }
 
         // Clear buffers before continuing.
@@ -367,33 +362,27 @@ extern "C" {
         f_macro_string_dynamic_t_delete_simple(data->buffer);
       }
 
-      if (data->remaining.used > 0) {
-        for (; counter < data->remaining.used; counter++) {
+      if (F_status_is_error_not(status) && data->remaining.used > 0) {
+        for (f_array_length_t i = 0; i < data->remaining.used; i++) {
           f_file_t file = f_file_t_initialize;
 
-          status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file);
+          status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file);
 
           data->quantity.total = original_size;
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file);
-
-            macro_fss_basic_read_depths_t_delete_simple(depths);
-            fss_basic_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file);
+            break;
           }
 
           if (!data->quantity.total) {
             status = f_file_size_by_id(file.id, &data->quantity.total);
 
             if (F_status_is_error(status)) {
-              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
+              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
 
               f_file_stream_close(F_true, &file);
-
-              macro_fss_basic_read_depths_t_delete_simple(depths);
-              fss_basic_read_delete_data(data);
-              return status;
+              break;
             }
 
             // Skip past empty files.
@@ -412,19 +401,15 @@ extern "C" {
           f_file_stream_close(F_true, &file);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
-
-            macro_fss_basic_read_depths_t_delete_simple(depths);
-            fss_basic_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
-          status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths);
+          status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths);
 
           if (F_status_is_error(status)) {
-            macro_fss_basic_read_depths_t_delete_simple(depths);
-            fss_basic_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
           // Clear buffers before repeating the loop.
@@ -432,6 +417,12 @@ extern "C" {
           f_macro_fss_objects_t_delete_simple(data->objects);
           f_macro_string_dynamic_t_delete_simple(data->buffer);
         } // for
+
+        if (F_status_is_error(status)) {
+          f_macro_fss_contents_t_delete_simple(data->contents);
+          f_macro_fss_objects_t_delete_simple(data->objects);
+          f_macro_string_dynamic_t_delete_simple(data->buffer);
+        }
       }
 
       macro_fss_basic_read_depths_t_delete_simple(depths);
index 1709fb5bd88f2f2292997e36f159c37061bdc1f3..ea35952769f3623c1b0e4a7e58681a54752f98ea 100644 (file)
@@ -62,6 +62,9 @@ extern "C" {
 #endif // _di_fss_basic_read_name_
 
 #ifndef _di_fss_basic_read_defines_
+  #define fss_basic_read_pipe_content_start '\0'
+  #define fss_basic_read_pipe_content_end   '\f'
+
   #define fss_basic_read_short_at      "a"
   #define fss_basic_read_short_content "c"
   #define fss_basic_read_short_depth   "d"
@@ -69,6 +72,7 @@ extern "C" {
   #define fss_basic_read_short_line    "l"
   #define fss_basic_read_short_name    "n"
   #define fss_basic_read_short_object  "o"
+  #define fss_basic_read_short_pipe    "p"
   #define fss_basic_read_short_select  "s"
   #define fss_basic_read_short_total   "t"
   #define fss_basic_read_short_trim    "T"
@@ -80,6 +84,7 @@ extern "C" {
   #define fss_basic_read_long_line    "line"
   #define fss_basic_read_long_name    "name"
   #define fss_basic_read_long_object  "object"
+  #define fss_basic_read_long_pipe    "pipe"
   #define fss_basic_read_long_select  "select"
   #define fss_basic_read_long_total   "total"
   #define fss_basic_read_long_trim    "trim"
@@ -102,6 +107,7 @@ extern "C" {
     fss_basic_read_parameter_line,
     fss_basic_read_parameter_name,
     fss_basic_read_parameter_object,
+    fss_basic_read_parameter_pipe,
     fss_basic_read_parameter_select,
     fss_basic_read_parameter_total,
     fss_basic_read_parameter_trim,
@@ -125,12 +131,13 @@ extern "C" {
       f_console_parameter_t_initialize(fss_basic_read_short_line, fss_basic_read_long_line, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_read_short_name, fss_basic_read_long_name, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_read_short_object, fss_basic_read_long_object, 0, 0, f_console_type_normal), \
+      f_console_parameter_t_initialize(fss_basic_read_short_pipe, fss_basic_read_long_pipe, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_read_short_select, fss_basic_read_long_select, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_read_short_total, fss_basic_read_long_total, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_basic_read_short_trim, fss_basic_read_long_trim, 0, 0, f_console_type_normal), \
     }
 
-  #define fss_basic_read_total_parameters 19
+  #define fss_basic_read_total_parameters 20
 #endif // _di_fss_basic_read_defines_
 
 #ifndef _di_fss_basic_read_data_t_
index cb6b9cfc5b42b9fc93a40964f73dea6af8c5fadb..477fad430b97d4fdb5519646c7e5a2303f87737c 100644 (file)
@@ -182,39 +182,10 @@ extern "C" {
       status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0);
 
       if (F_status_is_error(status)) {
-        status = F_status_set_fine(status);
-
-        if (status == F_parameter) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
-        else if (status == F_memory_allocation || status == F_memory_reallocation) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_stop) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_eos) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status);
-          fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling ");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_basic_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
+        // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate.
+        fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, filename, "process", fll_error_file_type_file);
 
-        return F_status_set_error(status);
+        return status;
       }
       else if (status == F_data_not_stop || status == F_data_not_eos) {
         if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) {
@@ -353,12 +324,12 @@ extern "C" {
 
               if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) {
                 if (data->contents.array[i].used) {
-                  fprintf(f_type_output, "%c", f_fss_space);
+                  fss_basic_read_print_object_end(*data);
                   f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
                 }
               }
 
-              fprintf(f_type_output, "%c", f_fss_eol);
+              fss_basic_read_print_set_end(*data);
               break;
             }
 
@@ -376,12 +347,12 @@ extern "C" {
 
         if (data->parameters[fss_basic_read_parameter_content].result == f_console_result_found) {
           if (data->contents.array[i].used) {
-            fprintf(f_type_output, "%c", f_fss_space);
+            fss_basic_read_print_object_end(*data);
             f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
           }
         }
 
-        fprintf(f_type_output, "%c", f_fss_eol);
+        fss_basic_read_print_set_end(*data);
       } // for
 
       return F_none;
@@ -419,19 +390,19 @@ extern "C" {
             else if (data->parameters[fss_basic_read_parameter_line].result == f_console_result_additional) {
               if (data->contents.array[i].used > 0) {
                 f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_basic_read_print_set_end(*data);
               }
               else if (include_empty) {
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_basic_read_print_set_end(*data);
               }
             }
             else {
               if (data->contents.array[i].used > 0) {
                 f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_basic_read_print_set_end(*data);
               }
               else if (include_empty) {
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_basic_read_print_set_end(*data);
               }
             }
 
@@ -471,7 +442,7 @@ extern "C" {
         if (!data->contents.array[i].used) {
           if (include_empty) {
             if (line_current == line) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_basic_read_print_set_end(*data);
               break;
             }
 
@@ -483,7 +454,7 @@ extern "C" {
 
         if (line_current == line) {
           f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_basic_read_print_set_end(*data);
 
           break;
         }
@@ -499,20 +470,44 @@ extern "C" {
 
       if (!data->contents.array[i].used) {
         if (include_empty) {
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_basic_read_print_set_end(*data);
         }
 
         continue;
       }
 
       f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[0]);
-      fprintf(f_type_output, "%c", f_string_eol[0]);
+      fss_basic_read_print_set_end(*data);
     } // for
 
     return F_none;
   }
 #endif // _di_fss_basic_read_main_process_file_
 
+#ifndef _di_fss_basic_read_print_object_end_
+  void fss_basic_read_print_object_end(const fss_basic_read_data_t data) {
+
+    if (data.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_basic_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_space);
+    }
+  }
+#endif // _di_fss_basic_read_print_object_end_
+
+#ifndef _di_fss_basic_read_print_set_end_
+  void fss_basic_read_print_set_end(const fss_basic_read_data_t data) {
+
+    if (data.parameters[fss_basic_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_basic_read_pipe_content_end);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_basic_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index dd6d371a1112c286b5b4f3467d8a63d3e7cf5998..7cd013812358d5e23d0a4216e778eb8d63d94450 100644 (file)
@@ -195,6 +195,26 @@ extern "C" {
   extern f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t file_name, const fss_basic_read_depths_t depths) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_basic_read_main_process_file_
 
+/**
+ * Print the end of an object (which is essentially the start of a content).
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_basic_read_print_object_end_
+  extern void fss_basic_read_print_object_end(const fss_basic_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_read_print_object_end_
+
+/**
+ * Print the end of an object/content set.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_basic_read_print_set_end_
+  extern void fss_basic_read_print_set_end(const fss_basic_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 500a89bd7faee909c93cd9331abed25ed4333ebe..85b4268cf120fcdbebc8b1206431940af48c6368 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
     fll_program_print_help_option(file, context, fss_extended_list_read_short_line, fss_extended_list_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print only the content at the given line.");
     fll_program_print_help_option(file, context, fss_extended_list_read_short_name, fss_extended_list_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Select object with this name.");
     fll_program_print_help_option(file, context, fss_extended_list_read_short_object, fss_extended_list_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Print the object.");
+    fll_program_print_help_option(file, context, fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print using the special pipe format.");
     fll_program_print_help_option(file, context, fss_extended_list_read_short_select, fss_extended_list_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Select sub-content at this index.");
     fll_program_print_help_option(file, context, fss_extended_list_read_short_total, fss_extended_list_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Print the total number of lines.");
     fll_program_print_help_option(file, context, fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Trim object names on select or print.");
@@ -209,71 +210,64 @@ extern "C" {
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_at);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_depth].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_depth);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_name].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_name);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]);
 
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
       if (data->parameters[fss_extended_list_read_parameter_object].result == f_console_result_found) {
-        if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
-        if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_select);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
         if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) {
-          if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
+          if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
             fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot 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_extended_list_read_long_object);
             fl_color_print(data->error.to.stream, data->context.set.error, "' and the '");
@@ -282,49 +276,56 @@ extern "C" {
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-            fss_extended_list_read_delete_data(data);
-            return F_status_set_error(F_parameter);
+            status = F_status_set_error(F_parameter);
           }
         }
       }
 
       if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) {
-        if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_list_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
+        }
+      }
+
+      if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_pipe);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_list_read_long_total);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+          status = F_status_set_error(F_parameter);
         }
       }
 
       fss_extended_list_read_depths_t depths = fss_extended_list_read_depths_t_initialize;
 
-      f_string_length_t counter = 0;
       f_string_length_t original_size = data->quantity.total;
 
-      status = fss_extended_list_read_main_preprocess_depth(arguments, *data, &depths);
+      if (F_status_is_error_not(status)) {
+        status = fss_extended_list_read_main_preprocess_depth(arguments, *data, &depths);
 
-      if (F_status_is_error(status)) {
-        macro_fss_extended_list_read_depths_t_delete_simple(depths);
-        fss_extended_list_read_delete_data(data);
-        return status;
+        if (F_status_is_error(status)) {
+          fll_error_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_preprocess_depth", F_true);
+        }
       }
 
-      if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) {
         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_list_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]);
 
-        macro_fss_extended_list_read_depths_t_delete_simple(depths);
-        fss_extended_list_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->process_pipe) {
+      if (F_status_is_error_not(status) && data->process_pipe) {
         f_file_t file = f_file_t_initialize;
 
         file.id = f_type_descriptor_input;
@@ -332,19 +333,14 @@ extern "C" {
         status = f_file_read(file, &data->buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file);
-
-          macro_fss_extended_list_read_depths_t_delete_simple(depths);
-          fss_extended_list_read_delete_data(data);
-          return status;
+          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe);
         }
+        else {
+          status = fss_extended_list_read_main_process_file(arguments, data, "-", depths);
 
-        status = fss_extended_list_read_main_process_file(arguments, data, "-", depths);
-
-        if (F_status_is_error(status)) {
-          macro_fss_extended_list_read_depths_t_delete_simple(depths);
-          fss_extended_list_read_delete_data(data);
-          return status;
+          if (F_status_is_error(status)) {
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe);
+          }
         }
 
         // Clear buffers before continuing.
@@ -352,32 +348,26 @@ extern "C" {
         f_macro_string_dynamic_t_delete_simple(data->buffer);
       }
 
-      if (data->remaining.used > 0) {
-        for (; counter < data->remaining.used; counter++) {
+      if (F_status_is_error_not(status) && data->remaining.used > 0) {
+        for (f_array_length_t i = 0; i < data->remaining.used; i++) {
           f_file_t file = f_file_t_initialize;
 
-          status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file);
+          status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file);
 
           data->quantity.total = original_size;
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file);
-
-            macro_fss_extended_list_read_depths_t_delete_simple(depths);
-            fss_extended_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file);
+            break;
           }
 
           if (!data->quantity.total) {
             status = f_file_size_by_id(file.id, &data->quantity.total);
             if (F_status_is_error(status)) {
-              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
+              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
 
               f_file_stream_close(F_true, &file);
-
-              macro_fss_extended_list_read_depths_t_delete_simple(depths);
-              fss_extended_list_read_delete_data(data);
-              return status;
+              break;
             }
 
             // Skip past empty files.
@@ -396,25 +386,26 @@ extern "C" {
           f_file_stream_close(F_true, &file);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
-
-            macro_fss_extended_list_read_depths_t_delete_simple(depths);
-            fss_extended_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
-          status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths);
+          status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths);
 
           if (F_status_is_error(status)) {
-            macro_fss_extended_list_read_depths_t_delete_simple(depths);
-            fss_extended_list_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
           // Clear buffers before repeating the loop.
           f_macro_fss_nest_t_delete_simple(data->nest);
           f_macro_string_dynamic_t_delete_simple(data->buffer);
         } // for
+
+        if (F_status_is_error(status)) {
+          f_macro_fss_nest_t_delete_simple(data->nest);
+          f_macro_string_dynamic_t_delete_simple(data->buffer);
+        }
       }
 
       macro_fss_extended_list_read_depths_t_delete_simple(depths);
index 516b305cfaa0481e215163833e4994410cd3eb47..57942c361d32ae6adf6739fecc8d8feb2a657b13 100644 (file)
@@ -62,6 +62,9 @@ extern "C" {
 #endif // _di_fss_extended_list_read_name_
 
 #ifndef _di_fss_extended_list_read_defines_
+  #define fss_extended_list_read_pipe_content_start '\0'
+  #define fss_extended_list_read_pipe_content_end   '\f'
+
   #define fss_extended_list_read_short_at      "a"
   #define fss_extended_list_read_short_content "c"
   #define fss_extended_list_read_short_depth   "d"
@@ -69,6 +72,7 @@ extern "C" {
   #define fss_extended_list_read_short_line    "l"
   #define fss_extended_list_read_short_name    "n"
   #define fss_extended_list_read_short_object  "o"
+  #define fss_extended_list_read_short_pipe    "p"
   #define fss_extended_list_read_short_select  "s"
   #define fss_extended_list_read_short_total   "t"
   #define fss_extended_list_read_short_trim    "T"
@@ -80,6 +84,7 @@ extern "C" {
   #define fss_extended_list_read_long_line    "line"
   #define fss_extended_list_read_long_name    "name"
   #define fss_extended_list_read_long_object  "object"
+  #define fss_extended_list_read_long_pipe    "pipe"
   #define fss_extended_list_read_long_select  "select"
   #define fss_extended_list_read_long_total   "total"
   #define fss_extended_list_read_long_trim    "trim"
@@ -102,6 +107,7 @@ extern "C" {
     fss_extended_list_read_parameter_line,
     fss_extended_list_read_parameter_name,
     fss_extended_list_read_parameter_object,
+    fss_extended_list_read_parameter_pipe,
     fss_extended_list_read_parameter_select,
     fss_extended_list_read_parameter_total,
     fss_extended_list_read_parameter_trim,
@@ -125,12 +131,13 @@ extern "C" {
       f_console_parameter_t_initialize(fss_extended_list_read_short_line, fss_extended_list_read_long_line, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_list_read_short_name, fss_extended_list_read_long_name, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_list_read_short_object, fss_extended_list_read_long_object, 0, 0, f_console_type_normal), \
+      f_console_parameter_t_initialize(fss_extended_list_read_short_pipe, fss_extended_list_read_long_pipe, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_list_read_short_select, fss_extended_list_read_long_select, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_list_read_short_total, fss_extended_list_read_long_total, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_list_read_short_trim, fss_extended_list_read_long_trim, 0, 0, f_console_type_normal), \
     }
 
-  #define fss_extended_list_read_total_parameters 19
+  #define fss_extended_list_read_total_parameters 20
 #endif // _di_fss_extended_list_read_defines_
 
 #ifndef _di_fss_extended_list_read_data_t_
index 9f29a959955b10ce8823164e8de4becb23d0f8ce..bd823534b4b287261ea44c7c9829a0edd11ce33c 100644 (file)
@@ -182,39 +182,10 @@ extern "C" {
       status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest);
 
       if (F_status_is_error(status)) {
-        status = F_status_set_fine(status);
-
-        if (status == F_parameter) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
-        else if (status == F_memory_allocation || status == F_memory_reallocation) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_stop) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_eos) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status);
-          fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling ");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_list_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
+        // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate.
+        fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_list_read", F_true, filename, "process", fll_error_file_type_file);
 
-        return F_status_set_error(status);
+        return status;
       }
       else if (status == F_data_not_stop || status == F_data_not_eos) {
         if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) {
@@ -369,16 +340,14 @@ extern "C" {
           print_object(f_type_output, data->buffer, items->array[depth_setting.value_at].object);
 
           if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) {
+            fss_extended_list_read_print_object_end(*data);
+
             if (items->array[depth_setting.value_at].content.used) {
-              fprintf(f_type_output, "%c", f_fss_eol);
               f_print_dynamic_partial(f_type_output, data->buffer, items->array[depth_setting.value_at].content.array[0]);
             }
-            else {
-              fprintf(f_type_output, "%c", f_fss_eol);
-            }
           }
 
-          fprintf(f_type_output, "%c", f_fss_eol);
+          fss_extended_list_read_print_set_end(*data);
         }
 
         return F_none;
@@ -390,16 +359,14 @@ extern "C" {
           print_object(f_type_output, data->buffer, items->array[i].object);
 
           if (data->parameters[fss_extended_list_read_parameter_content].result == f_console_result_found) {
+            fss_extended_list_read_print_object_end(*data);
+
             if (items->array[i].content.used) {
-              fprintf(f_type_output, "%c", f_fss_eol);
               f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]);
             }
-            else {
-              fprintf(f_type_output, "%c", f_fss_eol);
-            }
           }
 
-          fprintf(f_type_output, "%c", f_fss_eol);
+          fss_extended_list_read_print_set_end(*data);
         }
       } // for
 
@@ -445,7 +412,7 @@ extern "C" {
             if (data->parameters[fss_extended_list_read_parameter_line].result == f_console_result_additional) {
               if (!items->array[i].content.used) {
                 if (include_empty && !line) {
-                  fprintf(f_type_output, "%c", f_string_eol[0]);
+                  fss_extended_list_read_print_set_end(*data);
                 }
               }
               else {
@@ -498,9 +465,13 @@ extern "C" {
 
             if (items->array[i].content.used > 0) {
               f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]);
+
+              if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+                fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end);
+              }
             }
             else if (include_empty) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_extended_list_read_print_set_end(*data);
             }
 
             break;
@@ -549,7 +520,7 @@ extern "C" {
         if (!items->array[i].content.used) {
           if (include_empty) {
             if (line_current == line) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_extended_list_read_print_set_end(*data);
               break;
             }
 
@@ -600,19 +571,59 @@ extern "C" {
 
       if (!items->array[i].content.used) {
         if (include_empty) {
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_extended_list_read_print_set_end(*data);
         }
 
         continue;
       }
 
       f_print_dynamic_partial(f_type_output, data->buffer, items->array[i].content.array[0]);
+
+      if (data->parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+        fprintf(data->output.stream, "%c", fss_extended_list_read_pipe_content_end);
+      }
     } // for
 
     return F_none;
   }
 #endif // _di_fss_extended_list_read_main_process_for_depth_
 
+#ifndef _di_fss_extended_list_read_print_object_end_
+  void fss_extended_list_read_print_object_end(const fss_extended_list_read_data_t data) {
+
+    if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_extended_list_read_print_object_end_
+
+#ifndef _di_fss_extended_list_read_print_content_end_
+  void fss_extended_list_read_print_content_end(const fss_extended_list_read_data_t data) {
+
+    if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_extended_list_read_print_content_end_
+
+#ifndef _di_fss_extended_list_read_print_set_end_
+  void fss_extended_list_read_print_set_end(const fss_extended_list_read_data_t data) {
+
+    if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_end);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_extended_list_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index f592c68a7d3c580feb7413a58064858f3e62a9da..fb1d31f2ddf1eeb342145ad621675be13624d8b1 100644 (file)
@@ -219,6 +219,36 @@ extern "C" {
   extern f_return_status fss_extended_list_read_main_process_for_depth(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depth_t depth_setting, const f_array_length_t line) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_extended_list_read_main_process_for_depth_
 
+/**
+ * Print the end of an object (which is essentially the start of a content).
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_list_read_print_object_end_
+  extern void fss_extended_list_read_print_object_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_list_read_print_object_end_
+
+/**
+ * Print the end of an content.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_list_read_print_content_end_
+  extern void fss_extended_list_read_print_content_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_list_read_print_content_end_
+
+/**
+ * Print the end of an object/content set.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_list_read_print_set_end_
+  extern void fss_extended_list_read_print_set_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_list_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 429c34b34536d6246f88c162a0b9343a75e8f4b1..db54be0c3c6c8ef09f81db779988ce9d9b7be4c1 100644 (file)
@@ -23,12 +23,13 @@ extern "C" {
     printf("%c", f_string_eol[0]);
 
     fll_program_print_help_option(file, context, fss_extended_read_short_at, fss_extended_read_long_at, f_console_symbol_short_enable, f_console_symbol_long_enable, "      Select object at this numeric index.");
-    fll_program_print_help_option(file, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Print the content (default).");
+    fll_program_print_help_option(file, context, fss_extended_read_short_content, fss_extended_read_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print the content (default).");
     fll_program_print_help_option(file, context, fss_extended_read_short_depth, fss_extended_read_long_depth, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Select object at this numeric depth.");
     fll_program_print_help_option(file, context, fss_extended_read_short_empty, fss_extended_read_long_empty, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Include empty content when processing.");
     fll_program_print_help_option(file, context, fss_extended_read_short_line, fss_extended_read_long_line, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print only the content at the given line.");
     fll_program_print_help_option(file, context, fss_extended_read_short_name, fss_extended_read_long_name, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Select object with this name.");
     fll_program_print_help_option(file, context, fss_extended_read_short_object, fss_extended_read_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Print the object.");
+    fll_program_print_help_option(file, context, fss_extended_read_short_pipe, fss_extended_read_long_pipe, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Print using the special pipe format.");
     fll_program_print_help_option(file, context, fss_extended_read_short_select, fss_extended_read_long_select, f_console_symbol_short_enable, f_console_symbol_long_enable, "  Select sub-content at this index.");
     fll_program_print_help_option(file, context, fss_extended_read_short_total, fss_extended_read_long_total, f_console_symbol_short_enable, f_console_symbol_long_enable, "   Print the total number of lines.");
     fll_program_print_help_option(file, context, fss_extended_read_short_trim, fss_extended_read_long_trim, f_console_symbol_short_enable, f_console_symbol_long_enable, "    Trim object names on select or print.");
@@ -209,71 +210,64 @@ extern "C" {
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_at);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_read_parameter_depth].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_depth].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_depth);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_line].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_read_parameter_name].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_name].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_name);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a string.%c", f_string_eol[0]);
 
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) {
         fl_color_print(data->error.to.stream, data->context.set.error, "%sThe parameter '", fll_error_print_error);
         fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' requires a positive number.%c", f_string_eol[0]);
 
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
       if (data->parameters[fss_extended_read_parameter_object].result == f_console_result_found) {
-        if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
-        if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_object);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_select);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
         }
 
         if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) {
-          if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
+          if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
             fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot 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_extended_read_long_object);
             fl_color_print(data->error.to.stream, data->context.set.error, "' and the '");
@@ -282,31 +276,46 @@ extern "C" {
             fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total);
             fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-            fss_extended_read_delete_data(data);
-            return F_status_set_error(F_parameter);
+            status = F_status_set_error(F_parameter);
           }
         }
       }
 
       if (data->parameters[fss_extended_read_parameter_line].result == f_console_result_additional) {
-        if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
           fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_line);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
           fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total);
           fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
 
-          fss_extended_read_delete_data(data);
-          return F_status_set_error(F_parameter);
+          status = F_status_set_error(F_parameter);
+        }
+      }
+
+      if (data->parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) {
+        if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sCannot specify the '", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_pipe);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter with the '");
+          fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_read_long_total);
+          fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+          status = F_status_set_error(F_parameter);
         }
       }
 
       fss_extended_read_depths_t depths = fss_extended_read_depths_t_initialize;
 
-      f_string_length_t counter = 0;
       f_string_length_t original_size = data->quantity.total;
 
-      status = fss_extended_read_main_preprocess_depth(arguments, *data, &depths);
+      if (F_status_is_error_not(status)) {
+        status = fss_extended_read_main_preprocess_depth(arguments, *data, &depths);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data->error, F_status_set_fine(status), "fss_extended_read_main_preprocess_depth", F_true);
+        }
+      }
 
       if (F_status_is_error(status)) {
         macro_fss_extended_read_depths_t_delete_simple(depths);
@@ -315,31 +324,26 @@ extern "C" {
       }
 
       // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file.
-      if (depths.array[0].depth > 0) {
+      if (F_status_is_error_not(status) && depths.array[0].depth > 0) {
         macro_fss_extended_read_depths_t_delete_simple(depths);
 
         if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
           fprintf(f_type_output, "0%c", f_string_eol[0]);
-
-          fss_extended_read_delete_data(data);
-          return F_none;
         }
 
         fss_extended_read_delete_data(data);
         return F_none;
       }
 
-      if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) {
+      if (F_status_is_error_not(status) && data->parameters[fss_extended_read_parameter_select].result == f_console_result_found) {
         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_read_long_select);
         fl_color_print(data->error.to.stream, data->context.set.error, "' parameter requires a positive number.%c", f_string_eol[0]);
 
-        macro_fss_extended_read_depths_t_delete_simple(depths);
-        fss_extended_read_delete_data(data);
-        return F_status_set_error(F_parameter);
+        status = F_status_set_error(F_parameter);
       }
 
-      if (data->process_pipe) {
+      if (F_status_is_error_not(status) && data->process_pipe) {
         f_file_t file = f_file_t_initialize;
 
         file.id = f_type_descriptor_input;
@@ -347,19 +351,14 @@ extern "C" {
         status = f_file_read(file, &data->buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_file);
-
-          macro_fss_extended_read_depths_t_delete_simple(depths);
-          fss_extended_read_delete_data(data);
-          return status;
+          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe);
         }
+        else {
+          status = fss_extended_read_main_process_file(arguments, data, "-", depths);
 
-        status = fss_extended_read_main_process_file(arguments, data, "-", depths);
-
-        if (F_status_is_error(status)) {
-          macro_fss_extended_read_depths_t_delete_simple(depths);
-          fss_extended_read_delete_data(data);
-          return status;
+          if (F_status_is_error(status)) {
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe);
+          }
         }
 
         // Clear buffers before continuing.
@@ -368,33 +367,27 @@ extern "C" {
         f_macro_string_dynamic_t_delete_simple(data->buffer);
       }
 
-      if (data->remaining.used > 0) {
-        for (; counter < data->remaining.used; counter++) {
+      if (F_status_is_error_not(status) && data->remaining.used > 0) {
+        for (f_array_length_t i = 0; i < data->remaining.used; i++) {
           f_file_t file = f_file_t_initialize;
 
-          status = f_file_open(arguments.argv[data->remaining.array[counter]], 0, &file);
+          status = f_file_open(arguments.argv[data->remaining.array[i]], 0, &file);
 
           data->quantity.total = original_size;
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[counter]], "open", fll_error_file_type_file);
-
-            macro_fss_extended_read_depths_t_delete_simple(depths);
-            fss_extended_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_open", F_true, arguments.argv[data->remaining.array[i]], "open", fll_error_file_type_file);
+            break;
           }
 
           if (!data->quantity.total) {
             status = f_file_size_by_id(file.id, &data->quantity.total);
 
             if (F_status_is_error(status)) {
-              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
+              fll_error_file_print(data->error, F_status_set_fine(status), "f_file_size_by_id", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
 
               f_file_stream_close(F_true, &file);
-
-              macro_fss_extended_read_depths_t_delete_simple(depths);
-              fss_extended_read_delete_data(data);
-              return status;
+              break;
             }
 
             // Skip past empty files.
@@ -413,19 +406,15 @@ extern "C" {
           f_file_stream_close(F_true, &file);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[counter]], "read", fll_error_file_type_file);
-
-            macro_fss_extended_read_depths_t_delete_simple(depths);
-            fss_extended_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_until", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
-          status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[counter]], depths);
+          status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths);
 
           if (F_status_is_error(status)) {
-            macro_fss_extended_read_depths_t_delete_simple(depths);
-            fss_extended_read_delete_data(data);
-            return status;
+            fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file);
+            break;
           }
 
           // Clear buffers before repeating the loop.
@@ -433,6 +422,12 @@ extern "C" {
           f_macro_fss_objects_t_delete_simple(data->objects);
           f_macro_string_dynamic_t_delete_simple(data->buffer);
         } // for
+
+        if (F_status_is_error(status)) {
+          f_macro_fss_contents_t_delete_simple(data->contents);
+          f_macro_fss_objects_t_delete_simple(data->objects);
+          f_macro_string_dynamic_t_delete_simple(data->buffer);
+        }
       }
 
       macro_fss_extended_read_depths_t_delete_simple(depths);
index e3e7b83de3911fb0e4b83a33f66e9a824b2d1413..71d4ae03143717621b28168d76c09f80e90ff83f 100644 (file)
@@ -62,6 +62,9 @@ extern "C" {
 #endif // _di_fss_extended_read_name_
 
 #ifndef _di_fss_extended_read_defines_
+  #define fss_extended_read_pipe_content_start '\0'
+  #define fss_extended_read_pipe_content_end   '\f'
+
   #define fss_extended_read_short_at      "a"
   #define fss_extended_read_short_content "c"
   #define fss_extended_read_short_depth   "d"
@@ -69,6 +72,7 @@ extern "C" {
   #define fss_extended_read_short_line    "l"
   #define fss_extended_read_short_name    "n"
   #define fss_extended_read_short_object  "o"
+  #define fss_extended_read_short_pipe    "p"
   #define fss_extended_read_short_select  "s"
   #define fss_extended_read_short_total   "t"
   #define fss_extended_read_short_trim    "T"
@@ -80,6 +84,7 @@ extern "C" {
   #define fss_extended_read_long_line    "line"
   #define fss_extended_read_long_name    "name"
   #define fss_extended_read_long_object  "object"
+  #define fss_extended_read_long_pipe    "pipe"
   #define fss_extended_read_long_select  "select"
   #define fss_extended_read_long_total   "total"
   #define fss_extended_read_long_trim    "trim"
@@ -102,6 +107,7 @@ extern "C" {
     fss_extended_read_parameter_line,
     fss_extended_read_parameter_name,
     fss_extended_read_parameter_object,
+    fss_extended_read_parameter_pipe,
     fss_extended_read_parameter_select,
     fss_extended_read_parameter_total,
     fss_extended_read_parameter_trim,
@@ -125,12 +131,13 @@ extern "C" {
       f_console_parameter_t_initialize(fss_extended_read_short_line, fss_extended_read_long_line, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_read_short_name, fss_extended_read_long_name, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_read_short_object, fss_extended_read_long_object, 0, 0, f_console_type_normal), \
+      f_console_parameter_t_initialize(fss_extended_read_short_pipe, fss_extended_read_long_pipe, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_read_short_select, fss_extended_read_long_select, 0, 1, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_read_short_total, fss_extended_read_long_total, 0, 0, f_console_type_normal), \
       f_console_parameter_t_initialize(fss_extended_read_short_trim, fss_extended_read_long_trim, 0, 0, f_console_type_normal), \
     }
 
-  #define fss_extended_read_total_parameters 19
+  #define fss_extended_read_total_parameters 20
 #endif // _di_fss_extended_read_defines_
 
 #ifndef _di_fss_extended_read_data_t_
index de8cda2603c3d476cd8c00af3177f3ae14a9ecbe..559c742748407c3e45ef339301bd05cc4f172748 100644 (file)
@@ -182,39 +182,10 @@ extern "C" {
       status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0);
 
       if (F_status_is_error(status)) {
-        status = F_status_set_fine(status);
-
-        if (status == F_parameter) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sInvalid parameter when calling ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
-        else if (status == F_memory_allocation || status == F_memory_reallocation) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sUnable to allocate memory.%c", fll_error_print_error, f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_stop) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at stop position (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else if (status == F_incomplete_utf_eos) {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sError occurred on invalid UTF-8 character at end of string (at ", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%d", input.start);
-          fl_color_print(data->error.to.stream, data->context.set.error, ").%c", f_string_eol[0]);
-        }
-        else {
-          fl_color_print(data->error.to.stream, data->context.set.error, "%sAn unhandled error (", fll_error_print_error);
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%u", status);
-          fl_color_print(data->error.to.stream, data->context.set.error, ") has occurred while calling ");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "fll_fss_extended_read()");
-          fl_color_print(data->error.to.stream, data->context.set.error, " for the file '");
-          fl_color_print(data->error.to.stream, data->context.set.notable, "%s", filename);
-          fl_color_print(data->error.to.stream, data->context.set.error, "'.%c", f_string_eol[0]);
-        }
+        // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate.
+        fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, filename, "process", fll_error_file_type_file);
 
-        return F_status_set_error(status);
+        return status;
       }
       else if (status == F_data_not_stop || status == F_data_not_eos) {
         if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) {
@@ -349,20 +320,20 @@ extern "C" {
 
               if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) {
                 if (data->contents.array[i].used) {
-                  fprintf(f_type_output, "%c", f_fss_space);
+                  fss_extended_read_print_object_end(*data);
 
                   for (j = 0; j < data->contents.array[i].used; j++) {
 
                     f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
                     if (j + 1 < data->contents.array[i].used) {
-                      fprintf(f_type_output, "%c", f_fss_space);
+                      fss_extended_read_print_content_end(*data);
                     }
                   } // for
                 }
               }
 
-              fprintf(f_type_output, "%c", f_fss_eol);
+              fss_extended_read_print_set_end(*data);
               break;
             }
 
@@ -380,20 +351,20 @@ extern "C" {
 
         if (data->parameters[fss_extended_read_parameter_content].result == f_console_result_found) {
           if (data->contents.array[i].used) {
-            fprintf(f_type_output, "%c", f_fss_space);
+            fss_extended_read_print_object_end(*data);
 
             for (j = 0; j < data->contents.array[i].used; j++) {
 
               f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
               if (j + 1 < data->contents.array[i].used) {
-                fprintf(f_type_output, "%c", f_fss_space);
+                fss_extended_read_print_content_end(*data);
               }
             } // for
           }
         }
 
-        fprintf(f_type_output, "%c", f_fss_eol);
+        fss_extended_read_print_set_end(*data);
       } // for
 
       return F_none;
@@ -433,7 +404,7 @@ extern "C" {
                   if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
                     if (select < data->contents.array[i].used) {
                       f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]);
-                      fprintf(f_type_output, "%c", f_string_eol[0]);
+                      fss_extended_read_print_set_end(*data);
                     }
                   }
                   else {
@@ -441,21 +412,21 @@ extern "C" {
                       f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
                       if (j + 1 < data->contents.array[i].used) {
-                        printf(" ");
+                        fss_extended_read_print_content_end(*data);
                       }
                     } // for
 
-                    fprintf(f_type_output, "%c", f_string_eol[0]);
+                    fss_extended_read_print_set_end(*data);
                   }
                 }
                 else if (include_empty) {
                   if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
                     if (!select) {
-                      fprintf(f_type_output, "%c", f_string_eol[0]);
+                      fss_extended_read_print_set_end(*data);
                     }
                   }
                   else {
-                    fprintf(f_type_output, "%c", f_string_eol[0]);
+                    fss_extended_read_print_set_end(*data);
                   }
                 }
               }
@@ -469,7 +440,7 @@ extern "C" {
               if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
                 if (select < data->contents.array[i].used) {
                   f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]);
-                  fprintf(f_type_output, "%c", f_string_eol[0]);
+                  fss_extended_read_print_set_end(*data);
                 }
               }
               else {
@@ -477,21 +448,21 @@ extern "C" {
                   f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
                   if (j + 1 < data->contents.array[i].used) {
-                    printf(" ");
+                    fss_extended_read_print_content_end(*data);
                   }
                 } // for
 
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_extended_read_print_set_end(*data);
               }
             }
             else if (include_empty) {
               if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
                 if (!select) {
-                  fprintf(f_type_output, "%c", f_string_eol[0]);
+                  fss_extended_read_print_set_end(*data);
                 }
               }
               else {
-                fprintf(f_type_output, "%c", f_string_eol[0]);
+                fss_extended_read_print_set_end(*data);
               }
             }
 
@@ -533,7 +504,7 @@ extern "C" {
         if (!data->contents.array[i].used) {
           if (include_empty) {
             if (line_current == line) {
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_extended_read_print_set_end(*data);
               break;
             }
 
@@ -547,7 +518,7 @@ extern "C" {
           if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
             if (select < data->contents.array[i].used) {
               f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]);
-              fprintf(f_type_output, "%c", f_string_eol[0]);
+              fss_extended_read_print_set_end(*data);
             }
           }
           else {
@@ -555,11 +526,11 @@ extern "C" {
               f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
               if (j + 1 < data->contents.array[i].used) {
-                printf(" ");
+                fss_extended_read_print_content_end(*data);
               }
             } // for
 
-            fprintf(f_type_output, "%c", f_string_eol[0]);
+            fss_extended_read_print_set_end(*data);
           }
 
           break;
@@ -576,7 +547,7 @@ extern "C" {
 
       if (!data->contents.array[i].used) {
         if (include_empty && !select) {
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_extended_read_print_set_end(*data);
         }
 
         continue;
@@ -585,7 +556,7 @@ extern "C" {
       if (data->parameters[fss_extended_read_parameter_select].result == f_console_result_additional) {
         if (select < data->contents.array[i].used) {
           f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[select]);
-          fprintf(f_type_output, "%c", f_string_eol[0]);
+          fss_extended_read_print_set_end(*data);
         }
       }
       else {
@@ -593,11 +564,11 @@ extern "C" {
           f_print_dynamic_partial(f_type_output, data->buffer, data->contents.array[i].array[j]);
 
           if (j + 1 < data->contents.array[i].used) {
-            printf(" ");
+            fss_extended_read_print_content_end(*data);
           }
         } // for
 
-        fprintf(f_type_output, "%c", f_string_eol[0]);
+        fss_extended_read_print_set_end(*data);
       }
     } // for
 
@@ -605,6 +576,42 @@ extern "C" {
   }
 #endif // _di_fss_extended_read_main_process_file_
 
+#ifndef _di_fss_extended_read_print_object_end_
+  void fss_extended_read_print_object_end(const fss_extended_read_data_t data) {
+
+    if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_space);
+    }
+  }
+#endif // _di_fss_extended_read_print_object_end_
+
+#ifndef _di_fss_extended_read_print_content_end_
+  void fss_extended_read_print_content_end(const fss_extended_read_data_t data) {
+
+    if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_start);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_space);
+    }
+  }
+#endif // _di_fss_extended_read_print_content_end_
+
+#ifndef _di_fss_extended_read_print_set_end_
+  void fss_extended_read_print_set_end(const fss_extended_read_data_t data) {
+
+    if (data.parameters[fss_extended_read_parameter_pipe].result == f_console_result_found) {
+      fprintf(data.output.stream, "%c", fss_extended_read_pipe_content_end);
+    }
+    else {
+      fprintf(data.output.stream, "%c", f_fss_eol);
+    }
+  }
+#endif // _di_fss_extended_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 7b89827d07067cb54fb6491dad46492194d8d5c3..06bb8e8f19deba1ea8be60e99af183cc933fea13 100644 (file)
@@ -195,6 +195,36 @@ extern "C" {
   extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_extended_read_main_process_file_
 
+/**
+ * Print the end of an object (which is essentially the start of a content).
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_read_print_object_end_
+  extern void fss_extended_read_print_object_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_read_print_object_end_
+
+/**
+ * Print the end of an content.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_read_print_content_end_
+  extern void fss_extended_read_print_content_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_read_print_content_end_
+
+/**
+ * Print the end of an object/content set.
+ *
+ * @param data
+ *   The program specific data.
+ */
+#ifndef _di_fss_extended_read_print_set_end_
+  extern void fss_extended_read_print_set_end(const fss_extended_read_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_read_print_set_end_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 71fa531d79a5b0706f414166b4db9eb1e9882d1d..e624007b43e7efa795443d3e4ee95c0d51ada3bc 100644 (file)
@@ -93,7 +93,7 @@ Featureless Settings Specifications:
 
   Unless otherwise specified, comments are designated by the pound symbol '#' but only if only whitespace is to the left of the pound or the pound '#' is at the start of the line.
   There is no support for inline comments.
-  Unless explicitly defined, the start comment may be delimited by '\' in the same manner as Objects and Contents are.
+  Unless otherwise specified, the start comment may be delimited by '\' in the same manner as Objects and Contents are.
   This delimit only applies to the start of a comment (the pound '#' character) as there is no terminating character for a comment (other than a newline '\n').
 
   Unless otherwise specified, all designation characters MUST represent ASCII codes.