]> Kevux Git Server - fll/commitdiff
Update: implement UTF-8 support in fss processing code and add additional functionality
authorKevin Day <thekevinday@gmail.com>
Fri, 23 Aug 2019 03:50:50 +0000 (22:50 -0500)
committerKevin Day <thekevinday@gmail.com>
Fri, 23 Aug 2019 03:57:24 +0000 (22:57 -0500)
Additional functionality includes implementing f_utf_character in f_utf.

Includes numerous other small UTF-8 updates.

Some macros have been wrapped in parenthesis to avoid unobvious issues such as when adding an exclamation before a macro call (and the possible order of operation issues).

40 files changed:
level_0/f_errors/c/errors.h
level_0/f_fss/c/fss.h
level_0/f_print/c/print.c
level_0/f_print/c/print.h
level_0/f_utf/c/utf.c
level_0/f_utf/c/utf.h
level_1/fl_fss/c/fss.c
level_1/fl_fss/c/fss.h
level_1/fl_fss/c/fss_basic.c
level_1/fl_fss/c/fss_basic.h
level_1/fl_fss/c/fss_basic_list.c
level_1/fl_fss/c/fss_basic_list.h
level_1/fl_fss/c/fss_extended.c
level_1/fl_fss/c/fss_extended.h
level_1/fl_fss/c/fss_macro.h
level_1/fl_fss/data/build/dependencies
level_1/fl_fss/data/build/settings
level_1/fl_strings/c/strings.c
level_1/fl_strings/c/strings.h
level_1/fl_strings/data/build/dependencies
level_1/fl_strings/data/build/settings
level_2/fll_fss/c/fss_basic.c
level_2/fll_fss/c/fss_basic.h
level_2/fll_fss/c/fss_basic_list.c
level_2/fll_fss/data/build/settings
level_3/firewall/data/build/settings
level_3/fss_basic_list_read/c/fss_basic_list_read.c
level_3/fss_basic_list_read/data/build/settings
level_3/fss_basic_list_write/data/build/settings
level_3/fss_basic_read/c/fss_basic_read.c
level_3/fss_basic_read/data/build/settings
level_3/fss_basic_write/data/build/settings
level_3/fss_extended_read/c/fss_extended_read.c
level_3/fss_extended_read/data/build/settings
level_3/fss_extended_write/c/fss_extended_write.c
level_3/fss_extended_write/data/build/settings
level_3/fss_return_code/data/build/settings
level_3/init/c/init.h
level_3/init/data/build/settings
level_3/return_code/data/build/settings

