]> Kevux Git Server - fll/commitdiff
Feature: provide string "except" functions.
authorKevin Day <thekevinday@gmail.com>
Sat, 24 Oct 2020 13:36:54 +0000 (08:36 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 24 Oct 2020 16:55:00 +0000 (11:55 -0500)
The FSS Read functions utilize matching and printing on potentially delimited data.
If the delimits are not applied, then the matches and prints will be incorrect.
To avoid this, it seems that I need some way to not print the delimited data.

Provide "except" functions that accept and "except" array of strings representing locations within some string that are to be ignored.
The printing functions and comparison functions now have "except" equivalents.

The level_1 fl_print project appears outdated and needed updating anyway.
Restructure this project to use the private function practice, hopefully reducing the code size (and ideally binary size).
The "_string" part can be removed from the fl_print function names.
The parameter checks are loosened and now more closely match the approaches used in level_0 f_print.

16 files changed:
build/level_1/settings
build/monolithic/settings
level_0/f_print/c/print.c
level_0/f_print/c/print.h
level_0/f_print/c/private-print.c
level_0/f_print/c/private-print.h
level_1/fl_fss/c/private-fss.c
level_1/fl_print/c/print.c
level_1/fl_print/c/print.h
level_1/fl_print/c/private-print.c [new file with mode: 0644]
level_1/fl_print/c/private-print.h [new file with mode: 0644]
level_1/fl_print/data/build/settings
level_1/fl_string/c/private-string.c
level_1/fl_string/c/private-string.h
level_1/fl_string/c/string.c
level_1/fl_string/c/string.h

index 86d8ee59ee17439b1d69d86c6ae620465f92a222..d34a818dbebbb58258f7c56f1d969aa76b4a55b0 100644 (file)
@@ -20,7 +20,7 @@ build_indexer ar
 build_language c
 build_libraries -lc
 build_libraries-level -lfll_0
-build_sources_library color.c console.c conversion.c directory.c private-directory.c environment.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c iki.c print.c status.c string.c private-string.c utf.c private-utf.c utf_file.c private-utf_file.c
+build_sources_library color.c console.c conversion.c directory.c private-directory.c environment.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c iki.c print.c private-print.c status.c string.c private-string.c utf.c private-utf.c utf_file.c private-utf_file.c
 build_sources_program
 build_sources_headers color.h console.h conversion.h directory.h environment.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_macro.h fss_status.h iki.h print.h status.h string.h utf.h utf_file.h
 build_sources_script
index 30ee6208247aa5951d76a82938d9227c53858479..152db4933cb228500887b3f49e47bef1a2ecd6f0 100644 (file)
@@ -20,7 +20,7 @@ build_indexer ar
 build_language c
 build_libraries -lc
 build_libraries-monolithic
-build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-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/iki.c level_1/print.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_1/private-utf_file.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-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/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
+build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-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/iki.c level_1/print.c level_1/private-print.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_1/private-utf_file.c level_2/error.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-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/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
 build_sources_program
 build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/error.h level_2/error-common.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/iki.h level_2/path.h level_2/program.h level_2/status.h
 build_sources_script
index ecd47c44a1381d40bd4f8d2604540a69b5a3ffac..2499ae6b7f7a8815d9f34e9f23ede78f1660a7c9 100644 (file)
@@ -55,7 +55,7 @@ extern "C" {
 
     if (!string || length == 0) return F_data_not;
 
-    return private_f_print_except(output, string, length, except);
+    return private_f_print_except(output, string, 0, length, except);
   }
 #endif // _di_f_print_except_
 
@@ -67,7 +67,7 @@ extern "C" {
 
     if (!buffer.used) return F_data_not;
 
-    return private_f_print_except(output, buffer.string, buffer.used, except);
+    return private_f_print_except(output, buffer.string, 0, buffer.used, except);
   }
 #endif // _di_f_print_except_dynamic_
 
@@ -85,7 +85,7 @@ extern "C" {
       length = buffer.used - range.start;
     }
 
-    return private_f_print_except(output, buffer.string + range.start, length, except);
+    return private_f_print_except(output, buffer.string, range.start, range.start + length, except);
   }
 #endif // _di_f_print_except_dynamic_partial_
 
@@ -139,7 +139,7 @@ extern "C" {
 
     if (!string || length == 0) return F_data_not;
 
-    return private_f_print_to_except(id, string, length, except);
+    return private_f_print_to_except(id, string, 0, length, except);
   }
 #endif // _di_f_print_to_except_
 
@@ -151,7 +151,7 @@ extern "C" {
 
     if (!buffer.used) return F_data_not;
 
-    return private_f_print_to_except(id, buffer.string, buffer.used, except);
+    return private_f_print_to_except(id, buffer.string, 0, buffer.used, except);
   }
 #endif // _di_f_print_to_except_dynamic_
 
@@ -169,7 +169,7 @@ extern "C" {
       length = buffer.used - range.start;
     }
 
-    return private_f_print_to_except(id, buffer.string + range.start, length, except);
+    return private_f_print_to_except(id, buffer.string, range.start, range.start + length, except);
   }
 #endif // _di_f_print_to_except_dynamic_partial_
 
