]> Kevux Git Server - fll/commitdiff
Bugfix: The print safely functions are not fully UTF-8 aware.
authorKevin Day <thekevinday@gmail.com>
Sat, 13 Nov 2021 16:07:53 +0000 (10:07 -0600)
committerKevin Day <thekevinday@gmail.com>
Sat, 13 Nov 2021 16:07:53 +0000 (10:07 -0600)
The f_print_character_safely_get() can only handle a single byte.
This makes it impossible to be UTF-8 aware.

Provide a new function f_print_safely_get() that accepts a string and a max width.
This string is intended to represent a single character, but can be multi-byte based on max width.
This function checks to see if the character is invalid or a control character, in which case it is replaced.

level_0/f_print/c/print.c
level_0/f_print/c/print.h
level_0/f_print/c/print_to.c
level_0/f_print/c/private-print.c
level_0/f_print/c/private-print.h
level_0/f_print/c/private-print_to.c

index 53bec2c23991e82c11e84b91d2b4d42353bb0dec..e8cc5c60fef7596e146d591e1d9c68019b88e4e0 100644 (file)
@@ -51,7 +51,7 @@ extern "C" {
     }
     else if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) {
       if (fwrite_unlocked(&character, 1, 1, output) != -1) {
-        return F_none;
+        return F_utf;
       }
     }
     else {
@@ -491,6 +491,12 @@ extern "C" {
   }
 #endif // _di_f_print_safely_
 
+#ifndef _di_f_print_safely_get_
+  f_string_t f_print_safely_get(const f_string_t character, const f_array_length_t width_max) {
+    return private_f_print_safely_get(character, width_max);
+  }
+#endif // _di_f_print_safely_get_
+
 #ifndef _di_f_print_safely_terminated_
   f_status_t f_print_safely_terminated(const f_string_t string, FILE *output) {
     #ifndef _di_level_0_parameter_checking_
@@ -501,8 +507,6 @@ extern "C" {
       return F_data_not;
     }
 
-    f_status_t status = F_none;
-
     f_array_length_t start = 0;
     f_array_length_t total = 0;
 
@@ -512,133 +516,67 @@ extern "C" {
 
     for (register f_array_length_t i = 0; string[i]; ) {
 
-      width = macro_f_utf_character_t_width_is(string[i]);
-
-      if (width) {
-        if (width > 1) {
-          if (string[i + 1]) {
-            if (width > 2) {
-              if (string[i + 2]) {
-                if (width > 3) {
-                  if (string[i + 3]) {
-                    status = f_utf_is_control(string + i, 4);
-                  }
-                  else {
-                    status = F_utf;
-                  }
-                }
-                else {
-                  status = f_utf_is_control(string + i, 3);
+      safe = 0;
+      width = macro_f_utf_character_t_width(string[i]);
+
+      if (width > 1) {
+        if (string[i + 1]) {
+          if (width > 2) {
+            if (string[i + 2]) {
+              if (width > 3) {
+                if (!string[i + 3]) {
+                  safe = (f_string_t) f_print_sequence_unknown_s;
                 }
               }
-              else {
-                status = F_utf;
-              }
             }
             else {
-              status = f_utf_is_control(string + i, 2);
+              safe = (f_string_t) f_print_sequence_unknown_s;
             }
           }
-          else {
-            status = F_utf;
-          }
         }
         else {
-          status = f_utf_is_control(string + i, 1);
-        }
-
-        if (status == F_false && total + width < F_print_write_max_d) {
-          total += width;
-          i += width;
-
-          continue;
+          safe = (f_string_t) f_print_sequence_unknown_s;
         }
       }
-      else {
-        if ((string[i] > 0x1f && string[i] != 0x7f) && total < F_print_write_max_d) {
-          ++total;
-          ++i;
 
-          continue;
-        }
-
-        status = F_none;
+      if (!safe) {
+        safe = private_f_print_safely_get(string + i, width);
       }
 
-      if (total) {
-        if (fwrite_unlocked(string + start, 1, total, output) == -1) {
-          return F_status_set_error(F_output);
-        }
-
-        total = 0;
-      }
+      if (safe) {
+        if (total) {
+          if (fwrite_unlocked(string + start, 1, total, output) == -1) {
+            return F_status_set_error(F_output);
+          }
 
-      if (status == F_true || F_status_set_fine(status) == F_utf) {
-        if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) != -1) {
-          return F_status_set_error(F_output);
+          total = 0;
         }
 
-        for (start = 0; string[start] && start < width; ) {
-          ++start;
-        } // while
-
-        if (start != width) break;
-
-        i += width;
-      }
-      else if (status == F_false) {
-        if (fwrite_unlocked(string + start, 1, width, output) == -1) {
+        if (fwrite_unlocked(safe, 1, 3, output) == -1) {
           return F_status_set_error(F_output);
         }
 
-        for (start = 0; string[start] && start < width; ) {
-          ++start;
-        } // while
-
-        if (start != width) break;
-
         i += width;
+        start = i;
+        continue;
       }
-      else {
-        safe = private_f_print_character_safely_get(string[i]);
 
-        if (safe) {
-          if (fwrite_unlocked(safe, 1, 3, output) == -1) {
+      if (total + width >= F_print_write_max_d) {
+        if (total) {
+          if (fwrite_unlocked(string + start, 1, total, output) == -1) {
             return F_status_set_error(F_output);
           }
-        }
-        else {
-          status = f_utf_is_valid(string + i, width);
-
-          if (F_status_is_error(status) || status == F_false) {
-            if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) {
-              return F_status_set_error(F_output);
-            }
-
-            for (start = 0; string[start] && start < width; ) {
-              ++start;
-            } // while
 
-            if (start != width) break;
-          }
-          else {
-            for (start = 0; string[start] && start < width; ) {
-              ++start;
-            } // while
-
-            if (start != width) break;
-
-            total = width;
-            start = i;
-            i += width;
-            continue;
-          }
+          total = 0;
         }
 
         i += width;
+        start = i - 1;
+        continue;
       }
 
-      start = i;
+      total += width;
+      i += width;
     } // for
 
     if (total) {
index 23799cbb508aa3aeb743f20737c28d7f6c2d1520..480df703dae9912b1873030c668bb15e30211a93 100644 (file)
@@ -95,6 +95,9 @@ extern "C" {
  * UTF-8 sequences with invalid widths are converted to the unknown character '�'.
  * This can result in the 1-byte character being substituted with a 3-byte character when printing.
  *
+ * For UTF-8 characters, this cannot detect if the UTF-8 character is a control or anything else.
+ * This is, in genereal, not safe for printing UTF-8 characters given that a character is 1-byte.
+ *
  * This should only be called for the first 1-byte character of a multibyte character.
  *
  * @param character
@@ -104,6 +107,7 @@ extern "C" {
  *
  * @return
  *   F_none on success.
+ *   F_utf on success, but character is a UTF-8 character.
  *   F_data_not if there is nothing to print.
  *
  *   F_output (with error bit) on failure.
@@ -1094,6 +1098,34 @@ extern "C" {
 #endif // _di_f_print_safely_
 
 /**
+ * Get a safe representation of the character if the character is considered unsafe.
+ *
+ * Control characters are converted to the Unicode control character symbols, including NULL.
+ * UTF-8 sequences with a width of 1 are converted to the unknown character '�'.
+ * For all other UTF-8 sequences, 0 is returned because it cannot be processed via a single 8-byte character.
+ *
+ * The returned string will either be NULL (for characters that are already safe) or a string representing the replacement.
+ * This can result in a 3-byte character being returned as a string of 3 1-bytes.
+ *
+ * This should only be called for the first 1-byte character of a multibyte character.
+ *
+ * @param character
+ *   The character to verify as safe or not and then print.
+ * @param width_max
+ *   This is set to the max number of bytes available.
+ *   This is then updated to represent the max bytes used if enough space is available.
+ *
+ * @return
+ *   NULL is returned if the character is already safe or if the character has a UTF-8 width of 2 or greater.
+ *   A non-NULL string is returned if the character needs safe replacement.
+ *   The non-NULL strings returned are NULL terminated.
+ *   The non-NULL strings returned are the 3-byte characters used as placeholder symbols.
+ */
+#ifndef _di_f_print_safely_get_
+  extern f_string_t f_print_safely_get(const f_string_t character, const f_array_length_t width_max);
+#endif // _di_f_print_safely_get_
+
+/**
  * Similar to a c-library printf.
  *
  * Control characters are converted to the Unicode control character symbols, excluding NULL.
index fab6fa833561071cd8e4bc4abc13a451a24e48ad..e29f189d0c0a7b0f9989cdf8dd65c621bf67946a 100644 (file)
@@ -506,8 +506,6 @@ static inline f_status_t private_inline_f_print_to_error() {
       return F_data_not;
     }
 
-    f_status_t status = F_none;
-
     f_array_length_t start = 0;
     f_array_length_t total = 0;
 
@@ -517,133 +515,67 @@ static inline f_status_t private_inline_f_print_to_error() {
 
     for (register f_array_length_t i = 0; string[i]; ) {
 
-      width = macro_f_utf_character_t_width_is(string[i]);
-
-      if (width) {
-        if (width > 1) {
-          if (string[i + 1]) {
-            if (width > 2) {
-              if (string[i + 2]) {
-                if (width > 3) {
-                  if (string[i + 3]) {
-                    status = f_utf_is_control(string + i, 4);
-                  }
-                  else {
-                    status = F_utf;
-                  }
-                }
-                else {
-                  status = f_utf_is_control(string + i, 3);
+      safe = 0;
+      width = macro_f_utf_character_t_width(string[i]);
+
+      if (width > 1) {
+        if (string[i + 1]) {
+          if (width > 2) {
+            if (string[i + 2]) {
+              if (width > 3) {
+                if (!string[i + 3]) {
+                  safe = (f_string_t) f_print_sequence_unknown_s;
                 }
               }
-              else {
-                status = F_utf;
-              }
             }
             else {
-              status = f_utf_is_control(string + i, 2);
+              safe = (f_string_t) f_print_sequence_unknown_s;
             }
           }
-          else {
-            status = F_utf;
-          }
         }
         else {
-          status = f_utf_is_control(string + i, 1);
-        }
-
-        if (status == F_false && total + width < F_print_write_max_d) {
-          total += width;
-          i += width;
-
-          continue;
+          safe = (f_string_t) f_print_sequence_unknown_s;
         }
       }
-      else {
-        if ((string[i] > 0x1f && string[i] != 0x7f) && total < F_print_write_max_d) {
-          ++total;
-          ++i;
 
-          continue;
-        }
-
-        status = F_none;
+      if (!safe) {
+        safe = private_f_print_safely_get(string + i, width);
       }
 
-      if (total) {
-        if (write(id, string + start, total) == -1) {
-          return private_inline_f_print_to_error();
-        }
-
-        total = 0;
-      }
+      if (safe) {
+        if (total) {
+          if (write(id, string + start, total) == -1) {
+            return private_inline_f_print_to_error();
+          }
 
-      if (status == F_true || F_status_set_fine(status) == F_utf) {
-        if (write(id, f_print_sequence_unknown_s, 3) == -1) {
-          return private_inline_f_print_to_error();
+          total = 0;
         }
 
-        for (start = 0; string[start] && start < width; ) {
-          ++start;
-        } // while
-
-        if (start != width) break;
-
-        i += width;
-      }
-      else if (status == F_false) {
-        if (write(id, string + start, width) == -1) {
+        if (write(id, safe, 3) == -1) {
           return private_inline_f_print_to_error();
         }
 
-        for (start = 0; string[start] && start < width; ) {
-          ++start;
-        } // while
-
-        if (start != width) break;
-
         i += width;
+        start = i;
+        continue;
       }
-      else {
-        safe = private_f_print_character_safely_get(string[i]);
 
-        if (safe) {
-          if (write(id, safe, 3) == -1) {
+      if (total + width >= F_print_write_max_d) {
+        if (total) {
+          if (write(id, string + start, total) == -1) {
             return private_inline_f_print_to_error();
           }
-        }
-        else {
-          status = f_utf_is_valid(string + i, width);
-
-          if (F_status_is_error(status) || status == F_false) {
-            if (write(id, f_print_sequence_unknown_s, 3) == -1) {
-              return private_inline_f_print_to_error();
-            }
-
-            for (start = 0; string[start] && start < width; ) {
-              ++start;
-            } // while
-
-            if (start != width) break;
-          }
-          else {
-            for (start = 0; string[start] && start < width; ) {
-              ++start;
-            } // while
 
-            if (start != width) break;
-
-            total = width;
-            start = i;
-            i += width;
-            continue;
-          }
+          total = 0;
         }
 
         i += width;
+        start = i - 1;
+        continue;
       }
 
-      start = i;
+      total += width;
+      i += width;
     } // for
 
     if (total) {
index 393124bb30b66a28510de0e5e66f45fd50b2bfb9..8251c4fd8ae1e4496ca0f07584e2ceec22c8c9a7 100644 (file)
@@ -44,10 +44,12 @@ extern "C" {
     if (character == 0x7f) {
       return (f_string_t) f_print_sequence_delete_s;
     }
-    else if (macro_f_utf_character_t_width_is(character) == 1) {
+
+    if (macro_f_utf_character_t_width_is(character) == 1) {
       return (f_string_t) f_print_sequence_unknown_s;
     }
-    else if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) {
+
+    if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) {
       return 0;
     }
 
@@ -302,7 +304,9 @@ extern "C" {
       }
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -317,8 +321,6 @@ extern "C" {
         continue;
       }
 
-      width = macro_f_utf_character_t_width(string[i]);
-
       if (safe) {
         if (total) {
           if (fwrite_unlocked(string + start, 1, total, output) == -1) {
@@ -337,33 +339,6 @@ extern "C" {
         continue;
       }
 
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false || i + width >= stop) {
-        if (total) {
-          if (fwrite_unlocked(string + start, 1, total, output) == -1) {
-            return F_status_set_error(F_output);
-          }
-
-          total = 0;
-        }
-
-        if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) {
-          return F_status_set_error(F_output);
-        }
-
-        if (F_status_is_error(status) || status == F_false) {
-          i += width;
-          start = i;
-        }
-        else {
-          i = stop;
-          start = stop;
-        }
-
-        continue;
-      }
-
       if (total + width >= F_print_write_max_d) {
         if (fwrite_unlocked(string + start, 1, total, output) == -1) {
           return F_status_set_error(F_output);
@@ -469,7 +444,9 @@ extern "C" {
       }
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -504,33 +481,6 @@ extern "C" {
         continue;
       }
 
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false || i + width >= stop) {
-        if (total) {
-          if (fwrite_unlocked(string + start, 1, total, output) == -1) {
-            return F_status_set_error(F_output);
-          }
-
-          total = 0;
-        }
-
-        if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) {
-          return F_status_set_error(F_output);
-        }
-
-        if (F_status_is_error(status) || status == F_false) {
-          i += width;
-          start = i;
-        }
-        else {
-          i = stop;
-          start = stop;
-        }
-
-        continue;
-      }
-
       if (total + width >= F_print_write_max_d) {
         if (fwrite_unlocked(string + start, 1, total, output) == -1) {
           return F_status_set_error(F_output);
@@ -607,7 +557,9 @@ extern "C" {
     while (i < length) {
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -622,8 +574,6 @@ extern "C" {
         continue;
       }
 
-      width = macro_f_utf_character_t_width(string[i]);
-
       if (safe) {
         if (total) {
           if (fwrite_unlocked(string + start, 1, total, output) == -1) {
@@ -642,26 +592,6 @@ extern "C" {
         continue;
       }
 
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false) {
-        if (total) {
-          if (fwrite_unlocked(string + start, 1, total, output) == -1) {
-            return F_status_set_error(F_output);
-          }
-
-          total = 0;
-        }
-
-        if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) {
-          return F_status_set_error(F_output);
-        }
-
-        i += width;
-        start = i;
-        continue;
-      }
-
       if (total + width >= F_print_write_max_d) {
         if (fwrite_unlocked(string + start, 1, total, output) == -1) {
           return F_status_set_error(F_output);
@@ -685,6 +615,29 @@ extern "C" {
   }
 #endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_)
 
+#if !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_)
+  f_string_t private_f_print_safely_get(const f_string_t character, const f_array_length_t width_max) {
+
+    if (character[0] == 0x7f) {
+      return (f_string_t) f_print_sequence_delete_s;
+    }
+
+    if (macro_f_utf_character_t_width_is(character[0])) {
+      if (f_utf_is_valid(character, width_max) != F_true || f_utf_is_control(character, width_max)) {
+        return (f_string_t) f_print_sequence_unknown_s;
+      }
+
+      return 0;
+    }
+
+    if (character[0] > 0x1f) {
+      return 0;
+    }
+
+    return (f_string_t) f_print_sequence_set_control_s[character[0]];
+  }
+#endif // !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_)
+
 #if !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_)
   f_status_t private_f_print_terminated(const f_string_t string, FILE *output) {
 
index 6a53edcf8e4cee93e0d43a39d0dffc2380f56b14..f3752e614c87fb2c15ddc521b5f27e7bcf7ae9cd 100644 (file)
@@ -393,6 +393,48 @@ extern "C" {
 #endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_)
 
 /**
+ * Private implementation of f_print_safely_get().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param character
+ *   A string representing an ASCII or a UTF-8 character to get safe representation.
+ * @param width_max
+ *   This is set to the max number of bytes available.
+ *   This is then updated to represent the max bytes used if enough space is available.
+ *
+ * @return
+ *   NULL is returned if the character is already safe.
+ *   A non-NULL string is returned if the character needs safe replacement.
+ *   The non-NULL strings returned are NULL terminated.
+ *   The non-NULL strings returned are the 3-byte characters used as placeholder symbols.
+ *
+ * @see f_print_character_safely_get()
+ * @see f_print_dynamic_partial_safely()
+ * @see f_print_dynamic_safely()
+ * @see f_print_except_dynamic_partial_safely()
+ * @see f_print_except_dynamic_safely()
+ * @see f_print_except_in_dynamic_safely()
+ * @see f_print_except_in_dynamic_partial_safely()
+ * @see f_print_except_in_safely_
+ * @see f_print_except_safely()
+ * @see f_print_safely()
+ * @see f_print_safely_terminated()
+ * @see f_print_to_dynamic_partial_safely()
+ * @see f_print_to_dynamic_safely()
+ * @see f_print_to_except_dynamic_partial_safely()
+ * @see f_print_to_except_dynamic_safely()
+ * @see f_print_to_except_in_dynamic_safely()
+ * @see f_print_to_except_in_dynamic_partial_safely()
+ * @see f_print_to_except_in_safely_
+ * @see f_print_to_except_safely()
+ * @see f_print_to_safely()
+ */
+#if !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_)
+  extern f_string_t private_f_print_safely_get(const f_string_t character, const f_array_length_t width_max) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_)
+
+/**
  * Private implementation of f_print_terminated().
  *
  * Intended to be shared to each of the different implementation variations.
index 00c81ce58e8ef1a3a9f970d895b1611420d291ee..c2d309df3913f58c5091d4a226a54e2cd0f4af46 100644 (file)
@@ -215,7 +215,9 @@ static inline f_status_t private_inline_f_print_to_error() {
       }
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -247,39 +249,7 @@ static inline f_status_t private_inline_f_print_to_error() {
         continue;
       }
 
-      width = macro_f_utf_character_t_width(string[i]);
-
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false || i + width >= stop) {
-        if (total) {
-          if (write(id, string + start, total) == -1) {
-            return private_inline_f_print_to_error();
-          }
-
-          total = 0;
-        }
-
-        if (write(id, f_print_sequence_unknown_s, 3) == -1) {
-          return private_inline_f_print_to_error();
-        }
-
-        if (F_status_is_error(status) || status == F_false) {
-          i += width;
-          start = i;
-        }
-        else {
-          i = stop;
-          start = stop;
-        }
-
-        continue;
-      }
-
-      total += width;
-      i += width;
-
-      if (total >= F_print_write_max_d) {
+      if (total + width >= F_print_write_max_d) {
         if (write(id, string + start, total) == -1) {
           return private_inline_f_print_to_error();
         }
@@ -287,6 +257,9 @@ static inline f_status_t private_inline_f_print_to_error() {
         total = 0;
         start = i;
       }
+
+      total += width;
+      i += width;
     } // while
 
     if (total) {
@@ -495,7 +468,9 @@ static inline f_status_t private_inline_f_print_to_error() {
       }
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -527,39 +502,7 @@ static inline f_status_t private_inline_f_print_to_error() {
         continue;
       }
 
-      width = macro_f_utf_character_t_width(string[i]);
-
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false || i + width >= stop) {
-        if (total) {
-          if (write(id, string + start, total) == -1) {
-            return private_inline_f_print_to_error();
-          }
-
-          total = 0;
-        }
-
-        if (write(id, f_print_sequence_unknown_s, 3) == -1) {
-          return private_inline_f_print_to_error();
-        }
-
-        if (F_status_is_error(status) || status == F_false) {
-          i += width;
-          start = i;
-        }
-        else {
-          i = stop;
-          start = stop;
-        }
-
-        continue;
-      }
-
-      total += width;
-      i += width;
-
-      if (total >= F_print_write_max_d) {
+      if (total + width >= F_print_write_max_d) {
         if (write(id, string + start, total) == -1) {
           return private_inline_f_print_to_error();
         }
@@ -567,6 +510,9 @@ static inline f_status_t private_inline_f_print_to_error() {
         total = 0;
         start = i;
       }
+
+      total += width;
+      i += width;
     } // while
 
     if (total) {
@@ -638,7 +584,9 @@ static inline f_status_t private_inline_f_print_to_error() {
     while (i < length) {
 
       if (string[i]) {
-        safe = private_f_print_character_safely_get(string[i]);
+        width = macro_f_utf_character_t_width(string[i]);
+
+        safe = private_f_print_safely_get(string + i, width);
       }
       else {
         if (total) {
@@ -666,43 +614,12 @@ static inline f_status_t private_inline_f_print_to_error() {
           return private_inline_f_print_to_error();
         }
 
-        start = ++i;
-        continue;
-      }
-
-      width = macro_f_utf_character_t_width(string[i]);
-
-      status = f_utf_is_valid(string + i, width);
-
-      if (F_status_is_error(status) || status == F_false || i + width >= length) {
-        if (total) {
-          if (write(id, string + start, total) == -1) {
-            return private_inline_f_print_to_error();
-          }
-
-          total = 0;
-        }
-
-        if (write(id, f_print_sequence_unknown_s, 3) == -1) {
-          return private_inline_f_print_to_error();
-        }
-
-        if (F_status_is_error(status) || status == F_false) {
-          i += width;
-          start = i;
-        }
-        else {
-          i = length;
-          start = length;
-        }
-
+        i += width;
+        start = i;
         continue;
       }
 
-      total += width;
-      i += width;
-
-      if (total >= F_print_write_max_d) {
+      if (total + width >= F_print_write_max_d) {
         if (write(id, string + start, total) == -1) {
           return private_inline_f_print_to_error();
         }
@@ -710,6 +627,9 @@ static inline f_status_t private_inline_f_print_to_error() {
         total = 0;
         start = i;
       }
+
+      total += width;
+      i += width;
     } // while
 
     if (total) {