index 0eb0ef60b5c5d67c5e333226440d983655d0fa6d..911a89c0f4f16d451764b162607f5263b5c0969d 100644 (file)
@@ -141,30 +141,29 @@ extern "C" {
 
 #ifndef _di_f_error_masks_
   // f_status is required to be exactly 16 bits, the first two high order bits represent error and warning respectively.
-  #define f_error_bit_error   32768
-  #define f_error_bit_fine    16383
-  #define f_error_bit_mask    49152
-  #define f_error_bit_signal  49152
-  #define f_error_bit_warning 16384
+  #define f_error_bit_error   0x8000 // 1000 0000 0000 0000
+  #define f_error_bit_signal  0xc000 // 1100 0000 0000 0000
+  #define f_error_bit_warning 0x4000 // 0100 0000 0000 0000
 
-  #define f_error_is_error(status)   status & f_error_bit_error
-  #define f_error_is_fine(status)    (status & f_error_bit_mask) == 0
-  #define f_error_is_problem(status) status & f_error_bit_mask
-  #define f_error_is_warning(status) status & f_error_bit_warning
+  #define f_error_mask_fine 0x3fff // 0011 1111 1111 1111
+  #define f_error_mask_code 0xc000 // 1100 0000 0000 0000
 
-  #define f_error_is_not_error(status)   (status & f_error_bit_error) == 0
-  #define f_error_is_not_signal(status)  (status & f_error_bit_signal) == 0
-  #define f_error_is_not_warning(status) (status & f_error_bit_warning) == 0
+  #define f_error_is_error(status)   (status & f_error_bit_error)
+  #define f_error_is_fine(status)    ((status & f_error_mask_code) == 0)
+  #define f_error_is_problem(status) ((status & f_error_bit_error) || (status & f_error_bit_warning))
+  #define f_error_is_signal(status)  (status & f_error_bit_signal)
+  #define f_error_is_warning(status) (status & f_error_bit_warning)
 
-  // use both error and warning bits to designate that the response is a signal.
-  #define f_error_is_signal(status) (status & f_error_bit_signal) == f_error_bit_signal
+  #define f_error_is_not_error(status)   ((status & f_error_bit_error) == 0)
+  #define f_error_is_not_signal(status)  ((status & f_error_bit_signal) == 0)
+  #define f_error_is_not_warning(status) ((status & f_error_bit_warning) == 0)
 
-  #define f_error_set_error(status)   status | f_error_bit_error
-  #define f_error_set_signal(status)  status | f_error_bit_signal
-  #define f_error_set_warning(status) status | f_error_bit_warning
+  #define f_error_set_error(status)   (status | f_error_bit_error)
+  #define f_error_set_signal(status)  (status | f_error_bit_signal)
+  #define f_error_set_warning(status) (status | f_error_bit_warning)
 
   // use f_error_set_fine to remove the error, warning, and signal bits
-  #define f_error_set_fine(status) status & f_error_bit_fine
+  #define f_error_set_fine(status) (status & f_error_mask_fine)
 #endif // _di_f_error_masks_
 
 // use of an enumerator makes more sense here than explicitly defining every error code (or return code).
@@ -174,10 +173,6 @@ enum {
     f_true,
   #endif // _di_f_errors_booleans_
 
-  #ifndef _di_f_errors_maybe_
-    f_maybe = 2,
-  #endif // _di_f_errors_maybe_
-
   #ifndef _di_f_errors_signals_
     f_signal_hangup = 1,
     f_signal_interrupt,
@@ -249,6 +244,7 @@ enum {
 
   #ifndef _di_f_errors_basic_
     f_none = 197,          // start at 197 to allow compatibility with the reserved bash return codes (keep in mind fss return codes can be larger than 255).
+    f_maybe,
     f_dummy,               // to only be used as a placeholder
     f_warn,                // warning
     f_critical,
@@ -343,6 +339,8 @@ enum {
     f_unterminated_group_on_eol,
     f_unterminated_group_on_eos,
     f_unterminated_group_on_stop,
+    f_incomplete_utf_on_eos,
+    f_incomplete_utf_on_stop,
   #endif // _di_f_errors_buffers_
 
   #ifndef _di_f_errors_allocation_
index 04475795a51e1a889e2db429fd559074c23b2c76..ef32c26319e3f54f4193410cdfbcbc2bc67ce87b 100644 (file)
@@ -83,6 +83,9 @@ enum {
 
 #ifndef _di_f_fss_default_allocation_step_
   #define f_fss_default_allocation_step f_memory_default_allocation_step
+
+  // set to 4 to be UTF-8 friendlier.
+  #define f_fss_default_allocation_step_string 4
 #endif // _di_f_fss_default_allocation_step_
 
 #ifndef _di_f_fss_delimits_
index 77e38515c0da58d9c8495879b5db46e317f033cc..16ea4fbc9ee84e34aa875f3fe36356322ef4817f 100644 (file)
@@ -6,6 +6,11 @@ extern "C" {
 
 #ifndef _di_f_print_string_
   f_return_status f_print_string(FILE *output, const f_string string, const f_string_length length) {
+    #ifndef _di_level_0_parameter_checking_
+      if (string == 0) return f_error_set_error(f_invalid_parameter);
+      if (length < 1) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
     register f_string_length i = 0;
 
     for (; i < length; i++) {
@@ -23,7 +28,7 @@ extern "C" {
 #ifndef _di_f_print_dynamic_string_
   f_return_status f_print_dynamic_string(FILE *output, const f_dynamic_string buffer) {
     #ifndef _di_level_0_parameter_checking_
-      if (buffer.used <= 0) return f_invalid_parameter;
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
 
     register f_string_length i = 0;
index f8cbf2f6c19ad278e7c79eda6e15bcd8e869cf1d..2d08452743d9820124ac0e77a5b4663d1b483be6 100644 (file)
 extern "C" {
 #endif
 
+/**
+ * Similar to a c-library printf, except that this will only print a specific range.
+ *
+ * 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.
+ *
+ * @return
+ *   f_none on success.
+ *   f_output_error (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
 #ifndef _di_f_print_string_
-  /**
-   * Similar to a c-library printf, except that this will only print a specific range.
-   * will not stop at \0.
-   * will not print \0.
-   * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability.
-  */
   extern f_return_status f_print_string(FILE *output, const f_string string, const f_string_length length);
 #endif // _di_f_print_string_
 
+/**
+ * Similar to a c-library printf, except that this will only print a specific range.
+ *
+ * The string is printed as-is without interpretation.
+ *
+ * Will not stop at \0.
+ * Will not print \0.
+ * Will print the entire dynamic string.
+ *
+ * @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_output_error (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
 #ifndef _di_f_print_dynamic_string_
-  /**
-   * Similar to a c-library printf, except that this will only print a specific range.
-   * will not stop at \0.
-   * will not print \0.
-   * will print the entire dynamic string.
-   * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability.
-  */
   extern f_return_status f_print_dynamic_string(FILE *output, const f_dynamic_string buffer);
 #endif // _di_f_print_dynamic_string_
 
-
+/**
+ * Similar to a c-library printf, except that this will only print a specific range.
+ *
+ * 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 location.
+ *
+ * @param output
+ *   The file to output to, including standard streams such as stdout and stderr.
+ * @param buffer
+ *   The string to output.
+ * @param location
+ *   The range within the provided string to print.
+ *
+ * @return
+ *   f_none on success.
+ *   f_output_error (with error bit) on failure.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
 #ifndef _di_f_print_partial_dynamic_string_
-  /**
-   * Similar to a c-library printf, except that this will only print a specific range.
-   * will not stop at \0.
-   * will not print \0.
-   * will print the only the buffer range specified by location.
-   * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability.
-   */
   extern f_return_status f_print_partial_dynamic_string(FILE *output, const f_dynamic_string buffer, const f_string_location location);
 #endif // _di_f_print_partial_dynamic_string_
 
index ab589b326b15b7b299dc8aecb5e88b55a50c9e3c..3a947dc92f851a42a7043471233847f1ab1bb331 100644 (file)
@@ -4,8 +4,8 @@
 extern "C" {
 #endif
 
-#ifndef _di_f_utf_is_bom_
-  f_return_status f_utf_is_bom(const f_string character, const f_u_short max_width) {
+#ifndef _di_f_utf_is_bom_string_
+  f_return_status f_utf_is_bom_string(const f_string character, const f_u_short max_width) {
     #ifndef _di_level_0_parameter_checking_
       if (max_width < 1) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
@@ -28,10 +28,40 @@ extern "C" {
 
     return f_false;
   }
-#endif // _di_f_utf_is_bom_
+#endif // _di_f_utf_is_bom_string_
 
-#ifndef _di_f_utf_is_space_
-  f_return_status f_utf_is_space(const f_string character, const f_u_short max_width) {
+#ifndef _di_f_utf_is_graph_string_
+  f_return_status f_utf_is_graph_string(const f_string character, const f_u_short max_width) {
+    #ifndef _di_level_0_parameter_checking_
+      if (max_width < 1) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_u_short width = f_macro_utf_byte_width_is(*character);
+
+    if (width == 0) {
+      return f_false;
+    }
+
+    if (width > max_width) {
+      return f_error_set_error(f_maybe);
+    }
+
+    // for now, just assume that any non-whitespace, non-substitute utf-8 character is a graph.
+
+    if (f_utf_is_space_string(character, max_width) == f_true) {
+      return f_false;
+    }
+
+    if (f_utf_is_bom_string(character, max_width) == f_true) {
+      return f_false;
+    }
+
+    return f_true;
+  }
+#endif // _di_f_utf_is_graph_string_
+
+#ifndef _di_f_utf_is_space_string_
+  f_return_status f_utf_is_space_string(const f_string character, const f_u_short max_width) {
     #ifndef _di_level_0_parameter_checking_
       if (max_width < 1) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
@@ -160,10 +190,10 @@ extern "C" {
 
     return f_false;
   }
-#endif // _di_f_utf_is_space_
+#endif // _di_f_utf_is_space_string_
 
-#ifndef _di_f_utf_is_substitute_
-  f_return_status f_utf_is_substitute(const f_string character, const f_u_short max_width) {
+#ifndef _di_f_utf_is_substitute_string_
+  f_return_status f_utf_is_substitute_string(const f_string character, const f_u_short max_width) {
     #ifndef _di_level_0_parameter_checking_
       if (max_width < 1) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
@@ -208,10 +238,10 @@ extern "C" {
 
     return f_false;
   }
-#endif // _di_f_utf_is_substitute_
+#endif // _di_f_utf_is_substitute_string_
 
-#ifndef _di_f_utf_is_whitespace_
-  f_return_status f_utf_is_whitespace(const f_string character, const f_u_short max_width) {
+#ifndef _di_f_utf_is_whitespace_string_
+  f_return_status f_utf_is_whitespace_string(const f_string character, const f_u_short max_width) {
     #ifndef _di_level_0_parameter_checking_
       if (max_width < 1) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_0_parameter_checking_
@@ -320,7 +350,353 @@ extern "C" {
 
     return f_false;
   }
-#endif // _di_f_utf_is_whitespace_
+#endif // _di_f_utf_is_whitespace_string_
+
+#ifndef _di_f_utf_is_bom_character_
+  f_return_status f_utf_is_bom_character(const f_utf_character character) {
+    f_u_short width = f_macro_utf_byte_width(character.byte_1);
+
+    if (width == 1) {
+      return f_false;
+    }
+
+    if (width == 3) {
+      if (character.byte_1 == f_utf_bom[0] && character.byte_2 == f_utf_bom[1] && character.byte_3 == f_utf_bom[2]) {
+        return f_true;
+      }
+    }
+
+    return f_false;
+  }
+#endif // _di_f_utf_is_bom_character_
+
+#ifndef _di_f_utf_is_graph_character_
+  f_return_status f_utf_is_graph_character(const f_utf_character character) {
+    f_u_short width = f_macro_utf_byte_width(character.byte_1);
+
+    if (width == 0) {
+      return f_false;
+    }
+
+    // for now, just assume that any non-whitespace, non-substitute utf-8 character is a graph.
+
+    if (f_utf_is_space_character(character) == f_true) {
+      return f_false;
+    }
+
+    if (f_utf_is_bom_character(character) == f_true) {
+      return f_false;
+    }
+
+    return f_true;
+  }
+#endif // _di_f_utf_is_graph_character_
+
+#ifndef _di_f_utf_is_space_character_
+  f_return_status f_utf_is_space_character(const f_utf_character character) {
+    f_u_short width = f_macro_utf_byte_width(character.byte_1);
+
+    if (width == 1) {
+      return f_false;
+    }
+
+    if (width == 2) {
+      if (character.byte_1 == f_utf_space_no_break[0] && character.byte_2 == f_utf_space_no_break[1]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_line_feed_reverse[0] && character.byte_2 == f_utf_space_line_feed_reverse[1]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_line_next[0] && character.byte_2 == f_utf_space_line_next[1]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_middle_dot[0] && character.byte_2 == f_utf_substitute_middle_dot[1]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    if (width == 3) {
+      if (character.byte_1 == f_utf_space_no_break_narrow[0] && character.byte_2 == f_utf_space_no_break_narrow[1] && character.byte_3 == f_utf_space_no_break_narrow[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en[0] && character.byte_2 == f_utf_space_en[1] && character.byte_3 == f_utf_space_en[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em[0] && character.byte_2 == f_utf_space_em[1] && character.byte_3 == f_utf_space_em[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_quad[0] && character.byte_2 == f_utf_space_em_quad[1] && character.byte_3 == f_utf_space_em_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_three[0] && character.byte_2 == f_utf_space_em_per_three[1] && character.byte_3 == f_utf_space_em_per_three[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_four[0] && character.byte_2 == f_utf_space_em_per_four[1] && character.byte_3 == f_utf_space_em_per_four[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_six[0] && character.byte_2 == f_utf_space_em_per_six[1] && character.byte_3 == f_utf_space_em_per_six[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_figure[0] && character.byte_2 == f_utf_space_figure[1] && character.byte_3 == f_utf_space_figure[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_punctuation[0] && character.byte_2 == f_utf_space_punctuation[1] && character.byte_3 == f_utf_space_punctuation[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_thin[0] && character.byte_2 == f_utf_space_thin[1] && character.byte_3 == f_utf_space_thin[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_hair[0] && character.byte_2 == f_utf_space_hair[1] && character.byte_3 == f_utf_space_hair[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_separator_line[0] && character.byte_2 == f_utf_space_separator_line[1] && character.byte_3 == f_utf_space_separator_line[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_separator_paragraph[0] && character.byte_2 == f_utf_space_separator_paragraph[1] && character.byte_3 == f_utf_space_separator_paragraph[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_ogham[0] && character.byte_2 == f_utf_space_ogham[1] && character.byte_3 == f_utf_space_ogham[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_ideographic[0] && character.byte_2 == f_utf_space_ideographic[1] && character.byte_3 == f_utf_space_ideographic[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_medium_mathematical[0] && character.byte_2 == f_utf_space_medium_mathematical[1] && character.byte_3 == f_utf_space_medium_mathematical[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_symbol_blank[0] && character.byte_2 == f_utf_substitute_symbol_blank[1] && character.byte_3 == f_utf_substitute_symbol_blank[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_symbol_space[0] && character.byte_2 == f_utf_substitute_symbol_space[1] && character.byte_3 == f_utf_substitute_symbol_space[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_open_box[0] && character.byte_2 == f_utf_substitute_open_box[1] && character.byte_3 == f_utf_substitute_open_box[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_open_box_shouldered[0] && character.byte_2 == f_utf_substitute_open_box_shouldered[1] && character.byte_3 == f_utf_substitute_open_box_shouldered[2]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    return f_false;
+  }
+#endif // _di_f_utf_is_space_character_
+
+#ifndef _di_f_utf_is_substitute_character_
+  f_return_status f_utf_is_substitute_character(const f_utf_character character) {
+    f_u_short width = f_macro_utf_byte_width(character.byte_1);
+
+    if (width == 1) {
+      return f_false;
+    }
+
+    if (width == 2) {
+      if (character.byte_1 == f_utf_substitute_middle_dot[0] && character.byte_2 == f_utf_substitute_middle_dot[1]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    if (width == 3) {
+      if (character.byte_1 == f_utf_substitute_symbol_blank[0] && character.byte_2 == f_utf_substitute_symbol_blank[1] && character.byte_3 == f_utf_substitute_symbol_blank[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_symbol_space[0] && character.byte_2 == f_utf_substitute_symbol_space[1] && character.byte_3 == f_utf_substitute_symbol_space[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_open_box[0] && character.byte_2 == f_utf_substitute_open_box[1] && character.byte_3 == f_utf_substitute_open_box[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_substitute_open_box_shouldered[0] && character.byte_2 == f_utf_substitute_open_box_shouldered[1] && character.byte_3 == f_utf_substitute_open_box_shouldered[2]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    return f_false;
+  }
+#endif // _di_f_utf_is_substitute_character_
+
+#ifndef _di_f_utf_is_whitespace_character_
+  f_return_status f_utf_is_whitespace_character(const f_utf_character character) {
+    f_u_short width = f_macro_utf_byte_width(character.byte_1);
+
+    if (width == 1) {
+      return f_false;
+    }
+
+    if (width == 2) {
+      if (character.byte_1 == f_utf_space_no_break[0] && character.byte_2 == f_utf_space_no_break[1]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_line_feed_reverse[0] && character.byte_2 == f_utf_space_line_feed_reverse[1]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_line_next[0] && character.byte_2 == f_utf_space_line_next[1]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    if (width == 3) {
+      if (character.byte_1 == f_utf_space_no_break_narrow[0] && character.byte_2 == f_utf_space_no_break_narrow[1] && character.byte_3 == f_utf_space_no_break_narrow[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en[0] && character.byte_2 == f_utf_space_en[1] && character.byte_3 == f_utf_space_en[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em[0] && character.byte_2 == f_utf_space_em[1] && character.byte_3 == f_utf_space_em[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_quad[0] && character.byte_2 == f_utf_space_em_quad[1] && character.byte_3 == f_utf_space_em_quad[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_three[0] && character.byte_2 == f_utf_space_em_per_three[1] && character.byte_3 == f_utf_space_em_per_three[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_four[0] && character.byte_2 == f_utf_space_em_per_four[1] && character.byte_3 == f_utf_space_em_per_four[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_em_per_six[0] && character.byte_2 == f_utf_space_em_per_six[1] && character.byte_3 == f_utf_space_em_per_six[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_figure[0] && character.byte_2 == f_utf_space_figure[1] && character.byte_3 == f_utf_space_figure[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_punctuation[0] && character.byte_2 == f_utf_space_punctuation[1] && character.byte_3 == f_utf_space_punctuation[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_thin[0] && character.byte_2 == f_utf_space_thin[1] && character.byte_3 == f_utf_space_thin[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_hair[0] && character.byte_2 == f_utf_space_hair[1] && character.byte_3 == f_utf_space_hair[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_separator_line[0] && character.byte_2 == f_utf_space_separator_line[1] && character.byte_3 == f_utf_space_separator_line[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_separator_paragraph[0] && character.byte_2 == f_utf_space_separator_paragraph[1] && character.byte_3 == f_utf_space_separator_paragraph[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_ogham[0] && character.byte_2 == f_utf_space_ogham[1] && character.byte_3 == f_utf_space_ogham[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_ideographic[0] && character.byte_2 == f_utf_space_ideographic[1] && character.byte_3 == f_utf_space_ideographic[2]) {
+        return f_true;
+      }
+
+      if (character.byte_1 == f_utf_space_medium_mathematical[0] && character.byte_2 == f_utf_space_medium_mathematical[1] && character.byte_3 == f_utf_space_medium_mathematical[2]) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    return f_false;
+  }
+#endif // _di_f_utf_is_whitespace_character_
+
+#ifndef _di_f_utf_string_to_character_
+  f_return_status f_utf_string_to_character(const f_string character_string, const f_u_short max_width, f_utf_character *utf_character) {
+    #ifndef _di_level_0_parameter_checking_
+      if (max_width < 1) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    f_u_short width = f_macro_utf_byte_width_is(character_string[0]);
+
+    if (width >= max_width) {
+      return f_error_set_error(f_failure);
+    }
+
+    memset(utf_character, 0, sizeof(f_utf_character));
+
+    utf_character->byte_1 = character_string[0];
+
+    if (width < 2) {
+      return f_none;
+    }
+
+    utf_character->byte_2 = character_string[1];
+
+    if (width == 2) {
+      return f_none;
+    }
+
+    utf_character->byte_3 = character_string[2];
+
+    if (width == 3) {
+      return f_none;
+    }
+
+    utf_character->byte_4 = character_string[3];
+
+    return f_none;
+  }
+#endif // _di_f_utf_string_to_character_
 
 #ifdef __cplusplus
 } // extern "C"
index 53498dea0ff32737d8ed0a314a7cbea3c7f9b30d..e3569ec4fcb07300ce28fe2903a3d20cf486ad11 100644 (file)
@@ -61,6 +61,28 @@ extern "C" {
 #endif // _di_f_utf_bom_
 
 /**
+ * Provide a basic UTF-8 character.
+ *
+ * This is intended to be used so that a single path parameter can be passed to a function instead of an array of characters.
+ */
+#ifndef _di_f_utf_character_
+  typedef struct {
+    char byte_1;
+    char byte_2;
+    char byte_3;
+    char byte_4;
+  } f_utf_character;
+
+  #define f_utf_character_initialize \
+  { \
+    '\0', \
+    '\0', \
+    '\0', \
+    '\0', \
+  }
+#endif // _di_f_utf_char_
+
+/**
  * Define the UTF-8 bytes.
  *
  * The bytes are for checking a single 8-bit character value (specifically, checking the first bits).
@@ -93,7 +115,7 @@ extern "C" {
   #define f_macro_utf_byte_is_3(character) ((character & f_utf_byte_off_3) == f_utf_byte_3) // (1110 xxxx & 1111 0000) == 1110 0000
   #define f_macro_utf_byte_is_4(character) ((character & f_utf_byte_off_4) == f_utf_byte_4) // (1111 0xxx & 1111 1000) == 1111 0000
 
-  #define f_macro_utf_byte_width(character)    (!f_macro_utf_byte_is(character) || f_macro_utf_byte_is_1(character)) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4))
+  #define f_macro_utf_byte_width(character)    ((!f_macro_utf_byte_is(character) || f_macro_utf_byte_is_1(character)) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4)))
   #define f_macro_utf_byte_width_is(character) (f_macro_utf_byte_is(character) ? (f_macro_utf_byte_is_1(character) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4))) : 0)
 #endif // _di_f_utf_byte_
 
@@ -201,9 +223,31 @@ extern "C" {
  *   f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_utf_is_bom_
-  extern f_return_status f_utf_is_bom(const f_string character, const f_u_short max_width);
-#endif // _di_f_utf_is_bom_
+#ifndef _di_f_utf_is_bom_string_
+  extern f_return_status f_utf_is_bom_string(const f_string character, const f_u_short max_width);
+#endif // _di_f_utf_is_bom_string_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 printable character.
+ *
+ * This does not check non-UTF-8 graph.
+ *
+ * @param character
+ *   The character to validate.
+ *   There must be enough space allocated to compare against, as limited by max_width.
+ * @param max_width
+ *   The maximum width available for checking.
+ *   Can be anything greater than 0.
+ *
+ * @return
+ *   f_true if a UTF-8 graph.
+ *   f_false if not a UTF-8 graph.
+ *   f_maybe (with error bit) if this could be a graph but width is not long enough.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_graph_string_
+  extern f_return_status f_utf_is_graph_string(const f_string character, const f_u_short max_width);
+#endif // _di_f_utf_is_graph_string_
 
 /**
  * Check to see if the entire byte block of the character is a UTF-8 whitespace or substitute character.
@@ -223,9 +267,9 @@ extern "C" {
  *   f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_utf_is_space_
-  extern f_return_status f_utf_is_space(const f_string character, const f_u_short max_width);
-#endif // _di_f_utf_is_space_
+#ifndef _di_f_utf_is_space_string_
+  extern f_return_status f_utf_is_space_string(const f_string character, const f_u_short max_width);
+#endif // _di_f_utf_is_space_string_
 
 /**
  * Check to see if the entire byte block of the character is a UTF-8 whitespace substitute character.
@@ -245,9 +289,9 @@ extern "C" {
  *   f_maybe (with error bit) if this could be a substitute but width is not long enough.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_utf_is_substitute_
-  extern f_return_status f_utf_is_substitute(const f_string character, const f_u_short max_width);
-#endif // _di_f_utf_is_substitute_
+#ifndef _di_f_utf_is_substitute_string_
+  extern f_return_status f_utf_is_substitute_string(const f_string character, const f_u_short max_width);
+#endif // _di_f_utf_is_substitute_string_
 
 /**
  * Check to see if the entire byte block of the character is a UTF-8 general whitespace character.
@@ -267,9 +311,117 @@ extern "C" {
  *   f_maybe (with error bit) if this could be a whitespace but width is not long enough.
  *   f_invalid_parameter (with error bit) if a parameter is invalid.
  */
-#ifndef _di_f_utf_is_whitespace_
-  extern f_return_status f_utf_is_whitespace(const f_string character, const f_u_short max_width);
-#endif // _di_f_utf_is_whitespace_
+#ifndef _di_f_utf_is_whitespace_string_
+  extern f_return_status f_utf_is_whitespace_string(const f_string character, const f_u_short max_width);
+#endif // _di_f_utf_is_whitespace_string_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 BOM.
+ *
+ * @param character
+ *   The UTF-8 character to validate.
+ *
+ * @return
+ *   f_true if a UTF-8 whitespace or substitute.
+ *   f_false if not a UTF-8 whitespace or substitute.
+ *   f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_bom_character_
+  extern f_return_status f_utf_is_bom_character(const f_utf_character character);
+#endif // _di_f_utf_is_bom_character_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 printable character.
+ *
+ * This does not check non-UTF-8 graph.
+ *
+ * @param character
+ *   The character to validate.
+ *
+ * @return
+ *   f_true if a UTF-8 graph.
+ *   f_false if not a UTF-8 graph.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_graph_character_
+  extern f_return_status f_utf_is_graph_character(const f_utf_character character);
+#endif // _di_f_utf_is_graph_character_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 whitespace or substitute character.
+ *
+ * This does not check non-UTF-8 whitespace.
+ *
+ * @param character
+ *   The character to validate.
+ *
+ * @return
+ *   f_true if a UTF-8 whitespace or substitute.
+ *   f_false if not a UTF-8 whitespace or substitute.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_space_character_
+  extern f_return_status f_utf_is_space_character(const f_utf_character character);
+#endif // _di_f_utf_is_space_character_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 whitespace substitute character.
+ *
+ * This does not check non-UTF-8 whitespace.
+ *
+ * @param character
+ *   The character to validate.
+ *
+ * @return
+ *   f_true if a UTF-8 substitute.
+ *   f_false if not a UTF-8 substitute.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_substitute_character_
+  extern f_return_status f_utf_is_substitute_character(const f_utf_character character);
+#endif // _di_f_utf_is_substitute_character_
+
+/**
+ * Check to see if the entire byte block of the character is a UTF-8 general whitespace character.
+ *
+ * This does not check non-UTF-8 whitespace.
+ *
+ * @param character
+ *   The character to validate.
+ *
+ * @return
+ *   f_true if a UTF-8 whitespace.
+ *   f_false if not a UTF-8 whitespace.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_is_whitespace_character_
+  extern f_return_status f_utf_is_whitespace_character(const f_utf_character character);
+#endif // _di_f_utf_is_whitespace_character_
+
+/**
+ * Convert a UTF-8 character, stored as a string (character buffer), to the specialized f_utf_character type.
+ *
+ * This will also convert ASCII characters.
+ *
+ * @param character_string
+ *   The character string to be converted to the f_utf_character type.
+ *   There must be enough space allocated to convert against, as limited by max_width.
+ * @param max_width
+ *   The maximum width available for converting.
+ *   Can be anything greater than 0.
+ * @param utf_character
+ *   The generated character of type f_utf_character.
+ *   This value may be cleared, even on error.
+ *
+ * @return
+ *   f_none if conversion was successful.
+ *   f_failure (with error bit) if width is not long enough to convert.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_utf_string_to_character_
+  extern f_return_status f_utf_string_to_character(const f_string character_string, const f_u_short max_width, f_utf_character *utf_character);
+#endif // _di_f_utf_string_to_character_
 
 #ifdef __cplusplus
 } // extern "C"
index 1d8e5251b1af34bf70d3ac21d5d46558d30dd0a0..73edd321c3979dcee95fcc0ade5c124ae6d3f711 100644 (file)
@@ -4,6 +4,40 @@
 extern "C" {
 #endif
 
+#ifndef _di_fl_fss_decrement_buffer_
+  f_return_status fl_fss_decrement_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input->start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input->stop < input->start) return f_error_set_error(f_invalid_parameter);
+      if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+      if (step < 1) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    if (input->start < 1) return f_none_on_eos;
+
+    f_string_length i = 0;
+    f_u_short width = 0;
+
+    do {
+      width = f_macro_utf_byte_width(buffer.string[input->start - 1]);
+
+      if (width > input->start) {
+        if (width > 1) {
+          return f_error_set_error(f_incomplete_utf_on_eos);
+        }
+
+        return f_none_on_eos;
+      }
+
+      i++;
+      input->start -= width;
+    } while (i < step);
+
+    return f_none;
+  }
+#endif // _di_fl_fss_decrement_buffer_
+
 #ifndef _di_fl_fss_identify_
   f_return_status fl_fss_identify(const f_dynamic_string buffer, f_fss_header *header) {
     #ifndef _di_level_1_parameter_checking_
@@ -13,17 +47,61 @@ extern "C" {
 
     register f_string_length i = 0;
 
-    // If this correctly follows the FSS specification, then this should be all that needs to be done (as well as atoh for ascii to hex)
-    if                   (buffer.string[i] == f_fss_type_header_open) {  i++;
-      if                 (buffer.string[i] == f_fss_type_header_part1) { i++;
-        if               (buffer.string[i] == f_fss_type_header_part2) { i++;
-          if             (buffer.string[i] == f_fss_type_header_part3) { i++;
-            if           (buffer.string[i] == f_fss_type_header_part4) { i++;
-              if         (buffer.string[i] == f_fss_type_header_part5) { i++;
-                if       (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                  if     (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                    if   (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                      if (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
+    // A single UTF-8 BOM is allowed to exist before the valid FSS identifier.
+    if (buffer.used > 3) {
+      f_status status = f_utf_is_bom_string(buffer.string, 4);
+
+      if (f_error_is_error(status)) {
+        return f_error_set_error(fl_fss_no_header);
+      }
+
+      if (status == f_true) {
+        i = f_utf_bom_length;
+
+        if (buffer.used < 10 + f_utf_bom_length) {
+          return fl_fss_no_header;
+        }
+      }
+      else if (buffer.used < 10) {
+        // "# fss-0000" without UTF-8 BOM is always 10 characters.
+        return fl_fss_no_header;
+      }
+    }
+    else {
+      return fl_fss_no_header;
+    }
+
+    // If this correctly follows the FSS specification, then this should be all that needs to be done (as well as atoh for ascii to hex).
+    // All characters used in the identifier are only in the ascii equivalents of the characters, any similarly looking character or number representing in UTF-8 is considered invalid.
+    if (buffer.string[i] == f_fss_type_header_open) {
+      i++;
+
+      if (buffer.string[i] == f_fss_type_header_part1) {
+        i++;
+
+        if (buffer.string[i] == f_fss_type_header_part2) {
+          i++;
+
+          if (buffer.string[i] == f_fss_type_header_part3) {
+            i++;
+
+            if (buffer.string[i] == f_fss_type_header_part4) {
+              i++;
+
+              if (buffer.string[i] == f_fss_type_header_part5) {
+                i++;
+
+                if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                  i++;
+
+                  if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                    i++;
+
+                    if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                      i++;
+
+                      if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                        i++;
 
                         f_string_location location = f_string_location_initialize;
 
@@ -55,16 +133,31 @@ extern "C" {
             }
           }
         }
-      // people can miss spaces, so lets accept in an attempt to interpret the file anyway, but return values at this point are to be flagged as invalid
       }
-      else if          (buffer.string[i] == f_fss_type_header_part2) { i++;
-        if             (buffer.string[i] == f_fss_type_header_part3) { i++;
-          if           (buffer.string[i] == f_fss_type_header_part4) { i++;
-            if         (buffer.string[i] == f_fss_type_header_part5) { i++;
-              if       (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                if     (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                  if   (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
-                    if (f_is_hexdigit(buffer.string[i]) == f_true) {   i++;
+      // people can miss spaces, so lets accept in an attempt to interpret the file anyway, but return values at this point are to be flagged as invalid
+      else if (buffer.string[i] == f_fss_type_header_part2) {
+        i++;
+
+        if (buffer.string[i] == f_fss_type_header_part3) {
+          i++;
+
+          if (buffer.string[i] == f_fss_type_header_part4) {
+            i++;
+
+            if (buffer.string[i] == f_fss_type_header_part5) {
+              i++;
+
+              if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                i++;
+
+                if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                  i++;
+
+                  if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                    i++;
+
+                    if (f_is_hexdigit(buffer.string[i]) == f_true) {
+                      i++;
 
                       f_string_location location = f_string_location_initialize;
 
@@ -98,8 +191,8 @@ extern "C" {
     #ifndef _di_level_1_parameter_checking_
       if (file_information == 0) return f_error_set_error(f_invalid_parameter);
       if (header == 0) return f_error_set_error(f_invalid_parameter);
-      if (file_information->file == 0) return f_file_not_open;
-      if (ferror(file_information->file) != 0) return f_file_error;
+      if (file_information->file == 0) return f_error_set_error(f_file_not_open);
+      if (ferror(file_information->file) != 0) return f_error_set_error(f_file_error);
     #endif // _di_level_1_parameter_checking_
 
     clearerr(file_information->file);
@@ -112,7 +205,7 @@ extern "C" {
     {
       f_s_int seek_result = f_file_seek_from_beginning(file_information->file, 0);
 
-      if (seek_result != 0) return f_file_seek_error;
+      if (seek_result != 0) return f_error_set_error(f_file_seek_error);
     }
 
     // 1: Prepare the buffer to handle a size of f_fss_max_header_length
@@ -138,47 +231,251 @@ extern "C" {
   }
 #endif // _di_fl_fss_identify_file_
 
-#ifndef _di_fl_fss_shift_delimiters_
-f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location location) {
-  #ifndef _di_level_1_parameter_checking_
-    if (buffer->used <= 0) return f_error_set_error(f_invalid_parameter);
-    if (location.start < 0) return f_error_set_error(f_invalid_parameter);
-    if (location.stop < location.start) return f_error_set_error(f_invalid_parameter);
-    if (location.start >= buffer->used) return f_error_set_error(f_invalid_parameter);
-  #endif // _di_level_1_parameter_checking_
+#ifndef _di_fl_fss_increment_buffer_
+  f_return_status fl_fss_increment_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input->start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input->stop < input->start) return f_error_set_error(f_invalid_parameter);
+      if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+      if (step < 1) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_string_length i = 0;
+    f_u_short width = 0;
+
+    do {
+      width = f_macro_utf_byte_width(buffer.string[input->start]);
+
+      if (input->start + width > input->stop) {
+        if (width > 1) {
+          return f_error_set_error(f_incomplete_utf_on_stop);
+        }
 
-  f_string_length position = 0;
-  f_string_length distance = 0;
+        input->start += width;
+        return f_none_on_stop;
+      }
+      else if (input->start + width >= buffer.used) {
+        if (width > 1) {
+          return f_error_set_error(f_incomplete_utf_on_eos);
+        }
+
+        input->start += width;
+        return f_none_on_eos;
+      }
 
-  position = location.start;
+      i++;
+      input->start += width;
+    } while (i < step);
 
-  while (position < buffer->used && position <= location.stop) {
-    if (buffer->string[position] == f_fss_delimit_placeholder) {
-      distance++;
+    return f_none;
+  }
+#endif // _di_fl_fss_increment_buffer_
+
+#ifndef _di_fl_fss_is_graph_
+  f_return_status fl_fss_is_graph(const f_dynamic_string buffer, const f_string_location input) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input.start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input.stop < input.start) return f_error_set_error(f_invalid_parameter);
+      if (input.start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_u_short utf_width = f_macro_utf_byte_width_is(buffer.string[input.start]);
+
+    if (utf_width == 0) {
+      if (isgraph(buffer.string[input.start])) {
+        return f_true;
+      }
+
+      return f_false;
     }
 
-    // do not waste time trying to process what is only going to be replaced with a delimit placeholder
-    if (position + distance >= buffer->used || position + distance > location.stop) {
-      break;
+    f_string_length max_width = (input.stop - input.start) + 1;
+
+    if (max_width > buffer.used - input.start) {
+      max_width = buffer.used - input.start;
     }
 
-    // shift everything down one for each placeholder found
-    if (distance > 0) {
-      buffer->string[position] = buffer->string[position + distance];
+    f_status status = f_utf_is_space_string(buffer.string + input.start, max_width);
+
+    if (f_error_is_error(status)) {
+      return status;
+    }
+
+    if (status == f_true) {
+      return f_false;
     }
 
-    ++position;
+    return f_true;
   }
+#endif // _di_fl_fss_is_graph_
+
+#ifndef _di_fl_fss_is_space_
+  f_return_status fl_fss_is_space(const f_dynamic_string buffer, const f_string_location input) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input.start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input.stop < input.start) return f_error_set_error(f_invalid_parameter);
+      if (input.start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_u_short utf_width = f_macro_utf_byte_width_is(buffer.string[input.start]);
+
+    if (utf_width == 0) {
+      if (isspace(buffer.string[input.start])) {
+        return f_true;
+      }
+
+      return f_false;
+    }
+
+    f_string_length max_width = (input.stop - input.start) + 1;
 
-  if (distance > 0) {
-    while (position < buffer->used + distance && position <= location.stop) {
-      buffer->string[position] = f_fss_delimit_placeholder;
-      ++position;
+    if (max_width > buffer.used - input.start) {
+      max_width = buffer.used - input.start;
     }
+
+    f_status status = f_utf_is_space_string(buffer.string + input.start, max_width);
+
+    if (f_error_is_error(status)) {
+      return status;
+    }
+
+    if (status == f_true) {
+      return f_true;
+    }
+
+    return f_false;
+  }
+#endif // _di_fl_fss_is_space_
+
+#ifndef _di_fl_fss_skip_past_whitespace_
+  f_return_status fl_fss_skip_past_whitespace(const f_dynamic_string buffer, f_string_location *input) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input->start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input->stop < input->start) return f_error_set_error(f_invalid_parameter);
+      if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_status status = f_none;
+    f_u_short max_width = 0;
+
+    while (input->start < buffer.used && input->start > input->stop) {
+      if (isgraph(buffer.string[input->start])) break;
+
+      if (buffer.string[input->start] == f_eol) break;
+
+      if (buffer.string[input->start] != f_fss_delimit_placeholder) {
+        max_width = (input->stop - input->start) + 1;
+
+        if (f_utf_is_space_string(buffer.string +input->start, max_width) != f_true) {
+          if (f_utf_is_bom_string(buffer.string + input->start, max_width) != f_true) {
+            break;
+          }
+        }
+      }
+
+      input->start++;
+    } // while
+
+    return f_none;
   }
+#endif // _di_fl_fss_skip_past_whitespace_
+
+#ifndef _di_fl_fss_skip_past_all_whitespace_
+  f_return_status fl_fss_skip_past_all_whitespace(const f_dynamic_string buffer, f_string_location *input) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input->start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input->stop < input->start) return f_error_set_error(f_invalid_parameter);
+      if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
 
-  return f_none;
-}
+    f_status status = f_none;
+    f_u_short max_width = 0;
+
+    while (input->start < buffer.used && input->start > input->stop) {
+      if (isgraph(buffer.string[input->start])) break;
+
+      if (buffer.string[input->start] != f_fss_delimit_placeholder) {
+        max_width = (input->stop - input->start) + 1;
+
+        if (f_utf_is_space_string(buffer.string + input->start, max_width) != f_true) {
+          if (f_utf_is_bom_string(buffer.string + input->start, max_width) != f_true) {
+            break;
+          }
+        }
+      }
+
+      input->start++;
+    } // while
+
+    return f_none;
+  }
+#endif // _di_fl_fss_skip_past_all_whitespace_
+
+#ifndef _di_fl_fss_shift_delimiters_
+  f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location input) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer->used <= 0) return f_error_set_error(f_invalid_parameter);
+      if (input.start < 0) return f_error_set_error(f_invalid_parameter);
+      if (input.stop < input.start) return f_error_set_error(f_invalid_parameter);
+      if (input.start >= buffer->used) return f_error_set_error(f_invalid_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_string_length position = 0;
+    f_string_length distance = 0;
+    f_u_short utf_width = 0;
+    f_u_short i = 0;
+
+    position = input.start;
+
+    while (position < buffer->used && position <= input.stop) {
+      if (buffer->string[position] == f_fss_delimit_placeholder) {
+        distance++;
+      }
+
+      // do not waste time trying to process what is only going to be replaced with a delimit placeholder
+      if (position + distance >= buffer->used || position + distance > input.stop) {
+        break;
+      }
+
+      utf_width = f_macro_utf_byte_width_is(buffer->string[position]);
+      if (utf_width > 1) {
+        // not enough space in buffer or in input range to process UTF-8 character.
+        if (position + utf_width >= buffer->used || position + utf_width > input.stop) {
+          return f_error_set_error(f_invalid_utf);
+        }
+
+        if (distance > 0) {
+          while (utf_width > 0) {
+            buffer->string[position] = buffer->string[position + distance];
+            utf_width--;
+            position++;
+          }
+        }
+      }
+      else {
+        // shift everything down one for each placeholder found
+        if (distance > 0) {
+          buffer->string[position] = buffer->string[position + distance];
+        }
+
+        position++;
+      }
+    }
+
+    if (distance > 0) {
+      while (position < buffer->used + distance && position <= input.stop) {
+        buffer->string[position] = f_fss_delimit_placeholder;
+        ++position;
+      }
+    }
+
+    return f_none;
+  }
 #endif // _di_fl_fss_shift_delimiters_
 
 #ifdef __cplusplus
index a0c26b3ab48da318c7f3208162a1c94216fc2833..43a896cfaceaa21367db54f6514e1f262960964e 100644 (file)
@@ -19,6 +19,7 @@
 #include <level_0/fss.h>
 #include <level_0/strings.h>
 #include <level_0/types.h>
+#include <level_0/utf.h>
 
 // fll-1 includes
 #include <level_1/fss_errors.h>
 extern "C" {
 #endif
 
+/**
+ * Continue to the previous character, based on step and character width.
+ *
+ * The start position must be at the start of a valid UTF-8 block.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The start and stop positions to be incremented.
+ *   The start position will be incremented by step.
+ * @param step
+ *   The number of steps to decrement the start position.
+ *   The steps refer to characters and not integers.
+ *   Essentially this number is considered against the width of every character found.
+ *   (For ASCII each step would be (sizeof(char)).
+ *   (For UTF-8 character of width 3, each step would be (3 * sizeof(char)).
+ *
+ * @return
+ *   f_none on success.
+ *   f_none_on_stop if the stop point is reached before all steps are completed.
+ *   f_none_on_eos if the end of buffer is reached before all steps are completed.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_incomplete_utf_on_stop (with error bit) if the stop point is reached before the complete UTF-8 character can be processed.
+ *   f_incomplete_utf_on_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed.
+ */
+#ifndef _di_fl_fss_decrement_buffer_
+  extern f_return_status fl_fss_decrement_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step);
+#endif // _di_fl_fss_decrement_buffer_
+
+/**
+ * Identify FSS type from a buffered string.
+ *
+ * The UTF-8 BOM is allowed to exist as the first character of the FSS header, but not anywhere else.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param header
+ *   The header data to populate with results of this function.
+ *
+ * @return
+ *   fl_fss_no_header if no header is found.
+ *   fl_fss_no_header (with error bit) if the an error occured prior to identifying a valid header.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
 #ifndef _di_fl_fss_identify_
-  /**
-   * Identify FSS type from a buffered string.
-   */
   extern f_return_status fl_fss_identify(const f_dynamic_string buffer, f_fss_header *header);
 #endif // _di_fl_fss_identify_
 
+/**
+ * Identify FSS type from a file.
+ *
+ * @param file_information
+ *   The file information.
+ * @param header
+ *   The header data to populate with results of this function.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors from (with error bit): f_file_read().
+ *   Errors from (with error bit): fl_fss_identify()
+ *   File errors (with error bit): f_file_seek_error, f_file_not_open.
+ *
+ * @see f_file_read()
+ * @see fl_fss_identify()
+ */
 #ifndef _di_fl_fss_identify_file_
-  /**
-   * Ideentify FSS type from a file.
-   */
   extern f_return_status fl_fss_identify_file(f_file *file_information, f_fss_header *header);
 #endif // _di_fl_fss_identify_file_
 
+/**
+ * Continue to the next character, based on step and character width.
+ *
+ * The start position must be at the start of a valid UTF-8 block.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The start and stop positions to be incremented.
+ *   The start position will be incremented by step.
+ * @param step
+ *   The number of steps to increment the start position.
+ *   The steps refer to characters and not integers.
+ *   Essentially this number is considered against the width of every character found.
+ *   (For ASCII each step would be (sizeof(char)).
+ *   (For UTF-8 character of width 3, each step would be (3 * sizeof(char)).
+ *
+ * @return
+ *   f_none on success.
+ *   f_none_on_stop if the stop point is reached before all steps are completed.
+ *   f_none_on_eos if the end of buffer is reached before all steps are completed.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ *   f_incomplete_utf_on_stop (with error bit) if the stop point is reached before the complete UTF-8 character can be processed.
+ *   f_incomplete_utf_on_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed.
+ */
+#ifndef _di_fl_fss_increment_buffer_
+  extern f_return_status fl_fss_increment_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step);
+#endif // _di_fl_fss_increment_buffer_
+
+/**
+ * Identify whether or not a character in the buffer is a graph (ASCII or UTF-8) character.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The character at the start position will be checked against the graph.
+ * @param header
+ *   The header data to populate with results of this function.
+ *
+ * @return
+ *   f_true if the character in the buffer is a graph character.
+ *   f_false if the character in the buffer is not a graph character.
+ *   f_maybe (with error bit) if the character width is outside the stop position.
+ *   f_failure (with error bit) if the buffer is not wide enough or the width is outside the stop position.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_fss_is_graph_
+  extern f_return_status fl_fss_is_graph(const f_dynamic_string buffer, const f_string_location input);
+#endif // _di_fl_fss_is_graph_
+
+/**
+ * Identify whether or not a character in the buffer is a space (ASCII or UTF-8) character.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The character at the start position will be checked against the graph.
+ * @param header
+ *   The header data to populate with results of this function.
+ *
+ * @return
+ *   f_true if the character in the buffer is a space character.
+ *   f_false if the character in the buffer is not a space character.
+ *   f_maybe (with error bit) if the character width is outside the stop position.
+ *   f_failure (with error bit) if the buffer is not wide enough or the width is outside the stop position.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_fss_is_space_
+  extern f_return_status fl_fss_is_space(const f_dynamic_string buffer, const f_string_location input);
+#endif // _di_fl_fss_is_space_
+
+/**
+ * Shift all of the delimiters to the end of the used buffer.
+ *
+ * This allows one to do a printf on the dynamic string without the delimiters arbitrarily stopping the output.
+ * No reallocations are performed, this will only shift characters.
+ *
+ * @param buffer
+ *   The string to process.
+ *   This gets updated.
+ * @param input
+ *   A restriction on where within the buffer the shifting happens.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_utf (with error bit) if UTF-8 cannot be fully processed (buffer or location range not long enough).
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
 #ifndef _di_fl_fss_shift_delimiters_
-  /**
-   * This provides a means to shift all of the delimiters to the end of the used buffer.
-   * This allows one to do a printf on the dynamic string without the delimiters arbitrarily stopping the output.
-   * No reallocations are performed, this will only shift characters.
-   */
-  extern f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location location);
+  extern f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location input);
 #endif // _di_fl_fss_shift_delimiters_
 
+/**
+ * Skip past all whitespace and control characters, except newline.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The start and stop positions in the buffer being processed.
+ *   This increments location->start.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_fss_skip_past_whitespace_
+  extern f_return_status fl_fss_skip_past_whitespace(const f_dynamic_string buffer, f_string_location *input);
+#endif // _di_fl_fss_skip_past_whitespace_
+
+/**
+ * Skip past all whitespace and control characters.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param input
+ *   The start and stop positions in the buffer being processed.
+ *   This increments input->start.
+ *
+ * @return
+ *   f_none on success.
+ *   f_invalid_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_fl_fss_skip_past_all_whitespace_
+  extern f_return_status fl_fss_skip_past_all_whitespace(const f_dynamic_string buffer, f_string_location *input);
+#endif // _di_fl_fss_skip_past_all_whitespace_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 20d67d490b0dbb644ce21b823e8819a1991410a4..cdd12cfbc3f93e02c8aab3cac7cf46703b721ed7 100644 (file)
@@ -16,15 +16,19 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
-    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_fss_skip_past_whitespace(*buffer, input);
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
     // return found nothing if this line only contains whitespace and delimit placeholders
     if (buffer->string[input->start] == f_fss_basic_close) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -39,7 +43,9 @@ extern "C" {
     if (buffer->string[input->start] == f_fss_comment) {
       fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -49,24 +55,41 @@ extern "C" {
     // identify where the object begins
     if (buffer->string[input->start] == f_fss_delimit_slash) {
       f_string_length last_slash = input->start;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
 
       while (input->start <= input->stop && input->start < buffer->used) {
         if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         }
-        else if (!isgraph(buffer->string[input->start])) {
-          found->stop = input->start - 1;
-          input->start++;
-          return fl_fss_found_object;
-        }
-        else if (buffer->string[input->start] != f_fss_delimit_slash) {
-          break;
+        else {
+          status = fl_fss_is_graph(*buffer, *input);
+          if (status == f_false) {
+            found->stop = input->start - 1;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
+            return fl_fss_found_object;
+          }
+          else if (f_error_is_error(status)) {
+            return status;
+          }
+          else if (buffer->string[input->start] != f_fss_delimit_slash) {
+            break;
+          }
         }
 
         last_slash = input->start;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
@@ -85,46 +108,70 @@ extern "C" {
 
         delimits.array[delimits.used] = last_slash;
         delimits.used++;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       }
     }
     else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
       quoted = buffer->string[input->start];
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       found->start = input->start;
     }
 
     // identify where the object ends
     if (quoted == f_eos) {
-      while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) {
-        input->start++;
+      status = f_none;
+      while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
       } // while
 
-      if (isspace(buffer->string[input->start])) {
+      if (f_error_is_error(status)) return status;
+
+      status = fl_fss_is_space(*buffer, *input);
+      if (status == f_true) {
         found->stop = input->start - 1;
 
         fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
         if (buffer->string[input->start] == f_eol) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           return fl_fss_found_object_no_content;
         }
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         return fl_fss_found_object;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
     }
     else {
       while (input->start <= input->stop && input->start < buffer->used) {
         if (buffer->string[input->start] == f_fss_delimit_slash) {
           f_string_length first_slash = input->start;
           f_string_length slash_count = 1;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
 
           while (input->start <= input->stop && input->start < buffer->used) {
             if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               continue;
             }
             else if (buffer->string[input->start] != f_fss_delimit_slash) {
@@ -132,7 +179,9 @@ extern "C" {
             }
 
             slash_count++;
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -164,7 +213,9 @@ extern "C" {
                   slash_count--;
                 }
 
-                input->start++;
+
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               input->start = location + 1;
@@ -172,9 +223,10 @@ extern "C" {
               fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
               fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
 
-              if (isgraph(buffer->string[input->start])) {
+              if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) {
                 while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
                 } // while
 
                 fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
@@ -185,14 +237,22 @@ extern "C" {
                   f_delete_string_lengths(allocation_status, delimits);
                 }
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 return fl_fss_found_no_object;
               }
+              else if (f_error_is_error(status)) {
+                return status;
+              }
               else if (buffer->string[input->start] == f_eol) {
                 fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
                 found->stop = location - 1;
-                input->start++;
+
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
 
                 return fl_fss_found_object_no_content;
               }
@@ -200,7 +260,10 @@ extern "C" {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
               found->stop = location - 1;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object;
             }
             else {
@@ -225,7 +288,8 @@ extern "C" {
                   slash_count--;
                 }
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               input->start = location;
@@ -234,22 +298,36 @@ extern "C" {
         }
         else if (buffer->string[input->start] == quoted) {
           found->stop = input->start - 1;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start <= input->stop && input->start < buffer->used) {
             if (buffer->string[input->start] == f_eol) {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object_no_content;
             }
-            else if (isspace(buffer->string[input->start])) {
+            else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object;
             }
+            else if (f_error_is_error(status)) {
+              return status;
+            }
             else if (buffer->string[input->start] != f_fss_delimit_placeholder) {
               while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                input->start++;
+
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
               } // while
 
               fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
@@ -260,11 +338,15 @@ extern "C" {
                 f_delete_string_lengths(allocation_status, delimits);
               }
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_no_object;
             }
 
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
@@ -276,11 +358,15 @@ extern "C" {
             f_delete_string_lengths(allocation_status, delimits);
           }
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           return fl_fss_found_no_object;
         }
 
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -288,7 +374,8 @@ extern "C" {
 
     // seek to the end of the line when no valid object is found
     while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
@@ -299,7 +386,10 @@ extern "C" {
       f_delete_string_lengths(allocation_status, delimits);
     }
 
-    input->start++;
+
+    status = fl_fss_increment_buffer(*buffer, input, 1);
+    if (f_error_is_error(status)) return status;
+
     return fl_fss_found_no_object;
   }
 #endif // _di_fl_fss_basic_object_read_
@@ -316,15 +406,19 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
-    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_fss_skip_past_whitespace(*buffer, input);
     fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
 
     // return found nothing if this line only contains whitespace and delimit placeholders
     if (buffer->string[input->start] == f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_content;
     }
 
@@ -344,7 +438,10 @@ extern "C" {
     // Save the stop point
     found->array[found->used].stop = input->start - 1;
     found->used++;
-    input->start++;
+
+    status = fl_fss_increment_buffer(*buffer, input, 1);
+    if (f_error_is_error(status)) return status;
+
     return fl_fss_found_content;
   }
 #endif // _di_fl_fss_basic_content_read_
@@ -374,7 +471,7 @@ extern "C" {
     start_position = input->start;
 
     // add an additional 3 to ensure that there is room for the start and stop quotes or a slash delimit and the object open character.
-    pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step_string;
 
     if (pre_allocate_size > buffer->size) {
       f_resize_dynamic_string(status, (*buffer), pre_allocate_size);
@@ -388,7 +485,9 @@ extern "C" {
     if (object.string[input->start] == f_fss_delimit_slash) {
       while (input->start <= input->stop && input->start < object.used) {
         if (object.string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         }
         else if (object.string[input->start] != f_fss_delimit_slash) {
@@ -397,14 +496,16 @@ extern "C" {
 
         buffer->string[buffer_position.stop] = object.string[input->start];
         buffer_position.stop++;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) {
         pre_allocate_size++;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -412,14 +513,16 @@ extern "C" {
         buffer->string[buffer_position.stop] = f_fss_delimit_slash;
         buffer->string[buffer_position.stop + 1] = object.string[input->start];
         buffer_position.stop += 2;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       }
     }
     else if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) {
       pre_allocate_size++;
 
       if (pre_allocate_size > buffer->size) {
-        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
         if (f_error_is_error(status)) return status;
       }
@@ -427,7 +530,9 @@ extern "C" {
       buffer->string[buffer_position.stop] = f_fss_delimit_slash;
       buffer->string[buffer_position.stop + 1] = object.string[input->start];
       buffer_position.stop += 2;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     }
     else if (object.string[input->start] == f_fss_comment) {
       quoted = f_true;
@@ -435,7 +540,9 @@ extern "C" {
 
     while (input->start <= input->stop && input->start < object.used) {
       if (object.string[input->start] == f_fss_delimit_placeholder) {
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         continue;
       }
       else if (object.string[input->start] == f_eol) {
@@ -449,11 +556,11 @@ extern "C" {
 
         return f_none_on_eol;
       }
-      else if (isspace(object.string[input->start]) || quoted) {
+      else if ((status = fl_fss_is_space(*buffer, *input)) == f_true || quoted) {
         pre_allocate_size++;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -467,14 +574,16 @@ extern "C" {
 
         while (input->start <= input->stop && input->start < object.used) {
           if (object.string[input->start] == f_fss_delimit_placeholder) {
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
             continue;
           }
           else if (object.string[input->start] == f_fss_delimit_double_quote) {
             pre_allocate_size++;
 
             if (pre_allocate_size > buffer->size) {
-              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) return status;
             }
@@ -489,7 +598,10 @@ extern "C" {
               buffer->string[buffer_position.stop] = object.string[input->start];
               buffer_position.stop++;
               slash_count++;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
 
               fl_macro_fss_skip_past_delimit_placeholders(object, (*input));
 
@@ -501,7 +613,7 @@ extern "C" {
                 pre_allocate_size += slash_count;
 
                 if (pre_allocate_size > buffer->size) {
-                  f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+                  f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
                   if (f_error_is_error(status)) return status;
                 }
@@ -533,7 +645,10 @@ extern "C" {
           }
 
           buffer->string[buffer_position.stop] = object.string[input->start];
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           buffer_position.stop++;
         } // while
 
@@ -542,9 +657,15 @@ extern "C" {
         buffer->used = buffer_position.stop + 2;
         break;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
 
       buffer->string[buffer_position.stop] = object.string[input->start];
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       buffer_position.stop++;
     } // while
 
@@ -577,7 +698,7 @@ extern "C" {
     f_string_length pre_allocate_size = 0;
 
     // add an additional 1 to ensure that there is room for the terminating newline.
-    pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string;
 
     buffer_position.start = buffer->used;
     buffer_position.stop = buffer->used;
@@ -600,7 +721,7 @@ extern "C" {
         buffer_position.stop++;
       }
 
-      input->start++;
+      fl_fss_increment_buffer(*buffer, input, 1);
     } // while
 
     buffer->string[buffer_position.stop] = f_eol;
index eaf227fb9134e5435de9f56f317b124686b13fe2..bc913f3f7efea7ef98fcda8fb585c314509216b2 100644 (file)
@@ -20,6 +20,7 @@
 #include <level_0/strings.h>
 #include <level_0/types.h>
 #include <level_0/memory.h>
+#include <level_0/utf.h>
 
 // fll-1 includes
 #include <level_1/fss.h>
index a3d090adb52e78c5e35d6779a84fe8dfcba46f34..db5d3e18d100baf4f123006dfc6f1e815ab89eaa 100644 (file)
@@ -16,15 +16,19 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
-    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_fss_skip_past_whitespace(*buffer, input);
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
     // return found nothing if this line only contains whitespace and delimit placeholders
     if (buffer->string[input->start] == f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -35,7 +39,9 @@ extern "C" {
     if (buffer->string[input->start] == f_fss_comment) {
       fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -45,14 +51,16 @@ extern "C" {
         f_string_length first_slash = input->start;
         f_string_length slash_count = 1;
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start < buffer->used && input->start <= input->stop && (buffer->string[input->start] == f_fss_delimit_placeholder || buffer->string[input->start] == f_fss_delimit_slash)) {
           if (buffer->string[input->start] == f_fss_delimit_slash) {
             slash_count++;
           }
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
@@ -60,14 +68,18 @@ extern "C" {
         if (buffer->string[input->start] == f_fss_basic_list_open) {
           f_string_length stop_point = input->start - 1;
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start < buffer->used && input->start <= input->stop) {
-            if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) {
+            if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
               break;
             }
 
-            input->start++;
+            if (f_error_is_error(status)) return status;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
@@ -99,7 +111,8 @@ extern "C" {
                   slash_count--;
                 }
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
@@ -120,14 +133,18 @@ extern "C" {
       else if (buffer->string[input->start] == f_fss_basic_list_open) {
         f_string_length stop_point = input->start - 1;
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start < buffer->used && input->start <= input->stop) {
-          if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) {
+          if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
             break;
           }
 
-          input->start++;
+          if (f_error_is_error(status)) return status;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
@@ -136,7 +153,9 @@ extern "C" {
           fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
           found->stop = stop_point;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           return fl_fss_found_object;
         }
@@ -144,17 +163,21 @@ extern "C" {
         continue;
       }
 
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     // seek to the end of the line when no valid object is found
     while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-    input->start++;
+    status = fl_fss_increment_buffer(*buffer, input, 1);
+    if (f_error_is_error(status)) return status;
+
     return fl_fss_found_no_object;
   }
 #endif // _di_fl_fss_basic_list_object_read_
@@ -171,6 +194,8 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
@@ -188,7 +213,12 @@ extern "C" {
       if (buffer->string[input->start] == f_eol) {
         found_newline = f_true;
         last_newline = input->start;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
+        fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
+
         continue;
       }
 
@@ -196,14 +226,16 @@ extern "C" {
         f_string_length first_slash = input->start;
         f_string_length slash_count = 1;
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start < buffer->used && input->start <= input->stop && (buffer->string[input->start] == f_fss_delimit_placeholder || buffer->string[input->start] == f_fss_delimit_slash)) {
           if (buffer->string[input->start] == f_fss_delimit_slash) {
             slash_count++;
           }
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         if (found_newline) {
@@ -216,14 +248,18 @@ extern "C" {
         if (buffer->string[input->start] == f_fss_basic_list_open) {
           f_string_length stop_point = input->start - 1;
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start < buffer->used && input->start <= input->stop) {
-            if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) {
+            if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
               break;
             }
 
-            input->start++;
+            if (f_error_is_error(status)) return status;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           if (found_newline) {
@@ -274,7 +310,8 @@ extern "C" {
                 slash_count--;
               }
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
             } // while
 
             found_newline = f_true;
@@ -285,14 +322,18 @@ extern "C" {
         continue;
       }
       else if (buffer->string[input->start] == f_fss_basic_list_open) {
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start < buffer->used && input->start <= input->stop) {
-          if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) {
+          if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
             break;
           }
 
-          input->start++;
+          if (f_error_is_error(status)) return status;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         if (found_newline) {
@@ -323,7 +364,8 @@ extern "C" {
         continue;
       }
 
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     if (found_newline) {
@@ -369,7 +411,7 @@ extern "C" {
     start_position = input->start;
 
     // add an additional 2 to ensure that there is room for the slash delimit and the object open character.
-    pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step_string;
 
     if (pre_allocate_size > buffer->size) {
       f_resize_dynamic_string(status, (*buffer), pre_allocate_size);
@@ -385,16 +427,20 @@ extern "C" {
         // comments are not allowed and this format has no way of "wrapping" a comment.
         return f_invalid_data;
       }
-      else if (isgraph(object.string[input->start])) {
+      else if ((status = fl_fss_is_graph(object, *input)) == f_true) {
         break;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
 
       if (object.string[input->start] != f_fss_delimit_placeholder) {
         buffer->string[buffer_position.stop] = object.string[input->start];
         buffer_position.stop++;
       }
 
-      input->start++;
+      status = fl_fss_increment_buffer(object, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     while (input->start <= input->stop && input->start < object.used) {
@@ -404,11 +450,14 @@ extern "C" {
         buffer->string[buffer_position.stop] = object.string[input->start];
         buffer_position.stop++;
 
-        input->start++;
+        status = fl_fss_increment_buffer(object, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start <= input->stop && input->start < object.used) {
           if (object.string[input->start] == f_fss_delimit_placeholder) {
-            input->start++;
+            status = fl_fss_increment_buffer(object, input, 1);
+            if (f_error_is_error(status)) return status;
+
             continue;
           } else if (object.string[input->start] != f_fss_delimit_slash) {
             break;
@@ -416,7 +465,10 @@ extern "C" {
 
           buffer->string[buffer_position.stop] = object.string[input->start];
           buffer_position.stop++;
-          input->start++;
+
+          status = fl_fss_increment_buffer(object, input, 1);
+          if (f_error_is_error(status)) return status;
+
           slash_count++;
         } // while
 
@@ -424,7 +476,7 @@ extern "C" {
           pre_allocate_size += slash_count;
 
           if (pre_allocate_size > buffer->size) {
-            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
             if (f_error_is_error(status)) return status;
           }
@@ -451,7 +503,8 @@ extern "C" {
         buffer_position.stop++;
       }
 
-      input->start++;
+      status = fl_fss_increment_buffer(object, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     buffer->string[buffer_position.stop] = f_fss_basic_list_open;
@@ -495,7 +548,7 @@ extern "C" {
     start_position = input->start;
 
     // add an additional 2 to ensure that there is room for the slash delimit and the content open character.
-    pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step_string;
 
     if (pre_allocate_size > buffer->size) {
       f_resize_dynamic_string(status, (*buffer), pre_allocate_size);
@@ -514,11 +567,14 @@ extern "C" {
         buffer_position.stop++;
 
         has_graph = f_true;
-        input->start++;
+        status = fl_fss_increment_buffer(content, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start <= input->stop && input->start < content.used) {
           if (content.string[input->start] == f_fss_delimit_placeholder) {
-            input->start++;
+            status = fl_fss_increment_buffer(content, input, 1);
+            if (f_error_is_error(status)) return status;
+
             continue;
           }
           else if (content.string[input->start] != f_fss_delimit_slash) {
@@ -527,28 +583,35 @@ extern "C" {
 
           buffer->string[buffer_position.stop] = content.string[input->start];
           buffer_position.stop++;
-          input->start++;
+
+          status = fl_fss_increment_buffer(content, input, 1);
+          if (f_error_is_error(status)) return status;
+
           slash_count++;
         } // while
 
         if (content.string[input->start] == f_fss_basic_list_open) {
           f_string_length location = input->start;
 
-          input->start++;
+          status = fl_fss_increment_buffer(content, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start < content.used && input->start <= input->stop) {
-            if (content.string[input->start] == f_eol || isgraph(content.string[input->start])) {
+            if (content.string[input->start] == f_eol || (status = fl_fss_is_graph(content, *input)) == f_true) {
               break;
             }
 
-            input->start++;
+            if (f_error_is_error(status)) return status;
+
+            status = fl_fss_increment_buffer(content, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           if (content.string[input->start] == f_eol || input->start >= content.used || input->start > input->stop) {
             pre_allocate_size += slash_count + 1;
 
             if (pre_allocate_size > buffer->size) {
-              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) return status;
             }
@@ -575,21 +638,26 @@ extern "C" {
         f_string_length location = input->start;
 
         has_graph = f_true;
-        input->start++;
+
+        status = fl_fss_increment_buffer(content, input, 1);
+        if (f_error_is_error(status)) return status;
 
         while (input->start < content.used && input->start <= input->stop) {
-          if (content.string[input->start] == f_eol || isgraph(content.string[input->start])) {
+          if (content.string[input->start] == f_eol || (status = fl_fss_is_graph(content, *input)) == f_true) {
             break;
           }
 
-          input->start++;
+          if (f_error_is_error(status)) return status;
+
+          status = fl_fss_increment_buffer(content, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         if (content.string[input->start] == f_eol || input->start >= content.used || input->start > input->stop) {
           pre_allocate_size++;
 
           if (pre_allocate_size > buffer->size) {
-            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
             if (f_error_is_error(status)) return status;
           }
@@ -612,16 +680,20 @@ extern "C" {
         has_graph = f_false;
         is_comment = f_false;
       }
-      else if (isgraph(content.string[input->start])) {
+      else if ((status = fl_fss_is_graph(content, *input)) == f_true) {
         has_graph = f_true;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
 
       if (content.string[input->start] != f_fss_delimit_placeholder) {
         buffer->string[buffer_position.stop] = content.string[input->start];
         buffer_position.stop++;
       }
 
-      input->start++;
+      status = fl_fss_increment_buffer(content, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     buffer->string[buffer_position.stop] = f_eol;
index a1d5f5f3f853b7a081bf63308b29568db0cb3f80..ae16b076f85afa8718482118a9c11e2fced49cf1 100644 (file)
@@ -20,6 +20,7 @@
 #include <level_0/memory.h>
 #include <level_0/strings.h>
 #include <level_0/types.h>
+#include <level_0/utf.h>
 
 // fll-1 includes
 #include <level_1/fss.h>
index da86914a7c8286fc5a44465485d9ac2ddc599dd7..7c6a6a5f59dd0748882dd9d2e5c98439dc0bf970 100644 (file)
@@ -16,15 +16,19 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
-    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_fss_skip_past_whitespace(*buffer, input);
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
     // return found nothing if this line only contains whitespace and delimit placeholders
     if (buffer->string[input->start] == f_fss_extended_close) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -39,7 +43,9 @@ extern "C" {
     if (buffer->string[input->start] == f_fss_comment) {
       fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_object;
     }
 
@@ -49,24 +55,36 @@ extern "C" {
     // identify where the object begins
     if (buffer->string[input->start] == f_fss_delimit_slash) {
       f_string_length last_slash = input->start;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
 
       while (input->start <= input->stop && input->start < buffer->used) {
         if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         }
-        else if (!isgraph(buffer->string[input->start])) {
+        else if ((status = fl_fss_is_graph(*buffer, *input)) == f_false) {
           found->stop = input->start - 1;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           return fl_fss_found_object;
         }
+        else if (f_error_is_error(status)) {
+          return status;
+        }
         else if (buffer->string[input->start] != f_fss_delimit_slash) {
           break;
         }
 
         last_slash = input->start;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
@@ -85,46 +103,67 @@ extern "C" {
 
         delimits.array[delimits.used] = last_slash;
         delimits.used++;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       }
     }
     else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
       quoted = buffer->string[input->start];
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       found->start = input->start;
     }
 
     // identify where the object ends
     if (quoted == f_eos) {
-      while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) {
-        input->start++;
+      status = f_none;
+      while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
       } // while
 
-      if (isspace(buffer->string[input->start])) {
+      if (f_error_is_error(status)) return status;
+
+      if ((status = fl_fss_is_space(*buffer, *input)) == f_true) {
         found->stop = input->start - 1;
 
         fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
         if (buffer->string[input->start] == f_eol) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           return fl_fss_found_object_no_content;
         }
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         return fl_fss_found_object;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
     }
     else {
       while (input->start <= input->stop && input->start < buffer->used) {
         if (buffer->string[input->start] == f_fss_delimit_slash) {
           f_string_length first_slash = input->start;
           f_string_length slash_count = 1;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start <= input->stop && input->start < buffer->used) {
             if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               continue;
             }
             else if (buffer->string[input->start] != f_fss_delimit_slash) {
@@ -132,7 +171,9 @@ extern "C" {
             }
 
             slash_count++;
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -164,7 +205,8 @@ extern "C" {
                   slash_count--;
                 }
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               input->start = location + 1;
@@ -172,21 +214,29 @@ extern "C" {
               fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
               fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
 
-              if (isgraph(buffer->string[input->start])) {
+              if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) {
                 while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
                 } // while
 
                 fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 return fl_fss_found_no_object;
               }
+              else if (f_error_is_error(status)) {
+                return status;
+              }
               else if (buffer->string[input->start] == f_eol) {
                 fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
                 found->stop = location - 1;
-                input->start++;
+
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
 
                 return fl_fss_found_object_no_content;
               }
@@ -194,7 +244,10 @@ extern "C" {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
               found->stop = location - 1;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object;
             }
             else {
@@ -219,7 +272,8 @@ extern "C" {
                   slash_count--;
                 }
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               input->start = location;
@@ -228,43 +282,59 @@ extern "C" {
         }
         else if (buffer->string[input->start] == quoted) {
           found->stop = input->start - 1;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start <= input->stop && input->start < buffer->used) {
             if (buffer->string[input->start] == f_eol) {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object_no_content;
             }
-            else if (isspace(buffer->string[input->start])) {
+            else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_object;
             }
+            else if (f_error_is_error(status)) {
+              return status;
+            }
             else if (buffer->string[input->start] != f_fss_delimit_placeholder) {
               while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
               } // while
 
               fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_no_object;
             }
 
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
         }
         else if (buffer->string[input->start] == f_eol) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           return fl_fss_found_no_object;
         }
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -272,12 +342,15 @@ extern "C" {
 
     // seek to the end of the line when no valid object is found
     while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop)
 
-    input->start++;
+    status = fl_fss_increment_buffer(*buffer, input, 1);
+    if (f_error_is_error(status)) return status;
+
     return fl_fss_found_no_object;
   }
 #endif // _di_fl_fss_extended_object_read_
@@ -294,19 +367,22 @@ extern "C" {
       if (input->start >= buffer->used) return f_error_set_error(f_invalid_parameter);
     #endif // _di_level_1_parameter_checking_
 
+    f_status status = f_none;
+
     // delimits must only be applied once a valid object is found
     f_string_lengths delimits = f_string_lengths_initialize;
 
-    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_fss_skip_past_whitespace(*buffer, input);
     fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
 
     // return found nothing if this line only contains whitespace and delimit placeholders
     if (buffer->string[input->start] == f_fss_extended_close) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_content;
     }
 
-    f_status status = f_none;
     f_bool has_delimit = f_false;
     char quoted = f_eos;
 
@@ -337,16 +413,23 @@ extern "C" {
       if (buffer->string[input->start] == f_fss_delimit_slash) {
         f_string_length last_slash = input->start;
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
 
         while (input->start <= input->stop && input->start < buffer->used) {
           if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
             continue;
           }
-          else if (!isgraph(buffer->string[input->start])) {
+          else if ((status = fl_fss_is_graph(*buffer, *input)) == f_false) {
             found->array[found->used].stop = input->start - 1;
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
             found->used++;
 
             if (buffer->string[input->start] == f_eol) {
@@ -358,12 +441,17 @@ extern "C" {
             continue_main_loop = f_true;
             break;
           }
+          else if (f_error_is_error(status)) {
+            return status;
+          }
           else if (buffer->string[input->start] != f_fss_delimit_slash) {
             break;
           }
 
           last_slash = input->start;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         if (continue_main_loop) {
@@ -387,47 +475,68 @@ extern "C" {
 
           delimits.array[delimits.used] = last_slash;
           delimits.used++;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         }
       }
       else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
         quoted = buffer->string[input->start];
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         found->array[found->used].start = input->start;
       }
 
       // identify where the content ends
       if (quoted == f_eos) {
-        while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+        status = f_none;
+        while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) {
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
         } // while
 
-        if (isspace(buffer->string[input->start])) {
+        if (f_error_is_error(status)) return status;
+
+        if ((status = fl_fss_is_space(*buffer, *input)) == f_true) {
           found->array[found->used].stop = input->start - 1;
           found->used++;
 
           if (buffer->string[input->start] == f_eol) {
             fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
             return fl_fss_found_content;
           }
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         }
+        else if (f_error_is_error(status)) {
+          return status;
+        }
       }
       else {
         while (input->start <= input->stop && input->start < buffer->used) {
           if (buffer->string[input->start] == f_fss_delimit_slash) {
             f_string_length first_slash = input->start;
             f_string_length slash_count = 1;
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
 
             while (input->start <= input->stop && input->start < buffer->used) {
               if (buffer->string[input->start] == f_fss_delimit_placeholder) {
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 continue;
               }
               else if (buffer->string[input->start] != f_fss_delimit_slash) {
@@ -435,7 +544,9 @@ extern "C" {
               }
 
               slash_count++;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
             } // while
 
             fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -466,7 +577,8 @@ extern "C" {
                     slash_count--;
                   }
 
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
                 } // while
 
                 input->start = location + 1;
@@ -474,28 +586,40 @@ extern "C" {
                 fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
                 fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
 
-                if (isgraph(buffer->string[input->start])) {
+                if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) {
                   while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                    input->start++;
+                    status = fl_fss_increment_buffer(*buffer, input, 1);
+                    if (f_error_is_error(status)) return status;
                   } // while
 
                   fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
 
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
+
                   return f_error_is_warning(f_unterminated_group);
                 }
+                else if (f_error_is_error(status)) {
+                  return status;
+                }
                 else if (buffer->string[input->start] == f_eol) {
                   fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
                   found->array[found->used].stop = location - 1;
-                  input->start++;
+
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
+
                   found->used++;
 
                   return fl_fss_found_content;
                 }
 
                 found->array[found->used].stop = location - 1;
-                input->start++;
+
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 found->used++;
                 continue;
               }
@@ -521,7 +645,8 @@ extern "C" {
                     slash_count--;
                   }
 
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
                 } // while
 
                 input->start = location;
@@ -530,35 +655,48 @@ extern "C" {
           }
           else if (buffer->string[input->start] == quoted) {
             found->array[found->used].stop = input->start - 1;
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
 
             while (input->start <= input->stop && input->start < buffer->used) {
               if (buffer->string[input->start] == f_eol) {
                 fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 found->used++;
 
                 return fl_fss_found_content;
               }
-              else if (isspace(buffer->string[input->start])) {
-                input->start++;
+              else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) {
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 found->used++;
                 continue_main_loop = f_true;
                 break;
               }
+              else if (f_error_is_error(status)) {
+                return status;
+              }
               else if (buffer->string[input->start] != f_fss_delimit_placeholder) {
                 while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-                  input->start++;
+                  status = fl_fss_increment_buffer(*buffer, input, 1);
+                  if (f_error_is_error(status)) return status;
                 } // while
 
                 fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
 
-                input->start++;
+                status = fl_fss_increment_buffer(*buffer, input, 1);
+                if (f_error_is_error(status)) return status;
+
                 return f_error_is_warning(f_unterminated_group);
               }
 
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
             } // while
 
             if (continue_main_loop) {
@@ -570,21 +708,27 @@ extern "C" {
           else if (buffer->string[input->start] == f_eol) {
 
             if (found->used == already_used) {
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               return fl_fss_found_no_content;
             }
             else {
               fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
               found->array[found->used].stop = input->start - 1;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               found->used++;
 
               return fl_fss_found_content;
             }
           }
 
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
         } // while
 
         fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop))
@@ -602,19 +746,24 @@ extern "C" {
 
     // seek to the end of the line when no valid content is found
     while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop)
 
     if (found->used == already_used) {
-      input->start++;
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       return fl_fss_found_no_content;
     }
 
     fl_macro_fss_apply_delimit_placeholders((*buffer), delimits);
 
-    input->start++;
+    status = fl_fss_increment_buffer(*buffer, input, 1);
+    if (f_error_is_error(status)) return status;
+
     return fl_fss_found_content;
   }
 #endif // _di_fl_fss_extended_content_read_
@@ -644,7 +793,7 @@ extern "C" {
     start_position = input->start;
 
     // add an additional 3 to ensure that there is room for the start and stop quotes or a slash delimit and the object open character.
-    pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step_string;
 
     if (pre_allocate_size > buffer->size) {
       f_resize_dynamic_string(status, (*buffer), pre_allocate_size);
@@ -658,7 +807,9 @@ extern "C" {
     if (object.string[input->start] == f_fss_delimit_slash) {
       while (input->start <= input->stop && input->start < object.used) {
         if (object.string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         } else if (object.string[input->start] != f_fss_delimit_slash) {
           break;
@@ -666,14 +817,16 @@ extern "C" {
 
         buffer->string[buffer_position.stop] = object.string[input->start];
         buffer_position.stop++;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) {
         pre_allocate_size++;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -681,14 +834,16 @@ extern "C" {
         buffer->string[buffer_position.stop] = f_fss_delimit_slash;
         buffer->string[buffer_position.stop + 1] = object.string[input->start];
         buffer_position.stop += 2;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       }
     }
     else if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) {
       pre_allocate_size++;
 
       if (pre_allocate_size > buffer->size) {
-        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
         if (f_error_is_error(status)) return status;
       }
@@ -696,7 +851,9 @@ extern "C" {
       buffer->string[buffer_position.stop] = f_fss_delimit_slash;
       buffer->string[buffer_position.stop + 1] = object.string[input->start];
       buffer_position.stop += 2;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     }
     else if (object.string[input->start] == f_fss_comment) {
       quoted = f_true;
@@ -704,7 +861,9 @@ extern "C" {
 
     while (input->start <= input->stop && input->start < object.used) {
       if (object.string[input->start] == f_fss_delimit_placeholder) {
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
+
         continue;
       }
       else if (object.string[input->start] == f_eol) {
@@ -718,14 +877,16 @@ extern "C" {
 
         return f_none_on_eol;
       }
-      else if (isspace(object.string[input->start]) || quoted) {
+      else if ((status = fl_fss_is_space(*buffer, *input)) == f_true || quoted) {
         f_string_length first_space = input->start;
 
         if (!quoted) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start <= input->stop && input->start < object.used && isspace(object.string[input->start])) {
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           if (input->start > input->stop || input->start >= object.used) {
@@ -738,7 +899,7 @@ extern "C" {
         pre_allocate_size++;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -752,14 +913,16 @@ extern "C" {
 
         while (input->start <= input->stop && input->start < object.used) {
           if (object.string[input->start] == f_fss_delimit_placeholder) {
-            input->start++;
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
+
             continue;
           }
           else if (object.string[input->start] == f_fss_delimit_double_quote) {
             pre_allocate_size++;
 
             if (pre_allocate_size > buffer->size) {
-              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) return status;
             }
@@ -774,7 +937,10 @@ extern "C" {
               buffer->string[buffer_position.stop] = object.string[input->start];
               buffer_position.stop++;
               slash_count++;
-              input->start++;
+
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
 
               fl_macro_fss_skip_past_delimit_placeholders(object, (*input));
 
@@ -786,7 +952,7 @@ extern "C" {
                 pre_allocate_size += slash_count;
 
                 if (pre_allocate_size > buffer->size) {
-                  f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+                  f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
                   if (f_error_is_error(status)) return status;
                 }
@@ -818,7 +984,10 @@ extern "C" {
           }
 
           buffer->string[buffer_position.stop] = object.string[input->start];
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           buffer_position.stop++;
         } // while
 
@@ -827,9 +996,15 @@ extern "C" {
         buffer->used = buffer_position.stop + 2;
         break;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
 
       buffer->string[buffer_position.stop] = object.string[input->start];
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
+
       buffer_position.stop++;
     } // while
 
@@ -863,7 +1038,7 @@ extern "C" {
     f_string_length pre_allocate_size = 0;
 
     // add an additional 1 to ensure that there is room for the terminating newline.
-    pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step;
+    pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string;
 
     buffer_position.start = buffer->used;
     buffer_position.stop = buffer->used;
@@ -889,11 +1064,15 @@ extern "C" {
     if (content.string[input->start] == f_fss_delimit_slash) {
       buffer->string[buffer_position.stop] = f_fss_delimit_slash;
       buffer_position.stop++;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
 
       while (input->start <= input->stop && input->start < content.used) {
         if (content.string[input->start] == f_fss_delimit_placeholder) {
-          input->start++;
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
+
           continue;
         }
 
@@ -903,7 +1082,9 @@ extern "C" {
 
         buffer->string[buffer_position.stop] = f_fss_delimit_slash;
         buffer_position.stop++;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       if (input->start > input->stop) {
@@ -921,7 +1102,7 @@ extern "C" {
         pre_allocate_size++;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -929,14 +1110,16 @@ extern "C" {
         buffer->string[buffer_position.stop] = f_fss_delimit_slash;
         buffer->string[buffer_position.stop + 1] = content.string[input->start];
         buffer_position.stop += 2;
-        input->start++;
+
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       }
     }
     else if (content.string[input->start] == f_fss_delimit_single_quote || content.string[input->start] == f_fss_delimit_double_quote) {
       pre_allocate_size++;
 
       if (pre_allocate_size > buffer->size) {
-        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+        f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
         if (f_error_is_error(status)) return status;
       }
@@ -944,7 +1127,9 @@ extern "C" {
       buffer->string[buffer_position.stop] = f_fss_delimit_slash;
       buffer->string[buffer_position.stop + 1] = content.string[input->start];
       buffer_position.stop += 2;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     }
 
     while (input->start <= input->stop && input->start < content.used) {
@@ -954,13 +1139,13 @@ extern "C" {
         return f_none_on_eol;
       }
 
-      if (content.string[input->start] != f_fss_delimit_placeholder && !isgraph(content.string[input->start])) {
+      if (content.string[input->start] != f_fss_delimit_placeholder && (status = fl_fss_is_graph(*buffer, *input)) == f_false) {
         quoted = f_fss_delimit_double_quote;
 
         pre_allocate_size += 2;
 
         if (pre_allocate_size > buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
           if (f_error_is_error(status)) return status;
         }
@@ -971,10 +1156,15 @@ extern "C" {
         buffer_position.stop++;
         break;
       }
+      else if (f_error_is_error(status)) {
+        return status;
+      }
 
       buffer->string[buffer_position.stop] = content.string[input->start];
       buffer_position.stop++;
-      input->start++;
+
+      status = fl_fss_increment_buffer(*buffer, input, 1);
+      if (f_error_is_error(status)) return status;
     } // while
 
     if (quoted != f_eos) {
@@ -984,11 +1174,15 @@ extern "C" {
 
           buffer->string[buffer_position.stop] = f_fss_delimit_slash;
           buffer_position.stop++;
-          input->start++;
+
+          status = fl_fss_increment_buffer(*buffer, input, 1);
+          if (f_error_is_error(status)) return status;
 
           while (input->start <= input->stop && input->start < content.used) {
             if (content.string[input->start] == f_fss_delimit_placeholder) {
-              input->start++;
+              status = fl_fss_increment_buffer(*buffer, input, 1);
+              if (f_error_is_error(status)) return status;
+
               continue;
             }
 
@@ -999,14 +1193,16 @@ extern "C" {
             buffer->string[buffer_position.stop] = f_fss_delimit_slash;
             buffer_position.stop++;
             slash_count++;
-            input->start++;
+
+            status = fl_fss_increment_buffer(*buffer, input, 1);
+            if (f_error_is_error(status)) return status;
           } // while
 
           if (content.string[input->start] == quoted || input->start > input->stop || input->start >= content.used) {
             pre_allocate_size += slash_count + 1;
 
             if (pre_allocate_size > buffer->size) {
-              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) return status;
             }
@@ -1034,7 +1230,7 @@ extern "C" {
           pre_allocate_size++;
 
           if (pre_allocate_size > buffer->size) {
-            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step);
+            f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string);
 
             if (f_error_is_error(status)) return status;
           }
@@ -1054,7 +1250,8 @@ extern "C" {
           buffer_position.stop++;
         }
 
-        input->start++;
+        status = fl_fss_increment_buffer(*buffer, input, 1);
+        if (f_error_is_error(status)) return status;
       } // while
 
       buffer->string[buffer_position.stop] = quoted;
index 5216d6086708207f619110357dcec84337f0f438..6594d11fcf2f567630273919d88b75b8dbb4b51d 100644 (file)
@@ -20,6 +20,7 @@
 #include <level_0/memory.h>
 #include <level_0/strings.h>
 #include <level_0/types.h>
+#include <level_0/utf.h>
 
 // fll-1 includes
 #include <level_1/fss.h>
index 29a1790ba5bd90c07135802033f305b99bfa1410..148742d1ce054829445570fa660e33416e7216c2 100644 (file)
@@ -14,6 +14,7 @@
 extern "C" {
 #endif
 
+// TODO: check if character to be replaced is UTF and apply placeholder to entire width.
 #ifndef _di_fl_macro_fss_apply_delimit_placeholders_
   #define fl_macro_fss_apply_delimit_placeholders(buffer, delimits) \
   { \
@@ -30,28 +31,6 @@ extern "C" {
   }
 #endif // _di_fl_macro_fss_apply_delimit_placeholders_
 
-#ifndef _di_fl_macro_fss_skip_past_whitespace_
-  #define fl_macro_fss_skip_past_whitespace(buffer, input) \
-    while (!isgraph(buffer.string[input.start]) || buffer.string[input.start] == f_fss_delimit_placeholder) { \
-      if (buffer.string[input.start] == f_eol) break; \
-      \
-      ++input.start;\
-      \
-      if (input.start >= buffer.used) break; \
-      if (input.start  > input.stop) break; \
-    } // while
-#endif // _di_fl_macro_fss_skip_past_whitespace_
-
-#ifndef _di_fl_macro_fss_skip_past_all_whitespace_
-  #define fl_macro_fss_skip_past_all_whitespace(buffer, input) \
-    while (!isgraph(buffer.string[input.start]) || buffer.string[input.start] == f_fss_delimit_placeholder) { \
-      ++input.start;\
-      \
-      if (input.start >= buffer.used) break; \
-      if (input.start  > input.stop) break; \
-    } // while
-#endif // _di_fl_macro_fss_skip_past_all_whitespace_
-
 #ifndef _di_fl_macro_fss_skip_past_delimit_placeholders_
   #define fl_macro_fss_skip_past_delimit_placeholders(buffer, input) \
     while (buffer.string[input.start] == f_fss_delimit_placeholder) { \
index 33cb18bc075bf1ca312fd924f02503e461e3fe78..5dd4d0c8fb1d78bbd4b8230bb7247bde2e7783bc 100644 (file)
@@ -5,3 +5,4 @@ f_memory
 f_file
 f_conversion
 f_fss
+f_utf
index deade3e07f7b100662c17d6e12939357dcee4514..d4b1e3c21c74308c1e2f115e88b77be431ad5901 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lf_conversion -lf_file -lf_memory
+build_libraries_fll -lf_conversion -lf_file -lf_memory -lf_utf
 build_sources_library fss.c fss_basic.c fss_basic_list.c fss_extended.c
 build_sources_program 
 build_sources_headers fss.h fss_basic.h fss_basic_list.h fss_errors.h fss_extended.h fss_macro.h
index 0e4cd2c83c5f0f0723f4dd5afefe0dc5ba9608e7..a7d83872af138ff2b61875f3d1e90d23e412888a 100644 (file)
@@ -4,6 +4,8 @@
 extern "C" {
 #endif
 
+// TODO: this file needs to be rewriten with UTF-8 support.
+
 #ifndef _di_fl_rip_string_
   f_return_status fl_rip_string(const f_dynamic_string buffer, const f_string_location position, f_dynamic_string *results) {
     #ifndef _di_level_1_parameter_checking_
index 831d2ef28773012c0ab70156b5e2812630e53bb5..a8027da29e76c2af65e9513f74a5d4e1394787bb 100644 (file)
@@ -19,6 +19,7 @@
 #include <level_0/memory.h>
 #include <level_0/strings.h>
 #include <level_0/types.h>
+#include <level_0/utf.h>
 
 #ifdef __cplusplus
 extern "C" {
index a2496a1fa0782112d706db7ae82285f16a225949..7d0693b06a8a710281827f1f6cb27289e63069b4 100644 (file)
@@ -1,4 +1,5 @@
-f_types
 f_errors
-f_strings
+f_types
 f_memory
+f_strings
+f_utf
index 28ad104b90be8236d9a4b52ec9c6f74c533fe89a..5bdbe19ea46408117e855449ed2aa4c2df40e2a9 100644 (file)
@@ -10,9 +10,9 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lf_memory
+build_libraries_fll -lf_memory -lf_utf
 build_sources_library strings.c
-build_sources_program 
+build_sources_program
 build_sources_headers strings.h
 build_sources_bash
 build_sources_settings
index d9012f82092b4245711e2e4f2d971594ced96055..095d3110078ffdf30bc248dd15fdb72003e3b5f6 100644 (file)
@@ -165,7 +165,7 @@ extern "C" {
       }
       else {
         if (buffer->used >= buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step_string);
           if (f_error_is_error(status)) return status;
         }
 
index 0d892c5c9209fc54122b52d4de2d75a3e089ad3a..7ad05f7aab4c36c1e2049424a12d2683fabad964 100644 (file)
@@ -16,6 +16,7 @@
 #include <level_0/memory.h>
 #include <level_0/strings.h>
 #include <level_0/types.h>
+#include <level_0/utf.h>
 
 // fll-1 includes
 #include <level_1/fss.h>
index 42df25c03c28968e7b4c45c41fac00acbad1048a..bda34b51a20148ca5aef1473ea26dd991192aaf7 100644 (file)
@@ -165,7 +165,7 @@ extern "C" {
       }
       else {
         if (buffer->used >= buffer->size) {
-          f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step);
+          f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step_string);
           if (f_error_is_error(status)) return status;
         }
 
index 28488eb77557e21613d3bd453aebe426fbc74404..fcd05611cae2016de39a996f59867f39715fb981 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfl_errors -lfl_fss -lf_conversion -lf_file -lf_memory
+build_libraries_fll -lfl_errors -lfl_fss -lf_conversion -lf_file -lf_memory -lf_utf
 build_sources_library fss_basic.c fss_basic_list.c fss_extended.c fss_errors.c
 build_sources_program
 build_sources_headers fss_basic.h fss_basic_list.h fss_extended.h fss_errors.h
index 2acfc5d13a2f40d73d635be1166d66676237b76b..28b5513f2d611fd687a9e16c4c803e70fb9c34e6 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_fss -lfl_program -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_fss -lfl_program -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library firewall.c private-firewall.c
index 141d9d1f17934ff79ac0558e86cffd0a256235a8..141694fb8be4f824ab2b43af7a78942ed7a3743f 100644 (file)
@@ -329,31 +329,37 @@ extern "C" {
       input.stop  = data->buffer.used - 1;
 
       status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents);
-    }
 
-    if (f_error_is_error(status)) {
-      status = f_error_set_fine(status);
+      if (f_error_is_error(status)) {
+        status = f_error_set_fine(status);
 
-      if (status == f_invalid_parameter) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename);
-      }
-      else if (f_macro_test_for_allocation_errors(status)) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
-      }
-      else {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename);
-      }
+        if (status == f_invalid_parameter) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename);
+        }
+        else if (f_macro_test_for_allocation_errors(status)) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
+        }
+        else if (status == f_incomplete_utf_on_stop) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start);
+        }
+        else if (status == f_incomplete_utf_on_eos) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start);
+        }
+        else {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename);
+        }
 
-      fss_basic_list_read_delete_data(data);
-      return f_error_set_error(status);
-    }
-    else if (f_macro_test_for_no_data_errors(status)) {
-      // clear buffers, then attempt the next file
-      f_delete_fss_contents(status2, data->contents);
-      f_delete_fss_objects(status2, data->objects);
-      f_delete_dynamic_string(status2, data->buffer);
+        fss_basic_list_read_delete_data(data);
+        return f_error_set_error(status);
+      }
+      else if (f_macro_test_for_no_data_errors(status)) {
+        // clear buffers, then attempt the next file
+        f_delete_fss_contents(status2, data->contents);
+        f_delete_fss_objects(status2, data->objects);
+        f_delete_dynamic_string(status2, data->buffer);
 
-      return f_error_set_warning(status);
+        return f_error_set_warning(status);
+      }
     }
 
     // now that all of the files have been read, process the objects and contents
index eeb45c9429c0722e40c55d1d5a02b127189e675e..e3d412d90b34743f26de6781fa800e0e9c20dba4 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_list_read.c
index 91b61e31d85257634b5d0b0e6b4aa2ecdacbea32..8c1e854bc628b56d419c7bbaf06a99573b73793d 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss  -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss  -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_list_write.c
index 5f88489ce2725c955a08c6c9dfbbd7df48c5de22..ce1770f48ea15d4b08e80040fc39c811dafde3c9 100644 (file)
@@ -323,31 +323,37 @@ extern "C" {
       input.stop  = data->buffer.used - 1;
 
       status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents);
-    }
 
-    if (f_error_is_error(status)) {
-      status = f_error_set_fine(status);
+      if (f_error_is_error(status)) {
+        status = f_error_set_fine(status);
 
-      if (status == f_invalid_parameter) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename);
-      }
-      else if (f_macro_test_for_allocation_errors(status)) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
-      }
-      else {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename);
-      }
+        if (status == f_invalid_parameter) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename);
+        }
+        else if (f_macro_test_for_allocation_errors(status)) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
+        }
+        else if (status == f_incomplete_utf_on_stop) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start);
+        }
+        else if (status == f_incomplete_utf_on_eos) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start);
+        }
+        else {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename);
+        }
 
-      fss_basic_read_delete_data(data);
-      return f_error_set_error(status);
-    }
-    else if (f_macro_test_for_no_data_errors(status)) {
-      // clear buffers, then attempt the next file
-      f_delete_fss_contents(status2, data->contents);
-      f_delete_fss_objects(status2, data->objects);
-      f_delete_dynamic_string(status2, data->buffer);
+        fss_basic_read_delete_data(data);
+        return f_error_set_error(status);
+      }
+      else if (f_macro_test_for_no_data_errors(status)) {
+        // clear buffers, then attempt the next file
+        f_delete_fss_contents(status2, data->contents);
+        f_delete_fss_objects(status2, data->objects);
+        f_delete_dynamic_string(status2, data->buffer);
 
-      return f_error_set_warning(status);
+        return f_error_set_warning(status);
+      }
     }
 
     // now that the file has been read, process the objects and contents
index af3078611678c4a81df1ee90b5f9e51d011de800..ba964b68e95f772530ae0aaf155cf0db3239d070 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_print -lf_file -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_print -lf_file -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_read.c
index 19f44bb83828836f849a0ddf883b5e2990280084..accc86f27a0f3776300461ae8c20adb8c0134b2f 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_basic_write.c
index c03314c01b0f062e3c2ad0017936fb43ec2a30e8..0043fe90e37bf00918c4ca68cc04dae09fa91a87 100644 (file)
@@ -336,31 +336,37 @@ extern "C" {
       input.stop = data->buffer.used - 1;
 
       status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents);
-    }
 
-    if (f_error_is_error(status)) {
-      status = f_error_set_fine(status);
+      if (f_error_is_error(status)) {
+        status = f_error_set_fine(status);
 
-      if (status == f_invalid_parameter) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", filename);
-      }
-      else if (f_macro_test_for_allocation_errors(status)) {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
-      }
-      else {
-        fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", f_error_set_error(status), filename);
-      }
+        if (status == f_invalid_parameter) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", filename);
+        }
+        else if (f_macro_test_for_allocation_errors(status)) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory");
+        }
+        else if (status == f_incomplete_utf_on_stop) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start);
+        }
+        else if (status == f_incomplete_utf_on_eos) {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start);
+        }
+        else {
+          fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", f_error_set_error(status), filename);
+        }
 
-      fss_extended_read_delete_data(data);
-      return f_error_set_error(status);
-    }
-    else if (f_macro_test_for_no_data_errors(status)) {
-      // clear buffers, then attempt the next file
-      f_delete_fss_contents(status2, data->contents);
-      f_delete_fss_objects(status2, data->objects);
-      f_delete_dynamic_string(status2, data->buffer);
+        fss_extended_read_delete_data(data);
+        return f_error_set_error(status);
+      }
+      else if (f_macro_test_for_no_data_errors(status)) {
+        // clear buffers, then attempt the next file
+        f_delete_fss_contents(status2, data->contents);
+        f_delete_fss_objects(status2, data->objects);
+        f_delete_dynamic_string(status2, data->buffer);
 
-      return f_error_set_warning(status);
+        return f_error_set_warning(status);
+      }
     }
 
     // now that all of the files have been read, process the objects and contents
index a9624dc294689eaee4ee5bd8ceb79fab8ddb29c5..5491abd9b7ddd44c09505f0ad58221802328e0eb 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_extended_read.c
index 08013ea59a08f98bd61ba079ed55663cd3fd94db..a7282e9e173f0bb7383d2a66ca55d829094e296f 100644 (file)
@@ -203,7 +203,7 @@ extern "C" {
 
           if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) {
             if (buffer.used >= buffer.size) {
-              f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) {
                 return status;
@@ -254,7 +254,7 @@ extern "C" {
 
           if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) {
             if (buffer.used >= buffer.size) {
-              f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step);
+              f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step_string);
 
               if (f_error_is_error(status)) {
                 return status;
index 68978a02274e3c86796e006857324941f7403935..1797d0485715d205fe33db23200cb80cb8aded02 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_extended_write.c
index aad1f03528e0ff4f28c516a91d687b8d59f7bae6..c34203164a9647d6af9b46065303c5e174cc6ab7 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library fss_return_code.c
index 7567fa2d3a7632d83f3ae266633971c8ddfb7e07..cee48ab3ba6565b145735bed2171f5442488fe5d 100644 (file)
@@ -212,15 +212,15 @@ extern "C" {
 #endif // _di_init_argument_
 
 #ifndef _di_init_print_version_
-  f_extern f_return_status init_print_version(const init_argument data);
+  extern f_return_status init_print_version(const init_argument data);
 #endif // _di_init_print_version_
 
 #ifndef _di_init_print_help_
-  f_extern f_return_status init_print_help(const init_argument data);
+  extern f_return_status init_print_help(const init_argument data);
 #endif // _di_init_print_help_
 
 #ifndef _di_init_main_
-  f_extern f_return_status init_main(const f_s_int argc, const f_string argv[], init_argument *data);
+  extern f_return_status init_main(const f_s_int argc, const f_string argv[], init_argument *data);
 #endif // _di_init_main_
 
 #ifdef __cplusplus
index 034e2f899b45e31f101d3c4f5bba5d22e9d411b0..254ae05406bdb29df823b99bcdf1c66fd12cc6d0 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library init.c private-init.c
index 79346fb64455832234cc556e54c772898344e867..2e6284f8f50354e34b54fd9762dbd8ffa542d519 100644 (file)
@@ -10,7 +10,7 @@ version_micro 0
 build_compiler gcc
 build_linker ar
 build_libraries -lc
-build_libraries_fll -lfll_colors -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory
+build_libraries_fll -lfll_colors -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf
 #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0
 #build_libraries_fll-monolithic -lfll
 build_sources_library return_code.c