index 0c11f4ebd202b730b0c6fb409780e24a240ce2b4..95c0c6868207865962f5c4b71b269aa0085549ce 100644 (file)
@@ -121,7 +121,7 @@ extern "C" {
  *   The total number of characters to print.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -149,7 +149,7 @@ extern "C" {
  *   The string to output.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -179,7 +179,7 @@ extern "C" {
  *   The range within the provided string to print.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -306,7 +306,7 @@ extern "C" {
  *   The total number of characters to print.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -342,7 +342,7 @@ extern "C" {
  *   The string to output.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -380,7 +380,7 @@ extern "C" {
  *   The range within the provided string to print.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
index 2b5319e9537c580f78693c1bc0dd54d96c653cb2..54e6b6ddfa19cb9a8d00f1e5a76a1519707fc977 100644 (file)
@@ -7,10 +7,8 @@ extern "C" {
 
 #if !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_)
   f_return_status private_f_print(FILE *output, const f_string_t string, const f_string_length_t length) {
-
-    if (!length) return F_data_not;
-
     for (register f_string_length_t i = 0; i < length; ++i) {
+
       if (string[i]) {
         if (!fputc(string[i], output)) {
           return F_status_set_error(F_output);
@@ -23,15 +21,13 @@ extern "C" {
 #endif // !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_)
 
 #if !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_)
-  f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) {
-
-    if (!length) return F_data_not;
-
+  f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t offset, const f_string_length_t stop, const f_string_lengths_t except) {
     f_string_length_t j = 0;
 
-    for (register f_string_length_t i = 0; i < length; ++i) {
-      for (; j < except.used; j++) {
-        if (except.array[j] >= i) break;
+    for (register f_string_length_t i = offset; i < stop; ++i) {
+
+      for (; j < except.used && except.array[j] < i; ++j) {
+        // do nothing.
       } // for
 
       if (j < except.used && except.array[j] == i) continue;
@@ -49,10 +45,8 @@ extern "C" {
 
 #if !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_)
   f_return_status private_f_print_to(const int id, const f_string_t string, const f_string_length_t length) {
-
-    if (!length) return F_data_not;
-
     register f_string_length_t i = 0;
+
     f_string_length_t start = 0;
     f_string_length_t total = 0;
 
@@ -100,19 +94,17 @@ extern "C" {
 #endif // !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_)
 
 #if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_)
-  f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) {
-
-    if (!length) return F_data_not;
+  f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t offset, const f_string_length_t stop, const f_string_lengths_t except) {
+    register f_string_length_t i = offset;
 
-    register f_string_length_t i = 0;
     f_string_length_t j = 0;
-    f_string_length_t start = 0;
+    f_string_length_t start = offset;
     f_string_length_t total = 0;
 
-    for (; i < length; ++i) {
+    for (; i < stop; ++i) {
 
-      for (; j < except.used; j++) {
-        if (except.array[j] >= i) break;
+      for (; j < except.used && except.array[j] < i; ++j) {
+        // do nothing.
       } // for
 
       if (j >= except.used || except.array[j] != i) {
index 0dbc3169190bf5240c904cd2d7b46092edbb80b2..410670242eb80866105ee2c8453407fc64cee2ca 100644 (file)
@@ -50,11 +50,13 @@ extern "C" {
  *   The file to output to, including standard streams such as stdout and stderr.
  * @param string
  *   The string to output.
- * @param length
- *   The total number of characters to print.
+ * @param offset
+ *   The inclusive start point to start printing.
+ * @param stop
+ *   The exclusive stop point to stop printing.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -67,7 +69,7 @@ extern "C" {
  * @see f_print_except_dynamic_partial()
  */
 #if !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_)
-  extern f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) f_gcc_attribute_visibility_internal;
+  extern f_return_status private_f_print_except(FILE *output, const f_string_t string, const f_string_length_t offset, const f_string_length_t stop, const f_string_lengths_t except) f_gcc_attribute_visibility_internal;
 #endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_)
 
 /**
@@ -111,11 +113,13 @@ extern "C" {
  *   The file to output to, including standard streams such as stdout and stderr.
  * @param string
  *   The string to output.
- * @param length
- *   The total number of characters to print.
+ * @param offset
+ *   The inclusive start point to start printing.
+ * @param stop
+ *   The exclusive stop point to stop printing.
  * @param except
  *   An array of locations within the given string to not print.
- *   The array of locations is assumed to be in linear order.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
@@ -134,7 +138,7 @@ extern "C" {
  * @see f_print_to_except_dynamic_partial()
  */
 #if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_)
-  extern f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) f_gcc_attribute_visibility_internal;
+  extern f_return_status private_f_print_to_except(const int id, const f_string_t string, const f_string_length_t offset, const f_string_length_t stop, const f_string_lengths_t except) f_gcc_attribute_visibility_internal;
 #endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_)
 
 #ifdef __cplusplus
index 4a2e02a278bca5885a3fe5cb2e5b8a7d0ad8c488..e9e9ddecfcdb6737f2ea6ecc89fcb0f8b7b4743b 100644 (file)
@@ -120,7 +120,6 @@ extern "C" {
   }
 #endif // !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_)
 
-
 #if !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_)
   f_return_status private_fl_fss_basic_list_write_object_trim(const f_string_length_t used_start, f_string_dynamic_t *destination) {
     f_status_t status = F_none;
index f1d64797301df1bb5e44935ee9d73392ae223bce..6c847d046c3d0c0091fdb5054cbc409239e80478 100644 (file)
 #include "print.h"
+#include "private-print.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#ifndef _di_fl_print_trim_string_
-  f_return_status fl_print_trim_string(FILE *output, const f_string_t string, const f_string_length_t length) {
+#ifndef _di_fl_print_trim_except_
+  f_return_status fl_print_trim_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except) {
     #ifndef _di_level_1_parameter_checking_
-      if (!string) return F_status_set_error(F_parameter);
-      if (length < 1) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_string_length_t i = 0;
-    f_status_t status = F_none;
-    uint8_t width_max = 0;
+    if (!string || !length) return F_data_not;
 
-    for (; i < length; i += f_macro_utf_byte_width(string[i])) {
-
-      width_max = (length - i) + 1;
-      status = f_utf_is_whitespace(string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_false) break;
-    } // for
-
-    for (; i < length; i += f_macro_utf_byte_width(string[i])) {
-      if (!string[i]) continue;
-
-      width_max = (length - i) + 1;
-      status = f_utf_is_whitespace(string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_true) {
-        f_string_length_t j = i + f_macro_utf_byte_width(string[i]);
-
-        if (j == length) return F_none;
-
-        for (; j < length; j += f_macro_utf_byte_width(string[j])) {
-          width_max = (length - j) + 1;
-          status = f_utf_is_whitespace(string + j, width_max);
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-            return status;
-          }
-
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i < j; i++) {
-              if (!string[i]) continue;
-
-              if (!fputc(string[i], output)) return F_status_set_error(F_output);
-            } // for
-
-            break;
-          }
-        } // for
-
-        if (status == F_true) break;
-      }
-
-      if (!fputc(string[i], output)) return F_status_set_error(F_output);
-    } // for
-
-    return F_none;
+    return private_fl_print_trim_except(output, string, 0, length, except);
   }
-#endif // _di_fl_print_trim_string_
+#endif // _di_fl_print_trim_except_
 
-#ifndef _di_fl_print_trim_string_dynamic_
-  f_return_status fl_print_trim_string_dynamic(FILE *output, const f_string_static_t buffer) {
+#ifndef _di_fl_print_trim_except_dynamic_
+  f_return_status fl_print_trim_except_dynamic(FILE *output, const f_string_static_t buffer, const f_string_lengths_t except) {
     #ifndef _di_level_1_parameter_checking_
-      if (!buffer.used) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_string_length_t i = 0;
-    f_status_t status = F_none;
-    uint8_t width_max = 0;
-
-    for (; i < buffer.used; i += f_macro_utf_byte_width(buffer.string[i])) {
-      width_max = (buffer.used - i) + 1;
-      status = f_utf_is_whitespace(buffer.string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_false) break;
-    } // for
-
-    for (; i < buffer.used; i += f_macro_utf_byte_width(buffer.string[i])) {
-      if (!buffer.string[i]) continue;
-
-      width_max = (buffer.used - i) + 1;
-      status = f_utf_is_whitespace(buffer.string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+    if (!buffer.used) return F_data_not;
 
-        return status;
-      }
-
-      if (status == F_true) {
-        f_string_length_t j = i + f_macro_utf_byte_width(buffer.string[i]);
-
-        if (j == buffer.used) return F_none;
-
-        for (; j < buffer.used; j += f_macro_utf_byte_width(buffer.string[j])) {
-          width_max = (buffer.used - j) + 1;
-          status = f_utf_is_whitespace(buffer.string + j, width_max);
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-            return status;
-          }
-
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i < j; i++) {
-              if (!buffer.string[i]) continue;
-
-              if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-            } // for
-
-            break;
-          }
-        } // for
-
-        if (status == F_true) {
-          break;
-        }
-      }
-
-      if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-    } // for
-
-    return F_none;
+    return private_fl_print_trim_except(output, buffer.string, 0, buffer.used, except);
   }
-#endif // _di_fl_print_trim_string_dynamic_
+#endif // _di_fl_print_trim_except_dynamic_
 
-#ifndef _di_fl_print_trim_string_dynamic_partial_
-  f_return_status fl_print_trim_string_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range) {
+#ifndef _di_fl_print_trim_except_dynamic_partial_
+  f_return_status fl_print_trim_except_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.start < 0) return F_status_set_error(F_parameter);
-      if (range.stop < range.start) return F_status_set_error(F_parameter);
-      if (!buffer.used) return F_status_set_error(F_parameter);
-      if (range.start >= buffer.used) return F_status_set_error(F_parameter);
-      if (range.stop >= buffer.used) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_string_length_t i = range.start;
-    f_status_t status = F_none;
-
-    uint8_t width_max = 0;
-
-    for (; i <= range.stop; i += f_macro_utf_byte_width(buffer.string[i])) {
-      width_max = (range.stop - i) + 1;
-      status = f_utf_is_whitespace(buffer.string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_false) break;
-    } // for
-
-    for (uint8_t width_i = f_macro_utf_byte_width(buffer.string[i]); i <= range.stop; i += width_i) {
-      if (!buffer.string[i]) {
-        width_i = 1;
-        continue;
-      }
-
-      width_i = f_macro_utf_byte_width(buffer.string[i]);
-      width_max = (range.stop - i) + 1;
-      status = f_utf_is_whitespace(buffer.string + i, width_max);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) {
-          return F_status_set_error(F_utf);
-        }
-
-        return status;
-      }
-
-      if (status == F_true) {
-        f_string_length_t j = i + width_i;
-
-        if (j == range.stop) return F_none;
-
-        for (uint8_t width_j = f_macro_utf_byte_width(buffer.string[j]); j <= range.stop; j += width_j) {
-          width_j = f_macro_utf_byte_width(buffer.string[j]);
-          width_max = (range.stop - j) + 1;
-          status = f_utf_is_whitespace(buffer.string + j, width_max);
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-            return status;
-          }
-
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i <= j; i += width_i) {
-              if (!buffer.string[i]) {
-                width_i = 1;
-                continue;
-              }
+    if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not;
 
-              width_i = f_macro_utf_byte_width(buffer.string[i]);
+    f_string_length_t length = (range.stop - range.start) + 1;
 
-              for (uint8_t k = 0; k < width_i; k++) {
-                if (!fputc(buffer.string[i + k], output)) return F_status_set_error(F_output);
-              } // for
-            } // for
+    if (length + range.start > buffer.used) {
+      length = buffer.used - range.start;
+    }
 
-            break;
-          }
-        } // for
-
-        if (status == F_true) {
-          break;
-        }
-      }
-
-      for (uint8_t k = 0; k < width_i; k++) {
-        if (!fputc(buffer.string[i + k], output)) return F_status_set_error(F_output);
-      } // for
-    } // for
-
-    return F_none;
+    return private_fl_print_trim_except(output, buffer.string, range.start, range.start + length, except);
   }
-#endif // _di_fl_print_trim_string_dynamic_partial_
+#endif // _di_fl_print_trim_except_dynamic_partial_
 
-#ifndef _di_fl_print_trim_utf_string_
-  f_return_status fl_print_trim_utf_string(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length) {
+#ifndef _di_fl_print_trim_except_utf_
+  f_return_status fl_print_trim_except_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length, const f_utf_string_lengths_t except) {
     #ifndef _di_level_1_parameter_checking_
-      if (!string) return F_status_set_error(F_parameter);
-      if (length < 1) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_string_length_t i = 0;
-    f_status_t status = F_none;
-
-    for (; i < length; i++) {
-      status = f_utf_character_is_whitespace(string[i]);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_false) break;
-    } // for
-
-    for (; i < length; i++) {
-      if (!string[i]) continue;
-
-      status = f_utf_character_is_whitespace(string[i]);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_true) {
-        f_string_length_t j = i + 1;
-
-        if (j == length) return F_none;
+    if (!string || !length) return F_data_not;
 
-        for (; j < length; j++) {
-          status = f_utf_character_is_whitespace(string[j]);
-
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-            return status;
-          }
-
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i < j; i++) {
-              if (!string[i]) continue;
-
-              if (!fputc(string[i], output)) return F_status_set_error(F_output);
-            } // for
-
-            break;
-          }
-        } // for
-
-        if (status == F_true) break;
-      }
-
-      if (!fputc(string[i], output)) return F_status_set_error(F_output);
-    } // for
-
-    return F_none;
+    return private_fl_print_trim_except_utf(output, string, 0, length, except);
   }
-#endif // _di_fl_print_trim_utf_string_
+#endif // _di_fl_print_trim_except_utf_
 
-#ifndef _di_fl_print_trim_utf_string_dynamic_
-  f_return_status fl_print_trim_utf_string_dynamic(FILE *output, const f_utf_string_static_t buffer) {
+#ifndef _di_fl_print_trim_except_utf_dynamic_
+  f_return_status fl_print_trim_except_utf_dynamic(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_lengths_t except) {
     #ifndef _di_level_1_parameter_checking_
-      if (!buffer.used) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_utf_string_length_t i = 0;
-    f_status_t status = F_none;
-
-    for (; i < buffer.used; i++) {
-      status = f_utf_character_is_whitespace(buffer.string[i]);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_false) break;
-    } // for
-
-    for (; i < buffer.used; i++) {
-      if (!buffer.string[i]) continue;
+    if (!buffer.used) return F_data_not;
 
-      status = f_utf_character_is_whitespace(buffer.string[i]);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
-
-        return status;
-      }
-
-      if (status == F_true) {
-        f_string_length_t j = i + 1;
-
-        if (j == buffer.used) return F_none;
-
-        for (; j < buffer.used; j++) {
-          status = f_utf_character_is_whitespace(buffer.string[j]);
+    return private_fl_print_trim_except_utf(output, buffer.string, 0, buffer.used, except);
+  }
+#endif // _di_fl_print_trim_except_utf_dynamic_
 
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+#ifndef _di_fl_print_trim_except_utf_dynamic_partial_
+  f_return_status fl_print_trim_except_utf_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range, const f_utf_string_lengths_t except) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-            return status;
-          }
+    if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not;
 
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i < j; i++) {
-              if (!buffer.string[i]) continue;
+    f_string_length_t length = (range.stop - range.start) + 1;
 
-              if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-            } // for
+    if (length + range.start > buffer.used) {
+      length = buffer.used - range.start;
+    }
 
-            break;
-          }
-        } // for
+    return private_fl_print_trim_except_utf(output, buffer.string, range.start, range.start + length, except);
+  }
+#endif // _di_fl_print_trim_except_utf_dynamic_partial_
 
-        if (status == F_true) {
-          break;
-        }
-      }
+#ifndef _di_fl_print_trim_
+  f_return_status fl_print_trim(FILE *output, const f_string_t string, const f_string_length_t length) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-      if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-    } // for
+    if (!string || !length) return F_data_not;
 
