]> Kevux Git Server - fll/commitdiff
Progress: fss write programs and related, including console changes.
authorKevin Day <thekevinday@gmail.com>
Mon, 5 Oct 2020 02:13:20 +0000 (21:13 -0500)
committerKevin Day <thekevinday@gmail.com>
Mon, 5 Oct 2020 02:13:20 +0000 (21:13 -0500)
Finish updating the fss write programs.
I will sleep on this and then review them later to look for mistakes, oversights, bugs, inconsistencies, and possible cleanups.

Improve the console parameter handling functionality.
The sub-locations need to also have their locations stored.

Cleanup the struct stat file_stat name, renaming it to stat_file for more consistency.

Remove some memsets(), these might be better left to higher level operations.
Assuming I do not change my mind on this later.

Use the word "amount" instead of "length" when the increase/decrease is not the whole length but a fraction.

Reorganize some string functions parameters to be more consistent with the current design practices.

34 files changed:
level_0/f_console/c/console-common.h
level_0/f_console/c/console.c
level_0/f_file/c/file.c
level_0/f_file/c/file.h
level_0/f_print/c/private-print.c
level_1/fl_fss/c/fss_basic_list.c
level_1/fl_string/c/private-string.c
level_1/fl_string/c/private-string.h
level_1/fl_string/c/string.c
level_1/fl_string/c/string.h
level_3/byte_dump/c/byte_dump.c
level_3/fake/c/fake.c
level_3/firewall/c/firewall.c
level_3/fss_basic_list_read/c/fss_basic_list_read.c
level_3/fss_basic_list_write/c/fss_basic_list_write.c
level_3/fss_basic_list_write/c/fss_basic_list_write.h
level_3/fss_basic_list_write/c/private-fss_basic_list_write.c
level_3/fss_basic_list_write/c/private-fss_basic_list_write.h
level_3/fss_basic_read/c/fss_basic_read.c
level_3/fss_basic_write/c/fss_basic_write.c
level_3/fss_basic_write/c/fss_basic_write.h
level_3/fss_basic_write/c/main.c
level_3/fss_basic_write/c/private-fss_basic_write.c
level_3/fss_basic_write/c/private-fss_basic_write.h
level_3/fss_extended_list_read/c/fss_extended_list_read.c
level_3/fss_extended_read/c/fss_extended_read.c
level_3/fss_extended_write/c/fss_extended_write.c
level_3/fss_extended_write/c/fss_extended_write.h
level_3/fss_extended_write/c/private-fss_extended_write.c
level_3/fss_extended_write/c/private-fss_extended_write.h
level_3/fss_status_code/c/fss_status_code.c
level_3/iki_read/c/iki_read.c
level_3/iki_write/c/iki_write.c
level_3/status_code/c/status_code.c

