]> Kevux Git Server - fll/commitdiff
Update: numerous fixes and additions, mostly string related
authorKevin Day <thekevinday@gmail.com>
Fri, 8 May 2020 02:47:18 +0000 (21:47 -0500)
committerKevin Day <thekevinday@gmail.com>
Fri, 8 May 2020 04:38:03 +0000 (23:38 -0500)
Not sure how I let this one get through, but add missing return statement in a couple of private string functions where it is missing.

In retrospect, it seems that I was overzealous with some of the parameter checks.
Redo the parameter checks to not be as sting on string length and buffer size ranges.
Instead, just return that there is nothing to do instead of erroring out.

Add string terminate functions.
These functions are designed to guarantee that an end of string exists at the end of some dynamic string.

Add functions for appending one or more arguments to the arguments array for the execute functions.
This functionality is common enough (used extensively by firewall and soon to be used by fake).
Support providing an array of arguments to append.
This greatly simplifies long-winded code.

Minor fixes and cleanups in the execute functions:
- Add missing parameter checks.
- Rename results to result to be more accurate.

Add length defines for console symbols.

18 files changed:
build/level_2/settings
build/monolithic/settings
level_0/f_console/c/console.h
level_0/f_type/c/type.h
level_1/fl_file/c/file.h
level_1/fl_string/c/private-string.c
level_1/fl_string/c/string.c
level_1/fl_string/c/string.h
level_1/fl_utf/c/private-utf.c
level_1/fl_utf/c/utf.c
level_1/fl_utf/c/utf.h
level_1/fl_utf_file/c/utf_file.h
level_2/fll_execute/c/execute.c
level_2/fll_execute/c/execute.h
level_2/fll_execute/c/private-execute.c [new file with mode: 0644]
level_2/fll_execute/c/private-execute.h [new file with mode: 0644]
level_2/fll_execute/data/build/dependencies
level_2/fll_execute/data/build/settings

index 231da0986c62b2d0fc183710e55ee20ec2bd9f60..bc0aa1ba684e8b6061f95dc1b2cb60b6c582966e 100644 (file)
@@ -12,7 +12,7 @@ build_linker ar
 build_libraries -lc
 build_libraries_fll -lfll_0 -lfll_1
 build_libraries_fll-level -lfll_0 -lfll_1
-build_sources_library execute.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c program.c status.c
+build_sources_library execute.c private-execute.c file.c fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c program.c status.c
 build_sources_program 
 build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h program.h status.h
 build_shared yes
index 14bc65b43128a0e8d293e15d44124574901f5872..e79f99f18062904ba21d7ef802d613a85fd7e048 100644 (file)
@@ -11,7 +11,7 @@ build_compiler gcc
 build_linker ar
 build_libraries -lc
 build_libraries_fll
-build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/print.c level_1/serialized.c level_1/private-serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_2/execute.c level_2/file.c level_2/fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
+build_sources_library level_0/console.c level_0/conversion.c level_0/file.c level_0/memory.c level_0/pipe.c level_0/print.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/directory.c level_1/file.c level_1/fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/print.c level_1/serialized.c level_1/private-serialized.c level_1/socket.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/program.c level_2/status.c
 build_sources_program
 build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/file.h level_0/fss.h level_0/memory.h level_0/path_fll.h level_0/path_filesystem.h level_0/pipe.h level_0/print.h level_0/serialized.h level_0/socket.h level_0/status.h level_0/string.h level_0/type.h level_0/type_array.h level_0/utf.h level_1/color.h level_1/console.h level_1/directory.h level_1/file.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_status.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/print.h level_1/serialized.h level_1/socket.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/program.h level_2/status.h
 build_sources_bash