-    return F_none;
+    return private_fl_print_trim(output, string, length);
   }
-#endif // _di_fl_print_trim_utf_string_dynamic_
+#endif // _di_fl_print_trim_
 
-#ifndef _di_fl_print_trim_utf_string_dynamic_partial_
-  f_return_status fl_print_trim_utf_string_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range) {
+#ifndef _di_fl_print_trim_dynamic_
+  f_return_status fl_print_trim_dynamic(FILE *output, const f_string_static_t buffer) {
     #ifndef _di_level_1_parameter_checking_
-      if (range.start < 0) return F_status_set_error(F_parameter);
-      if (range.stop < range.start) return F_status_set_error(F_parameter);
-      if (!buffer.used) return F_status_set_error(F_parameter);
-      if (range.start >= buffer.used) return F_status_set_error(F_parameter);
-      if (range.stop >= buffer.used) return F_status_set_error(F_parameter);
+      if (!output) return F_status_set_error(F_parameter);
     #endif // _di_level_1_parameter_checking_
 
-    register f_string_length_t i = range.start;
-    f_status_t status = F_none;
-
-    for (; i <= range.stop; i++) {
-      status = f_utf_character_is_whitespace(buffer.string[i]);
-
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+    if (!buffer.used) return F_data_not;
 
-        return status;
-      }
+    return private_fl_print_trim(output, buffer.string, buffer.used);
+  }
+#endif // _di_fl_print_trim_dynamic_
 
-      if (status == F_false) break;
-    } // for
+#ifndef _di_fl_print_trim_dynamic_partial_
+  f_return_status fl_print_trim_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-    for (; i <= range.stop; i++) {
-      if (!buffer.string[i]) continue;
+    if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not;
 
-      status = f_utf_character_is_whitespace(buffer.string[i]);
+    f_string_length_t length = (range.stop - range.start) + 1;
 
-      if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+    if (length + range.start > buffer.used) {
+      length = buffer.used - range.start;
+    }
 
-        return status;
-      }
+    return private_fl_print_trim(output, buffer.string + range.start, length);
+  }
+#endif // _di_fl_print_trim_dynamic_partial_
 
-      if (status == F_true) {
-        f_string_length_t j = i + 1;
+#ifndef _di_fl_print_trim_utf_
+  f_return_status fl_print_trim_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-        if (j == range.stop) return F_none;
+    if (!string || !length) return F_data_not;
 
-        for (; j <= range.stop; j++) {
-          status = f_utf_character_is_whitespace(buffer.string[j]);
+    return private_fl_print_trim_utf(output, string, length);
+  }
+#endif // _di_fl_print_trim_utf_
 
-          if (F_status_is_error(status)) {
-            if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+#ifndef _di_fl_print_trim_utf_dynamic_
+  f_return_status fl_print_trim_utf_dynamic(FILE *output, const f_utf_string_static_t buffer) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-            return status;
-          }
+    if (!buffer.used) return F_data_not;
 
-          // all whitespaces found so far must be printed when a non-whitespace is found.
-          if (status == F_false) {
-            for (; i <= j; i++) {
-              if (!buffer.string[i]) continue;
+    return private_fl_print_trim_utf(output, buffer.string, buffer.used);
+  }
+#endif // _di_fl_print_trim_utf_dynamic_
 
-              if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-            } // for
+#ifndef _di_fl_print_trim_utf_dynamic_partial_
+  f_return_status fl_print_trim_utf_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range) {
+    #ifndef _di_level_1_parameter_checking_
+      if (!output) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-            break;
-          }
-        } // for
+    if (!buffer.used || range.start > range.stop || range.start >= buffer.used) return F_data_not;
 