index e5a094558bd791014a8b635c16f135f66d56fa22..f1a1a1395581910a9f981b73c02dce98f51a0caa 100644 (file)
@@ -220,6 +220,7 @@ extern "C" {
  * - location: The last location in argv[] where this parameter is found.
  * - location_sub: The last sub-location at location in argv (only used by short parameters, such as -h or +l).
  * - locations: All locations within argv where this parameter is found (order is preserved).
+ * - locations_sub: All sub-locations within argv where this parameter is found (order is preserved).
  * - additional: An array of locations representing where in the argv[] the additional arguments are found.
  */
 #ifndef _di_f_console_parameter_t_
@@ -237,12 +238,13 @@ extern "C" {
     f_array_length_t  location;
     f_string_length_t location_sub;
     f_array_lengths_t locations;
+    f_array_lengths_t locations_sub;
     f_array_lengths_t additional;
   } f_console_parameter_t;
 
-  #define f_console_parameter_t_initialize(symbol_short, symbol_long, symbol_other, has_additional, type_value) { symbol_short, symbol_long, symbol_other, has_additional, type_value, f_console_result_none, 0, 0, 0, f_array_lengths_t_initialize, f_array_lengths_t_initialize }
+  #define f_console_parameter_t_initialize(symbol_short, symbol_long, symbol_other, has_additional, type_value) { symbol_short, symbol_long, symbol_other, has_additional, type_value, f_console_result_none, 0, 0, 0, f_array_lengths_t_initialize, f_array_lengths_t_initialize, f_array_lengths_t_initialize }
 
-  #define f_macro_console_parameter_t_initialize(symbol_short, symbol_long, symbol_other, has_additional, type_value, result, total, location, location_sub, locations, additional) { symbol_short, symbol_long, symbol_other, has_additional, type_value, result, total, location, location_sub, locations, additional }
+  #define f_macro_console_parameter_t_initialize(symbol_short, symbol_long, symbol_other, has_additional, type_value, result, total, location, location_sub, locations, locations_sub, additional) { symbol_short, symbol_long, symbol_other, has_additional, type_value, result, total, location, location_sub, locations, locations_sub, additional }
 #endif // _di_f_console_parameter_t_
 
 /**
index 5559d534f56c4caded3b6d020017f1acfbc17d46..f73f307c899cae2bd65083111066fe90f7cf12bd 100644 (file)
@@ -207,6 +207,15 @@ extern "C" {
               }
             }
 
+            if (parameters.parameter[i].locations_sub.used == parameters.parameter[i].locations_sub.size) {
+              f_macro_string_lengths_t_resize(status, parameters.parameter[i].locations_sub, parameters.parameter[i].locations_sub.size + f_console_default_allocation_step);
+
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_t_delete_simple(needs_additional);
+                return status;
+              }
+            }
+
             parameters.parameter[i].locations.array[parameters.parameter[i].locations.used++] = location;
 
             parameters.parameter[i].result = f_console_result_found;
@@ -216,6 +225,10 @@ extern "C" {
 
             if (result == console_short) {
               parameters.parameter[i].location_sub = sub_location;
+              parameters.parameter[i].locations_sub.array[parameters.parameter[i].locations_sub.used++] = sub_location;
+            }
+            else {
+              parameters.parameter[i].locations_sub.array[parameters.parameter[i].locations_sub.used++] = 0;
             }
 
             if (parameters.parameter[i].has_additional) {
@@ -259,7 +272,17 @@ extern "C" {
             }
           }
 
+          if (parameters.parameter[i].locations_sub.used == parameters.parameter[i].locations_sub.size) {
+            f_macro_string_lengths_t_resize(status, parameters.parameter[i].locations_sub, parameters.parameter[i].locations_sub.size + f_console_default_allocation_step);
+
+            if (F_status_is_error(status)) {
+              f_macro_string_lengths_t_delete_simple(needs_additional);
+              return status;
+            }
+          }
+
           parameters.parameter[i].locations.array[parameters.parameter[i].locations.used++] = location;
+          parameters.parameter[i].locations_sub.array[parameters.parameter[i].locations_sub.used++] = 0;
 
           parameters.parameter[i].result = f_console_result_found;
           parameters.parameter[i].location = location;
index b49b61b263cb31020a8f70659b0cd939fbe0474d..e600e4f558e1930c94c5fc2264dc3770e79b3144 100644 (file)
@@ -318,11 +318,11 @@ extern "C" {
     #endif // _di_level_0_parameter_checking_
 
     f_status_t status = F_none;
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    status = private_f_file_stat(path, F_false, &file_stat);
+    status = private_f_file_stat(path, F_false, &stat_file);
 
     if (F_status_is_error(status)) {
       if (F_status_set_fine(status) == F_file_found_not) return F_false;
@@ -341,11 +341,11 @@ extern "C" {
     #endif // _di_level_0_parameter_checking_
 
     f_status_t status = F_none;
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    status = private_f_file_stat_at(at_id, path, flag, &file_stat);
+    status = private_f_file_stat_at(at_id, path, flag, &stat_file);
 
     if (F_status_is_error(status)) {
       if (F_status_set_fine(status) == F_file_found_not) return F_false;
@@ -391,14 +391,14 @@ extern "C" {
       if (!path) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    f_status_t status = private_f_file_stat(path, dereference, &file_stat);
+    f_status_t status = private_f_file_stat(path, dereference, &stat_file);
     if (F_status_is_error(status)) return status;
 
-    if (f_macro_file_type_get(file_stat.st_mode) == type) return F_true;
+    if (f_macro_file_type_get(stat_file.st_mode) == type) return F_true;
 
     return F_false;
   }
@@ -410,11 +410,11 @@ extern "C" {
       if (!path) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    if (fstatat(at_id, path, &file_stat, flag) < 0) {
+    if (fstatat(at_id, path, &stat_file, flag) < 0) {
       if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
       if (errno == EFAULT) return F_status_set_error(F_buffer);
       if (errno == ENOMEM) return F_status_set_error(F_memory_out);
@@ -428,7 +428,7 @@ extern "C" {
       return F_status_set_error(F_file_stat);
     }
 
-    if (file_stat.st_mode == (S_IFMT & S_IFDIR)) return F_true;
+    if (stat_file.st_mode == (S_IFMT & S_IFDIR)) return F_true;
 
     return F_false;
   }
@@ -1463,8 +1463,6 @@ extern "C" {
 
         f_macro_string_dynamic_t_resize(status, (*buffer), buffer->size + file.size_read);
         if (F_status_is_error(status)) return status;
-
-        memset(buffer->string + buffer->used, 0, sizeof(file.size_read));
       }
 
       buffer_read = buffer->string + buffer->used;
@@ -1506,15 +1504,13 @@ extern "C" {
 
     f_string_t buffer_read = 0;
 
-    if (buffer->used + size_read > buffer->size) {
-      if (buffer->size + size_read > f_string_length_t_size) {
+    if (buffer->used + file.size_read > buffer->size) {
+      if (buffer->size + file.size_read > f_string_length_t_size) {
         return F_status_set_error(F_string_too_large);
       }
 
-      f_macro_string_dynamic_t_resize(status, (*buffer), buffer->size + size_read);
+      f_macro_string_dynamic_t_resize(status, (*buffer), buffer->size + file.size_read);
       if (F_status_is_error(status)) return status;
-
-      memset(buffer->string + buffer->used, 0, sizeof(file.size_read));
     }
 
     buffer_read = buffer->string + buffer->used;
@@ -1573,8 +1569,6 @@ extern "C" {
 
         f_macro_string_dynamic_t_resize(status, (*buffer), buffer->size + buffer_size);
         if (F_status_is_error(status)) return status;
-
-        memset(buffer->string + buffer->used, 0, sizeof(buffer_size));
       }
 
       buffer_read = buffer->string + buffer->used;
@@ -1786,15 +1780,15 @@ extern "C" {
       if (!size) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    f_status_t status = private_f_file_stat(path, dereference, &file_stat);
+    f_status_t status = private_f_file_stat(path, dereference, &stat_file);
 
     if (F_status_is_error(status)) return status;
 
-    *size = file_stat.st_size;
+    *size = stat_file.st_size;
 
     return F_none;
   }
@@ -1808,15 +1802,15 @@ extern "C" {
       if (!size) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    f_status_t status = private_f_file_stat_at(at_id, path, dereference, &file_stat);
+    f_status_t status = private_f_file_stat_at(at_id, path, dereference, &stat_file);
 
     if (F_status_is_error(status)) return status;
 
-    *size = file_stat.st_size;
+    *size = stat_file.st_size;
 
     return F_none;
   }
@@ -1829,51 +1823,51 @@ extern "C" {
       if (!size) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    f_status_t status = private_f_file_stat_by_id(id, &file_stat);
+    f_status_t status = private_f_file_stat_by_id(id, &stat_file);
 
     if (F_status_is_error(status)) return status;
 
-    *size = file_stat.st_size;
+    *size = stat_file.st_size;
 
     return F_none;
   }
 #endif // _di_f_file_size_by_id_
 
 #ifndef _di_f_file_stat_
-  f_return_status f_file_stat(const f_string_t path, const bool dereference, struct stat *file_stat) {
+  f_return_status f_file_stat(const f_string_t path, const bool dereference, struct stat *stat_file) {
     #ifndef _di_level_0_parameter_checking_
       if (!path) return F_status_set_error(F_parameter);
-      if (!file_stat) return F_status_set_error(F_parameter);
+      if (!stat_file) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_file_stat(path, dereference, file_stat);
+    return private_f_file_stat(path, dereference, stat_file);
   }
 #endif // _di_f_file_stat_
 
 #ifndef _di_f_file_stat_at_
-  f_return_status f_file_stat_at(const int at_id, const f_string_t path, const int flag, struct stat *file_stat) {
+  f_return_status f_file_stat_at(const int at_id, const f_string_t path, const int flag, struct stat *stat_file) {
     #ifndef _di_level_0_parameter_checking_
       if (!path) return F_status_set_error(F_parameter);
       if (at_id <= 0) return F_status_set_error(F_parameter);
-      if (!file_stat) return F_status_set_error(F_parameter);
+      if (!stat_file) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_file_stat_at(at_id, path, flag, file_stat);
+    return private_f_file_stat_at(at_id, path, flag, stat_file);
   }
 #endif // _di_f_file_stat_at_
 
 #ifndef _di_f_file_stat_by_id_
-  f_return_status f_file_stat_by_id(const int id, struct stat *file_stat) {
+  f_return_status f_file_stat_by_id(const int id, struct stat *stat_file) {
     #ifndef _di_level_0_parameter_checking_
       if (id <= 0) return F_status_set_error(F_parameter);
-      if (!file_stat) return F_status_set_error(F_parameter);
+      if (!stat_file) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    return private_f_file_stat_by_id(id, file_stat);
+    return private_f_file_stat_by_id(id, stat_file);
   }
 #endif // _di_f_file_stat_by_id_
 
@@ -2065,8 +2059,6 @@ extern "C" {
       if (F_status_is_error(status)) return status;
     }
 
-    memset(buffer->string + buffer->used, 0, sizeof(buffer_size));
-
     size_read = fread(buffer->string + buffer->used, amount, file.size_read, file.stream);
 
     if (ferror(file.stream)) {
@@ -2120,8 +2112,6 @@ extern "C" {
 
         f_macro_string_dynamic_t_resize(status, (*buffer), buffer->size + buffer_size);
         if (F_status_is_error(status)) return status;
-
-        memset(buffer->string + buffer->used, 0, sizeof(buffer_size));
       }
 
       size_read = fread(buffer->string + buffer->used, amount, file.size_read, file.stream);
@@ -2380,11 +2370,11 @@ extern "C" {
     #endif // _di_level_0_parameter_checking_
 
     f_status_t status = F_none;
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    status = private_f_file_stat(path, F_false, &file_stat);
+    status = private_f_file_stat(path, F_false, &stat_file);
 
     if (F_status_set_fine(status) == F_file_found_not) {
       return private_f_file_create(path, mode, dereference);
@@ -2420,11 +2410,11 @@ extern "C" {
     #endif // _di_level_0_parameter_checking_
 
     f_status_t status = F_none;
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    status = private_f_file_stat_at(at_id, path, flag, &file_stat);
+    status = private_f_file_stat_at(at_id, path, flag, &stat_file);
 
     if (F_status_set_fine(status) == F_file_found_not) {
       return private_f_file_create_at(at_id, path, mode, F_false);
@@ -2460,11 +2450,11 @@ extern "C" {
       if (!type) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    if (stat(path, &file_stat) < 0) {
+    if (stat(path, &stat_file) < 0) {
       if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
       if (errno == EFAULT) return F_status_set_error(F_buffer);
       if (errno == ENOMEM) return F_status_set_error(F_memory_out);
@@ -2477,7 +2467,7 @@ extern "C" {
       return F_status_set_error(F_file_stat);
     }
 
-    *type = f_macro_file_type_get(file_stat.st_mode);
+    *type = f_macro_file_type_get(stat_file.st_mode);
 
     return F_none;
   }
@@ -2490,11 +2480,11 @@ extern "C" {
       if (!type) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct stat file_stat;
+    struct stat stat_file;
 
-    memset(&file_stat, 0, sizeof(struct stat));
+    memset(&stat_file, 0, sizeof(struct stat));
 
-    if (fstatat(at_id, path, &file_stat, flag) < 0) {
+    if (fstatat(at_id, path, &stat_file, flag) < 0) {
       if (errno == ENAMETOOLONG) return F_status_set_error(F_name);
       if (errno == EFAULT) return F_status_set_error(F_buffer);
       if (errno == ENOMEM) return F_status_set_error(F_memory_out);
@@ -2508,7 +2498,7 @@ extern "C" {
       return F_status_set_error(F_file_stat);
     }
 
-    *type = f_macro_file_type_get(file_stat.st_mode);
+    *type = f_macro_file_type_get(stat_file.st_mode);
 
     return F_none;
   }
index 09e04d54999ab719618677dee0b4f3c2e48b2205..e66cebb063af6917261805d7e268049188e6d156 100644 (file)
@@ -1737,7 +1737,7 @@ extern "C" {
  * @param dereference
  *   Set to TRUE to dereferenc symlinks (often is what is desired).
  *   Set to FALSE to operate on the symlink itself.
- * @param file_stat
+ * @param stat_file
  *   The statistics read.
  *
  * @return
@@ -1754,7 +1754,7 @@ extern "C" {
  * @see stat()
  */
 #ifndef _di_f_file_stat_
-  extern f_return_status f_file_stat(const f_string_t path, const bool dereference, struct stat *file_stat);
+  extern f_return_status f_file_stat(const f_string_t path, const bool dereference, struct stat *stat_file);
 #endif // _di_f_file_stat_
 
 /**
@@ -1766,7 +1766,7 @@ extern "C" {
  *   The path to the file.
  * @param flag
  *   Any valid flag, such as f_file_at_path_empty, f_file_at_automount_no, or f_file_at_symlink_follow_no.
- * @param file_stat
+ * @param stat_file
  *   The statistics read.
  *
  * @return
@@ -1783,7 +1783,7 @@ extern "C" {
  * @see fstatat()
  */
 #ifndef _di_f_file_stat_at_
-  extern f_return_status f_file_stat_at(const int at_id, const f_string_t path, const int flag, struct stat *file_stat);
+  extern f_return_status f_file_stat_at(const int at_id, const f_string_t path, const int flag, struct stat *stat_file);
 #endif // _di_f_file_stat_at_
 
 /**
@@ -1791,7 +1791,7 @@ extern "C" {
  *
  * @param id
  *   The file descriptor.
- * @param file_stat
+ * @param stat_file
  *   The statistics read.
  *
  * @return
@@ -1808,7 +1808,7 @@ extern "C" {
  * @see fstat()
  */
 #ifndef _di_f_file_stat_by_id_
-  extern f_return_status f_file_stat_by_id(const int id, struct stat *file_stat);
+  extern f_return_status f_file_stat_by_id(const int id, struct stat *stat_file);
 #endif // _di_f_file_stat_by_id_
 
 /**
index e9d0f0d6ca02be591f8bfc9405d9e17ab48ff3fe..670fd37a9865056ed38b9afaf241e7ba9bd0d323 100644 (file)
@@ -11,10 +11,10 @@ extern "C" {
     if (!length) return F_data_not;
 
     for (register f_string_length_t i = 0; i < length; ++i) {
-      if (!string[i]) continue;
-
-      if (!fputc(string[i], output)) {
-        return F_status_set_error(F_output);
+      if (string[i]) {
+        if (!fputc(string[i], output)) {
+          return F_status_set_error(F_output);
+        }
       }
     } // for
 
index 37af59a0273298b3efde1232b2c3e0eaf914946e..0a3bfe24e6db1d69ae21c720d3810283b991d468 100644 (file)
@@ -557,11 +557,11 @@ extern "C" {
           return F_status_set_error(F_string_too_large);
         }
 
-        f_macro_string_dynamic_t_resize(status, (*destination), 1);
+        f_macro_string_dynamic_t_resize(status, (*destination), destination->used + 1);
         if (F_status_is_error(status)) return status;
       }
       else {
-        f_macro_string_dynamic_t_resize(status, (*destination), f_fss_default_allocation_step);
+        f_macro_string_dynamic_t_resize(status, (*destination), destination->used + f_fss_default_allocation_step);
         if (F_status_is_error(status)) return status;
       }
 
index a63750c137e6b07e8e13c288f40b9aae79a84397..cd27d983ff812126aa3daf35b3952b4d05cfcfb1 100644 (file)
@@ -247,10 +247,10 @@ extern "C" {
 #endif // !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_)
 
 #if !defined(_di_fl_string_dynamic_size_increase_) || !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) || !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_)
-  f_return_status private_fl_string_dynamic_size_increase(const f_string_length_t length, f_string_dynamic_t *string) {
+  f_return_status private_fl_string_dynamic_size_increase(const f_string_length_t amount, f_string_dynamic_t *string) {
     f_status_t status = F_none;
 
-    if (string->size + length > f_string_length_t_size) {
+    if (string->size + amount > f_string_length_t_size) {
       if (string->size == f_string_length_t_size) {
         return F_status_set_error(F_string_too_large);
       }
@@ -259,7 +259,7 @@ extern "C" {
       return F_string_too_large;
     }
 
-    f_macro_string_dynamic_t_resize(status, (*string), string->size + length);
+    f_macro_string_dynamic_t_resize(status, (*string), string->size + amount);
     return status;
   }
 #endif // !defined(_di_fl_string_dynamic_size_increase_) || !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) || !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_)
index 2b26e51c349845485a96a71125250190185fa37b..ee9aab0a806229f6cb91071733578218b7128b2e 100644 (file)
@@ -142,7 +142,7 @@ extern "C" {
  *
  * Intended to be shared to each of the different implementation variations.
  *
- * @param length
+ * @param amount
  *   A positive number greater than 0 representing how much to increase the size by.
  * @param string
  *   The string to resize.
@@ -156,7 +156,7 @@ extern "C" {
  *   F_string_too_large (with error bit) if the combined string is too large.
  */
 #if !defined(_di_fl_string_dynamic_size_increase_) || !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) || !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_)
-  extern f_return_status private_fl_string_dynamic_size_increase(const f_string_length_t length, f_string_dynamic_t *string) f_gcc_attribute_visibility_internal;
+  extern f_return_status private_fl_string_dynamic_size_increase(const f_string_length_t amount, f_string_dynamic_t *string) f_gcc_attribute_visibility_internal;
 #endif // !defined(_di_fl_string_dynamic_size_increase_) || !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) || !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_)
 
 /**
index 3eb234d511cffb0ddfe58166318ddce732f2a67c..0300ce835a7d4cc4f21f4bcbefb3b5e7f3b86c11 100644 (file)
@@ -795,18 +795,18 @@ extern "C" {
 #endif // _di_fl_string_dynamic_rip_nulless_
 
 #ifndef _di_fl_string_dynamic_size_decrease_
-  f_return_status fl_string_dynamic_size_decrease(const f_string_length_t length, f_string_dynamic_t *string) {
+  f_return_status fl_string_dynamic_size_decrease(const f_string_length_t amount, f_string_dynamic_t *string) {
     #ifndef _di_level_1_parameter_checking_
-      if (!length) return F_status_set_error(F_parameter);
+      if (!amount) return F_status_set_error(F_parameter);
       if (!string) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
     f_status_t status = F_none;
 
-    if (string->size - length > 0) {
-      f_macro_string_dynamic_t_resize(status, (*string), string->size - length);
+    if (string->size - amount > 0) {
+      f_macro_string_dynamic_t_resize(status, (*string), string->size - amount);
     }
-    else if (string->size - length <= 0) {
+    else if (string->size - amount <= 0) {
       f_macro_string_dynamic_t_delete(status, (*string));
     }
 
@@ -815,13 +815,13 @@ extern "C" {
 #endif // _di_fl_string_dynamic_size_decrease_
 
 #ifndef _di_fl_string_dynamic_size_increase_
-  f_return_status fl_string_dynamic_size_increase(const f_string_length_t length, f_string_dynamic_t *string) {
+  f_return_status fl_string_dynamic_size_increase(const f_string_length_t amount, f_string_dynamic_t *string) {
     #ifndef _di_level_1_parameter_checking_
-      if (!length) return F_status_set_error(F_parameter);
+      if (!amount) return F_status_set_error(F_parameter);
       if (!string) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    return private_fl_string_dynamic_size_increase(length, string);
+    return private_fl_string_dynamic_size_increase(amount, string);
   }
 #endif // _di_fl_string_dynamic_size_increase_
 
@@ -845,7 +845,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_line_
 
 #ifndef _di_fl_string_dynamic_seek_line_to_
-  f_return_status fl_string_dynamic_seek_line_to(const f_string_t string, f_string_range_t *range, const int8_t seek_to_this) {
+  f_return_status fl_string_dynamic_seek_line_to(const f_string_t string, const int8_t seek_to_this, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -867,7 +867,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_line_to_
 
 #ifndef _di_fl_string_dynamic_seek_line_to_utf_character_
-  f_return_status fl_string_dynamic_seek_line_to_utf_character(const f_string_t string, f_string_range_t *range, const f_utf_character_t seek_to_this) {
+  f_return_status fl_string_dynamic_seek_line_to_utf_character(const f_string_t string, const f_utf_character_t seek_to_this, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -923,7 +923,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_line_to_utf_character_
 
 #ifndef _di_fl_string_dynamic_seek_line_until_graph_
-  f_return_status fl_string_dynamic_seek_line_until_graph(const f_string_t string, f_string_range_t *range, const int8_t placeholder) {
+  f_return_status fl_string_dynamic_seek_line_until_graph(const f_string_t string, const int8_t placeholder, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -968,7 +968,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_line_until_graph_
 
 #ifndef _di_fl_string_dynamic_seek_line_until_non_graph_
-  f_return_status fl_string_dynamic_seek_line_until_non_graph(const f_string_t string, f_string_range_t *range, const int8_t placeholder) {
+  f_return_status fl_string_dynamic_seek_line_until_non_graph(const f_string_t string, const int8_t placeholder, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -1012,7 +1012,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_line_until_non_graph_
 
 #ifndef _di_fl_string_dynamic_seek_to_
-  f_return_status fl_string_dynamic_seek_to(const f_string_t string, f_string_range_t *range, const int8_t seek_to_this) {
+  f_return_status fl_string_dynamic_seek_to(const f_string_t string, const int8_t seek_to_this, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -1031,7 +1031,7 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_to_
 
 #ifndef _di_fl_string_dynamic_seek_to_utf_character_
-  f_return_status fl_string_dynamic_seek_to_utf_character(const f_string_t string, f_string_range_t *range, const f_utf_character_t seek_to_this) {
+  f_return_status fl_string_dynamic_seek_to_utf_character(const f_string_t string, const f_utf_character_t seek_to_this, f_string_range_t *range) {
     #ifndef _di_level_1_parameter_checking_
       if (!range) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
index e186c985a263cfc33f54e05bfce9c68b18a7d4a6..5510d1b817efa6feca2cfa226304b5c5b631f39f 100644 (file)
@@ -1116,7 +1116,7 @@ extern "C" {
  * If the given length is too small, then the resize will fail.
  * This will not shrink the size to less than 0.
  *
- * @param length
+ * @param amount
  *   A positive number greater than 0 representing how much to decrease the size by.
  * @param string
  *   The string to resize.
@@ -1129,7 +1129,7 @@ extern "C" {
  *   F_string_too_large (with error bit) if the combined string is too large.
  */
 #ifndef _di_fl_string_dynamic_size_decrease_
-  extern f_return_status fl_string_dynamic_size_decrease(const f_string_length_t length, f_string_dynamic_t *string);
+  extern f_return_status fl_string_dynamic_size_decrease(const f_string_length_t amount, f_string_dynamic_t *string);
 #endif // _di_fl_string_dynamic_size_decrease_
 
 /**
@@ -1139,7 +1139,7 @@ extern "C" {
  * If the given length is too large for the buffer, then attempt to set max buffer size (f_string_length_t_size).
  * If already set to the maximum buffer size, then the resize will fail.
  *
- * @param length
+ * @param amount
  *   A positive number greater than 0 representing how much to increase the size by.
  * @param string
  *   The string to resize.
@@ -1153,7 +1153,7 @@ extern "C" {
  *   F_string_too_large (with error bit) if the combined string is too large.
  */
 #ifndef _di_fl_string_dynamic_size_increase_
-  extern f_return_status fl_string_dynamic_size_increase(const f_string_length_t length, f_string_dynamic_t *string);
+  extern f_return_status fl_string_dynamic_size_increase(const f_string_length_t amount, f_string_dynamic_t *string);
 #endif // _di_fl_string_dynamic_size_increase_
 
 /**
@@ -1181,11 +1181,11 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
+ * @param seek_to_this
+ *   A single-width character representing a character to seek to.
  * @param range
  *   A range within the buffer representing the start and stop locations.
  *   The start location will be incremented by seek.
- * @param seek_to_this
- *   A single-width character representing a character to seek to.
  *
  * @return
  *   F_none on success.
@@ -1196,7 +1196,7 @@ extern "C" {
  *   F_parameter (with error bit) if a parameter is invalid.
  */
 #ifndef _di_fl_string_dynamic_seek_line_to_
-  extern f_return_status fl_string_dynamic_seek_line_to(const f_string_t string, f_string_range_t *range, const int8_t seek_to_this);
+  extern f_return_status fl_string_dynamic_seek_line_to(const f_string_t string, const int8_t seek_to_this, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_line_to_
 
 /**
@@ -1204,11 +1204,11 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
+ * @param seek_to_this
+ *   A 1-width, 2-width, 3-width, or 4-width character representing a character to seek to.
  * @param range
  *   A range within the buffer representing the start and stop locations.
  *   The start location will be incremented by seek.
- * @param seek_to_this
- *   A 1-width, 2-width, 3-width, or 4-width character representing a character to seek to.
  *
  * @return
  *   F_none on success.
@@ -1226,7 +1226,7 @@ extern "C" {
  * @see f_utf_char_to_character()
  */
 #ifndef _di_fl_string_dynamic_seek_line_to_utf_character_
-  extern f_return_status fl_string_dynamic_seek_line_to_utf_character(const f_string_t string, f_string_range_t *range, const f_utf_character_t seek_to_this);
+  extern f_return_status fl_string_dynamic_seek_line_to_utf_character(const f_string_t string, const f_utf_character_t seek_to_this, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_line_to_utf_character_
 
 /**
@@ -1234,10 +1234,10 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
- * @param range
- *   A range within the buffer representing the start and stop locations.
  * @param placeholder
  *   A single-width character representing a placeholder to ignore (may be NULL).
+ * @param range
+ *   A range within the buffer representing the start and stop locations.
  *
  * @return
  *   F_none on success.
@@ -1256,7 +1256,7 @@ extern "C" {
  * @see f_utf_is_graph()
  */
 #ifndef _di_fl_string_dynamic_seek_line_until_graph_
-  extern f_return_status fl_string_dynamic_seek_line_until_graph(const f_string_t string, f_string_range_t *range, const int8_t placeholder);
+  extern f_return_status fl_string_dynamic_seek_line_until_graph(const f_string_t string, const int8_t placeholder, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_line_until_graph_
 
 /**
@@ -1264,10 +1264,10 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
- * @param range
- *   A range within the buffer representing the start and stop locations.
  * @param placeholder
  *   A single-width character representing a placeholder to ignore (may be NULL).
+ * @param range
+ *   A range within the buffer representing the start and stop locations.
  *
  * @return
  *   F_none on success.
@@ -1286,7 +1286,7 @@ extern "C" {
  * @see f_utf_is_graph()
  */
 #ifndef _di_fl_string_dynamic_seek_line_until_non_graph_
-  extern f_return_status fl_string_dynamic_seek_line_until_non_graph(const f_string_t string, f_string_range_t *range, const int8_t placeholder);
+  extern f_return_status fl_string_dynamic_seek_line_until_non_graph(const f_string_t string, const int8_t placeholder, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_line_until_non_graph_
 
 /**
@@ -1294,11 +1294,11 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
+ * @param seek_to_this
+ *   A single-width character representing a character to seek to.
  * @param range
  *   A range within the buffer representing the start and stop locations.
  *   The start location will be incremented by seek.
- * @param seek_to_this
- *   A single-width character representing a character to seek to.
  *
  * @return
  *   F_none on success.
@@ -1310,7 +1310,7 @@ extern "C" {
  *   F_parameter (with error bit) if a parameter is invalid.
  */
 #ifndef _di_fl_string_dynamic_seek_to_
-  extern f_return_status fl_string_dynamic_seek_to(const f_string_t string, f_string_range_t *range, const int8_t seek_to_this);
+  extern f_return_status fl_string_dynamic_seek_to(const f_string_t string, const int8_t seek_to_this, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_to_
 
 /**
@@ -1318,11 +1318,11 @@ extern "C" {
  *
  * @param string
  *   The string to traverse.
+ * @param seek_to_this
+ *   A 1-width, 2-width, 3-width, or 4-width character representing a character to seek to.
  * @param range
  *   A range within the buffer representing the start and stop locations.
  *   The start location will be incremented by seek.
- * @param seek_to_this
- *   A 1-width, 2-width, 3-width, or 4-width character representing a character to seek to.
  *
  * @return
  *   F_none on success.
@@ -1339,7 +1339,7 @@ extern "C" {
  * @see f_utf_char_to_character()
  */
 #ifndef _di_fl_string_dynamic_seek_to_utf_character_
-  extern f_return_status fl_string_dynamic_seek_to_utf_character(const f_string_t string, f_string_range_t *range, const f_utf_character_t seek_to_this);
+  extern f_return_status fl_string_dynamic_seek_to_utf_character(const f_string_t string, const f_utf_character_t seek_to_this, f_string_range_t *range);
 #endif // _di_fl_string_dynamic_seek_to_utf_character_
 
 /**
index 16d53d8ec059bf1e6e350215248138e506aaf1fe..1ef274280d50e7382e233a8393c044d0940a92c5 100644 (file)
@@ -446,10 +446,12 @@ extern "C" {
 
     for (f_string_length_t i = 0; i < byte_dump_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
     } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 42267f793f9feedb55caab7f4fbfd35bb1d2259e..2513637644f27644aab13a2c6dcb2ddfe035670c 100644 (file)
@@ -362,6 +362,7 @@ extern "C" {
 
     for (f_string_length_t i = 0; i < fake_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
     } // for
 
index 741d6123956f386ae6d635b45bb3ad5d49e47193..3c394f47f52b43a9965a39e8389c5b013e2d4f1d 100644 (file)
@@ -695,13 +695,12 @@ extern "C" {
 
 #ifndef _di_firewall_delete_data_
   f_return_status firewall_delete_data(firewall_data_t *data) {
-    f_string_length_t i = 0;
 
-    while (i < firewall_total_parameters) {
+    for (f_string_length_t i = 0; i < firewall_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_dynamics_t_delete_simple(data->chains);
     f_macro_string_lengths_t_delete_simple(data->remaining);
index af054fde90071e377b5370e89cc9e7490be57a0c..27a819aea2a1a461ff29ef12aa62c79f1a44b4fc 100644 (file)
@@ -448,14 +448,12 @@ extern "C" {
 
 #ifndef _di_fss_basic_list_read_delete_data_
   f_return_status fss_basic_list_read_delete_data(fss_basic_list_read_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < fss_basic_list_read_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_basic_list_read_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_fss_contents_t_delete_simple(data->contents);
     f_macro_fss_objects_t_delete_simple(data->objects);
index f7676190f5c38cd5b802508352a4dc338c2b5eb9..9a2678166258d8ca249cae48c2900e277a559d73 100644 (file)
@@ -147,7 +147,7 @@ extern "C" {
             fss_basic_list_write_error_parameter_value_missing_print(*data, f_console_symbol_long_enable, fss_basic_list_write_long_content);
             status = F_status_set_error(F_parameter);
           }
-          else if (data->parameters[fss_basic_list_write_parameter_object].locations.used != data->parameters[fss_basic_list_write_parameter_content].locations.used) {
+          else if (data->parameters[fss_basic_list_write_parameter_object].locations.used != data->parameters[fss_basic_list_write_parameter_content].locations.used && data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_none) {
             fss_basic_list_write_error_parameter_same_times_print(*data);
             status = F_status_set_error(F_parameter);
           }
@@ -166,6 +166,33 @@ extern "C" {
               status = F_status_set_error(F_parameter);
             }
           }
+
+          if (F_status_is_error_not(status)) {
+            if (data->parameters[fss_basic_list_write_parameter_content].result == f_console_result_additional) {
+              f_array_length_t location_object = 0;
+              f_array_length_t location_content = 0;
+              f_array_length_t location_sub_object = 0;
+              f_array_length_t location_sub_content = 0;
+
+              for (f_array_length_t i = 0; i < data->parameters[fss_basic_list_write_parameter_object].locations.used; i++) {
+                location_object = data->parameters[fss_basic_list_write_parameter_object].locations.array[i];
+                location_content = data->parameters[fss_basic_list_write_parameter_content].locations.array[i];
+                location_sub_object = data->parameters[fss_basic_list_write_parameter_object].locations_sub.array[i];
+                location_sub_content = data->parameters[fss_basic_list_write_parameter_content].locations_sub.array[i];
+
+                if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
+                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_object);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_content);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+                  status = F_status_set_error(F_parameter);
+                  break;
+                }
+              } // for
+            }
+          }
         }
         else if (data->parameters[fss_basic_list_write_parameter_content].locations.used) {
           if (data->parameters[fss_basic_list_write_parameter_content].locations.used != data->parameters[fss_basic_list_write_parameter_content].additional.used) {
@@ -189,20 +216,32 @@ extern "C" {
 
         status = F_status_set_error(F_parameter);
       }
+
+      if (F_status_is_error_not(status) && data->process_pipe) {
+        if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) {
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_list_write_long_partial);
+            fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
+          }
+
+          status = F_status_set_error(F_parameter);
+        }
+      }
     }
 
-    f_fss_quote_t quoted = f_fss_delimit_quote_double;
+    f_fss_quote_t quote = f_fss_delimit_quote_double;
 
     if (F_status_is_error_not(status)) {
       if (data->parameters[fss_basic_list_write_parameter_double].result == f_console_result_found) {
         if (data->parameters[fss_basic_list_write_parameter_single].result == f_console_result_found) {
           if (data->parameters[fss_basic_list_write_parameter_double].location < data->parameters[fss_basic_list_write_parameter_single].location) {
-            quoted = f_fss_delimit_quote_single;
+            quote = f_fss_delimit_quote_single;
           }
         }
       }
       else if (data->parameters[fss_basic_list_write_parameter_single].result == f_console_result_found) {
-        quoted = f_fss_delimit_quote_single;
+        quote = f_fss_delimit_quote_single;
       }
     }
 
@@ -214,232 +253,37 @@ extern "C" {
       f_string_dynamic_t escaped = f_string_dynamic_t_initialize;
 
       if (data->process_pipe) {
-        f_file_t input = f_file_t_initialize;
-
-        input.id = f_type_descriptor_input;
-        input.size_read = 1;
-
-        bool object_ended = F_false;
-
-        f_string_length_t previous = 0;
-        f_string_range_t range = f_string_range_t_initialize;
-
-        range.start = 0;
-
-        if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) {
-          for (f_status_t status_pipe = F_none; ; ) {
-
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
-
-                status = F_status_set_error(F_pipe);
-                break;
-              }
-
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
-
-                status = F_status_set_error(F_parameter);
-                break;
-              }
-
-              range.stop = buffer.used - 1;
-            }
-
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
-
-            if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
-
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (data->parameters[fss_basic_list_write_parameter_object].result == f_console_result_found) {
-              object.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-            }
-            else {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-            }
-
-            status = fss_basic_list_write_process(*data, output, object, content, quoted, &buffer);
-            if (F_status_is_error(status)) break;
-
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
-
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
-            }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
-        }
-        else {
-          for (f_status_t status_pipe = F_none; ; ) {
-
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
-
-                status = F_status_set_error(F_pipe);
-                break;
-              }
-
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
-
-                status = F_status_set_error(F_parameter);
-                break;
-              }
-
-              range.stop = buffer.used - 1;
-            }
-
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
-
-            if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
-
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (object_ended && previous == range.start) {
-              if (data->error.verbosity != f_console_verbosity_quiet) {
-                fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has incorrectly placed newlines.%c", fll_error_print_error, f_string_eol[0]);
-              }
-
-              status = F_status_set_error(F_parameter);
-              break;
-            }
-
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (object_ended) {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &content);
+        status = fss_basic_list_write_process_pipe(*data, output, quote, &buffer);
 
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-
-              status = fss_basic_list_write_process(*data, output, object, content, quoted, &buffer);
-              if (F_status_is_error(status)) break;
-
-              object_ended = F_false;
-            }
-            else {
-              object.used = 0;
-
-              status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-              if (F_status_is_error(status)) {
-                fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                break;
-              }
-
-              object_ended = F_true;
-            }
-
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
-
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
-            }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
-
-          if (F_status_is_error_not(status) && object_ended) {
-            if (data->error.verbosity != f_console_verbosity_quiet) {
-              fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has an object without content.%c", fll_error_print_error, f_string_eol[0]);
-            }
-
-            status = F_status_set_error(F_parameter);
-          }
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
         }
       }
 
       if (F_status_is_error_not(status)) {
         if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) {
-          if (data->parameters[fss_basic_list_write_parameter_object].result == f_console_result_found) {
-            content.used = 0;
 
+          if (data->parameters[fss_basic_list_write_parameter_object].result == f_console_result_additional) {
             for (f_array_length_t i = 0; i < data->parameters[fss_basic_list_write_parameter_object].additional.used; i++) {
 
               object.string = arguments.argv[data->parameters[fss_basic_list_write_parameter_object].additional.array[i]];
               object.used = strnlen(object.string, f_console_length_size);
               object.size = object.used;
 
-              status = fss_basic_list_write_process(*data, output, object, content, quoted, &buffer);
+              status = fss_basic_list_write_process(*data, output, quote, &object, 0, &buffer);
               if (F_status_is_error(status)) break;
             } // for
           }
           else {
-            object.used = 0;
-
-            for (f_array_length_t i = 0; i < data->parameters[fss_basic_list_write_parameter_object].additional.used; i++) {
+            for (f_array_length_t i = 0; i < data->parameters[fss_basic_list_write_parameter_content].additional.used; i++) {
 
               content.string = arguments.argv[data->parameters[fss_basic_list_write_parameter_content].additional.array[i]];
               content.used = strnlen(content.string, f_console_length_size);
               content.size = content.used;
 
-              status = fss_basic_list_write_process(*data, output, object, content, quoted, &buffer);
+              status = fss_basic_list_write_process(*data, output, quote, 0, &content, &buffer);
               if (F_status_is_error(status)) break;
             } // for
           }
@@ -455,13 +299,18 @@ extern "C" {
             content.used = strnlen(content.string, f_console_length_size);
             content.size = content.used;
 
-            status = fss_basic_list_write_process(*data, output, object, content, quoted, &buffer);
+            status = fss_basic_list_write_process(*data, output, quote, &object, &content, &buffer);
             if (F_status_is_error(status)) break;
           } // for
         }
 
-        // ensure there is always a newline at the end, unless in quiet mode.
-        if (F_status_is_error_not(status) && data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_none) {
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+        }
+        else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_list_write_parameter_file].result == f_console_result_none) {
+          // ensure there is always a newline at the end, unless in quiet mode.
           fprintf(f_type_output, "%c", f_string_eol[0]);
         }
       }
@@ -501,15 +350,15 @@ extern "C" {
 
 #ifndef _di_fss_basic_list_write_delete_data_
   f_return_status fss_basic_list_write_delete_data(fss_basic_list_write_data_t *data) {
-    f_string_length_t i = 0;
 
-    while (i < fss_basic_list_write_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_basic_list_write_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 1a1850f3f5c4540ffeab9dc9dc985a3170474192..092d5f359717d89fab78ab22bf5e726159c71b90 100644 (file)
@@ -54,6 +54,9 @@ extern "C" {
 #endif // _di_fss_basic_list_write_name_
 
 #ifndef _di_fss_basic_list_write_defines_
+  #define fss_basic_list_write_pipe_content_start '\0'
+  #define fss_basic_list_write_pipe_content_end   '\f'
+
   #define fss_basic_list_write_short_file    "f"
   #define fss_basic_list_write_short_content "c"
   #define fss_basic_list_write_short_double  "d"
index eb3b45f09690c0c80cbb09331546a0ea0870fd14..a189661119ad7b2785f7a03ac61d89111d4ef030 100644 (file)
@@ -36,54 +36,198 @@ extern "C" {
 #endif // _di_fss_basic_list_write_error_parameter_value_missing_print_
 
 #ifndef _di_fss_basic_list_write_process_
-  f_return_status fss_basic_list_write_process(const fss_basic_list_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, const f_fss_quote_t quoted, f_string_dynamic_t *buffer) {
+  f_return_status fss_basic_list_write_process(const fss_basic_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) {
     f_status_t status = F_none;
 
-    f_string_range_t range = f_macro_string_range_t_initialize(object.used);
+    f_string_range_t range = f_string_range_t_initialize;
 
-    buffer->used = 0;
-
-    if (data.parameters[fss_basic_list_write_parameter_object].result == f_console_result_found) {
+    if (object) {
+      if (object->used) {
+        range.start = 0;
+        range.stop = object->used - 1;
+      }
+      else {
+        range.start = 1;
+        range.stop = 0;
+      }
 
-      status = fl_fss_basic_list_object_write(object, quoted, &range, buffer);
+      status = fl_fss_basic_list_object_write(*object, quote, &range, buffer);
 
-      if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) {
-        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_object_write", F_true);
+      if (status == F_data_not_stop || status == F_data_not_eos) {
+        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
         return F_status_set_error(status);
       }
+      else if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
+        return status;
+      }
     }
 
-    if (data.parameters[fss_basic_list_write_parameter_content].result == f_console_result_found) {
-      if (content.used) {
+    if (content) {
+      if (content->used) {
         range.start = 0;
-        range.stop = content.used;
+        range.stop = content->used - 1;
       }
       else {
         range.start = 1;
         range.stop = 0;
       }
 
-      status = fl_fss_basic_list_content_write(content, &range, buffer);
+      status = fl_fss_basic_list_content_write(*content, &range, buffer);
 
-      if (F_status_is_error(status) || data.parameters[fss_basic_list_write_parameter_content].result == f_console_result_found) {
-        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
-        return F_status_set_error(status);
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_content_write", F_true);
+        return status;
       }
     }
 
-    status = fl_string_dynamic_terminate(buffer);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate", F_true);
-      return F_status_set_error(status);
-    }
-
     f_print_dynamic(output.stream, *buffer);
 
+    buffer->used = 0;
     return status;
   }
 #endif // _di_fss_basic_list_write_process_
 
+#ifndef _di_fss_basic_list_write_process_pipe_
+  f_return_status fss_basic_list_write_process_pipe(const fss_basic_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) {
+    f_status_t status = F_none;
+    f_status_t status_pipe = F_none;
+
+    f_file_t input = f_file_t_initialize;
+
+    input.id = f_type_descriptor_input;
+    input.size_read = 2048;
+
+    f_string_length_t total = 0;
+    f_string_length_t previous = 0;
+    f_string_range_t range = f_string_range_t_initialize;
+
+    f_string_dynamic_t block = f_string_dynamic_t_initialize;
+    f_string_dynamic_t object = f_string_dynamic_t_initialize;
+    f_string_dynamic_t content = f_string_dynamic_t_initialize;
+
+    // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set.
+    uint8_t state = 0;
+
+    for (;;) {
+
+      if (range.start > range.stop) {
+        if (status_pipe == F_none_eof) break;
+
+        block.used = 0;
+
+        status_pipe = f_file_read_block(input, &block);
+
+        if (F_status_is_error(status_pipe)) {
+          fll_error_print(data.error, F_status_set_fine(status_pipe), "f_file_read_block", F_true);
+
+          status_pipe = F_status_set_error(F_pipe);
+          break;
+        }
+
+        range.start = 0;
+        range.stop = block.used - 1;
+      }
+
+      if (!state || state == 0x1) {
+        if (!state) {
+          object.used = 0;
+          content.used = 0;
+
+          state = 0x1;
+        }
+
+        if (object.used + block.used > object.size) {
+          status = fl_string_dynamic_size_increase(block.used, &object);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+            break;
+          }
+        }
+
+        for (; range.start <= range.stop; range.start++) {
+
+          if (block.string[range.start] == fss_basic_list_write_pipe_content_start) {
+            state = 0x2;
+            range.start++;
+            break;
+          }
+
+          object.string[object.used++] = block.string[range.start];
+        } // for
+
+        if (F_status_is_error(status)) break;
+
+        // if the start of content was not found, then fetch the next block.
+        if (state != 0x2) continue;
+
+        // if the end of the current block is reached, fetch the next block.
+        if (range.start > range.stop) continue;
+      }
+
+      if (state == 0x2) {
+        if (block.used && range.start <= range.stop) {
+          total = (range.stop - range.start) + 1;
+        }
+        else {
+          total = 0;
+        }
+
+        if (total) {
+          if (content.used + total > content.size) {
+            status = fl_string_dynamic_size_increase(total, &content);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+              break;
+            }
+          }
+
+          for (; range.start <= range.stop; range.start++) {
+
+            if (block.string[range.start] == fss_basic_list_write_pipe_content_start) {
+              fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+
+              status = F_status_set_error(F_unsupported);
+              break;
+            }
+            else if (block.string[range.start] == fss_basic_list_write_pipe_content_end) {
+              state = 0x3;
+              range.start++;
+              break;
+            }
+
+            content.string[content.used++] = block.string[range.start];
+          } // for
+
+          if (F_status_is_error(status)) break;
+        }
+        else {
+          state = 0x3;
+        }
+      }
+
+      if (state == 0x3) {
+        status = fss_basic_list_write_process(data, output, quote, &object, &content, buffer);
+        if (F_status_is_error(status)) break;
+
+        state = 0;
+      }
+    } // for
+
+    // if the pipe ended before finishing, then attempt to wrap up.
+    if (status_pipe == F_none_eof && state) {
+      status = fss_basic_list_write_process(data, output, quote, &object, &content, buffer);
+    }
+
+    f_macro_string_dynamic_t_delete_simple(block);
+    f_macro_string_dynamic_t_delete_simple(object);
+    f_macro_string_dynamic_t_delete_simple(content);
+    return status;
+  }
+#endif // _di_fss_basic_list_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 2e9fcbd399a12a30d45218f7a9802326b76be500..bb18a92b961fc6de38af1d3f8089c10833c06ace 100644 (file)
@@ -51,13 +51,13 @@ extern "C" {
  *   The program data.
  * @param output
  *   The file to output to.
+ * @param quote
+ *   The quote character to use.
+ *   This is either single our double quote.
  * @param object
  *   The object to validate and print.
  * @param content
  *   The content to escape and print.
- * @param quoted
- *   The quote character to use.
- *   This is either single our double quote.
  * @param buffer
  *   The buffer array used as a cache to construct the output before printing.
  *
@@ -66,9 +66,30 @@ extern "C" {
  *   F_failure (with error bit) for any othe failure.
  */
 #ifndef _di_fss_basic_list_write_process_
-  extern f_return_status fss_basic_list_write_process(const fss_basic_list_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, const f_fss_quote_t quoted, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+  extern f_return_status fss_basic_list_write_process(const fss_basic_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_basic_list_write_process_
 
+/**
+ * Process the pipe, reading from the pipe and writing to the output.
+ *
+ * @param data
+ *   The program data.
+ * @param output
+ *   The file to output to.
+ * @param quote
+ *   The quote character to use.
+ *   This is either single our double quote.
+ * @param buffer
+ *   The buffer array used as a cache to construct the output before printing.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_basic_list_write_process_pipe_
+  extern f_return_status fss_basic_list_write_process_pipe(const fss_basic_list_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_list_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index e77bad40b606d55d312afe1f2b64de09be11ca98..c660853793dbbb5de8ac15eefe8e970ee6538e3e 100644 (file)
@@ -448,14 +448,12 @@ extern "C" {
 
 #ifndef _di_fss_basic_read_delete_data_
   f_return_status fss_basic_read_delete_data(fss_basic_read_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < fss_basic_read_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_basic_read_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_fss_contents_t_delete_simple(data->contents);
     f_macro_fss_objects_t_delete_simple(data->objects);
index a9419ff077e759d2a9b7f4d0bc19c337bc280b2c..a0e7889cd7c4ac8fce050a4af0b03df0bf6522fe 100644 (file)
@@ -147,7 +147,7 @@ extern "C" {
             fss_basic_write_error_parameter_value_missing_print(*data, f_console_symbol_long_enable, fss_basic_write_long_content);
             status = F_status_set_error(F_parameter);
           }
-          else if (data->parameters[fss_basic_write_parameter_object].locations.used != data->parameters[fss_basic_write_parameter_content].locations.used) {
+          else if (data->parameters[fss_basic_write_parameter_object].locations.used != data->parameters[fss_basic_write_parameter_content].locations.used && data->parameters[fss_basic_write_parameter_partial].result == f_console_result_none) {
             fss_basic_write_error_parameter_same_times_print(*data);
             status = F_status_set_error(F_parameter);
           }
@@ -166,6 +166,33 @@ extern "C" {
               status = F_status_set_error(F_parameter);
             }
           }
+
+          if (F_status_is_error_not(status)) {
+            if (data->parameters[fss_basic_write_parameter_content].result == f_console_result_additional) {
+              f_array_length_t location_object = 0;
+              f_array_length_t location_content = 0;
+              f_array_length_t location_sub_object = 0;
+              f_array_length_t location_sub_content = 0;
+
+              for (f_array_length_t i = 0; i < data->parameters[fss_basic_write_parameter_object].locations.used; i++) {
+                location_object = data->parameters[fss_basic_write_parameter_object].locations.array[i];
+                location_content = data->parameters[fss_basic_write_parameter_content].locations.array[i];
+                location_sub_object = data->parameters[fss_basic_write_parameter_object].locations_sub.array[i];
+                location_sub_content = data->parameters[fss_basic_write_parameter_content].locations_sub.array[i];
+
+                if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
+                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_object);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_content);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+                  status = F_status_set_error(F_parameter);
+                  break;
+                }
+              } // for
+            }
+          }
         }
         else if (data->parameters[fss_basic_write_parameter_content].locations.used) {
           if (data->parameters[fss_basic_write_parameter_content].locations.used != data->parameters[fss_basic_write_parameter_content].additional.used) {
@@ -189,6 +216,18 @@ extern "C" {
 
         status = F_status_set_error(F_parameter);
       }
+
+      if (F_status_is_error_not(status) && data->process_pipe) {
+        if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) {
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_basic_write_long_partial);
+            fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
+          }
+
+          status = F_status_set_error(F_parameter);
+        }
+      }
     }
 
     f_fss_quote_t quote = f_fss_delimit_quote_double;
@@ -214,210 +253,18 @@ extern "C" {
       f_string_dynamic_t escaped = f_string_dynamic_t_initialize;
 
       if (data->process_pipe) {
-        f_file_t input = f_file_t_initialize;
-
-        input.id = f_type_descriptor_input;
-        input.size_read = 1;
-
-        bool object_ended = F_false;
-
-        f_string_length_t previous = 0;
-        f_string_range_t range = f_string_range_t_initialize;
-
-        range.start = 0;
-
-        if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) {
-          for (f_status_t status_pipe = F_none; ; ) {
-
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
-
-                status = F_status_set_error(F_pipe);
-                break;
-              }
-
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
-
-                status = F_status_set_error(F_parameter);
-                break;
-              }
-
-              range.stop = buffer.used - 1;
-            }
-
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
-
-            if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
-
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (data->parameters[fss_basic_write_parameter_object].result == f_console_result_found) {
-              object.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-            }
-            else {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-            }
-
-            status = fss_basic_write_process(*data, output, object, content, quote, &buffer);
-            if (F_status_is_error(status)) break;
-
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
-
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
-            }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
-        }
-        else {
-          for (f_status_t status_pipe = F_none; ; ) {
-
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
-
-                status = F_status_set_error(F_pipe);
-                break;
-              }
-
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
-
-                status = F_status_set_error(F_parameter);
-                break;
-              }
-
-              range.stop = buffer.used - 1;
-            }
-
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
-
-            if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
-
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (object_ended && previous == range.start) {
-              if (data->error.verbosity != f_console_verbosity_quiet) {
-                fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has incorrectly placed newlines.%c", fll_error_print_error, f_string_eol[0]);
-              }
-
-              status = F_status_set_error(F_parameter);
-              break;
-            }
-
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (object_ended) {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &content);
+        status = fss_basic_write_process_pipe(*data, output, quote, &buffer);
 
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-
-              status = fss_basic_write_process(*data, output, object, content, quote, &buffer);
-              if (F_status_is_error(status)) break;
-
-              object_ended = F_false;
-            }
-            else {
-              object.used = 0;
-
-              status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-              if (F_status_is_error(status)) {
-                fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                break;
-              }
-
-              object_ended = F_true;
-            }
-
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
-
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
-            }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
-
-          if (F_status_is_error_not(status) && object_ended) {
-            if (data->error.verbosity != f_console_verbosity_quiet) {
-              fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has an object without content.%c", fll_error_print_error, f_string_eol[0]);
-            }
-
-            status = F_status_set_error(F_parameter);
-          }
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
         }
       }
 
       if (F_status_is_error_not(status)) {
         if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) {
-          if (data->parameters[fss_basic_write_parameter_object].result == f_console_result_found) {
+          if (data->parameters[fss_basic_write_parameter_object].result == f_console_result_additional) {
             content.used = 0;
 
             for (f_array_length_t i = 0; i < data->parameters[fss_basic_write_parameter_object].additional.used; i++) {
@@ -426,20 +273,20 @@ extern "C" {
               object.used = strnlen(object.string, f_console_length_size);
               object.size = object.used;
 
-              status = fss_basic_write_process(*data, output, object, content, quote, &buffer);
+              status = fss_basic_write_process(*data, output, quote, &object, 0, &buffer);
               if (F_status_is_error(status)) break;
             } // for
           }
           else {
             object.used = 0;
 
-            for (f_array_length_t i = 0; i < data->parameters[fss_basic_write_parameter_object].additional.used; i++) {
+            for (f_array_length_t i = 0; i < data->parameters[fss_basic_write_parameter_content].additional.used; i++) {
 
               content.string = arguments.argv[data->parameters[fss_basic_write_parameter_content].additional.array[i]];
               content.used = strnlen(content.string, f_console_length_size);
               content.size = content.used;
 
-              status = fss_basic_write_process(*data, output, object, content, quote, &buffer);
+              status = fss_basic_write_process(*data, output, quote, 0, &content, &buffer);
               if (F_status_is_error(status)) break;
             } // for
           }
@@ -455,13 +302,18 @@ extern "C" {
             content.used = strnlen(content.string, f_console_length_size);
             content.size = content.used;
 
-            status = fss_basic_write_process(*data, output, object, content, quote, &buffer);
+            status = fss_basic_write_process(*data, output, quote, &object, &content, &buffer);
             if (F_status_is_error(status)) break;
           } // for
         }
 
-        // ensure there is always a newline at the end, unless in quiet mode.
-        if (F_status_is_error_not(status) && data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_write_parameter_file].result == f_console_result_none) {
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+        }
+        else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_basic_write_parameter_file].result == f_console_result_none) {
+          // ensure there is always a newline at the end, unless in quiet mode.
           fprintf(f_type_output, "%c", f_string_eol[0]);
         }
       }
@@ -501,14 +353,15 @@ extern "C" {
 
 #ifndef _di_fss_basic_write_delete_data_
   f_return_status fss_basic_write_delete_data(fss_basic_write_data_t *data) {
-    f_status_t status = F_none;
 
     for (f_string_length_t i = 0; i < fss_basic_write_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
     } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 8f82db6cb3408e849c3d7cdc87de02b3977edf43..ce3e0c091c87e73fe7edffc5aaa9714947f460cf 100644 (file)
@@ -55,6 +55,9 @@ extern "C" {
 #endif // _di_fss_basic_write_name_
 
 #ifndef _di_fss_basic_write_defines_
+  #define fss_basic_write_pipe_content_start '\0'
+  #define fss_basic_write_pipe_content_end   '\f'
+
   #define fss_basic_write_short_file    "f"
   #define fss_basic_write_short_content "c"
   #define fss_basic_write_short_double  "d"
index 4b494418731a539a0cc33a3f02489cc25421b102..8a52fc72f2df404c3cf8dfaa132552b4e3a05d43 100644 (file)
@@ -4,6 +4,10 @@ int main(const unsigned long argc, const f_string_t *argv) {
   const f_console_arguments_t arguments = { argc, argv };
   fss_basic_write_data_t data = fss_basic_write_data_t_initialize;
 
+  if (f_pipe_input_exists()) {
+    data.process_pipe = F_true;
+  }
+
   if (F_status_is_error(fss_basic_write_main(arguments, &data))) {
     return 1;
   }
index 8cfde33f033365a512d58e8d56fa4347dd5cd415..e05b2d17efeb895b6e4bd7a37c23d5be8d413c7d 100644 (file)
@@ -36,22 +36,215 @@ extern "C" {
 #endif // _di_fss_basic_write_error_parameter_value_missing_print_
 
 #ifndef _di_fss_basic_write_process_
-  f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, const f_fss_quote_t quote, f_string_dynamic_t *buffer) {
-    buffer->used = 0;
+  f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) {
+    f_status_t status = F_none;
+
+    f_string_range_t range = f_string_range_t_initialize;
+
+    if (object) {
+      if (object->used) {
+        range.start = 0;
+        range.stop = object->used - 1;
+      }
+      else {
+        range.start = 1;
+        range.stop = 0;
+      }
+
+      status = fl_fss_basic_object_write(*object, quote, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
-    f_status_t status = fll_fss_basic_write(object, content, quote, buffer);
+      if (F_status_set_fine(status) == F_none_eol) {
+        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+        fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+        fl_color_print(data.error.to.stream, data.context.set.error, "'.%c", f_string_eol[0]);
 
-    if (F_status_is_error(status)) {
-      fll_error_print(data.error, F_status_set_fine(status), "fll_fss_basic_write", F_true);
-      return F_status_set_error(status);
+        return F_status_set_error(F_unsupported);
+      }
+
+      if (status == F_data_not_stop || status == F_data_not_eos) {
+        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
+        return F_status_set_error(status);
+      }
+      else if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
+        return status;
+      }
+    }
+
+    if (content) {
+      if (content->used) {
+        range.start = 0;
+        range.stop = content->used - 1;
+      }
+      else {
+        range.start = 1;
+        range.stop = 0;
+      }
+
+      status = fl_fss_basic_content_write(*content, object ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
+        return status;
+      }
+    }
+    else {
+      // objects in this standard do not have EOL, so add an EOL for printing purposes when there is no desired content.
+      status = fl_string_append(f_string_eol, 1, buffer);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_content_write", F_true);
+        return status;
+      }
     }
 
     f_print_dynamic(output.stream, *buffer);
 
+    buffer->used = 0;
     return status;
   }
 #endif // _di_fss_basic_write_process_
 
+#ifndef _di_fss_basic_write_process_pipe_
+  f_return_status fss_basic_write_process_pipe(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) {
+    f_status_t status = F_none;
+    f_status_t status_pipe = F_none;
+
+    f_file_t input = f_file_t_initialize;
+
+    input.id = f_type_descriptor_input;
+    input.size_read = 2048;
+
+    f_string_length_t total = 0;
+    f_string_length_t previous = 0;
+    f_string_range_t range = f_string_range_t_initialize;
+
+    f_string_dynamic_t block = f_string_dynamic_t_initialize;
+    f_string_dynamic_t object = f_string_dynamic_t_initialize;
+    f_string_dynamic_t content = f_string_dynamic_t_initialize;
+
+    // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set.
+    uint8_t state = 0;
+
+    for (;;) {
+
+      if (range.start > range.stop) {
+        if (status_pipe == F_none_eof) break;
+
+        block.used = 0;
+
+        status_pipe = f_file_read_block(input, &block);
+
+        if (F_status_is_error(status_pipe)) {
+          fll_error_print(data.error, F_status_set_fine(status_pipe), "f_file_read_block", F_true);
+
+          status_pipe = F_status_set_error(F_pipe);
+          break;
+        }
+
+        range.start = 0;
+        range.stop = block.used - 1;
+      }
+
+      if (!state || state == 0x1) {
+        if (!state) {
+          object.used = 0;
+          content.used = 0;
+
+          state = 0x1;
+        }
+
+        if (object.used + block.used > object.size) {
+          status = fl_string_dynamic_size_increase(block.used, &object);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+            break;
+          }
+        }
+
+        for (; range.start <= range.stop; range.start++) {
+
+          if (block.string[range.start] == fss_basic_write_pipe_content_start) {
+            state = 0x2;
+            range.start++;
+            break;
+          }
+
+          object.string[object.used++] = block.string[range.start];
+        } // for
+
+        if (F_status_is_error(status)) break;
+
+        // if the start of content was not found, then fetch the next block.
+        if (state != 0x2) continue;
+
+        // if the end of the current block is reached, fetch the next block.
+        if (range.start > range.stop) continue;
+      }
+
+      if (state == 0x2) {
+        if (block.used && range.start <= range.stop) {
+          total = (range.stop - range.start) + 1;
+        }
+        else {
+          total = 0;
+        }
+
+        if (total) {
+          if (content.used + total > content.size) {
+            status = fl_string_dynamic_size_increase(total, &content);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+              break;
+            }
+          }
+
+          for (; range.start <= range.stop; range.start++) {
+
+            if (block.string[range.start] == fss_basic_write_pipe_content_start) {
+              fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard only supports one content per object.%c", fll_error_print_error, f_string_eol[0]);
+
+              status = F_status_set_error(F_unsupported);
+              break;
+            }
+            else if (block.string[range.start] == fss_basic_write_pipe_content_end) {
+              state = 0x3;
+              range.start++;
+              break;
+            }
+
+            content.string[content.used++] = block.string[range.start];
+          } // for
+
+          if (F_status_is_error(status)) break;
+        }
+        else {
+          state = 0x3;
+        }
+      }
+
+      if (state == 0x3) {
+        status = fss_basic_write_process(data, output, quote, &object, &content, buffer);
+        if (F_status_is_error(status)) break;
+
+        state = 0;
+      }
+    } // for
+
+    // if the pipe ended before finishing, then attempt to wrap up.
+    if (status_pipe == F_none_eof && state) {
+      status = fss_basic_write_process(data, output, quote, &object, &content, buffer);
+    }
+
+    f_macro_string_dynamic_t_delete_simple(block);
+    f_macro_string_dynamic_t_delete_simple(object);
+    f_macro_string_dynamic_t_delete_simple(content);
+    return status;
+  }
+#endif // _di_fss_basic_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 687ed35563306d82e3a6f218c00e6f5693b21197..ad3f60dd3179297f46858b6918992332c6805211 100644 (file)
@@ -51,13 +51,15 @@ extern "C" {
  *   The program data.
  * @param output
  *   The file to output to.
- * @param object
- *   The object to validate and print.
- * @param content
- *   The content to escape and print.
  * @param quote
  *   The quote character to use.
  *   This is either single our double quote.
+ * @param object
+ *   A pointer to the object to validate and print.
+ *   Set to 0 to disable.
+ * @param content
+ *   A pointer to the  content to escape and print.
+ *   Set to 0 to disable.
  * @param buffer
  *   The buffer array used as a cache to construct the output before printing.
  *
@@ -66,9 +68,30 @@ extern "C" {
  *   F_failure (with error bit) for any othe failure.
  */
 #ifndef _di_fss_basic_write_process_
-  extern f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_static_t content, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+  extern f_return_status fss_basic_write_process(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_static_t *content, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_basic_write_process_
 
+/**
+ * Process the pipe, reading from the pipe and writing to the output.
+ *
+ * @param data
+ *   The program data.
+ * @param output
+ *   The file to output to.
+ * @param quote
+ *   The quote character to use.
+ *   This is either single our double quote.
+ * @param buffer
+ *   The buffer array used as a cache to construct the output before printing.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_basic_write_process_pipe_
+  extern f_return_status fss_basic_write_process_pipe(const fss_basic_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index a02cb3a93bcbdcf30505f00eba6d5fdd6eb6021d..500a89bd7faee909c93cd9331abed25ed4333ebe 100644 (file)
@@ -431,14 +431,12 @@ extern "C" {
 
 #ifndef _di_fss_extended_list_read_delete_data_
   f_return_status fss_extended_list_read_delete_data(fss_extended_list_read_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < fss_extended_list_read_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_extended_list_read_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_fss_nest_t_delete_simple(data->nest);
 
index 4fa0f4229d1534e7afe3fcf9d799dc58f0883ced..429c34b34536d6246f88c162a0b9343a75e8f4b1 100644 (file)
@@ -449,14 +449,12 @@ extern "C" {
 
 #ifndef _di_fss_extended_read_delete_data_
   f_return_status fss_extended_read_delete_data(fss_extended_read_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < fss_extended_read_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_extended_read_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_fss_contents_t_delete_simple(data->contents);
     f_macro_fss_objects_t_delete_simple(data->objects);
index 306415f34a4528345a0433ba6f606f5504907b8a..e7efbf5cdd36c46f182fbec69bf327cc80d92875 100644 (file)
@@ -147,8 +147,8 @@ extern "C" {
             fss_extended_write_error_parameter_value_missing_print(*data, f_console_symbol_long_enable, fss_extended_write_long_content);
             status = F_status_set_error(F_parameter);
           }
-          else if (data->parameters[fss_extended_write_parameter_object].locations.used != data->parameters[fss_extended_write_parameter_content].locations.used) {
-            fss_extended_write_error_parameter_same_times_print(*data);
+          else if (!data->parameters[fss_extended_write_parameter_content].locations.used && data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) {
+            fss_extended_write_error_parameter_at_least_once(*data);
             status = F_status_set_error(F_parameter);
           }
           else if (data->parameters[fss_extended_write_parameter_content].locations.used && data->parameters[fss_extended_write_parameter_partial].locations.used) {
@@ -166,6 +166,41 @@ extern "C" {
               status = F_status_set_error(F_parameter);
             }
           }
+
+          if (F_status_is_error_not(status)) {
+            if (data->parameters[fss_extended_write_parameter_content].result == f_console_result_additional) {
+              f_array_length_t location_object = data->parameters[fss_extended_write_parameter_object].locations.array[0];
+              f_array_length_t location_content = data->parameters[fss_extended_write_parameter_content].locations.array[0];
+              f_array_length_t location_sub_object = data->parameters[fss_extended_write_parameter_object].locations_sub.array[0];
+              f_array_length_t location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[0];
+
+              if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
+                fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+                fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must be specified before a '");
+                fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+                fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+                status = F_status_set_error(F_parameter);
+              }
+              else {
+                location_object = data->parameters[fss_extended_write_parameter_object].locations.array[data->parameters[fss_extended_write_parameter_object].locations.used - 1];
+                location_content = data->parameters[fss_extended_write_parameter_content].locations.array[data->parameters[fss_extended_write_parameter_content].locations.used - 1];
+                location_sub_object = data->parameters[fss_extended_write_parameter_object].locations_sub.array[data->parameters[fss_extended_write_parameter_object].locations_sub.used - 1];
+                location_sub_content = data->parameters[fss_extended_write_parameter_content].locations_sub.array[data->parameters[fss_extended_write_parameter_content].locations_sub.used - 1];
+
+                if (location_object > location_content || location_object == location_content && location_sub_object > location_sub_content) {
+                  fl_color_print(data->error.to.stream, data->context.set.error, "%sEach ", fll_error_print_error);
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter must have at least one '");
+                  fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
+                  fl_color_print(data->error.to.stream, data->context.set.error, "' parameter.%c", f_string_eol[0]);
+
+                  status = F_status_set_error(F_parameter);
+                }
+              }
+            }
+          }
         }
         else if (data->parameters[fss_extended_write_parameter_content].locations.used) {
           if (data->parameters[fss_extended_write_parameter_content].locations.used != data->parameters[fss_extended_write_parameter_content].additional.used) {
@@ -173,7 +208,7 @@ extern "C" {
             status = F_status_set_error(F_parameter);
           }
           else if (!data->parameters[fss_extended_write_parameter_partial].locations.used) {
-            fss_extended_write_error_parameter_same_times_print(*data);
+            fss_extended_write_error_parameter_at_least_once(*data);
             status = F_status_set_error(F_parameter);
           }
         }
@@ -189,6 +224,18 @@ extern "C" {
 
         status = F_status_set_error(F_parameter);
       }
+
+      if (F_status_is_error_not(status) && data->process_pipe) {
+        if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) {
+          if (data->error.verbosity != f_console_verbosity_quiet) {
+            fl_color_print(data->error.to.stream, data->context.set.error, "%sThe '", fll_error_print_error);
+            fl_color_print(data->error.to.stream, data->context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_partial);
+            fl_color_print(data->error.to.stream, data->context.set.error, "' parameter cannot be used when processing a pipe.%c", f_string_eol[0]);
+          }
+
+          status = F_status_set_error(F_parameter);
+        }
+      }
     }
 
     f_fss_quote_t quote = f_fss_delimit_quote_double;
@@ -208,274 +255,138 @@ extern "C" {
 
     f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
     f_string_dynamic_t object = f_string_dynamic_t_initialize;
-    f_string_dynamic_t content = f_string_dynamic_t_initialize;
+    f_string_dynamics_t contents = f_string_dynamics_t_initialize;
 
     if (F_status_is_error_not(status)) {
       f_string_dynamic_t escaped = f_string_dynamic_t_initialize;
 
       if (data->process_pipe) {
-        f_file_t input = f_file_t_initialize;
-
-        input.id = f_type_descriptor_input;
-        input.size_read = 1;
-
-        bool object_ended = F_false;
-
-        f_string_length_t previous = 0;
-        f_string_range_t range = f_string_range_t_initialize;
+        status = fss_extended_write_process_pipe(*data, output, quote, &buffer);
 
-        range.start = 0;
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input pipe");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+        }
+      }
 
+      if (F_status_is_error_not(status)) {
         if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) {
-          for (f_status_t status_pipe = F_none; ; ) {
+          if (data->parameters[fss_extended_write_parameter_object].result == f_console_result_additional) {
+            contents.used = 0;
 
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
+            for (f_array_length_t i = 0; i < data->parameters[fss_extended_write_parameter_object].additional.used; i++) {
 
-                status = F_status_set_error(F_pipe);
-                break;
-              }
+              object.string = arguments.argv[data->parameters[fss_extended_write_parameter_object].additional.array[i]];
+              object.used = strnlen(object.string, f_console_length_size);
+              object.size = object.used;
 
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
+              status = fss_extended_write_process(*data, output, quote, &object, 0, &buffer);
+              if (F_status_is_error(status)) break;
+            } // for
+          }
+          else {
+            object.used = 0;
 
-                status = F_status_set_error(F_parameter);
-                break;
-              }
+            status = fl_string_dynamics_size_increase(data->parameters[fss_extended_write_parameter_content].additional.used, &contents);
 
-              range.stop = buffer.used - 1;
+            if (status == F_buffer_too_large) {
+              status = F_status_set_error(status);
             }
 
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
-
             if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
-
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
-
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (data->parameters[fss_extended_write_parameter_object].result == f_console_result_found) {
-              object.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
+              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
             }
             else {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
-              }
-            }
-
-            status = fss_extended_write_process(*data, output, object, content, quote, &buffer);
-            if (F_status_is_error(status)) break;
+              for (f_array_length_t i = 0; i < data->parameters[fss_extended_write_parameter_content].additional.used; i++) {
 
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
+                contents.array[contents.used].string = arguments.argv[data->parameters[fss_extended_write_parameter_content].additional.array[i]];
+                contents.array[contents.used].used = strnlen(contents.array[contents.used].string, f_console_length_size);
+                contents.array[contents.used].size = contents.array[contents.used].used;
+                contents.used++;
+              } // for
 
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
+              status = fss_extended_write_process(*data, output, quote, 0, &contents, &buffer);
             }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
+          }
         }
         else {
-          for (f_status_t status_pipe = F_none; ; ) {
-
-            if (status_pipe != F_none_eof) {
-              status_pipe = f_file_read(input, &buffer);
-
-              if (F_status_is_error(status_pipe)) {
-                fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read_to", F_true, "-", "read", fll_error_file_type_pipe);
-
-                status = F_status_set_error(F_pipe);
-                break;
-              }
+          f_array_length_t i = 0;
+          f_array_length_t j = 0;
+          f_array_length_t object_current = 0;
+          f_array_length_t object_next = 0;
+          f_array_length_t content_current = 0;
 
-              if (!buffer.used) {
-                if (data->error.verbosity != f_console_verbosity_quiet) {
-                  fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has no data.%c", fll_error_print_error, f_string_eol[0]);
-                }
+          for (; i < data->parameters[fss_extended_write_parameter_object].additional.used; i++) {
 
-                status = F_status_set_error(F_parameter);
-                break;
-              }
+            object_current = data->parameters[fss_extended_write_parameter_object].locations.array[i];
 
-              range.stop = buffer.used - 1;
+            if (i + 1 < data->parameters[fss_extended_write_parameter_object].additional.used) {
+              object_next = data->parameters[fss_extended_write_parameter_object].locations.array[i + 1];
             }
 
-            previous = range.start;
-            status = fl_string_dynamic_seek_line(buffer.string, &range);
+            object.string = arguments.argv[data->parameters[fss_extended_write_parameter_object].additional.array[i]];
+            object.used = strnlen(object.string, f_console_length_size);
+            object.size = object.used;
 
-            if (F_status_is_error(status)) {
-              fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
+            contents.used = 0;
 
-            if (status == F_data_not_stop) {
-              status = F_status_set_error(F_parameter);
+            for (; j < data->parameters[fss_extended_write_parameter_content].additional.used; j++) {
 
-              fll_error_print(data->error, F_parameter, "fl_string_dynamic_seek_line", F_true);
-              break;
-            }
+              content_current = data->parameters[fss_extended_write_parameter_content].locations.array[j];
 
-            if (object_ended && previous == range.start) {
-              if (data->error.verbosity != f_console_verbosity_quiet) {
-                fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has incorrectly placed newlines.%c", fll_error_print_error, f_string_eol[0]);
+              if (i + 1 < data->parameters[fss_extended_write_parameter_object].additional.used) {
+                if (content_current < object_current || content_current > object_next) break;
               }
 
-              status = F_status_set_error(F_parameter);
-              break;
-            }
+              status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
 
-            range.stop = range.start - 1;
-            range.start = previous;
-
-            if (object_ended) {
-              content.used = 0;
-
-              if (buffer.used) {
-                status = fl_string_dynamic_partial_append_nulless(buffer, range, &content);
-
-                if (F_status_is_error(status)) {
-                  fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
-                  break;
-                }
+              if (F_status_is_error(status)) {
+                fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+                break;
               }
 
-              status = fss_extended_write_process(*data, output, object, content, quote, &buffer);
-              if (F_status_is_error(status)) break;
-
-              object_ended = F_false;
-            }
-            else {
-              object.used = 0;
+              if (contents.array[contents.used].used) {
+                contents.array[contents.used].used = 0;
+              }
 
-              status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
+              status = fl_string_append(arguments.argv[data->parameters[fss_extended_write_parameter_content].additional.array[j]], strnlen(arguments.argv[data->parameters[fss_extended_write_parameter_content].additional.array[j]], f_console_length_size), &contents.array[contents.used]);
 
               if (F_status_is_error(status)) {
-                fll_error_print(data->error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+                fll_error_print(data->error, F_status_set_fine(status), "fl_string_append", F_true);
                 break;
               }
 
-              object_ended = F_true;
-            }
-
-            // restore the range, positioned after the newline.
-            range.start = range.stop + 2;
-            range.stop = buffer.used - 1;
-
-            // only clear the buffer and reset the start when the entire buffer has been processed.
-            if (range.start > range.stop) {
-              range.start = 0;
-              buffer.used = 0;
-            }
-
-            if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
-          } // for
-
-          if (F_status_is_error_not(status) && object_ended) {
-            if (data->error.verbosity != f_console_verbosity_quiet) {
-              fl_color_print(data->error.to.stream, data->context.set.error, "%sThe pipe has an object without content.%c", fll_error_print_error, f_string_eol[0]);
-            }
-
-            status = F_status_set_error(F_parameter);
-          }
-        }
-      }
-
-      if (F_status_is_error_not(status)) {
-        if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) {
-          if (data->parameters[fss_extended_write_parameter_object].result == f_console_result_found) {
-            content.used = 0;
-
-            for (f_array_length_t i = 0; i < data->parameters[fss_extended_write_parameter_object].additional.used; i++) {
-
-              object.string = arguments.argv[data->parameters[fss_extended_write_parameter_object].additional.array[i]];
-              object.used = strnlen(object.string, f_console_length_size);
-              object.size = object.used;
-
-              status = fss_extended_write_process(*data, output, object, content, quote, &buffer);
-              if (F_status_is_error(status)) break;
+              contents.used++;
             } // for
-          }
-          else {
-            object.used = 0;
 
-            for (f_array_length_t i = 0; i < data->parameters[fss_extended_write_parameter_object].additional.used; i++) {
-
-              content.string = arguments.argv[data->parameters[fss_extended_write_parameter_content].additional.array[i]];
-              content.used = strnlen(content.string, f_console_length_size);
-              content.size = content.used;
-
-              status = fss_extended_write_process(*data, output, object, content, quote, &buffer);
-              if (F_status_is_error(status)) break;
-            } // for
-          }
-        }
-        else {
-          for (f_array_length_t i = 0; i < data->parameters[fss_extended_write_parameter_object].additional.used; i++) {
-
-            object.string = arguments.argv[data->parameters[fss_extended_write_parameter_object].additional.array[i]];
-            object.used = strnlen(object.string, f_console_length_size);
-            object.size = object.used;
-
-            content.string = arguments.argv[data->parameters[fss_extended_write_parameter_content].additional.array[i]];
-            content.used = strnlen(content.string, f_console_length_size);
-            content.size = content.used;
+            if (F_status_is_error(status)) break;
 
-            status = fss_extended_write_process(*data, output, object, content, quote, &buffer);
+            status = fss_extended_write_process(*data, output, quote, &object, &contents, &buffer);
             if (F_status_is_error(status)) break;
           } // for
         }
 
-        // ensure there is always a newline at the end, unless in quiet mode.
-        if (F_status_is_error_not(status) && data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_extended_write_parameter_file].result == f_console_result_none) {
+        if (F_status_is_error(status)) {
+          fl_color_print(data->error.to.stream, data->context.set.error, "%sWhile processing the ", fll_error_print_error);
+          fl_color_print(data->error.to.stream, data->context.set.notable, "input arguments");
+          fl_color_print(data->error.to.stream, data->context.set.error, ".%c", f_string_eol[0]);
+        }
+        else if (data->error.verbosity != f_console_verbosity_quiet && data->parameters[fss_extended_write_parameter_file].result == f_console_result_none) {
+          // ensure there is always a newline at the end, unless in quiet mode.
           fprintf(f_type_output, "%c", f_string_eol[0]);
         }
       }
 
       f_macro_string_dynamic_t_delete_simple(escaped);
 
-      // object and content, though being a "dynamic" type, is being used statically, so clear them up to avoid invalid free().
+      // object, though being a "dynamic" type, is being used statically, so clear them up to avoid invalid free().
       object.string = 0;
       object.used = 0;
       object.size = 0;
 
-      content.string = 0;
-      content.used = 0;
-      content.size = 0;
+      // reset contents used, it is dynamically allocated so leave everything else alone.
+      contents.used = 0;
     }
 
     if (data->parameters[fss_extended_write_parameter_file].result == f_console_result_additional) {
@@ -493,7 +404,7 @@ extern "C" {
 
     f_macro_string_dynamic_t_delete_simple(buffer);
     f_macro_string_dynamic_t_delete_simple(object);
-    f_macro_string_dynamic_t_delete_simple(content);
+    f_macro_string_dynamics_t_delete_simple(contents);
     fss_extended_write_delete_data(data);
     return status;
   }
@@ -501,14 +412,15 @@ extern "C" {
 
 #ifndef _di_fss_extended_write_delete_data_
   f_return_status fss_extended_write_delete_data(fss_extended_write_data_t *data) {
-    f_status_t status = F_none;
 
     for (f_string_length_t i = 0; i < fss_extended_write_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
     } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index f3e4033dbf48acfe3a52bae68b6fc1edae3e9cb0..56925a459c236fb02d0288e04e6f25e23199c9d6 100644 (file)
@@ -54,6 +54,9 @@ extern "C" {
 #endif // _di_fss_extended_write_name_
 
 #ifndef _di_fss_extended_write_defines_
+  #define fss_extended_write_pipe_content_start '\0'
+  #define fss_extended_write_pipe_content_end   '\f'
+
   #define fss_extended_write_short_file     "f"
   #define fss_extended_write_short_content  "c"
   #define fss_extended_write_short_double   "d"
index 1a8cac7b7840166366c0dc125b879872a8826ae4..d03d49c3bcd155d7ce2f330eaaad8ee160b7c081 100644 (file)
@@ -5,22 +5,22 @@
 extern "C" {
 #endif
 
-#ifndef _di_fss_extended_write_error_parameter_same_times_print_
-  void fss_extended_write_error_parameter_same_times_print(const fss_extended_write_data_t data) {
+#ifndef _di_fss_extended_write_error_parameter_at_least_once_print_
+  void fss_extended_write_error_parameter_at_least_once(const fss_extended_write_data_t data) {
 
     if (data.error.verbosity == f_console_verbosity_quiet) {
       return;
     }
 
-    fl_color_print(data.error.to.stream, data.context.set.error, "%sMust specify both the '", fll_error_print_error);
+    fl_color_print(data.error.to.stream, data.context.set.error, "%sMust specify the '", fll_error_print_error);
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_object);
-    fl_color_print(data.error.to.stream, data.context.set.error, "' parameter and the '");
+    fl_color_print(data.error.to.stream, data.context.set.error, "' parameter at least once and the '");
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_content);
-    fl_color_print(data.error.to.stream, data.context.set.error, "' parameter the same number of times when not specifying the ");
+    fl_color_print(data.error.to.stream, data.context.set.error, "' parameter one or more times when not specifying the ");
     fl_color_print(data.error.to.stream, data.context.set.notable, "%s%s", f_console_symbol_long_enable, fss_extended_write_long_partial);
     fl_color_print(data.error.to.stream, data.context.set.error, "' parameter.%c", f_string_eol[0]);
   }
-#endif // _di_fss_extended_write_error_parameter_same_times_print_
+#endif // _di_fss_extended_write_error_parameter_at_least_once_print_
 
 #ifndef _di_fss_extended_write_error_parameter_value_missing_print_
   void fss_extended_write_error_parameter_value_missing_print(const fss_extended_write_data_t data, const f_string_t symbol, const f_string_t parameter) {
@@ -36,22 +36,213 @@ extern "C" {
 #endif // _di_fss_extended_write_error_parameter_value_missing_print_
 
 #ifndef _di_fss_extended_write_process_
-  f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quote, f_string_dynamic_t *buffer) {
-    buffer->used = 0;
+  f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_statics_t *contents, f_string_dynamic_t *buffer) {
+    f_status_t status = F_none;
+
+    f_string_range_t range = f_string_range_t_initialize;
 
-    f_status_t status = fll_fss_extended_write(object, contents, quote, buffer);
+    if (object) {
+      if (object->used) {
+        range.start = 0;
+        range.stop = object->used - 1;
+      }
+      else {
+        range.start = 1;
+        range.stop = 0;
+      }
 
-    if (F_status_is_error(status)) {
-      fll_error_print(data.error, F_status_set_fine(status), "fll_fss_extended_write", F_true);
-      return F_status_set_error(status);
+      status = fl_fss_extended_object_write(*object, quote, contents ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
+
+      if (status == F_data_not_stop || status == F_data_not_eos) {
+        fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard requires an object.%c", fll_error_print_error, f_string_eol[0]);
+        return F_status_set_error(status);
+      }
+      else if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_object_write", F_true);
+        return F_status_set_error(status);
+      }
+    }
+
+    if (contents) {
+      for (f_array_length_t i = 0; i < contents->used; i++) {
+
+        if (contents->used) {
+          range.start = 0;
+          range.stop = contents->array[i].used - 1;
+        }
+        else {
+          range.start = 1;
+          range.stop = 0;
+        }
+
+        status = fl_fss_extended_content_write(contents->array[i], quote, i + 1 < contents->used ? f_fss_complete_next : f_fss_complete_end, &range, buffer);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_content_write", F_true);
+          return F_status_set_error(status);
+        }
+      } // for
     }
 
     f_print_dynamic(output.stream, *buffer);
 
+    buffer->used = 0;
     return status;
   }
 #endif // _di_fss_extended_write_process_
 
+#ifndef _di_fss_extended_write_process_pipe_
+  f_return_status fss_extended_write_process_pipe(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) {
+    f_status_t status = F_none;
+    f_status_t status_pipe = F_none;
+
+    f_file_t input = f_file_t_initialize;
+
+    input.id = f_type_descriptor_input;
+    input.size_read = 2048;
+
+    f_string_length_t total = 0;
+    f_string_length_t previous = 0;
+    f_string_range_t range = f_string_range_t_initialize;
+
+    f_string_dynamic_t block = f_string_dynamic_t_initialize;
+    f_string_dynamic_t object = f_string_dynamic_t_initialize;
+    f_string_dynamics_t contents = f_string_dynamics_t_initialize;
+
+    // 0x0 = start new object/content set, 0x1 = processing object, 0x2 = processing content, 0x3 = end object/content set.
+    uint8_t state = 0;
+
+    for (;;) {
+
+      if (range.start > range.stop) {
+        if (status_pipe == F_none_eof) break;
+
+        block.used = 0;
+
+        status_pipe = f_file_read_block(input, &block);
+
+        if (F_status_is_error(status_pipe)) {
+          fll_error_print(data.error, F_status_set_fine(status_pipe), "f_file_read_block", F_true);
+
+          status_pipe = F_status_set_error(F_pipe);
+          break;
+        }
+
+        range.start = 0;
+        range.stop = block.used - 1;
+      }
+
+      if (!state || state == 0x1) {
+        if (!state) {
+          object.used = 0;
+          contents.used = 0;
+
+          state = 0x1;
+        }
+
+        if (object.used + block.used > object.size) {
+          status = fl_string_dynamic_size_increase(block.used, &object);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+            break;
+          }
+        }
+
+        for (; range.start <= range.stop; range.start++) {
+
+          if (block.string[range.start] == fss_extended_write_pipe_content_start) {
+            state = 0x2;
+            range.start++;
+            break;
+          }
+
+          object.string[object.used++] = block.string[range.start];
+        } // for
+
+        if (F_status_is_error(status)) break;
+
+        // if the start of content was not found, then fetch the next block.
+        if (state != 0x2) continue;
+
+        // if the end of the current block is reached, fetch the next block.
+        if (range.start > range.stop) continue;
+      }
+
+      if (state == 0x2) {
+        if (block.used && range.start <= range.stop) {
+          total = (range.stop - range.start) + 1;
+        }
+        else {
+          total = 0;
+        }
+
+        if (total) {
+          for (; range.start <= range.stop; range.start++) {
+
+            if (block.string[range.start] == fss_extended_write_pipe_content_start) {
+              contents.used++;
+
+              if (contents.used < contents.size && contents.array[contents.used].used) {
+                contents.array[contents.used].used = 0;
+              }
+
+              continue;
+            }
+            else if (block.string[range.start] == fss_extended_write_pipe_content_end) {
+              state = 0x3;
+              range.start++;
+              break;
+            }
+
+            if (contents.used + 1 > contents.size) {
+              status = fl_string_dynamics_size_increase(f_fss_default_allocation_step, &contents);
+
+              if (F_status_is_error(status)) {
+                fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_size_increase", F_true);
+                break;
+              }
+            }
+
+            if (contents.array[contents.used].used + 1 > contents.array[contents.used].size) {
+              status = fl_string_dynamic_size_increase(f_fss_default_allocation_step, &contents.array[contents.used]);
+
+              if (F_status_is_error(status)) {
+                fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_size_increase", F_true);
+                break;
+              }
+            }
+
+            contents.array[contents.used].string[contents.array[contents.used].used++] = block.string[range.start];
+          } // for
+
+          if (F_status_is_error(status)) break;
+        }
+        else {
+          state = 0x3;
+        }
+      }
+
+      if (state == 0x3) {
+        status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
+        if (F_status_is_error(status)) break;
+
+        state = 0;
+      }
+    } // for
+
+    // if the pipe ended before finishing, then attempt to wrap up.
+    if (status_pipe == F_none_eof && state) {
+      status = fss_extended_write_process(data, output, quote, &object, &contents, buffer);
+    }
+
+    f_macro_string_dynamic_t_delete_simple(block);
+    f_macro_string_dynamic_t_delete_simple(object);
+    f_macro_string_dynamics_t_delete_simple(contents);
+    return status;
+  }
+#endif // _di_fss_extended_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index c81e9b3dff4f7f99fe661c5d66e1ca9deeeab03a..d884210260a3525a8991c1df0dc9b75ad5684596 100644 (file)
@@ -13,7 +13,7 @@ extern "C" {
 #endif
 
 /**
- * Print an message about the object and content parameters not being specified the same number of times.
+ * Print an message about the object and content parameters not being specified the correct number of times.
  *
  * @param data
  *   The program data.
@@ -22,9 +22,9 @@ extern "C" {
  *   F_none on success.
  *   F_failure (with error bit) for any othe failure.
  */
-#ifndef _di_fss_extended_write_error_parameter_same_times_print_
-  void fss_extended_write_error_parameter_same_times_print(const fss_extended_write_data_t data) f_gcc_attribute_visibility_internal;
-#endif // _di_fss_extended_write_error_parameter_same_times_print_
+#ifndef _di_fss_extended_write_error_parameter_at_least_once_print_
+  void fss_extended_write_error_parameter_at_least_once(const fss_extended_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_write_error_parameter_at_least_once_print_
 
 /**
  * Print an message about a parameter missing a value.
@@ -51,13 +51,15 @@ extern "C" {
  *   The program data.
  * @param output
  *   The file to output to.
- * @param object
- *   The object to validate and print.
- * @param contents
- *   An array of content to escape and print.
  * @param quote
  *   The quote character to use.
  *   This is either single our double quote.
+ * @param object
+ *   A pointer to the object to validate and print.
+ *   Set to 0 to disable.
+ * @param content
+ *   A pointer to the  content to escape and print.
+ *   Set to 0 to disable.
  * @param buffer
  *   The buffer array used as a cache to construct the output before printing.
  *
@@ -66,9 +68,30 @@ extern "C" {
  *   F_failure (with error bit) for any othe failure.
  */
 #ifndef _di_fss_extended_write_process_
-  extern f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_string_static_t object, const f_string_statics_t contents, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+  extern f_return_status fss_extended_write_process(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, const f_string_static_t *object, const f_string_statics_t *contents, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
 #endif // _di_fss_extended_write_process_
 
+/**
+ * Process the pipe, reading from the pipe and writing to the output.
+ *
+ * @param data
+ *   The program data.
+ * @param output
+ *   The file to output to.
+ * @param quote
+ *   The quote character to use.
+ *   This is either single our double quote.
+ * @param buffer
+ *   The buffer array used as a cache to construct the output before printing.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_extended_write_process_pipe_
+  extern f_return_status fss_extended_write_process_pipe(const fss_extended_write_data_t data, const f_file_t output, const f_fss_quote_t quote, f_string_dynamic_t *buffer) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_extended_write_process_pipe_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 9675b3c19f6e3f40609c88f408b7634b0106b704..ba42cfdd277c30ac197b7dc19d5993ac3c3e55d3 100644 (file)
@@ -196,15 +196,15 @@ extern "C" {
 
 #ifndef _di_fss_status_code_delete_data_
   f_return_status fss_status_code_delete_data(fss_status_code_data_t *data) {
-    f_string_length_t i = 0;
 
-    while (i < fss_status_code_total_parameters) {
+    for (f_string_length_t i = 0; i < fss_status_code_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 15747a7778f17dd856831adae418ed6fa33ef9fc..d495a95d11b42c5ab81de398d63e045473f1dd66 100644 (file)
@@ -459,17 +459,16 @@ extern "C" {
 
 #ifndef _di_iki_read_delete_data_
   f_return_status iki_read_delete_data(iki_read_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < iki_read_total_parameters) {
+    for (f_string_length_t i = 0; i < iki_read_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
     f_macro_string_dynamic_t_delete_simple(data->buffer);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 08969514688ec3611ef12660e5cd60031d378e75..9fd68b8cc7fffa2a1664027943f2d6d857dc7a5f 100644 (file)
@@ -405,17 +405,16 @@ extern "C" {
 
 #ifndef _di_iki_write_delete_data_
   f_return_status iki_write_delete_data(iki_write_data_t *data) {
-    f_status_t status = F_none;
-    f_string_length_t i = 0;
 
-    while (i < iki_write_total_parameters) {
+    for (f_string_length_t i = 0; i < iki_write_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
     f_macro_string_dynamic_t_delete_simple(data->buffer);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;
index 15006f9fc0297996e1ebb9219e5ffd32ef099daf..38df4928c9daed6ee33e0a343c6a35dc21c62c51 100644 (file)
@@ -197,16 +197,15 @@ extern "C" {
 
 #ifndef _di_status_code_delete_data_
   f_return_status status_code_delete_data(status_code_data_t *data) {
-    f_string_length_t i = 0;
-
-    while (i < status_code_total_parameters) {
 
+    for (f_string_length_t i = 0; i < status_code_total_parameters; i++) {
       f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+      f_macro_string_lengths_t_delete_simple(data->parameters[i].locations_sub);
       f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
-      i++;
-    } // while
+    } // for
 
     f_macro_string_lengths_t_delete_simple(data->remaining);
+
     f_macro_color_context_t_delete_simple(data->context);
 
     return F_none;