index 3ca9b6e4eaa147e01307ee7143c9d93b83a48e53..7f60c71685c873d37738ec6ab1302fc8de2cee97 100644 (file)
@@ -56,8 +56,14 @@ extern "C" {
   #define f_console_symbol_short_enable  "-"
   #define f_console_symbol_short_disable "+"
 
+  #define f_console_symbol_short_enable_length  1
+  #define f_console_symbol_short_disable_length 1
+
   #define f_console_symbol_long_enable  "--"
   #define f_console_symbol_long_disable "++"
+
+  #define f_console_symbol_long_enable_length  2
+  #define f_console_symbol_long_disable_length 2
 #endif // _di_f_console_symbols_
 
 /**
index 6a253ea9001f9542266af99a70da057687b897bb..e70e8407d160e12698607629e81ad265dc1ca601 100644 (file)
@@ -189,7 +189,8 @@ extern "C" {
 #ifndef _di_f_array_
   typedef f_number_unsigned f_array_length;
 
-  #define f_array_max_size f_type_number_size_unsigned
+  #define f_array_length_size     f_type_number_size_unsigned
+  #define f_array_length_size_max f_type_number_size_max_unsigned
 #endif // _di_f_array_
 
 /**
index 65aded3ffbff3fdd233da6392fd947dea7fcdb52..e3a6bf1a4c5a3a1fe52c833bd5c0ee665e7158a0 100644 (file)
@@ -35,7 +35,7 @@ extern "C" {
  *   f_file_error_read (with error bit) if file read failed.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_reallocation (with error bit) on memory reallocation error.
- *   f_string_too_large (with error bit) if string is too large to fit into buffer.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
  */
 #ifndef _di_fl_file_read_
   extern f_return_status fl_file_read(f_file *file, f_string_dynamic *buffer);
@@ -59,7 +59,7 @@ extern "C" {
  *   f_file_error_read (with error bit) if file read failed.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_reallocation (with error bit) on memory reallocation error.
- *   f_string_too_large (with error bit) if string is too large to fit into buffer.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
  */
 #ifndef _di_fl_file_read_position_
   extern f_return_status fl_file_read_position(f_file *file, f_string_dynamic *buffer, const f_file_position position);
index 3643126a90122f679ac338c3e9c566874c64839b..11e053b4a47bdc0665bf378782de714fd9ca4e21 100644 (file)
@@ -117,6 +117,8 @@ extern "C" {
     for (; i2 < stop2; i2++) {
       if (string2[i2] != f_string_eos) return f_not_equal_to;
     } // for
+
+    return f_equal_to;
   }
 #endif // !defined(_di_fl_string_compare_) || !defined(_di_fl_string_dynamic_compare_) || !defined(_di_fl_string_dynamic_partial_compare_)
 
index 41bb209e060e7881c773efd176d87a72e1a98923..84dd1ac348cf2d7285729b2db2e7ce92abc4de4a 100644 (file)
@@ -8,10 +8,11 @@ extern "C" {
 #ifndef _di_fl_string_append_
   f_return_status fl_string_append(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_string_append(source, start, stop, destination);
   }
 #endif // _di_fl_string_append_
@@ -19,54 +20,35 @@ extern "C" {
 #ifndef _di_fl_string_append_nulless_
   f_return_status fl_string_append_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_string_append_nulless(source, start, stop, destination);
   }
 #endif // _di_fl_string_append_nulless_
 
 #ifndef _di_fl_string_compare_
   f_return_status fl_string_compare(const f_string string1, const f_string string2, const f_string_length length1, const f_string_length length2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (length1 <= 0) return f_status_set_error(f_invalid_parameter);
-      if (length2 <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_string_compare(string1, string2, 0, 0, length1, length2);
   }
 #endif // _di_fl_string_compare_
 
 #ifndef _di_fl_string_compare_trim_
   f_return_status fl_string_compare_trim(const f_string string1, const f_string string2, const f_string_length length1, const f_string_length length2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (length1 <= 0) return f_status_set_error(f_invalid_parameter);
-      if (length2 <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_string_compare_trim(string1, string2, 0, 0, length1, length2);
   }
 #endif // _di_fl_string_compare_trim_
 
 #ifndef _di_fl_string_dynamic_compare_
   f_return_status fl_string_dynamic_compare(const f_string_dynamic string1, const f_string_dynamic string2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_string_compare(string1.string, string2.string, 0, 0, string1.used, string2.used);
   }
 #endif // _di_fl_string_dynamic_compare_
 
 #ifndef _di_fl_string_dynamic_compare_trim_
   f_return_status fl_string_dynamic_compare_trim(const f_string_dynamic string1, const f_string_dynamic string2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_string_compare_trim(string1.string, string2.string, 0, 0, string1.used, string2.used);
   }
 #endif // _di_fl_string_dynamic_compare_trim_
@@ -74,10 +56,11 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_append_
   f_return_status fl_string_dynamic_append(const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_string_append(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_string_dynamic_append_
@@ -85,10 +68,11 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_append_nulless_
   f_return_status fl_string_dynamic_append_nulless(const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_string_append_nulless(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_string_dynamic_append_nulless_
@@ -96,17 +80,15 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_mash_
   f_return_status fl_string_dynamic_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append(source.string, 0, source.used - 1, destination);
@@ -116,17 +98,15 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_mash_nulless_
   f_return_status fl_string_dynamic_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append_nulless(source.string, 0, source.used - 1, destination);
@@ -136,17 +116,15 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_mish_
   f_return_status fl_string_dynamic_mish(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend(source.string, 0, source.used - 1, destination);
@@ -156,17 +134,15 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_mish_nulless_
   f_return_status fl_string_dynamic_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend_nulless(source.string, 0, source.used - 1, destination);
@@ -176,12 +152,13 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_append_
   f_return_status fl_string_dynamic_partial_append(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_append(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_partial_append_
@@ -189,12 +166,13 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_append_nulless_
   f_return_status fl_string_dynamic_partial_append_nulless(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_append_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_append_nulless_
@@ -202,12 +180,6 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_compare_
   f_return_status fl_string_dynamic_partial_compare(const f_string_dynamic string1, const f_string_dynamic string2, const f_string_location range1, const f_string_location range2) {
     #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-
-      if (range1.start > range1.stop) return f_status_set_error(f_invalid_parameter);
-      if (range2.start > range2.stop) return f_status_set_error(f_invalid_parameter);
-
       if (string1.used <= range1.stop) return f_status_set_error(f_invalid_parameter);
       if (string2.used <= range2.stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -219,12 +191,6 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_compare_trim_
   f_return_status fl_string_dynamic_partial_compare_trim(const f_string_dynamic string1, const f_string_dynamic string2, const f_string_location range1, const f_string_location range2) {
     #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-
-      if (range1.start > range1.stop) return f_status_set_error(f_invalid_parameter);
-      if (range2.start > range2.stop) return f_status_set_error(f_invalid_parameter);
-
       if (string1.used <= range1.stop) return f_status_set_error(f_invalid_parameter);
       if (string2.used <= range2.stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -236,19 +202,17 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_mash_
   f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append(source.string, range.start, range.stop, destination);
@@ -258,19 +222,17 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_mash_nulless_
   f_return_status fl_string_dynamic_partial_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append_nulless(source.string, range.start, range.stop, destination);
@@ -280,19 +242,17 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_mish_
   f_return_status fl_string_partial_dynamic_mish(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend(source.string, range.start, range.stop, destination);
@@ -302,19 +262,17 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_mish_nulless_
   f_return_status fl_string_dynamic_partial_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend_nulless(source.string, range.start, range.stop, destination);
@@ -324,12 +282,13 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_prepend_
   f_return_status fl_string_dynamic_partial_prepend(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_prepend(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_partial_prepend_
@@ -337,12 +296,13 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_partial_prepend_nulless_
   f_return_status fl_string_dynamic_partial_prepend_nulless(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_prepend_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_partial_prepend_nulless
@@ -350,10 +310,11 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_prepend_
   f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_string_prepend(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_string_dynamic_prepend_
@@ -361,10 +322,11 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_prepend_nulless_
   f_return_status fl_string_dynamic_prepend_nulless(const f_string_dynamic source, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_string_prepend_nulless(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_string_dynamic_prepend_nulless_
@@ -372,13 +334,14 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_rip_
   f_return_status fl_string_dynamic_rip(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.stop < range.start) return f_status_set_error(f_invalid_parameter);
-      if (source.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.start) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_append(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_rip_
@@ -386,13 +349,14 @@ extern "C" {
 #ifndef _di_fl_string_dynamic_rip_nulless_
   f_return_status fl_string_dynamic_rip_nulless(const f_string_dynamic source, const f_string_location range, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.stop < range.start) return f_status_set_error(f_invalid_parameter);
-      if (source.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.start) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_string_append_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_string_dynamic_rip_nulless_
@@ -401,13 +365,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_line_to(const f_string_dynamic buffer, f_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     while (buffer.string[location->start] != seek_to_this) {
       if (buffer.string[location->start] == f_string_eol) return f_none_on_eol;
 
@@ -425,13 +389,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_line_to_utf_character(const f_string_dynamic buffer, f_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     const unsigned short seek_width = f_macro_utf_character_width(seek_to_this);
 
     f_status status = f_none;
@@ -470,13 +434,8 @@ extern "C" {
           f_utf_character character = 0;
           status = f_utf_char_to_character(buffer.string + location->start, width_max, &character);
 
-          if (f_status_is_error(status)) {
-            return status;
-          }
-
-          if (character == seek_to_this) {
-            return f_none;
-          }
+          if (f_status_is_error(status)) return status;
+          if (character == seek_to_this) return f_none;
         }
       }
 
@@ -493,13 +452,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_line_until_graph(const f_string_dynamic buffer, f_string_location *location, const int8_t placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
     unsigned short width = 0;
 
@@ -510,10 +469,7 @@ extern "C" {
     }
 
     while (buffer.string[location->start] == placeholder || (status = f_utf_is_graph(buffer.string + location->start, width_max)) == f_false) {
-      if (f_status_is_error(status)) {
-        return status;
-      }
-
+      if (f_status_is_error(status)) return status;
       if (buffer.string[location->start] == f_string_eol) return f_none_on_eol;
 
       width = f_macro_utf_byte_width_is(buffer.string[location->start]);
@@ -542,9 +498,7 @@ extern "C" {
       }
     } // while
 
-    if (f_status_is_error(status)) {
-      return status;
-    }
+    if (f_status_is_error(status)) return status;
 
     return f_none;
   }
@@ -554,13 +508,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_line_until_non_graph(const f_string_dynamic buffer, f_string_location *location, const int8_t placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
     unsigned short width = 0;
 
@@ -571,10 +525,7 @@ extern "C" {
     }
 
     while (buffer.string[location->start] == placeholder || (status = f_utf_is_whitespace(buffer.string + location->start, width_max)) == f_false) {
-      if (f_status_is_error(status)) {
-        return status;
-      }
-
+      if (f_status_is_error(status)) return status;
       if (buffer.string[location->start] == f_string_eol) return f_none_on_eol;
 
       width = f_macro_utf_byte_width_is(buffer.string[location->start]);
@@ -603,9 +554,7 @@ extern "C" {
       }
     } // while
 
-    if (f_status_is_error(status)) {
-      return status;
-    }
+    if (f_status_is_error(status)) return status;
 
     return f_none;
   }
@@ -615,13 +564,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_to(const f_string_dynamic buffer, f_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     while (buffer.string[location->start] != seek_to_this) {
       location->start++;
 
@@ -637,13 +586,13 @@ extern "C" {
   f_return_status fl_string_dynamic_seek_to_utf_character(const f_string_dynamic buffer, f_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     const unsigned short seek_width = f_macro_utf_character_width(seek_to_this);
 
     f_status status = f_none;
@@ -680,13 +629,8 @@ extern "C" {
           f_utf_character character = 0;
           status = f_utf_char_to_character(buffer.string + location->start, width_max, &character);
 
-          if (f_status_is_error(status)) {
-            return status;
-          }
-
-          if (character == seek_to_this) {
-            return f_none;
-          }
+          if (f_status_is_error(status)) return status;
+          if (character == seek_to_this) return f_none;
         }
       }
 
@@ -699,20 +643,45 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_seek_to_utf_character_
 
+#ifndef _di_fl_string_dynamic_terminate_
+  f_return_status fl_string_dynamic_terminate(f_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+      if (destination->used > destination->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    if (destination->used > 0 && destination->string[destination->used - 1] == f_string_eos) return f_none;
+
+    if (destination->used + 1 > f_string_max_size) return f_status_set_error(f_string_too_large);
+
+    const f_string_length total = destination->used + 1;
+
+    if (total > destination->size) {
+      f_status status = f_none;
+
+      f_macro_string_dynamic_resize(status, (*destination), total);
+      if (f_status_is_error(status)) return status;
+    }
+
+    destination->string[destination->used] = f_string_eos;
+    destination->used = total;
+
+    return f_none;
+  }
+#endif // _di_fl_string_dynamic_terminate_
+
 #ifndef _di_fl_string_mash_
   f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append(source, start, stop, destination);
@@ -722,17 +691,15 @@ extern "C" {
 #ifndef _di_fl_string_mash_nulless_
   f_return_status fl_string_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_append_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_append_nulless(source, start, stop, destination);
@@ -742,17 +709,15 @@ extern "C" {
 #ifndef _di_fl_string_mish_
   f_return_status fl_string_mish(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend(source, start, stop, destination);
@@ -762,17 +727,15 @@ extern "C" {
 #ifndef _di_fl_string_mish_nulless_
   f_return_status fl_string_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
-      if (f_status_is_error(status)) {
-        return status;
-      }
+      if (f_status_is_error(status)) return status;
     }
 
     return private_fl_string_prepend_nulless(source, start, stop, destination);
@@ -782,10 +745,11 @@ extern "C" {
 #ifndef _di_fl_string_prepend_
   f_return_status fl_string_prepend(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_string_prepend(source, start, stop, destination);
   }
 #endif // _di_fl_string_prepend_
@@ -793,10 +757,11 @@ extern "C" {
 #ifndef _di_fl_string_prepend_nulless_
   f_return_status fl_string_prepend_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_string_prepend_nulless(source, start, stop, destination);
   }
 #endif // _di_fl_string_prepend_nulless_
@@ -804,10 +769,11 @@ extern "C" {
 #ifndef _di_fl_string_rip_
   f_return_status fl_string_rip(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     f_string_length begin = start;
     f_string_length end = stop;
 
@@ -823,10 +789,11 @@ extern "C" {
 #ifndef _di_fl_string_rip_nulless_
   f_return_status fl_string_rip_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     f_string_length begin = start;
     f_string_length end = stop;
 
@@ -843,10 +810,10 @@ extern "C" {
   f_return_status fl_string_seek_line_to(const f_string string, f_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     while (string[location->start] != seek_to_this) {
       if (string[location->start] == f_string_eol) return f_none_on_eol;
 
@@ -863,10 +830,10 @@ extern "C" {
   f_return_status fl_string_seek_line_to_utf_character(const f_string string, f_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     const unsigned short seek_width = f_macro_utf_character_width(seek_to_this);
 
     f_status status = f_none;
@@ -900,13 +867,8 @@ extern "C" {
           f_utf_character character = 0;
           status = f_utf_char_to_character(string + location->start, width_max, &character);
 
-          if (f_status_is_error(status)) {
-            return status;
-          }
-
-          if (character == seek_to_this) {
-            return f_none;
-          }
+          if (f_status_is_error(status)) return status;
+          if (character == seek_to_this) return f_none;
         }
       }
     } // for
@@ -919,20 +881,17 @@ extern "C" {
   f_return_status fl_string_seek_line_until_graph(const f_string string, f_string_location *location, const int8_t placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
     unsigned short width = 0;
 
     f_string_length width_max = (location->stop - location->start) + 1;
 
     while (string[location->start] == placeholder || (status = f_utf_is_graph(string + location->start, width_max)) == f_false) {
-      if (f_status_is_error(status)) {
-        return status;
-      }
-
+      if (f_status_is_error(status)) return status;
       if (string[location->start] == f_string_eol) return f_none_on_eol;
 
       width = f_macro_utf_byte_width_is(string[location->start]);
@@ -955,9 +914,7 @@ extern "C" {
       width_max = (location->stop - location->start) + 1;
     } // while
 
-    if (f_status_is_error(status)) {
-      return status;
-    }
+    if (f_status_is_error(status)) return status;
 
     return f_none;
   }
@@ -967,10 +924,10 @@ extern "C" {
   f_return_status fl_string_seek_line_until_non_graph(const f_string string, f_string_location *location, const int8_t placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
     unsigned short width = 0;
 
@@ -1003,9 +960,7 @@ extern "C" {
       width_max = (location->stop - location->start) + 1;
     } // while
 
-    if (f_status_is_error(status)) {
-      return status;
-    }
+    if (f_status_is_error(status)) return status;
 
     return f_none;
   }
@@ -1015,10 +970,10 @@ extern "C" {
   f_return_status fl_string_seek_to(const f_string string, f_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     while (string[location->start] != seek_to_this) {
       location->start++;
 
@@ -1033,10 +988,10 @@ extern "C" {
   f_return_status fl_string_seek_to_utf_character(const f_string string, f_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     const unsigned short seek_width = f_macro_utf_character_width(seek_to_this);
 
     f_status status = f_none;
@@ -1068,13 +1023,8 @@ extern "C" {
           f_utf_character character = 0;
           status = f_utf_char_to_character(string + location->start, width_max, &character);
 
-          if (f_status_is_error(status)) {
-            return status;
-          }
-
-          if (character == seek_to_this) {
-            return f_none;
-          }
+          if (f_status_is_error(status)) return status;
+          if (character == seek_to_this) return f_none;
         }
       }
     } // for
index d01393bcbc8f63b5d9793c4f47677035009fda43..4f2ad971f881f5d8dc49d80612f32262f46f781c 100644 (file)
@@ -48,6 +48,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -75,6 +76,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -155,6 +157,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -178,6 +181,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -256,6 +260,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -285,6 +290,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -312,6 +318,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -341,6 +348,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -364,6 +372,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -389,6 +398,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -477,6 +487,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -508,6 +519,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -537,6 +549,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -568,6 +581,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -593,6 +607,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -618,6 +633,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -641,6 +657,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -664,6 +681,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -895,6 +913,27 @@ extern "C" {
 #endif // _di_fl_string_dynamic_seek_to_utf_character_
 
 /**
+ * Guarantee that an end of string (NULL) exists at the end of the string.
+ *
+ * This is intended to be used for anything requiring NULL terminated strings.
+ * This will reallocate more space if necessary.
+ *
+ * If destination size is 0, then it will be reallocated and have the NULL assigned at index 0.
+ *
+ * @param destination
+ *   The new string, which will be allocated or reallocated as necessary.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
+ */
+#ifndef _di_fl_string_dynamic_terminate_
+  extern f_return_status fl_string_dynamic_terminate(f_string_dynamic *destination);
+#endif // _di_fl_string_dynamic_terminate_
+
+/**
  * Append the source string onto the destination with the glue in between.
  *
  * If the destination string is empty, then no glue is appended.
@@ -914,6 +953,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -947,6 +987,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -978,6 +1019,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1011,6 +1053,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1038,6 +1081,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1067,6 +1111,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
index d324f88a505bcce3064788b9f5fc11b0b82d09c6..12046f9a9a9c56022297b31824e60688cf2f2aee 100644 (file)
@@ -117,6 +117,8 @@ extern "C" {
     for (; i2 < stop2; i2++) {
       if (string2[i2] != f_string_eos) return f_not_equal_to;
     } // for
+
+    return f_equal_to;
   }
 #endif // !defined(_di_fl_utf_string_compare_) || !defined(_di_fl_utf_string_dynamic_compare_) || !defined(_di_fl_utf_string_dynamic_partial_compare_)
 
index f2ec2f8b67a5d1fdb34d20ab19fd8459ecf23656..470ae072ed68549276f2ffa8fee5f8ab4a87a4ed 100644 (file)
@@ -8,10 +8,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_append_
   f_return_status fl_utf_string_append(const f_utf_string source, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_utf_string_append(source, start, stop, destination);
   }
 #endif // _di_fl_utf_string_append_
@@ -19,10 +20,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_append_nulless_
   f_return_status fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_utf_string_append_nulless(source, start, stop, destination);
   }
 #endif // _di_fl_utf_string_append_nulless_
@@ -30,8 +32,8 @@ extern "C" {
 #ifndef _di_fl_utf_string_compare_
   f_return_status fl_utf_string_compare(const f_utf_string string1, const f_utf_string string2, const f_utf_string_length length1, const f_utf_string_length length2) {
     #ifndef _di_level_1_parameter_checking_
-      if (length1 <= 0) return f_status_set_error(f_invalid_parameter);
-      if (length2 <= 0) return f_status_set_error(f_invalid_parameter);
+      if (length1 == 0) return f_status_set_error(f_invalid_parameter);
+      if (length2 == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
     return private_fl_utf_string_compare(string1, string2, 0, 0, length1, length2);
@@ -41,8 +43,8 @@ extern "C" {
 #ifndef _di_fl_utf_string_compare_trim_
   f_return_status fl_utf_string_compare_trim(const f_utf_string string1, const f_utf_string string2, const f_utf_string_length length1, const f_utf_string_length length2) {
     #ifndef _di_level_1_parameter_checking_
-      if (length1 <= 0) return f_status_set_error(f_invalid_parameter);
-      if (length2 <= 0) return f_status_set_error(f_invalid_parameter);
+      if (length1 == 0) return f_status_set_error(f_invalid_parameter);
+      if (length2 == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
     return private_fl_utf_string_compare_trim(string1, string2, 0, 0, length1, length2);
@@ -52,10 +54,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_append_
   f_return_status fl_utf_string_dynamic_append(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_utf_string_append(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_utf_string_dynamic_append_
@@ -63,10 +66,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_append_nulless_
   f_return_status fl_utf_string_dynamic_append_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_utf_string_append_nulless(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_utf_string_dynamic_append_nulless_
@@ -74,12 +78,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_mash_
   f_return_status fl_utf_string_dynamic_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -94,12 +98,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_mash_nulless_
   f_return_status fl_utf_string_dynamic_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -114,12 +118,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_mish_
   f_return_status fl_utf_string_dynamic_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -134,12 +138,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_mish_nulless_
   f_return_status fl_utf_string_dynamic_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -153,22 +157,12 @@ extern "C" {
 
 #ifndef _di_fl_utf_string_dynamic_compare_
   f_return_status fl_utf_string_dynamic_compare(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_utf_string_compare(string1.string, string2.string, 0, 0, string1.used, string2.used);
   }
 #endif // _di_fl_utf_string_dynamic_compare_
 
 #ifndef _di_f_utf_string_dynamic_compare_trim_
   f_return_status f_utf_string_dynamic_compare_trim(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2) {
-    #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-    #endif // _di_level_1_parameter_checking_
-
     return private_fl_utf_string_compare_trim(string1.string, string2.string, 0, 0, string1.used, string2.used);
   }
 #endif // _di_f_utf_string_dynamic_compare_trim_
@@ -176,12 +170,13 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_append_
   f_return_status fl_utf_string_dynamic_partial_append(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_append(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_partial_append_
@@ -189,12 +184,13 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_append_nulless_
   f_return_status fl_utf_string_dynamic_partial_append_nulless(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_append_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_partial_append_nulless_
@@ -202,12 +198,6 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_compare_
   f_return_status fl_utf_string_dynamic_partial_compare(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2, const f_utf_string_location range1, const f_utf_string_location range2) {
     #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-
-      if (range1.start > range1.stop) return f_status_set_error(f_invalid_parameter);
-      if (range2.start > range2.stop) return f_status_set_error(f_invalid_parameter);
-
       if (string1.used <= range1.stop) return f_status_set_error(f_invalid_parameter);
       if (string2.used <= range2.stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -219,12 +209,6 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_compare_trim_
   f_return_status fl_utf_string_dynamic_partial_comparetrim(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2, const f_utf_string_location range1, const f_utf_string_location range2) {
     #ifndef _di_level_1_parameter_checking_
-      if (string1.used <= 0) return f_status_set_error(f_invalid_parameter);
-      if (string2.used <= 0) return f_status_set_error(f_invalid_parameter);
-
-      if (range1.start > range1.stop) return f_status_set_error(f_invalid_parameter);
-      if (range2.start > range2.stop) return f_status_set_error(f_invalid_parameter);
-
       if (string1.used <= range1.stop) return f_status_set_error(f_invalid_parameter);
       if (string2.used <= range2.stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
@@ -236,14 +220,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_mash_
   f_return_status fl_utf_string_dynamic_partial_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -258,14 +242,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_mash_nulless_
   f_return_status fl_utf_string_dynamic_partial_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -280,14 +264,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_mish_
   f_return_status fl_utf_string_dynamic_partial_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -302,14 +286,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_mish_nulless_
   f_return_status fl_utf_string_dynamic_partial_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -324,12 +308,13 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_prepend_
   f_return_status fl_utf_string_dynamic_partial_prepend(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_prepend(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_partial_prepend_
@@ -337,12 +322,13 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_partial_prepend_nulless_
   f_return_status fl_utf_string_dynamic_partial_prepend_nulless(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
-      if (range.start > range.stop) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_prepend_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_partial_prepend_nulless_
@@ -350,10 +336,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_prepend_
   f_return_status fl_utf_string_dynamic_prepend(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_utf_string_prepend(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_utf_string_dynamic_prepend_
@@ -361,10 +348,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_prepend_nulless_
   f_return_status fl_utf_string_dynamic_prepend_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (source.used < 1) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+
     return private_fl_utf_string_prepend_nulless(source.string, 0, source.used - 1, destination);
   }
 #endif // _di_fl_utf_string_dynamic_prepend_nulless_
@@ -372,13 +360,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_rip_
   f_return_status fl_utf_string_dynamic_rip(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.stop < range.start) return f_status_set_error(f_invalid_parameter);
-      if (source.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.start) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_append(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_rip_
@@ -386,13 +375,14 @@ extern "C" {
 #ifndef _di_fl_utf_string_dynamic_rip_nulless_
   f_return_status fl_utf_string_dynamic_rip_nulless(const f_utf_string_dynamic source, const f_utf_string_location range, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.stop < range.start) return f_status_set_error(f_invalid_parameter);
-      if (source.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.start) return f_status_set_error(f_invalid_parameter);
       if (source.used <= range.stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (source.used == 0) return f_no_data;
+    if (range.start > range.stop) return f_no_data;
+
     return private_fl_utf_string_append_nulless(source.string, range.start, range.stop, destination);
   }
 #endif // _di_fl_utf_string_dynamic_rip_nulless_
@@ -401,13 +391,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_line_to(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
       return f_status_set_error(f_invalid_utf);
     }
@@ -433,13 +423,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_line_to_char(const f_utf_string_dynamic buffer, f_utf_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_utf_character seek_to_character = seek_to_this << 24;
 
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
@@ -467,13 +457,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_line_until_graph(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
 
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
@@ -509,13 +499,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_line_until_non_graph(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
 
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
@@ -551,13 +541,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_to(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
       return f_status_set_error(f_invalid_utf);
     }
@@ -581,13 +571,13 @@ extern "C" {
   f_return_status fl_utf_string_dynamic_seek_to_char(const f_utf_string_dynamic buffer, f_utf_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
-      if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->start) return f_status_set_error(f_invalid_parameter);
       if (buffer.used <= location->stop) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (buffer.used == 0) return f_none_on_eos;
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_utf_character seek_to_character = seek_to_this << 24;
 
     if (f_macro_utf_character_width_is(buffer.string[location->start]) == 1) {
@@ -609,15 +599,42 @@ extern "C" {
   }
 #endif // _di_fl_utf_string_dynamic_seek_to_char_
 
+#ifndef _di_fl_utf_string_dynamic_terminate_
+  f_return_status fl_utf_string_dynamic_terminate(f_utf_string_dynamic *destination) {
+    #ifndef _di_level_1_parameter_checking_
+      if (destination == 0) return f_status_set_error(f_invalid_parameter);
+      if (destination->used > destination->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    if (destination->used > 0 && destination->string[destination->used - 1] == f_utf_character_eos) return f_none;
+
+    if (destination->used + 1 > f_utf_string_max_size) return f_status_set_error(f_string_too_large);
+
+    const f_utf_string_length total = destination->used + 1;
+
+    if (total > destination->size) {
+      f_status status = f_none;
+
+      f_macro_string_dynamic_resize(status, (*destination), total);
+      if (f_status_is_error(status)) return status;
+    }
+
+    destination->string[destination->used] = f_string_eos;
+    destination->used = total;
+
+    return f_none;
+  }
+#endif // _di_fl_utf_string_dynamic_terminate_
+
 #ifndef _di_fl_utf_string_mash_
   f_return_status fl_utf_string_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -632,12 +649,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_mash_nulless_
   f_return_status fl_utf_string_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_append_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -652,12 +669,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_mish_
   f_return_status fl_utf_string_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -672,12 +689,12 @@ extern "C" {
 #ifndef _di_fl_utf_string_mish_nulless_
   f_return_status fl_utf_string_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (glue_length < 1) return f_status_set_error(f_invalid_parameter);
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    if (destination->used > 0) {
+    if (start > stop) return f_no_data;
+
+    if (glue_length > 0 && destination->used > 0) {
       f_status status = private_fl_utf_string_prepend_nulless(glue, 0, glue_length - 1, destination);
 
       if (f_status_is_error(status)) {
@@ -692,10 +709,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_prepend_
   f_return_status fl_utf_string_prepend(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_utf_string_prepend(source, start, stop, destination);
   }
 #endif // _di_fl_utf_string_prepend_
@@ -703,10 +721,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_prepend_nulless_
   f_return_status fl_utf_string_prepend_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (stop > start) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     return private_fl_utf_string_prepend_nulless(source, start, stop, destination);
   }
 #endif // _di_fl_utf_string_prepend_nulless_
@@ -714,10 +733,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_rip_
   f_return_status fl_utf_string_rip(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     f_utf_string_length begin = start;
     f_utf_string_length end = stop;
 
@@ -733,10 +753,11 @@ extern "C" {
 #ifndef _di_fl_utf_string_rip_nulless_
   f_return_status fl_utf_string_rip_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) {
     #ifndef _di_level_1_parameter_checking_
-      if (start > stop) return f_status_set_error(f_invalid_parameter);
       if (destination == 0) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (start > stop) return f_no_data;
+
     f_utf_string_length begin = start;
     f_utf_string_length end = stop;
 
@@ -753,10 +774,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_line_to(const f_utf_string string, f_utf_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     if (f_macro_utf_character_width_is(string[location->start]) == 1) {
       return f_status_set_error(f_invalid_utf);
     }
@@ -781,10 +802,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_line_to_char(const f_utf_string string, f_utf_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_utf_character seek_to_character = seek_to_this << 24;
 
     f_status status = f_none;
@@ -806,10 +827,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_line_until_graph(const f_utf_string string, f_utf_string_location *location, const f_utf_character placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
 
     if (f_macro_utf_character_width_is(string[location->start]) == 1) {
@@ -844,10 +865,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_line_until_non_graph(const f_utf_string string, f_utf_string_location *location, const f_utf_character placeholder) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_status status = f_none;
 
     if (f_macro_utf_character_width_is(string[location->start]) == 1) {
@@ -882,10 +903,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_to(const f_utf_string string, f_utf_string_location *location, const f_utf_character seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     if (f_macro_utf_character_width_is(string[location->start]) == 1) {
       return f_status_set_error(f_invalid_utf);
     }
@@ -908,10 +929,10 @@ extern "C" {
   f_return_status fl_utf_string_seek_to_char(const f_utf_string string, f_utf_string_location *location, const int8_t seek_to_this) {
     #ifndef _di_level_1_parameter_checking_
       if (location == 0) return f_status_set_error(f_invalid_parameter);
-      if (location->start < 0) return f_status_set_error(f_invalid_parameter);
-      if (location->stop < location->start) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    if (location->start > location->stop) return f_none_on_stop;
+
     f_utf_character seek_to_character = seek_to_this << 24;
 
     f_status status = f_none;
index fd42bfdfca8a16b004921a1fe2bee7d22ddadecb..23064cfce633ae3241695e016cadc9740cc5c63f 100644 (file)
@@ -48,6 +48,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -75,6 +76,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -157,6 +159,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -180,6 +183,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -260,6 +264,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -290,6 +295,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -318,6 +324,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -348,6 +355,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -372,6 +380,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -397,6 +406,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -487,6 +497,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -518,6 +529,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -547,6 +559,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -578,6 +591,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -603,6 +617,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -628,6 +643,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 or range is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -651,6 +667,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -674,6 +691,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0.
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -919,6 +937,27 @@ extern "C" {
 #endif // _di_fl_utf_string_dynamic_seek_to_utf_character_
 
 /**
+ * Guarantee that an end of UTF-8 string (NULL) exists at the end of the string.
+ *
+ * This is intended to be used for anything requiring NULL terminated strings.
+ * This will reallocate more space if necessary.
+ *
+ * If destination size is 0, then it will be reallocated and have the NULL assigned at index 0.
+ *
+ * @param destination
+ *   The new string, which will be allocated or reallocated as necessary.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_reallocation (with error bit) on memory reallocation error.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
+ */
+#ifndef _di_fl_utf_string_dynamic_terminate_
+  extern f_return_status fl_utf_string_dynamic_terminate(f_utf_string_dynamic *destination);
+#endif // _di_fl_utf_string_dynamic_terminate_
+
+/**
  * Append the UTF-8 source string onto the destination with the glue in between.
  *
  * If the destination string is empty, then no glue is appended.
@@ -938,6 +977,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -971,6 +1011,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1002,6 +1043,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1035,6 +1077,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1062,6 +1105,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
@@ -1091,6 +1135,7 @@ extern "C" {
  *
  * @return
  *   f_none on success.
+ *   f_no_data if source length is 0 (start > stop).
  *   f_string_max_size (with error bit) if the combined string is too large.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_allocation (with error bit) on memory allocation error.
index ca97550f7b828b3659c35f2b3c921ce039bc74d8..94e9f86f4e20464d7af823dc89d89981ca3571fd 100644 (file)
@@ -41,7 +41,7 @@ extern "C" {
  *   f_file_error_read (with error bit) if file read failed.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_reallocation (with error bit) on memory reallocation error.
- *   f_string_too_large (with error bit) if string is too large to fit into buffer.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
  *   f_incomplete_utf_on_eof (with error bit) if UTF-8 character was incomplete at the end of the file.
  */
 #ifndef _di_fl_utf_file_read_
@@ -68,7 +68,7 @@ extern "C" {
  *   f_file_error_read (with error bit) if file read failed.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  *   f_error_reallocation (with error bit) on memory reallocation error.
- *   f_string_too_large (with error bit) if string is too large to fit into buffer.
+ *   f_string_too_large (with error bit) if string is too large to fit into the buffer.
  *   f_incomplete_utf_on_eof (with error bit) if UTF-8 character was incomplete at the end of the file.
  */
 #ifndef _di_fl_utf_file_read_position_
index 0fc4cc9201d4a6659cf32b767f450db0cfcae372..ab779e8ab6ccf90f404198ed7a550916aa92c4a2 100644 (file)
 #include <level_2/execute.h>
+#include "private-execute.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifndef _di_fll_execute_path_
-  f_return_status fll_execute_path(const f_string program_path, const f_string_dynamics arguments, int *results) {
+#ifndef _di_fll_execute_arguments_add_
+  f_return_status fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (length == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    status = private_fll_execute_arguments_add(source, length, arguments);
+
+    if (f_status_is_error(status)) return status;
+
+    return f_none;
+  }
+#endif // _di_fll_execute_arguments_add_
+
+#ifndef _di_fll_execute_arguments_add_parameter_
+  f_return_status fll_execute_arguments_add_parameter(const f_string prefix, const f_string_length prefix_length, const f_string name, const f_string_length name_length, const f_string value, const f_string_length value_length, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (name_length == 0) return f_no_data;
+    if (value_length == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    status = private_fll_execute_arguments_add_parameter(prefix, prefix_length, name, name_length, value, value_length, arguments);
+
+    if (f_status_is_error(status)) return status;
+
+    return f_none;
+  }
+#endif // _di_fll_execute_arguments_add_parameter_
+
+#ifndef _di_fll_execute_arguments_add_parameter_set_
+  f_return_status fll_execute_arguments_add_parameter_set(const f_string prefix[], const f_string_length prefix_length[], const f_string name[], const f_string_length name_length[], const f_string value[], const f_string_length value_length[], const f_array_length size, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (size == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    for (f_array_length i = 0; i < size; i++) {
+      if (name_length[i] == 0) continue;
+      if (value_length[i] == 0) continue;
+
+      status = private_fll_execute_arguments_add_parameter(prefix[i], prefix_length[i], name[i], name_length[i], value[i], value_length[i], arguments);
+
+      if (f_status_is_error(status)) return status;
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_execute_arguments_add_parameter_set_
+
+#ifndef _di_fll_execute_arguments_add_set_
+  f_return_status fll_execute_arguments_add_set(const f_string source[], const f_string_length length[], const f_array_length size, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (size == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    for (f_array_length i = 0; i < size; i++) {
+      if (length[i] == 0) continue;
+
+      status = private_fll_execute_arguments_add(source[i], length[i], arguments);
+
+      if (f_status_is_error(status)) return status;
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_execute_arguments_add_set_
+
+#ifndef _di_fll_execute_arguments_dynamic_add_
+  f_return_status fll_execute_arguments_dynamic_add(const f_string_dynamic source, f_string_dynamics *arguments) {
     #ifndef _di_level_2_parameter_checking_
-      if (results == 0) return f_status_set_error(f_invalid_parameter);
+      if (source.used > source.size) return f_status_set_error(f_invalid_parameter);
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
 
-      if (arguments.used < 0) return f_status_set_error(f_invalid_parameter);
+    if (source.used == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    status = private_fll_execute_arguments_add(source.string, source.used, arguments);
+
+    if (f_status_is_error(status)) return status;
+
+    return f_none;
+  }
+#endif // _di_fll_execute_arguments_dynamic_add_
+
+#ifndef _di_fll_execute_arguments_dynamic_add_parameter_
+  f_return_status fll_execute_arguments_dynamic_add_parameter(const f_string_dynamic prefix, const f_string_dynamic name, const f_string_dynamic value, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (prefix.used > prefix.size) return f_status_set_error(f_invalid_parameter);
+      if (name.used > name.size) return f_status_set_error(f_invalid_parameter);
+      if (value.used > value.size) return f_status_set_error(f_invalid_parameter);
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (name.used == 0) return f_no_data;
+    if (value.used == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    status = private_fll_execute_arguments_add_parameter(prefix.string, prefix.used, name.string, name.used, value.string, value.used, arguments);
+
+    if (f_status_is_error(status)) return status;
+
+    return f_none;
+  }
+#endif // _di_fll_execute_arguments_dynamic_add_parameter_
+
+#ifndef _di_fll_execute_arguments_dynamic_add_parameter_set_
+  f_return_status fll_execute_arguments_dynamic_add_parameter_set(const f_string_dynamic prefix[], const f_string_dynamic name[], const f_string_dynamic value[], const f_array_length size, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (size == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    for (f_array_length i = 0; i < size; i++) {
+      if (prefix[i].used > prefix[i].size) continue;
+      if (name[i].used == 0) continue;
+      if (name[i].used > name[i].size) continue;
+      if (value[i].used == 0) continue;
+      if (value[i].used > value[i].size) continue;
+
+      status = private_fll_execute_arguments_add_parameter(prefix[i].string, prefix[i].used, name[i].string, name[i].used, value[i].string, value[i].used, arguments);
+
+      if (f_status_is_error(status)) return status;
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_execute_arguments_dynamic_add_parameter_set_
+
+#ifndef _di_fll_execute_arguments_dynamic_add_set_
+  f_return_status fll_execute_arguments_dynamic_add_set(const f_string_dynamic source[], const f_array_length size, f_string_dynamics *arguments) {
+    #ifndef _di_level_2_parameter_checking_
+      if (arguments == 0) return f_status_set_error(f_invalid_parameter);
+      if (arguments->used > arguments->size) return f_status_set_error(f_invalid_parameter);
+    #endif // _di_level_2_parameter_checking_
+
+    if (size == 0) return f_no_data;
+
+    f_status status = f_none;
+
+    for (f_array_length i = 0; i < size; i++) {
+      if (source[i].used == 0) continue;
+      if (source[i].used > source[i].size) continue;
+
+      status = private_fll_execute_arguments_add(source[i].string, source[i].used, arguments);
+
+      if (f_status_is_error(status)) return status;
+    } // for
+
+    return status;
+  }
+#endif // _di_fll_execute_arguments_dynamic_add_set_
+
+#ifndef _di_fll_execute_path_
+  f_return_status fll_execute_path(const f_string program_path, const f_string_dynamics arguments, int *result) {
+    #ifndef _di_level_2_parameter_checking_
+      if (result == 0) return f_status_set_error(f_invalid_parameter);
       if (arguments.used > arguments.size) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_2_parameter_checking_
 
@@ -70,7 +249,7 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // TODO: validate that the file at program_path actually exists before attempting to fork and execute
+    // @todo validate that the file at program_path actually exists before attempting to fork and execute
     int process_id = 0;
 
     process_id = vfork();
@@ -94,7 +273,7 @@ extern "C" {
     }
 
     // have the parent wait for the child process to finish
-    waitpid(process_id, results, 0);
+    waitpid(process_id, result, 0);
 
     if (name_size > 0) f_macro_string_delete_simple(program_name, name_size);
 
@@ -102,18 +281,16 @@ extern "C" {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*results != 0) return f_status_set_error(f_failure);
+    if (*result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
 #endif // _di_fll_execute_path_
 
 #ifndef _di_fll_execute_program_
-  f_return_status fll_execute_program(const f_string program_name, const f_string_dynamics arguments, int *results) {
+  f_return_status fll_execute_program(const f_string program_name, const f_string_dynamics arguments, int *result) {
     #ifndef _di_level_2_parameter_checking_
-      if (results == 0) return f_status_set_error(f_invalid_parameter);
-
-      if (arguments.used < 0) return f_status_set_error(f_invalid_parameter);
+      if (result == 0) return f_status_set_error(f_invalid_parameter);
       if (arguments.used > arguments.size) return f_status_set_error(f_invalid_parameter);
     #endif // _di_level_2_parameter_checking_
 
@@ -124,6 +301,7 @@ extern "C" {
     fixed_arguments[0] = program_name;
 
     f_status status = f_none;
+
     for (f_string_length i = 0; i < arguments.used; i++) {
       f_macro_string_new(status, fixed_arguments[i + 1], arguments.array[i].used + 1);
 
@@ -142,7 +320,7 @@ extern "C" {
     // insert the required array terminated
     fixed_arguments[arguments.used + 2] = 0;
 
-    // TODO: validate that the file at program_path actually exists before attempting to fork and execute
+    // @todo validate that the file at program_path actually exists before attempting to fork and execute
     int process_id = 0;
 
     process_id = vfork();
@@ -164,13 +342,13 @@ extern "C" {
     }
 
     // have the parent wait for the child process to finish
-    waitpid(process_id, results, 0);
+    waitpid(process_id, result, 0);
 
     for (f_string_length i = 0; i < arguments.used; i++) {
       f_macro_string_delete_simple(fixed_arguments[i + 1], arguments.array[i].used + 1);
     } // for
 
-    if (*results != 0) return f_status_set_error(f_failure);
+    if (*result != 0) return f_status_set_error(f_failure);
 
     return f_none;
   }
index 152023598903427aefd9dae1b210c2ccddcf7808..cc8dcdebf5d5a74b3afa7f878924d87dca87e30e 100644 (file)
 #include <level_0/type.h>
 
 // fll-1 includes
+#include <level_1/string.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * Add an argument to the execution arguments array.
+ *
+ * This guarantees that an end of string exists at the end of the copied string.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param source
+ *   The string to add to the arguments array.
+ * @param length
+ *   Length of string to prepend.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_add_
+  extern f_return_status fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_add_
+/**
+ * Add parameters as arguments to the execution arguments array.
+ *
+ * This is intended to simplify adding arguments that have prefixes and values such as those common in console parameters.
+ * For example, a pefix of '--', a name of 'do', and a value of 'something' would result in two arguments added:
+ *   '--do' and 'something'.
+ *
+ * The arguments are only appended if the length of name and value are not 0.
+ *
+ * This guarantees that an end of string exists at the end of each argument.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param prefix
+ *   The string prepend to the name.
+ * @param prefix_length
+ *   Length of prefix to prepend.
+ * @param name
+ *   The string to add to the arguments array.
+ * @param name_length
+ *   Length of name to prepend.
+ * @param value
+ *   The string to add to the arguments array.
+ * @param value_length
+ *   Length of value to prepend.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_add_parameter_
+  extern f_return_status fll_execute_arguments_add_parameter(const f_string prefix, const f_string_length prefix_length, const f_string name, const f_string_length name_length, const f_string value, const f_string_length value_length, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_add_parameter_
+
+/**
+ * Add set of parameters as arguments to the execution arguments array.
+ *
+ * This is intended to simplify adding arguments that have prefixes and values such as those common in console parameters.
+ * For example, a pefix of '--', a name of 'do', and a value of 'something' would result in two arguments added:
+ *   '--do' and 'something'.
+ *
+ * The arguments are only appended if the length of name and value are not 0.
+ *
+ * This guarantees that an end of string exists at the end of each argument.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param prefix
+ *   An array of the strings prepend to the name.
+ * @param prefix_length
+ *   Length of prefix to prepend.
+ * @param name
+ *   An array of the strings to add to the arguments array.
+ * @param name_length
+ *   Length of name to prepend.
+ * @param value
+ *   An array of the strings to add to the arguments array.
+ * @param value_length
+ *   Length of value to prepend.
+ * @param size
+ *   The array size of prefix, prefix_length, name, name_length, value, and value_length (all of which must be of the same array size).
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if size is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_add_parameter_set_
+  extern f_return_status fll_execute_arguments_add_parameter_set(const f_string prefix[], const f_string_length prefix_length[], const f_string name[], const f_string_length name_length[], const f_string value[], const f_string_length value_length[], const f_array_length size, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_add_parameter_set_
+
+/**
+ * Add a set of arguments to the execution arguments array.
+ *
+ * This guarantees that an end of string exists at the end of the copied string.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param source
+ *   An array of strings to add to the arguments array.
+ * @param length
+ *   An array of lengths of each string to prepend.
+ * @param size
+ *   The array size of source and length (all of which must be of the same array size).
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if size is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_add_set_
+  extern f_return_status fll_execute_arguments_add_set(const f_string source[], const f_string_length length[], const f_array_length size, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_add_set_
+
+/**
+ * Add an argument to the execution arguments array.
+ *
+ * This guarantees that an end of string exists at the end of the copied string.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param source
+ *   The string to add to the arguments array.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_dynamic_add_
+  extern f_return_status fll_execute_arguments_dynamic_add(const f_string_dynamic source, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_dynamic_add_
+
+/**
+ * Add parameters as arguments to the execution arguments array.
+ *
+ * This is intended to simplify adding arguments that have prefixes and values such as those common in console parameters.
+ * For example, a pefix of '--', a name of 'do', and a value of 'something' would result in two arguments added:
+ *   '--do' and 'something'.
+ *
+ * The arguments are only appended if the length of name and value are not 0.
+ *
+ * This guarantees that an end of string exists at the end of each argument.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param prefix
+ *   The string prepend to the name.
+ * @param name
+ *   The string to add to the arguments array.
+ * @param value
+ *   The string to add to the arguments array.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_dynamic_add_parameter_
+  extern f_return_status fll_execute_arguments_dynamic_add_parameter(const f_string_dynamic prefix, const f_string_dynamic name, const f_string_dynamic value, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_dynamic_add_parameter_
+
+/**
+ * Add set of parameters as arguments to the execution arguments array.
+ *
+ * This is intended to simplify adding arguments that have prefixes and values such as those common in console parameters.
+ * For example, a pefix of '--', a name of 'do', and a value of 'something' would result in two arguments added:
+ *   '--do' and 'something'.
+ *
+ * The arguments are only appended if the length of name and value are not 0.
+ *
+ * This guarantees that an end of string exists at the end of each argument.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param prefix
+ *   The string prepend to the name.
+ * @param name
+ *   The string to add to the arguments array.
+ * @param value
+ *   The string prepend to the name.
+ * @param size
+ *   The array size of buffer.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_dynamic_add_parameter_set_
+  extern f_return_status fll_execute_arguments_dynamic_add_parameter_set(const f_string_dynamic prefix[], const f_string_dynamic name[], const f_string_dynamic value[], const f_array_length size, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_dynamic_add_parameter_set_
+
+/**
+ * Add a set of arguments to the execution arguments array.
+ *
+ * This guarantees that an end of string exists at the end of the copied string.
+ * This does not check for NULL characters anywhere else in the string.
+ *
+ * @param source
+ *   An array of strings to add to the arguments array.
+ * @param size
+ *   The array size of buffer.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if source length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ */
+#ifndef _di_fll_execute_arguments_dynamic_add_set_
+  extern f_return_status fll_execute_arguments_dynamic_add_set(const f_string_dynamic source[], const f_array_length size, f_string_dynamics *arguments);
+#endif // _di_fll_execute_arguments_dynamic_add_set_
+
+/**
+ * Execute a program given some path + program name (such as "/bin/bash").
+ *
+ * @param program_path
+ *   The entire path to the program.
+ * @param arguments
+ *   An array of strings representing the arguments.
+ * @param result
+ *   The code returned after finishing execution of program_path.
+ *
+ * @return
+ *   f_none on success.
+ *   f_failure (with error bit) if result is non-zero.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *
+ * @see execv()
+ */
 #ifndef _di_fll_execute_path_
-  /**
-   * This will execute a program given some path + program name (such as "/bin/bash").
-   */
-  extern f_return_status fll_execute_path(const f_string program_path, const f_string_dynamics arguments, int *results);
+  extern f_return_status fll_execute_path(const f_string program_path, const f_string_dynamics arguments, int *result);
 #endif // _di_fll_execute_path_
 
+/**
+ * Execute a program given by name found in the PATH environment (such as "bash").
+ *
+ * @param program_name
+ *   The name of the program.
+ * @param arguments
+ *   An array of strings representing the arguments.
+ * @param result
+ *   The code returned after finishing execution of program.
+ *
+ * @return
+ *   f_none on success.
+ *   f_failure (with error bit) if result is non-zero.
+ *   f_fork_failed (with error bit) on fork failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *
+ * @see execvp()
+ */
 #ifndef _di_fll_execute_program_
-  /**
-   * This will find the program based on PATH environment so that static paths do not have to be used as with f_execute_path.
-   */
-  extern f_return_status fll_execute_program(const f_string program_name, const f_string_dynamics arguments, int *results);
+  extern f_return_status fll_execute_program(const f_string program_name, const f_string_dynamics arguments, int *result);
 #endif // _di_fll_execute_program_
 
 #ifdef __cplusplus
diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c
new file mode 100644 (file)
index 0000000..7f71d29
--- /dev/null
@@ -0,0 +1,115 @@
+#include <level_2/execute.h>
+#include "private-execute.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fll_execute_arguments_add_) || !defined(_di_fll_execute_arguments_add_set_) || !defined(_di_fll_execute_arguments_dynamic_add_) || !defined(_di_fll_execute_arguments_dynamic_add_set_)
+  f_return_status private_fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments) {
+    f_status status = f_none;
+
+    if (arguments->used >= arguments->size) {
+      if (arguments->size + f_memory_default_allocation_step > f_array_length_size) {
+        if (arguments->size + 1 > f_array_length_size) return f_array_too_large;
+        f_macro_string_dynamics_resize(status, (*arguments), arguments->size + 1);
+      }
+      else {
+        f_macro_string_dynamics_resize(status, (*arguments), arguments->size + f_memory_default_allocation_step);
+      }
+
+      if (f_status_is_error(status)) return status;
+    }
+
+    f_string_dynamic argument = f_string_dynamic_initialize;
+
+    status = fl_string_append(source, 0, length - 1, &argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    status = fl_string_dynamic_terminate(&argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    arguments->array[arguments->used].string = argument.string;
+    arguments->array[arguments->used].used = argument.used;
+    arguments->array[arguments->used].size = argument.size;
+    arguments->used++;
+
+    return f_none;
+  }
+#endif // !defined(_di_fll_execute_arguments_add_) || !defined(_di_fll_execute_arguments_add_set_) || !defined(_di_fll_execute_arguments_dynamic_add_) || !defined(_di_fll_execute_arguments_dynamic_add_set_)
+
+#if !defined(_di_fll_execute_arguments_add_parameter_) || !defined(_di_fll_execute_arguments_add_parameter_set_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_set_)
+  f_return_status private_fll_execute_arguments_add_parameter(const f_string prefix, const f_string_length prefix_length, const f_string name, const f_string_length name_length, const f_string value, const f_string_length value_length, f_string_dynamics *arguments) {
+    f_status status = f_none;
+
+    if (arguments->used + 1 >= arguments->size) {
+      if (arguments->size + f_memory_default_allocation_step > f_array_length_size) {
+        if (arguments->size + 2 > f_array_length_size) return f_array_too_large;
+        f_macro_string_dynamics_resize(status, (*arguments), arguments->size + 2);
+      }
+      else {
+        f_macro_string_dynamics_resize(status, (*arguments), arguments->size + f_memory_default_allocation_step + 1);
+      }
+
+      if (f_status_is_error(status)) return status;
+    }
+
+    f_string_dynamic argument = f_string_dynamic_initialize;
+
+    if (prefix_length > 0) {
+      status = fl_string_append(prefix, 0, prefix_length - 1, &argument);
+      if (f_status_is_error(status)) {
+        f_macro_string_dynamic_delete_simple(argument);
+        return status;
+      }
+    }
+
+    status = fl_string_append(name, 0, name_length - 1, &argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    status = fl_string_dynamic_terminate(&argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    arguments->array[arguments->used].string = argument.string;
+    arguments->array[arguments->used].used = argument.used;
+    arguments->array[arguments->used].size = argument.size;
+    arguments->used++;
+
+    f_macro_string_dynamic_clear(argument);
+
+    status = fl_string_append(value, 0, value_length - 1, &argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    status = fl_string_dynamic_terminate(&argument);
+    if (f_status_is_error(status)) {
+      f_macro_string_dynamic_delete_simple(argument);
+      return status;
+    }
+
+    arguments->array[arguments->used].string = argument.string;
+    arguments->array[arguments->used].used = argument.used;
+    arguments->array[arguments->used].size = argument.size;
+    arguments->used++;
+
+    return f_none;
+  }
+#endif // !defined(_di_fll_execute_arguments_add_parameter_) || !defined(_di_fll_execute_arguments_add_parameter_set_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_set_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_2/fll_execute/c/private-execute.h b/level_2/fll_execute/c/private-execute.h
new file mode 100644 (file)
index 0000000..0c0af7b
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * FLL - Level 2
+ *
+ * Project: Execute
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * These are provided for internal reduction in redundant code.
+ * These should not be exposed/used outside of this project.
+ */
+#ifndef _PRIVATE_FLL_execute_h
+#define _PRIVATE_FLL_execute_h
+
+// libc includes
+#include <linux/limits.h> // defines PATH_MAX
+#include <memory.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+// fll-0 includes
+#include <level_0/status.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/type.h>
+
+// fll-1 includes
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation of fll_execute_arguments_add().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ *   The string to add to the arguments array.
+ * @param length
+ *   Length of string to prepend.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ *
+ * @see fll_execute_arguments_add()
+ * @see fll_execute_arguments_add_set()
+ * @see fll_execute_arguments_dynamic_add()
+ * @see fll_execute_arguments_dynamic_add_set()
+ */
+#if !defined(_di_fll_execute_arguments_add_) || !defined(_di_fll_execute_arguments_add_set_) || !defined(_di_fll_execute_arguments_dynamic_add_) || !defined(_di_fll_execute_arguments_dynamic_add_set_)
+  extern f_return_status private_fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_execute_arguments_add_) || !defined(_di_fll_execute_arguments_add_set_) || !defined(_di_fll_execute_arguments_dynamic_add_) || !defined(_di_fll_execute_arguments_dynamic_add_set_)
+
+/**
+ * Private implementation of fll_execute_arguments_add_parameter().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param prefix
+ *   The string prepend to the name.
+ * @param prefix_length
+ *   Length of prefix to prepend.
+ * @param name
+ *   The string to add to the arguments array.
+ * @param name_length
+ *   Length of name to prepend.
+ * @param value
+ *   The string prepend to the name.
+ * @param value_length
+ *   Length of value to prepend.
+ * @param arguments
+ *   The array of string arguments intended to pass to the execute functions.
+ *
+ * @return
+ *   f_none on success.
+ *   f_no_data if name_length is 0.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_error_allocation (with error bit) on allocation error.
+ *   f_error_reallocation (with error bit) on reallocation error.
+ *   f_array_too_large (with error bit) if arguments array is too larger for further allocation.
+ *
+ * @see fll_execute_arguments_add_parameter()
+ * @see fll_execute_arguments_add_parameter_set()
+ * @see fll_execute_arguments_dynamic_add_parameter()
+ * @see fll_execute_arguments_dynamic_add_parameter_set()
+ */
+#if !defined(_di_fll_execute_arguments_add_parameter_) || !defined(_di_fll_execute_arguments_add_parameter_set_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_set_)
+  extern f_return_status private_fll_execute_arguments_add_parameter(const f_string prefix, const f_string_length prefix_length, const f_string name, const f_string_length name_length, const f_string value, const f_string_length value_length, f_string_dynamics *arguments) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_execute_arguments_add_parameter_) || !defined(_di_fll_execute_arguments_add_parameter_set_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_) || !defined(_di_fll_execute_arguments_dynamic_add_parameter_set_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_FLL_execute_h
index d8175f560a573638a52fec738c6bd984a86a5620..4804427cfaf4ad3129354334e7f2950cd6bfbfc4 100644 (file)
@@ -2,3 +2,4 @@ f_type
 f_status
 f_memory
 f_string
+fl_string
index 40d9aefe271001ac0ec2538564c64550ea7c720b..c51b88da61e3e79f797b4fdb7f18304ba7a2c377 100644 (file)
@@ -10,9 +10,9 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lf_memory
-build_sources_library execute.c
-build_sources_program 
+build_libraries_fll -lfl_string -lf_memory
+build_sources_library execute.c private-execute.c
+build_sources_program
 build_sources_headers execute.h
 build_sources_bash
 build_sources_settings