-        if (status == F_true) break;
-      }
+    f_string_length_t length = (range.stop - range.start) + 1;
 
-      if (!fputc(buffer.string[i], output)) return F_status_set_error(F_output);
-    } // for
+    if (length + range.start > buffer.used) {
+      length = buffer.used - range.start;
+    }
 
-    return F_none;
+    return private_fl_print_trim_utf(output, buffer.string + range.start, length);
   }
-#endif // _di_fl_print_trim_utf_string_dynamic_partial_
+#endif // _di_fl_print_trim_utf_dynamic_partial_
 
 #ifdef __cplusplus
 } // extern "C"
index 0683a3ac905665b438830f4db34d8b38644b55bb..6fbd6521e86cd65f278233f4bff89dfcb5890838 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
  *
  * Will not stop at \0.
  * Will not print \0.
+ * Will not print any 1-byte character at a location specified in except array.
  *
  * @param output
  *   The file to output to, including standard streams such as stdout and stderr.
@@ -38,9 +39,13 @@ extern "C" {
  *   The string to output.
  * @param length
  *   The total number of characters to print.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -48,9 +53,9 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_is_whitespace().
  */
-#ifndef _di_fl_print_trim_string_
-  extern f_return_status fl_print_trim_string(FILE *output, const f_string_t string, const f_string_length_t length);
-#endif // _di_fl_print_trim_string_
+#ifndef _di_fl_print_trim_except_
+  extern f_return_status fl_print_trim_except(FILE *output, const f_string_t string, const f_string_length_t length, const f_string_lengths_t except);
+#endif // _di_fl_print_trim_except_
 
 /**
  * Print a dynamic string, stripping leading and trailing whitespace.
@@ -60,14 +65,19 @@ extern "C" {
  * Will not stop at \0.
  * Will not print \0.
  * Will print the entire dynamic string, except for leading/trailing whitespace.
+ * Will not print any 1-byte character at a location specified in except array.
  *
  * @param output
  *   The file to output to, including standard streams such as stdout and stderr.
  * @param buffer
  *   The string to output.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -75,9 +85,9 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_is_whitespace().
  */
-#ifndef _di_fl_print_trim_string_dynamic_
-  extern f_return_status fl_print_trim_string_dynamic(FILE *output, const f_string_static_t buffer);
-#endif // _di_fl_print_trim_string_dynamic_
+#ifndef _di_fl_print_trim_except_dynamic_
+  extern f_return_status fl_print_trim_except_dynamic(FILE *output, const f_string_static_t buffer, const f_string_lengths_t except);
+#endif // _di_fl_print_trim_except_dynamic_
 
 /**
  * Print a partial dynamic string, stripping leading and trailing whitespace.
@@ -86,6 +96,7 @@ extern "C" {
  *
  * Will not stop at \0.
  * Will not print \0.
+ * Will not print any 1-byte character at a location specified in except array.
  * Will print the only the buffer range specified by range, except for leading/trailing whitespace.
  *
  * @param output
@@ -94,9 +105,13 @@ extern "C" {
  *   The string to output.
  * @param range
  *   The range within the provided string to print.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -104,9 +119,9 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_is_whitespace().
  */
-#ifndef _di_fl_print_trim_string_dynamic_partial_
-  extern f_return_status fl_print_trim_string_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range);
-#endif // _di_fl_print_trim_string_dynamic_partial_
+#ifndef _di_fl_print_trim_except_dynamic_partial_
+  extern f_return_status fl_print_trim_except_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range, const f_string_lengths_t except);
+#endif // _di_fl_print_trim_except_dynamic_partial_
 
 /**
  * Print a string, stripping leading and trailing whitespace.
@@ -115,6 +130,7 @@ extern "C" {
  *
  * Will not stop at \0.
  * Will not print \0.
+ * Will not print any 1 UTF character at a location specified in except array.
  *
  * @param output
  *   The file to output to, including standard streams such as stdout and stderr.
@@ -122,9 +138,13 @@ extern "C" {
  *   The string to output.
  * @param length
  *   The total number of characters to print.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -132,9 +152,9 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_character_is_whitespace().
  */
-#ifndef _di_fl_print_trim_utf_string_
-  extern f_return_status fl_print_trim_utf_string(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length);
-#endif // _di_fl_print_trim_utf_string_
+#ifndef _di_fl_print_trim_except_utf_
+  extern f_return_status fl_print_trim_except_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length, const f_utf_string_lengths_t except);
+#endif // _di_fl_print_trim_except_utf_
 
 /**
  * Print a dynamic string, stripping leading and trailing whitespace.
@@ -143,15 +163,20 @@ extern "C" {
  *
  * Will not stop at \0.
  * Will not print \0.
+ * Will not print any 1 UTF character at a location specified in except array.
  * Will print the entire dynamic string, except for leading/trailing whitespace.
  *
  * @param output
  *   The file to output to, including standard streams such as stdout and stderr.
  * @param buffer
  *   The string to output.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -159,9 +184,9 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_character_is_whitespace().
  */
-#ifndef _di_fl_print_trim_utf_string_dynamic_
-  extern f_return_status fl_print_trim_utf_string_dynamic(FILE *output, const f_utf_string_static_t buffer);
-#endif // _di_fl_print_trim_utf_string_dynamic_
+#ifndef _di_fl_print_trim_except_utf_dynamic_
+  extern f_return_status fl_print_trim_except_utf_dynamic(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_lengths_t except);
+#endif // _di_fl_print_trim_except_utf_dynamic_
 
 /**
  * Print a partial dynamic string, stripping leading and trailing whitespace.
@@ -170,6 +195,7 @@ extern "C" {
  *
  * Will not stop at \0.
  * Will not print \0.
+ * Will not print any 1 UTF character at a location specified in except array.
  * Will print the only the buffer range specified by range, except for leading/trailing whitespace.
  *
  * @param output
@@ -178,9 +204,13 @@ extern "C" {
  *   The string to output.
  * @param range
  *   The range within the provided string to print.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
  *
  * @return
  *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
  *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
  *   F_output (with error bit) on error when printing to output.
  *   F_parameter (with error bit) if a parameter is invalid.
@@ -188,9 +218,183 @@ extern "C" {
  *
  *   Errors (with error bit) from: f_utf_character_is_whitespace().
  */
-#ifndef _di_fl_print_trim_utf_string_dynamic_partial_
-  extern f_return_status fl_print_trim_utf_string_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range);
-#endif // _di_fl_print_trim_utf_string_dynamic_partial_
+#ifndef _di_fl_print_trim_except_utf_dynamic_partial_
+  extern f_return_status fl_print_trim_except_utf_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range, const f_utf_string_lengths_t except);
+#endif // _di_fl_print_trim_except_utf_dynamic_partial_
+
+/**
+ * Print a string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_
+  extern f_return_status fl_print_trim(FILE *output, const f_string_t string, const f_string_length_t length);
+#endif // _di_fl_print_trim_
+
+/**
+ * Print a dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the entire dynamic string, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_dynamic_
+  extern f_return_status fl_print_trim_dynamic(FILE *output, const f_string_static_t buffer);
+#endif // _di_fl_print_trim_dynamic_
+
+/**
+ * Print a partial dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the only the buffer range specified by range, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ * @param range
+ *   The range within the provided string to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_dynamic_partial_
+  extern f_return_status fl_print_trim_dynamic_partial(FILE *output, const f_string_static_t buffer, const f_string_range_t range);
+#endif // _di_fl_print_trim_dynamic_partial_
+
+/**
+ * Print a string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_character_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_utf_
+  extern f_return_status fl_print_trim_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length);
+#endif // _di_fl_print_trim_utf_
+
+/**
+ * Print a dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the entire dynamic string, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_character_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_utf_dynamic_
+  extern f_return_status fl_print_trim_utf_dynamic(FILE *output, const f_utf_string_static_t buffer);
+#endif // _di_fl_print_trim_utf_dynamic_
+
+/**
+ * Print a partial dynamic string, stripping leading and trailing whitespace.
+ *
+ * Except for leading/trailing whitespace, the string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the only the buffer range specified by range, except for leading/trailing whitespace.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ * @param range
+ *   The range within the provided string to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_character_is_whitespace().
+ */
+#ifndef _di_fl_print_trim_utf_dynamic_partial_
+  extern f_return_status fl_print_trim_utf_dynamic_partial(FILE *output, const f_utf_string_static_t buffer, const f_utf_string_range_t range);
+#endif // _di_fl_print_trim_utf_dynamic_partial_
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/level_1/fl_print/c/private-print.c b/level_1/fl_print/c/private-print.c
new file mode 100644 (file)
index 0000000..bc957fd
--- /dev/null
@@ -0,0 +1,384 @@
+#include "print.h"
+#include "private-print.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_)
+  f_return_status private_fl_print_trim_except(FILE *output, const f_string_t string, const f_string_length_t start, const f_string_length_t stop, const f_string_lengths_t except) {
+    register f_string_length_t i = start;
+
+    f_string_length_t j = 0;
+    f_string_length_t e = 0;
+    f_string_length_t ej = 0;
+
+    f_status_t status = F_none;
+    uint8_t width_max = 0;
+
+    while (i < stop) {
+
+      for (; e < except.used && except.array[e] < i; ++e) {
+        // do nothing.
+      } // for
+
+      if (e < except.used && except.array[e] == i) {
+        i++;
+        continue;
+      }
+
+      width_max = (stop - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+
+      i += f_macro_utf_byte_width(string[i]);
+    } // while
+
+    while (i < stop) {
+
+      if (!string[i]) continue;
+
+      for (; e < except.used && except.array[e] < i; ++e) {
+        // do nothing.
+      } // for
+
+      if (e < except.used && except.array[e] == i) {
+        i++;
+        continue;
+      }
+
+      width_max = (stop - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_true) {
+        j = i + f_macro_utf_byte_width(string[i]);
+
+        if (j == stop) return F_none;
+
+        ej = e;
+
+        while (j < stop) {
+
+          for (; ej < except.used && except.array[ej] < j; ++ej) {
+            // do nothing.
+          } // for
+
+          if (ej < except.used && except.array[ej] == j) {
+            j++;
+            continue;
+          }
+
+          width_max = (stop - j) + 1;
+          status = f_utf_is_whitespace(string + j, width_max);
+
+          if (F_status_is_error(status)) {
+            if (F_status_set_fine(status) == F_maybe) {
+              return F_status_set_error(F_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == F_false) {
+            for (; i < j; i++) {
+              if (!string[i]) continue;
+
+              for (; e < except.used && except.array[e] < i; ++e) {
+                // do nothing.
+              } // for
+
+              if (e < except.used && except.array[e] == i) continue;
+
+              if (!fputc(string[i], output)) return F_status_set_error(F_output);
+            } // for
+
+            break;
+          }
+
+          j += f_macro_utf_byte_width(string[j]);
+        } // while
+
+        if (status == F_true) break;
+      }
+
+      if (!fputc(string[i], output)) return F_status_set_error(F_output);
+
+      i += f_macro_utf_byte_width(string[i]);
+    } // while
+
+    return F_none;
+  }
+#endif // !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_)
+
+#if !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_)
+  f_return_status private_fl_print_trim_except_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t start, const f_utf_string_length_t stop, const f_utf_string_lengths_t except) {
+    register f_string_length_t i = start;
+
+    f_string_length_t j = 0;
+    f_string_length_t e = 0;
+    f_string_length_t ej = 0;
+
+    f_status_t status = F_none;
+
+    for (; i < stop; ++i) {
+
+      for (; e < except.used && except.array[e] < i; ++e) {
+        // do nothing.
+      } // for
+
+      if (e < except.used && except.array[e] == i) continue;
+
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+    } // for
+
+    for (; i < stop; ++i) {
+      if (!string[i]) continue;
+
+      for (; e < except.used && except.array[e] < i; ++e) {
+        // do nothing.
+      } // for
+
+      if (e < except.used && except.array[e] == i) continue;
+
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_true) {
+        j = i + 1;
+
+        if (j == stop) return F_none;
+
+        for (ej = e; j < stop; j++) {
+
+          for (; ej < except.used && except.array[ej] < j; ++ej) {
+            // do nothing.
+          } // for
+
+          if (ej < except.used && except.array[ej] == j) continue;
+
+          status = f_utf_character_is_whitespace(string[j]);
+
+          if (F_status_is_error(status)) {
+            if (F_status_set_fine(status) == F_maybe) {
+              return F_status_set_error(F_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == F_false) {
+            for (; i < j; i++) {
+              if (!string[i]) continue;
+
+              for (; e < except.used && except.array[e] < i; ++e) {
+                // do nothing.
+              } // for
+
+              if (e < except.used && except.array[e] == i) continue;
+
+              if (!fputc(string[i], output)) return F_status_set_error(F_output);
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == F_true) break;
+      }
+
+      if (!fputc(string[i], output)) return F_status_set_error(F_output);
+    } // for
+
+    return F_none;
+  }
+#endif // !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_)
+
+#if !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_)
+  f_return_status private_fl_print_trim(FILE *output, const f_string_t string, const f_string_length_t length) {
+    register f_string_length_t i = 0;
+
+    f_string_length_t j = 0;
+
+    f_status_t status = F_none;
+    uint8_t width_max = 0;
+
+    for (; i < length; i += f_macro_utf_byte_width(string[i])) {
+
+      width_max = (length - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+    } // for
+
+    for (; i < length; i += f_macro_utf_byte_width(string[i])) {
+      if (!string[i]) continue;
+
+      width_max = (length - i) + 1;
+      status = f_utf_is_whitespace(string + i, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_true) {
+        j = i + f_macro_utf_byte_width(string[i]);
+
+        if (j == length) return F_none;
+
+        for (; j < length; j += f_macro_utf_byte_width(string[j])) {
+
+          width_max = (length - j) + 1;
+          status = f_utf_is_whitespace(string + j, width_max);
+
+          if (F_status_is_error(status)) {
+            if (F_status_set_fine(status) == F_maybe) {
+              return F_status_set_error(F_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == F_false) {
+            for (; i < j; i++) {
+              if (!string[i]) continue;
+              if (!fputc(string[i], output)) return F_status_set_error(F_output);
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == F_true) break;
+      }
+
+      if (!fputc(string[i], output)) return F_status_set_error(F_output);
+    } // for
+
+    return F_none;
+  }
+#endif // !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_)
+
+#if !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_)
+  f_return_status private_fl_print_trim_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length) {
+    register f_string_length_t i = 0;
+
+    f_string_length_t j = 0;
+
+    f_status_t status = F_none;
+
+    for (; i < length; i++) {
+
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+    } // for
+
+    for (; i < length; i++) {
+      if (!string[i]) continue;
+
+      status = f_utf_character_is_whitespace(string[i]);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+
+        return status;
+      }
+
+      if (status == F_true) {
+        j = i + 1;
+
+        if (j == length) return F_none;
+
+        for (; j < length; j++) {
+
+          status = f_utf_character_is_whitespace(string[j]);
+
+          if (F_status_is_error(status)) {
+            if (F_status_set_fine(status) == F_maybe) {
+              return F_status_set_error(F_utf);
+            }
+
+            return status;
+          }
+
+          // all whitespaces found so far must be printed when a non-whitespace is found.
+          if (status == F_false) {
+            for (; i < j; i++) {
+              if (!string[i]) continue;
+              if (!fputc(string[i], output)) return F_status_set_error(F_output);
+            } // for
+
+            break;
+          }
+        } // for
+
+        if (status == F_true) break;
+      }
+
+      if (!fputc(string[i], output)) return F_status_set_error(F_output);
+    } // for
+
+    return F_none;
+  }
+#endif // !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_1/fl_print/c/private-print.h b/level_1/fl_print/c/private-print.h
new file mode 100644 (file)
index 0000000..45edce2
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ * FLL - Level 1
+ *
+ * Project: Print
+ * 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_FL_print_h
+#define _PRIVATE_FL_print_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation of fl_print_trim_except().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param offset
+ *   The inclusive start point to start printing.
+ * @param stop
+ *   The exclusive stop point to stop printing.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see fl_print_trim_except()
+ * @see fl_print_trim_except_dynamic()
+ * @see fl_print_trim_except_dynamic_partial()
+ */
+#if !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_)
+  extern f_return_status private_fl_print_trim_except(FILE *output, const f_string_t string, const f_string_length_t start, const f_string_length_t stop, const f_string_lengths_t except) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_)
+
+/**
+ * Private implementation of fl_print_trim_except_utf().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param offset
+ *   The inclusive start point to start printing.
+ * @param stop
+ *   The exclusive stop point to stop printing.
+ * @param except
+ *   An array of locations within the given string to not print.
+ *   The array of locations is required/assumed to be in linear order.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_character_is_whitespace().
+ *
+ * @see fl_print_trim_except_utf()
+ * @see fl_print_trim_except_utf_dynamic()
+ * @see fl_print_trim_except_utf_dynamic_partial()
+ */
+#if !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_)
+  extern f_return_status private_fl_print_trim_except_utf(FILE *output, const f_utf_string_t string, const f_string_length_t start, const f_utf_string_length_t stop, const f_utf_string_lengths_t except) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_)
+
+/**
+ * Private implementation of fl_print_trim().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see fl_print_trim()
+ * @see fl_print_trim_dynamic()
+ * @see fl_print_trim_dynamic_partial()
+ */
+#if !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_)
+  extern f_return_status private_fl_print_trim(FILE *output, const f_string_t string, const f_string_length_t length) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_)
+
+/**
+ * Private implementation of fl_print_trim_utf().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param string
+ *   The string to output.
+ * @param length
+ *   The total number of characters to print.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success but there is nothing to print.
+ *   F_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment.
+ *   F_output (with error bit) on error when printing to output.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_utf (with error bit) if character is an invalid UTF-8 character.
+ *
+ *   Errors (with error bit) from: f_utf_character_is_whitespace().
+ *
+ * @see fl_print_trim_utf()
+ * @see fl_print_trim_utf_dynamic()
+ * @see fl_print_trim_utf_dynamic_partial()
+ */
+#if !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_)
+  extern f_return_status private_fl_print_trim_utf(FILE *output, const f_utf_string_t string, const f_utf_string_length_t length) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_FL_print_h
index dcfb1804152e031b7cf99682b6e85308aced95ae..f32b4670ce4c1801864c885ceba89f0d46fd7b0e 100644 (file)
@@ -20,7 +20,7 @@ build_indexer ar
 build_language c
 build_libraries -lc
 build_libraries-individual -lf_conversion -lf_memory -lf_print -lf_utf
-build_sources_library print.c
+build_sources_library print.c private-print.c
 build_sources_program
 build_sources_headers print.h
 build_sources_script
index cd27d983ff812126aa3daf35b3952b4d05cfcfb1..325e5e057403b308d9afc3bcc283937c70858765 100644 (file)
@@ -108,6 +108,279 @@ extern "C" {
   }
 #endif // !defined(_di_fl_string_compare_) || !defined(_di_fl_string_dynamic_compare_) || !defined(_di_fl_string_dynamic_partial_compare_)
 
+#if !defined(_di_fl_string_compare_except_) || !defined(_di_fl_string_dynamic_compare_except_) || !defined(_di_fl_string_dynamic_partial_compare_except_)
+  f_return_status private_fl_string_compare_except(const f_string_t string1, const f_string_t string2, const f_string_length_t offset1, const f_string_length_t offset2, const f_string_length_t stop1, const f_string_length_t stop2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    f_string_length_t i1 = offset1;
+    f_string_length_t i2 = offset2;
+
+    f_string_length_t e1 = 0;
+    f_string_length_t e2 = 0;
+
+    while (i1 < stop1 && i2 < stop2) {
+
+      // skip past NULL in string1.
+      while (i1 < stop1 && !string1[i1]) i1++;
+      if (i1 == stop1) break;
+
+      // skip past NULL in string2.
+      while (i2 < stop2 && !string2[i2]) i2++;
+      if (i2 == stop2) break;
+
+      // skip past except characters in string1.
+      while (e1 < except1.used && except1.array[e1] < i1) e1++;
+      if (e1 < except1.used && except1.array[e1] == i1) {
+        i1++;
+        continue;
+      }
+
+      // skip past except characters in string2.
+      while (e2 < except2.used && except2.array[e2] < i2) e2++;
+      if (e2 < except2.used && except2.array[e2] == i2) {
+        i2++;
+        continue;
+      }
+
+      if (string1[i1] != string2[i2]) return F_equal_to_not;
+
+      i1++;
+      i2++;
+    } // while
+
+    // only return F_equal_to if all remaining characters are NULL or are designated to be ignored.
+    for (; i1 < stop1; i1++) {
+
+      // skip past except characters in string1.
+      while (e1 < except1.used && except1.array[e1] < i1) e1++;
+      if (e1 < except1.used && except1.array[e1] == i1) continue;
+
+      if (string1[i1] != 0) return F_equal_to_not;
+    } // for
+
+    for (; i2 < stop2; i2++) {
+
+      // skip past except characters in string2.
+      while (e2 < except2.used && except2.array[e2] < i2) e2++;
+      if (e2 < except2.used && except2.array[e2] == i2) continue;
+
+      if (string2[i2] != 0) return F_equal_to_not;
+    } // for
+
+    return F_equal_to;
+  }
+#endif // !defined(_di_fl_string_compare_except_) || !defined(_di_fl_string_dynamic_compare_except_) || !defined(_di_fl_string_dynamic_partial_compare_except_)
+
+#if !defined(_di_fl_string_compare_except_trim_) || !defined(_di_fl_string_dynamic_compare_except_trim_) || !defined(_di_fl_string_dynamic_partial_compare_except_trim_)
+  f_return_status private_fl_string_compare_except_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t offset1, const f_string_length_t offset2, const f_string_length_t stop1, const f_string_length_t stop2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    f_string_length_t i1 = offset1;
+    f_string_length_t i2 = offset2;
+
+    f_string_length_t e1 = 0;
+    f_string_length_t e2 = 0;
+
+    uint8_t width = 0;
+    uint8_t width_max = 0;
+    f_status_t status = F_none;
+
+    // skip past leading whitespace in string1.
+    for (; i1 < stop1; i1 += width) {
+
+      // skip past NULL in string1.
+      while (i1 < stop1 && !string1[i1]) i1++;
+      if (i1 == stop1) break;
+
+      // skip past except characters in string1.
+      while (e1 < except1.used && except1.array[e1] < i1) e1++;
+      if (e1 < except1.used && except1.array[e1] == i1) {
+        width = 1;
+        continue;
+      }
+
+      width_max = (stop1 - i1) + 1;
+      status = f_utf_is_whitespace(string1 + i1, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+
+      width = f_macro_utf_byte_width(string1[i1]);
+    } // for
+
+    // skip past leading whitespace in string2.
+    for (; i2 < stop2; i2 += width) {
+
+      // skip past NULL in string2.
+      while (i2 < stop2 && !string2[i2]) i2++;
+      if (i2 == stop2) break;
+
+      // skip past except characters in string2.
+      while (e2 < except2.used && except2.array[e2] < i2) e2++;
+      if (e2 < except2.used && except2.array[e2] == i2) {
+        width = 1;
+        continue;
+      }
+
+      width_max = (stop2 - i2) + 1;
+      status = f_utf_is_whitespace(string2 + i2, width_max);
+
+      if (F_status_is_error(status)) {
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
+
+        return status;
+      }
+
+      if (status == F_false) break;
+
+      width = f_macro_utf_byte_width(string2[i2]);
+    } // for
+
+    f_string_length_t last1 = i1;
+    f_string_length_t last2 = i2;
+
+    {
+      // size1 and size2 are to represent to total number of characters after trim.
+      f_string_length_t size1 = 0;
+      f_string_length_t size2 = 0;
+
+      f_string_length_t ej = e1;
+
+      // determine where the last non-whitespace is in string1.
+      for (f_string_length_t j = i1; j < stop1; j += width) {
+
+        // skip past NULL in string1.
+        while (j < stop1 && !string1[j]) j++;
+        if (j == stop1) break;
+
+        // skip past except characters in string1.
+        while (ej < except1.used && except1.array[ej] < j) ej++;
+        if (ej < except1.used && except1.array[ej] == j) {
+          width = 1;
+          continue;
+        }
+
+        width_max = (stop1 - j) + 1;
+        status = f_utf_is_whitespace(string1 + j, width_max);
+
+        if (F_status_is_error(status)) {
+          if (F_status_set_fine(status) == F_maybe) {
+            return F_status_set_error(F_utf);
+          }
+
+          return status;
+        }
+
+        width = f_macro_utf_byte_width(string1[j]);
+
+        if (status == F_false) {
+          last1 = j;
+          size1++;
+        }
+      } // for
+
+      ej = e2;
+
+      // determine where the last non-whitespace is in string2.
+      for (f_string_length_t j = i2; j < stop2; j += width) {
+
+        // skip past NULL in string2.
+        while (j < stop2 && !string2[j]) j++;
+        if (j == stop2) break;
+
+        // skip past except characters in string2.
+        while (ej < except2.used && except2.array[ej] < j) ej++;
+        if (ej < except2.used && except2.array[ej] == j) {
+          width = 1;
+          continue;
+        }
+
+        width_max = (stop2 - j) + 1;
+        status = f_utf_is_whitespace(string2 + j, width_max);
+
+        if (F_status_is_error(status)) {
+          if (F_status_set_fine(status) == F_maybe) {
+            return F_status_set_error(F_utf);
+          }
+
+          return status;
+        }
+
+        width = f_macro_utf_byte_width(string2[j]);
+
+        if (status == F_false) {
+          last2 = j;
+          size2++;
+        }
+      } // for
+
+      if (size1 != size2) return F_equal_to_not;
+    }
+
+    while (i1 < last1 && i2 < last2) {
+
+      // skip past NULL in string1.
+      while (i1 < last1 && !string1[i1]) i1++;
+      if (i1 == last1) break;
+
+      // skip past NULL in string2.
+      while (i2 < last2 && !string2[i2]) i2++;
+      if (i2 == last2) break;
+
+      // skip past except characters in string1.
+      while (e1 < except1.used && except1.array[e1] < i1) e1++;
+      if (e1 < except1.used && except1.array[e1] == i1) {
+        i1++;
+        continue;
+      }
+
+      // skip past except characters in string2.
+      while (e2 < except2.used && except2.array[e2] < i2) e2++;
+      if (e2 < except2.used && except2.array[e2] == i2) {
+        i2++;
+        continue;
+      }
+
+      if (string1[i1] != string2[i2]) return F_equal_to_not;
+
+      i1++;
+      i2++;
+    } // while
+
+    // only return F_equal_to if all remaining characters are NULL.
+    for (; i1 < last1; i1++) {
+
+      if (string1[i1] != 0) {
+
+        // skip past except characters in string1.
+        while (e1 < except1.used && except1.array[e1] < i1) e1++;
+        if (e1 < except1.used && except1.array[e1] == i1) continue;
+
+        return F_equal_to_not;
+      }
+    } // for
+
+    for (; i2 < last2; i2++) {
+
+      if (string2[i2] != 0) {
+
+        // skip past except characters in string1.
+        while (e2 < except2.used && except2.array[e2] < i2) e2++;
+        if (e2 < except2.used && except2.array[e2] == i2) continue;
+
+        return F_equal_to_not;
+      }
+    } // for
+
+    return F_equal_to;
+  }
+#endif // !defined(_di_fl_string_compare_except_trim_) || !defined(_di_fl_string_dynamic_compare_except_trim_) || !defined(_di_fl_string_dynamic_partial_compare_except_trim_)
+
 #if !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_)
   f_return_status private_fl_string_compare_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t offset1, const f_string_length_t offset2, const f_string_length_t stop1, const f_string_length_t stop2) {
     f_string_length_t i1 = offset1;
@@ -128,7 +401,9 @@ extern "C" {
       status = f_utf_is_whitespace(string1 + i1, width_max);
 
       if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
 
         return status;
       }
@@ -149,7 +424,9 @@ extern "C" {
       status = f_utf_is_whitespace(string2 + i2, width_max);
 
       if (F_status_is_error(status)) {
-        if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+        if (F_status_set_fine(status) == F_maybe) {
+          return F_status_set_error(F_utf);
+        }
 
         return status;
       }
@@ -178,7 +455,9 @@ extern "C" {
         status = f_utf_is_whitespace(string1 + j, width_max);
 
         if (F_status_is_error(status)) {
-          if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+          if (F_status_set_fine(status) == F_maybe) {
+            return F_status_set_error(F_utf);
+          }
 
           return status;
         }
@@ -202,7 +481,9 @@ extern "C" {
         status = f_utf_is_whitespace(string2 + j, width_max);
 
         if (F_status_is_error(status)) {
-          if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf);
+          if (F_status_set_fine(status) == F_maybe) {
+            return F_status_set_error(F_utf);
+          }
 
           return status;
         }
index ee9aab0a806229f6cb91071733578218b7128b2e..824bd90080e37ca8a3532d9dd540941c29035ff1 100644 (file)
@@ -105,6 +105,82 @@ extern "C" {
 #endif // !defined(_di_fl_string_compare_) || !defined(_di_fl_string_dynamic_compare_) || !defined(_di_fl_string_dynamic_partial_compare_)
 
 /**
+ * Private implementation of fl_string_compare_except().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param offset1
+ *   Offset of string1 to start at.
+ * @param offset2
+ *   Offset of string2 to start at.
+ * @param stop1
+ *   Exclusive stop position for string1.
+ * @param stop2
+ *   Exclusive stop position for string2.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see fl_string_compare_except()
+ * @see fl_string_dynamic_compare_except()
+ * @see fl_string_dynamic_partial_compare_except()
+ */
+#if !defined(_di_fl_string_compare_except_) || !defined(_di_fl_string_dynamic_compare_except_) || !defined(_di_fl_string_dynamic_partial_compare_except_)
+  extern f_return_status private_fl_string_compare_except(const f_string_t string1, const f_string_t string2, const f_string_length_t offset1, const f_string_length_t offset2, const f_string_length_t stop1, const f_string_length_t stop2, const f_string_lengths_t except1, const f_string_lengths_t except2) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_string_compare_except_) || !defined(_di_fl_string_dynamic_compare_except_) || !defined(_di_fl_string_dynamic_partial_compare_except_)
+
+/**
+ * Private implementation of fl_string_compare_except_trim().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param offset1
+ *   Offset of string1 to start at.
+ * @param offset2
+ *   Offset of string2 to start at.
+ * @param stop1
+ *   Exclusive stop position for string1.
+ * @param stop2
+ *   Exclusive stop position for string2.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see fl_string_compare_except_trim()
+ * @see fl_string_dynamic_compare_except_trim()
+ * @see fl_string_dynamic_partial_compare_except_trim()
+ */
+#if !defined(_di_fl_string_compare_except_trim_) || !defined(_di_fl_string_dynamic_compare_except_trim_) || !defined(_di_fl_string_dynamic_partial_compare_except_trim_)
+  extern f_return_status private_fl_string_compare_except_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t offset1, const f_string_length_t offset2, const f_string_length_t stop1, const f_string_length_t stop2, const f_string_lengths_t except1, const f_string_lengths_t except2) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fl_string_compare_except_trim_) || !defined(_di_fl_string_dynamic_compare_except_trim_) || !defined(_di_fl_string_dynamic_partial_compare_except_trim_)
+
+/**
  * Private implementation of fl_string_compare_trim().
  *
  * Intended to be shared to each of the different implementation variations.
index 0300ce835a7d4cc4f21f4bcbefb3b5e7f3b86c11..0f6816cb98a419d679d1a88d05dfcec4a09a5c9a 100644 (file)
@@ -108,6 +108,18 @@ extern "C" {
   }
 #endif // _di_fl_string_compare_
 
+#ifndef _di_fl_string_compare_except_
+  f_return_status fl_string_compare_except(const f_string_t string1, const f_string_t string2, const f_string_length_t length1, const f_string_length_t length2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except(string1, string2, 0, 0, length1, length2, except1, except2);
+  }
+#endif // _di_fl_string_compare_except_
+
+#ifndef _di_fl_string_compare_except_trim_
+  f_return_status fl_string_compare_except_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t length1, const f_string_length_t length2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except_trim(string1, string2, 0, 0, length1, length2, except1, except2);
+  }
+#endif // _di_fl_string_compare_except_trim_
+
 #ifndef _di_fl_string_compare_trim_
   f_return_status fl_string_compare_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t length1, const f_string_length_t length2) {
     return private_fl_string_compare_trim(string1, string2, 0, 0, length1, length2);
@@ -220,6 +232,30 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_compare_
 
+#ifndef _di_fl_string_dynamic_compare_except_
+  f_return_status fl_string_dynamic_compare_except(const f_string_static_t string1, const f_string_static_t string2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except(string1.string, string2.string, 0, 0, string1.used, string2.used, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_compare_except_
+
+#ifndef _di_fl_string_dynamic_compare_except_string_
+  f_return_status fl_string_dynamic_compare_except_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except(string1, string2.string, 0, 0, length1, string2.used, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_compare_except_string_
+
+#ifndef _di_fl_string_dynamic_compare_except_trim_
+  f_return_status fl_string_dynamic_compare_except_trim(const f_string_static_t string1, const f_string_static_t string2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except_trim(string1.string, string2.string, 0, 0, string1.used, string2.used, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_compare_except_trim_
+
+#ifndef _di_fl_string_dynamic_compare_except_trim_string_
+  f_return_status fl_string_dynamic_compare_except_trim_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    return private_fl_string_compare_except_trim(string1, string2.string, 0, 0, length1, string2.used, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_compare_except_trim_string_
+
 #ifndef _di_fl_string_dynamic_compare_string_
   f_return_status fl_string_dynamic_compare_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1) {
     return private_fl_string_compare(string1, string2.string, 0, 0, length1, string2.used);
@@ -445,6 +481,68 @@ extern "C" {
   }
 #endif // _di_fl_string_dynamic_partial_compare_string_
 
+#ifndef _di_fl_string_dynamic_partial_compare_except_
+  f_return_status fl_string_dynamic_partial_compare_except(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string1.used <= range1.stop) return F_status_set_error(F_parameter);
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except(string1.string, string2.string, range1.start, range2.start, range1.stop + 1, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_
+
+#ifndef _di_fl_string_dynamic_partial_compare_except_dynamic_
+  f_return_status fl_string_dynamic_partial_compare_except_dynamic(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except(string1.string, string2.string, 0, range2.start, string1.used, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_dynamic_
+
+#ifndef _di_fl_string_dynamic_partial_compare_except_string_
+  f_return_status fl_string_dynamic_partial_compare_except_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except(string1, string2.string, 0, range2.start, length1, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_string_
+
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_
+  f_return_status fl_string_dynamic_partial_compare_except_trim(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string1.used <= range1.stop) return F_status_set_error(F_parameter);
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except_trim(string1.string, string2.string, range1.start, range2.start, range1.stop + 1, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_
+
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_dynamic_
+  f_return_status fl_string_dynamic_partial_compare_except_trim_dynamic(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except_trim(string1.string, string2.string, 0, range2.start, string1.used, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_dynamic_
+
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_string_
+  f_return_status fl_string_dynamic_partial_compare_except_trim_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2) {
+    #ifndef _di_level_1_parameter_checking_
+      if (string2.used <= range2.stop) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    return private_fl_string_compare_except_trim(string1, string2.string, 0, range2.start, length1, range2.stop + 1, except1, except2);
+  }
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_string_
+
 #ifndef _di_fl_string_dynamic_partial_compare_trim_
   f_return_status fl_string_dynamic_partial_compare_trim(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2) {
     #ifndef _di_level_1_parameter_checking_
index 5510d1b817efa6feca2cfa226304b5c5b631f39f..c157dc28e7eb8288be3413a33e36287b21ce255e 100644 (file)
@@ -158,6 +158,73 @@ extern "C" {
  *
  * This does not stop on NULL.
  * NULL characters are ignored.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   Length of string1.
+ * @param length2
+ *   Length of string2.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_string_compare_except_
+  extern f_return_status fl_string_compare_except(const f_string_t string1, const f_string_t string2, const f_string_length_t length1, const f_string_length_t length2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_compare_except_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   Length of string1.
+ * @param length2
+ *   Length of string2.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_compare_except_trim_
+  extern f_return_status fl_string_compare_except_trim(const f_string_t string1, const f_string_t string2, const f_string_length_t length1, const f_string_length_t length2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_compare_except_trim_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
  * Ignores leading and trailing whitespace.
  *
  * @param string1
@@ -289,6 +356,137 @@ extern "C" {
 /**
  * Compare two strings, similar to strncmp().
  *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_string_dynamic_compare_except_
+  extern f_return_status fl_string_dynamic_compare_except(const f_string_static_t string1, const f_string_static_t string2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_compare_except_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
+ * This operates with the first string being a traditional string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   The length of string1.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_compare_except_string_
+  extern f_return_status fl_string_dynamic_compare_except_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_compare_except_string_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_compare_except_trim_
+  extern f_return_status fl_string_dynamic_compare_except_trim(const f_string_static_t string1, const f_string_static_t string2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_compare_except_trim_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
+ * This operates with the first string being a traditional string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   The length of string1.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_compare_except_trim_string_
+  extern f_return_status fl_string_dynamic_compare_except_trim_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_compare_except_trim_string_
+
+/**
+ * Compare two strings, similar to strncmp().
+ *
  * This operates with the first string being a traditional string.
  *
  * This does not stop on NULL.
@@ -602,6 +800,207 @@ extern "C" {
 #endif // _di_fl_string_dynamic_partial_compare_
 
 /**
+ * Compare two strings, similar to strncmp(), but restricted to the given ranges.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param range1
+ *   A range within the string1 to restrict the comparison to.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_
+  extern f_return_status fl_string_dynamic_partial_compare_except(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_
+
+/**
+ * Compare two strings, similar to strncmp(), but restricted to the given range for the second string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_dynamic_
+  extern f_return_status fl_string_dynamic_partial_compare_except_dynamic(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_dynamic_
+
+/**
+ * Compare two strings, similar to strncmp(), but restricted to the given range for the second string.
+ *
+ * This operates with the first string being a traditional string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   The length of string1.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_string_
+  extern f_return_status fl_string_dynamic_partial_compare_except_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_string_
+
+/**
+ * Compare two strings, similar to strncmp(), but restricted to the given range for the second string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_dynamic_
+  extern f_return_status fl_string_dynamic_partial_compare_except_trim_dynamic(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_dynamic_
+
+/**
+ * Compare two strings, similar to strncmp(), but restricted to the given range for the second string.
+ *
+ * This operates with the first string being a traditional string.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param length1
+ *   The length of string1.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_string_
+  extern f_return_status fl_string_dynamic_partial_compare_except_trim_string(const f_string_t string1, const f_string_static_t string2, const f_string_length_t length1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_string_
+
+/**
+ * Compare two strings, similar to strncmp(), but restricted to the given ranges.
+ *
+ * This does not stop on NULL.
+ * NULL characters are ignored.
+ * Ignores leading and trailing whitespace.
+ * All 1-byte characters in except1 and except2 are ignored.
+ *
+ * @param string1
+ *   String to compare.
+ * @param string2
+ *   String to compare.
+ * @param range1
+ *   A range within the string1 to restrict the comparison to.
+ * @param range2
+ *   A range within the string2 to restrict the comparison to.
+ * @param except1
+ *   A set of locations within string1 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ * @param except2
+ *   A set of locations within string2 to ignore.
+ *   This assumes/requires that the locations be in linear order.
+ *
+ * @return
+ *   F_equal_to when both strings equal.
+ *   F_equal_to_not when both strings do not equal.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_utf_is_whitespace().
+ *
+ * @see f_utf_is_whitespace()
+ */
+#ifndef _di_fl_string_dynamic_partial_compare_except_trim_
+  extern f_return_status fl_string_dynamic_partial_compare_except_trim(const f_string_static_t string1, const f_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_string_lengths_t except1, const f_string_lengths_t except2);
+#endif // _di_fl_string_dynamic_partial_compare_except_trim_
+
+/**
  * Compare two strings, similar to strncmp(), but restricted to the given range for the second string.
  *
  * This does not stop on NULL.