]> Kevux Git Server - fll/commitdiff
Update: Add unit tests for f_compare utf string functions.
authorKevin Day <kevin@kevux.org>
Thu, 30 Mar 2023 04:54:50 +0000 (23:54 -0500)
committerKevin Day <kevin@kevux.org>
Thu, 30 Mar 2023 04:54:50 +0000 (23:54 -0500)
I completely forgot about these and later noticed that they are not implemented.
This exposed problems where I neither had up to date utf stings nor did I have all of the expected functions implemented.

I took the lazy route to avoid spending time manually converting everything.
The files are direct copies from the non utf string compare functions.
I then provided functions that convert the regular strings into utf strings.
The comparisons are then against the generated utf strings.

51 files changed:
level_0/f_compare/data/build/settings-tests
level_0/f_compare/tests/unit/c/test-compare-utf.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_except.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_except.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_trim.c [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare-utf_trim.h [new file with mode: 0644]
level_0/f_compare/tests/unit/c/test-compare.c
level_0/f_compare/tests/unit/c/test-compare.h

index a646ad427d68027aa43f7b8f630c7cba53f3e06e..b2642ba2f2b1c5b7ef70ae60b7c8ecbfa833d6d5 100644 (file)
@@ -33,6 +33,16 @@ build_sources_program test-compare-dynamic_partial_except_trim.c test-compare-dy
 build_sources_program test-compare-except.c test-compare-dynamic_except.c test-compare-dynamic_except_string.c
 build_sources_program test-compare-trim.c test-compare-dynamic_trim.c test-compare-dynamic_trim_string.c
 build_sources_program test-compare-except_trim.c test-compare-dynamic_except_trim.c test-compare-dynamic_except_trim_string.c
+
+build_sources_program test-compare-utf.c test-compare-utf_dynamic.c test-compare-utf_dynamic_string.c
+build_sources_program test-compare-utf_dynamic_partial.c test-compare-utf_dynamic_partial_dynamic.c test-compare-utf_dynamic_partial_string.c
+build_sources_program test-compare-utf_dynamic_partial_trim.c test-compare-utf_dynamic_partial_trim_dynamic.c test-compare-utf_dynamic_partial_trim_string.c
+build_sources_program test-compare-utf_dynamic_partial_except.c test-compare-utf_dynamic_partial_except_dynamic.c test-compare-utf_dynamic_partial_except_string.c
+build_sources_program test-compare-utf_dynamic_partial_except_trim.c test-compare-utf_dynamic_partial_except_trim_dynamic.c test-compare-utf_dynamic_partial_except_trim_string.c
+build_sources_program test-compare-utf_except.c test-compare-utf_dynamic_except.c test-compare-utf_dynamic_except_string.c
+build_sources_program test-compare-utf_trim.c test-compare-utf_dynamic_trim.c test-compare-utf_dynamic_trim_string.c
+build_sources_program test-compare-utf_except_trim.c test-compare-utf_dynamic_except_trim.c test-compare-utf_dynamic_except_trim_string.c
+
 build_sources_program test-compare.c
 
 build_script no
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf.c b/level_0/f_compare/tests/unit/c/test-compare-utf.c
new file mode 100644 (file)
index 0000000..63ccdce
--- /dev/null
@@ -0,0 +1,285 @@
+#include "test-compare.h"
+#include "test-compare-utf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf(utf_string_1.string, utf_string_2.string, utf_string_1.used, utf_string_2.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf.h b/level_0/f_compare/tests/unit/c/test-compare-utf.h
new file mode 100644 (file)
index 0000000..3957cd5
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf__h
+#define _TEST__F_compare_utf__h
+
+// f_compare_utf() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf()
+ */
+extern void test__f_compare_utf__works(void **state);
+
+#endif // _TEST__F_compare_utf__h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.c
new file mode 100644 (file)
index 0000000..9659ea5
--- /dev/null
@@ -0,0 +1,285 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic(utf_string_1, utf_string_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic.h
new file mode 100644 (file)
index 0000000..efcd14e
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_h
+#define _TEST__F_compare_utf_dynamic_h
+
+// f_compare_utf_dynamic() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic()
+ */
+extern void test__f_compare_utf_dynamic__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.c
new file mode 100644 (file)
index 0000000..3fa3e3d
--- /dev/null
@@ -0,0 +1,308 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_except.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_except__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except(utf_string_1, utf_string_2, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except(utf_string_2, utf_string_1, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except.h
new file mode 100644 (file)
index 0000000..90ea744
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_except_h
+#define _TEST__F_compare_utf_dynamic_except_h
+
+// f_compare_utf_dynamic_except() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_except()
+ */
+extern void test__f_compare_utf_dynamic_except__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_except_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.c
new file mode 100644 (file)
index 0000000..cba23e6
--- /dev/null
@@ -0,0 +1,308 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_except_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_except_string__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_string(utf_string_1.string, utf_string_2, utf_string_1.used, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_string(utf_string_2.string, utf_string_1, utf_string_2.used, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_string.h
new file mode 100644 (file)
index 0000000..370966d
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_except_string_h
+#define _TEST__F_compare_utf_dynamic_except_string_h
+
+// f_compare_utf_dynamic_except_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_except_string()
+ */
+extern void test__f_compare_utf_dynamic_except_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_except_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.c
new file mode 100644 (file)
index 0000000..4905f3e
--- /dev/null
@@ -0,0 +1,321 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_except_trim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_except_trim__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_trim(utf_string_1, utf_string_2, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_trim(utf_string_2, utf_string_1, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim.h
new file mode 100644 (file)
index 0000000..670fd25
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_except_trim_h
+#define _TEST__F_compare_utf_dynamic_except_trim_h
+
+// f_compare_utf_dynamic_except_trim() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_except_trim()
+ */
+extern void test__f_compare_utf_dynamic_except_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_except_trim_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.c
new file mode 100644 (file)
index 0000000..ec24f8b
--- /dev/null
@@ -0,0 +1,321 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_except_trim_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_except_trim_string__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_trim_string(utf_string_1.string, utf_string_2, utf_string_1.used, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_except_trim_string(utf_string_2.string, utf_string_1, utf_string_2.used, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_except_trim_string.h
new file mode 100644 (file)
index 0000000..72c4d1d
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_except_trim_string_h
+#define _TEST__F_compare_utf_dynamic_except_trim_string_h
+
+// f_compare_utf_dynamic_except_trim_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_except_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_except_trim_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_except_trim_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.c
new file mode 100644 (file)
index 0000000..dd2c94c
--- /dev/null
@@ -0,0 +1,323 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+    macro_f_string_static_t_initialize("xxxyyy", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx1yyy", 0, 7),
+
+    // 4.
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxoneyyy", 0, 9),
+
+    // 5.
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxxOneyyy", 0, 9),
+
+    // 6.
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0neyyy", 0, 9),
+
+    // 7.
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0neyyy", 0, 10),
+
+    // 8.
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0yyy", 0, 10),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial(utf_string_1, utf_string_2, f_string_range_empty_c, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial(utf_string_1, utf_string_2, f_string_range_empty_c, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 4;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial(utf_string_1, utf_string_2, range_1, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial(utf_string_1, utf_string_2, range_1, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial.h
new file mode 100644 (file)
index 0000000..f3fa1e9
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_h
+#define _TEST__F_compare_utf_dynamic_partial_h
+
+// f_compare_utf_dynamic_partial() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial()
+ */
+extern void test__f_compare_utf_dynamic_partial__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.c
new file mode 100644 (file)
index 0000000..79dad57
--- /dev/null
@@ -0,0 +1,320 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_dynamic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_dynamic__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_dynamic(utf_string_1, utf_string_2, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_dynamic(utf_string_1, utf_string_2, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_dynamic.h
new file mode 100644 (file)
index 0000000..3c5471c
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_dynamic_h
+#define _TEST__F_compare_utf_dynamic_partial_dynamic_h
+
+// f_compare_utf_dynamic_partial_dynamic() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_dynamic()
+ */
+extern void test__f_compare_utf_dynamic_partial_dynamic__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_dynamic_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.c
new file mode 100644 (file)
index 0000000..602ff25
--- /dev/null
@@ -0,0 +1,328 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except(utf_string_1, utf_string_2, range_1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except(utf_string_1, utf_string_2, range_1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except(utf_string_1, utf_string_2, range_1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except(utf_string_1, utf_string_2, range_1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except.h
new file mode 100644 (file)
index 0000000..1cb2023
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_h
+#define _TEST__F_compare_utf_dynamic_partial_except_h
+
+// f_compare_utf_dynamic_partial_except() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except()
+ */
+extern void test__f_compare_utf_dynamic_partial_except__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.c
new file mode 100644 (file)
index 0000000..296e3bc
--- /dev/null
@@ -0,0 +1,325 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except_dynamic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except_dynamic__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_dynamic(utf_string_1, utf_string_2, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_dynamic(utf_string_1, utf_string_2, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_dynamic.h
new file mode 100644 (file)
index 0000000..455d20e
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_dynamic_h
+#define _TEST__F_compare_utf_dynamic_partial_except_dynamic_h
+
+// f_compare_utf_dynamic_partial_except_dynamic() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except_dynamic()
+ */
+extern void test__f_compare_utf_dynamic_partial_except_dynamic__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_dynamic_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.c
new file mode 100644 (file)
index 0000000..5d22c5d
--- /dev/null
@@ -0,0 +1,328 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except_string__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_string(utf_string_1.string, utf_string_2, 0, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_string(utf_string_1.string, utf_string_2, 0, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_string(utf_string_1.string, utf_string_2, range_1.stop + 1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_string(utf_string_1.string, utf_string_2, range_1.stop + 1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_string.h
new file mode 100644 (file)
index 0000000..9d44d58
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_string_h
+#define _TEST__F_compare_utf_dynamic_partial_except_string_h
+
+// f_compare_utf_dynamic_partial_except_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except_string()
+ */
+extern void test__f_compare_utf_dynamic_partial_except_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.c
new file mode 100644 (file)
index 0000000..4538ec1
--- /dev/null
@@ -0,0 +1,341 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except_trim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except_trim__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim(utf_string_1, utf_string_2, range_1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim(utf_string_1, utf_string_2, range_1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim(utf_string_1, utf_string_2, range_1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim(utf_string_1, utf_string_2, range_1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim.h
new file mode 100644 (file)
index 0000000..efe75f4
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_trim_h
+#define _TEST__F_compare_utf_dynamic_partial_except_trim_h
+
+// f_compare_utf_dynamic_partial_except_trim() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except_trim()
+ */
+extern void test__f_compare_utf_dynamic_partial_except_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_trim_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.c
new file mode 100644 (file)
index 0000000..dd17675
--- /dev/null
@@ -0,0 +1,338 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except_trim_dynamic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except_trim_dynamic__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim_dynamic(utf_string_1, utf_string_2, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim_dynamic(utf_string_1, utf_string_2, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_dynamic.h
new file mode 100644 (file)
index 0000000..e98d81f
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_trim_dynamic_h
+#define _TEST__F_compare_utf_dynamic_partial_except_trim_dynamic_h
+
+// f_compare_utf_dynamic_partial_except_trim_dynamic() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except_trim_dynamic()
+ */
+extern void test__f_compare_utf_dynamic_partial_except_trim_dynamic__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_trim_dynamic_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.c
new file mode 100644 (file)
index 0000000..be85057
--- /dev/null
@@ -0,0 +1,341 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_except_trim_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_except_trim_string__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim_string(utf_string_1.string, utf_string_2, 0, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim_string(utf_string_1.string, utf_string_2, 0, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_except_trim_string(utf_string_1.string, utf_string_2, range_1.stop + 1, f_string_range_empty_c, excepts_1, excepts_2);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_except_trim_string(utf_string_1.string, utf_string_2, range_1.stop + 1, range_2, excepts_1, excepts_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_except_trim_string.h
new file mode 100644 (file)
index 0000000..7a116b1
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_except_trim_string_h
+#define _TEST__F_compare_utf_dynamic_partial_except_trim_string_h
+
+// f_compare_utf_dynamic_partial_except_trim_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_except_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_partial_except_trim_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_except_trim_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.c
new file mode 100644 (file)
index 0000000..59dd7e6
--- /dev/null
@@ -0,0 +1,323 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_string__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+    macro_f_string_static_t_initialize("xxx", 0, 3),
+
+    // 3.
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+    macro_f_string_static_t_initialize("xxx1", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+    macro_f_string_static_t_initialize("xxxone", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+    macro_f_string_static_t_initialize("xxxOne", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0ne", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxxo\0ne", 0, 7),
+
+    // 8.
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+    macro_f_string_static_t_initialize("xxxone\0", 0, 7),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_string(utf_string_1.string, utf_string_2, 0, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_string(utf_string_1.string, utf_string_2, 0, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_string(utf_string_1.string + range_1.start, utf_string_2, (range_1.stop - range_1.start) + 1, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_string(utf_string_1.string + range_1.start, utf_string_2, (range_1.stop - range_1.start) + 1, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_string.h
new file mode 100644 (file)
index 0000000..5562030
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_string_h
+#define _TEST__F_compare_utf_dynamic_partial_string_h
+
+// f_compare_utf_dynamic_partial_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_string()
+ */
+extern void test__f_compare_utf_dynamic_partial_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.c
new file mode 100644 (file)
index 0000000..3dd3218
--- /dev/null
@@ -0,0 +1,336 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_trim__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'x', 'x', 'x', '\0', '1', 'y', 'y', 'y'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'x', 'x', 'x', '\0', '1', ' ', '\0', '\t', 'y', 'y', 'y'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'x', 'x', 'x', '\0', ' ', '\0', '1', 'y', 'y', 'y'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("xxx yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx\tyyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0yyy", 0, 7),
+    macro_f_string_static_t_initialize("xxx    yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx  \t yyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0 \0\tyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0 \0yyy", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0\0\tyyy", 0, 9),
+
+    // 3.
+    macro_f_string_static_t_initialize("xxx 1yyy", 0, 8),
+    macro_f_string_static_t_initialize("xxx\t1yyy", 0, 8),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 8),
+    macro_f_string_static_t_initialize("xxx  1  yyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx  1\t yyy", 0, 11),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 11),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 10),
+    macro_f_string_static_t_initialize("xxx1\0\0\tyyy", 0, 10),
+
+    // 4.
+    macro_f_string_static_t_initialize("xxx oneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\toneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0oneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx  one  yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx  one\t yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0one \0\tyyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0 \0oneyyy", 0, 12),
+    macro_f_string_static_t_initialize("xxxone\0\0\tyyy", 0, 12),
+
+    // 5.
+    macro_f_string_static_t_initialize("xxx Oneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\tOneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0Oneyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx  One  yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx  One\t yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0One \0\tyyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0 \0Oneyyy", 0, 12),
+    macro_f_string_static_t_initialize("xxxOne\0\0\tyyy", 0, 12),
+
+    // 6.
+    macro_f_string_static_t_initialize("xxx \0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\t\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0\0neyyy", 0, 10),
+    macro_f_string_static_t_initialize("xxx  \0ne  yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx  \0ne\t yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0\0ne \0\tyyy", 0, 13),
+    macro_f_string_static_t_initialize("xxx\0 \0\0neyyy", 0, 12),
+    macro_f_string_static_t_initialize("xxx\0ne\0\0\tyyy", 0, 12),
+
+    // 7.
+    macro_f_string_static_t_initialize("xxx o\0neyyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx\to\0neyyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0o\0neyyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx  o\0ne  yyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx  o\0ne\t yyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx\0o\0ne \0\tyyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx\0 \0o\0neyyy", 0, 13),
+    macro_f_string_static_t_initialize("xxxo\0ne\0\0\tyyy", 0, 13),
+
+    // 8.
+    macro_f_string_static_t_initialize("xxx one\0yyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx\tone\0yyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0one\0yyy", 0, 11),
+    macro_f_string_static_t_initialize("xxx  one\0  yyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx  one\0\t yyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx\0one\0 \0\tyyy", 0, 14),
+    macro_f_string_static_t_initialize("xxx\0 \0one\0yyy", 0, 13),
+    macro_f_string_static_t_initialize("xxxone\0\0\0\tyyy", 0, 13),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim(utf_string_1, utf_string_2, f_string_range_empty_c, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim(utf_string_1, utf_string_2, f_string_range_empty_c, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 4;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim(utf_string_1, utf_string_2, range_1, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim(utf_string_1, utf_string_2, range_1, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim.h
new file mode 100644 (file)
index 0000000..77d9d3a
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_trim_h
+#define _TEST__F_compare_utf_dynamic_partial_trim_h
+
+// f_compare_utf_dynamic_partial_trim() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_trim()
+ */
+extern void test__f_compare_utf_dynamic_partial_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_trim_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.c
new file mode 100644 (file)
index 0000000..175cb67
--- /dev/null
@@ -0,0 +1,333 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_dynamic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_trim_dynamic__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize(" ", 0, 1),
+    macro_f_string_static_t_initialize("\t", 0, 1),
+    macro_f_string_static_t_initialize("\0", 0, 1),
+    macro_f_string_static_t_initialize("    ", 0, 4),
+    macro_f_string_static_t_initialize("  \t ", 0, 4),
+    macro_f_string_static_t_initialize("\0 \0\t", 0, 4),
+    macro_f_string_static_t_initialize("\0 \0", 0, 3),
+    macro_f_string_static_t_initialize("\0\0\t", 0, 3),
+
+    // 3.
+    macro_f_string_static_t_initialize(" 1", 0, 2),
+    macro_f_string_static_t_initialize("\t1", 0, 2),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 2),
+    macro_f_string_static_t_initialize("  1  ", 0, 5),
+    macro_f_string_static_t_initialize("  1\t ", 0, 5),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 5),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 4),
+    macro_f_string_static_t_initialize("1\0\0\t", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(" one", 0, 4),
+    macro_f_string_static_t_initialize("\tone", 0, 4),
+    macro_f_string_static_t_initialize("\0one", 0, 4),
+    macro_f_string_static_t_initialize("  one  ", 0, 7),
+    macro_f_string_static_t_initialize("  one\t ", 0, 7),
+    macro_f_string_static_t_initialize("\0one \0\t", 0, 7),
+    macro_f_string_static_t_initialize("\0 \0one", 0, 6),
+    macro_f_string_static_t_initialize("one\0\0\t", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(" One", 0, 4),
+    macro_f_string_static_t_initialize("\tOne", 0, 4),
+    macro_f_string_static_t_initialize("\0One", 0, 4),
+    macro_f_string_static_t_initialize("  One  ", 0, 7),
+    macro_f_string_static_t_initialize("  One\t ", 0, 7),
+    macro_f_string_static_t_initialize("\0One \0\t", 0, 7),
+    macro_f_string_static_t_initialize("\0 \0One", 0, 6),
+    macro_f_string_static_t_initialize("One\0\0\t", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(" \0ne", 0, 4),
+    macro_f_string_static_t_initialize("\t\0ne", 0, 4),
+    macro_f_string_static_t_initialize("\0\0ne", 0, 4),
+    macro_f_string_static_t_initialize("  \0ne  ", 0, 7),
+    macro_f_string_static_t_initialize("  \0ne\t ", 0, 7),
+    macro_f_string_static_t_initialize("\0\0ne \0\t", 0, 7),
+    macro_f_string_static_t_initialize("\0 \0\0ne", 0, 6),
+    macro_f_string_static_t_initialize("\0ne\0\0\t", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(" o\0ne", 0, 5),
+    macro_f_string_static_t_initialize("\to\0ne", 0, 5),
+    macro_f_string_static_t_initialize("\0o\0ne", 0, 5),
+    macro_f_string_static_t_initialize("  o\0ne  ", 0, 8),
+    macro_f_string_static_t_initialize("  o\0ne\t ", 0, 8),
+    macro_f_string_static_t_initialize("\0o\0ne \0\t", 0, 8),
+    macro_f_string_static_t_initialize("\0 \0o\0ne", 0, 7),
+    macro_f_string_static_t_initialize("o\0ne\0\0\t", 0, 7),
+
+    // 8.
+    macro_f_string_static_t_initialize(" one\0", 0, 5),
+    macro_f_string_static_t_initialize("\tone\0", 0, 5),
+    macro_f_string_static_t_initialize("\0one\0", 0, 5),
+    macro_f_string_static_t_initialize("  one\0  ", 0, 8),
+    macro_f_string_static_t_initialize("  one\0\t ", 0, 8),
+    macro_f_string_static_t_initialize("\0one\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("\0 \0one\0", 0, 7),
+    macro_f_string_static_t_initialize("one\0\0\0\t", 0, 7),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim_dynamic(utf_string_1, utf_string_2, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim_dynamic(utf_string_1, utf_string_2, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim_dynamic(utf_string_1, utf_string_2, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_dynamic.h
new file mode 100644 (file)
index 0000000..c4138e1
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_trim_dynamic_h
+#define _TEST__F_compare_utf_dynamic_partial_trim_dynamic_h
+
+// f_compare_utf_dynamic_partial_trim_dynamic() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_trim_dynamic()
+ */
+extern void test__f_compare_utf_dynamic_partial_trim_dynamic__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_trim_dynamic_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.c
new file mode 100644 (file)
index 0000000..35d20f9
--- /dev/null
@@ -0,0 +1,336 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_partial_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_partial_trim_string__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'x', 'x', 'x', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'x', 'x', 'x', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'x', 'x', 'x', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("xxx ", 0, 4),
+    macro_f_string_static_t_initialize("xxx\t", 0, 4),
+    macro_f_string_static_t_initialize("xxx\0", 0, 4),
+    macro_f_string_static_t_initialize("xxx    ", 0, 7),
+    macro_f_string_static_t_initialize("xxx  \t ", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0 \0\t", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0 \0", 0, 6),
+    macro_f_string_static_t_initialize("xxx\0\0\t", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize("xxx 1", 0, 5),
+    macro_f_string_static_t_initialize("xxx\t1", 0, 5),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 5),
+    macro_f_string_static_t_initialize("xxx  1  ", 0, 8),
+    macro_f_string_static_t_initialize("xxx  1\t ", 0, 8),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 8),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 7),
+    macro_f_string_static_t_initialize("xxx1\0\0\t", 0, 7),
+
+    // 4.
+    macro_f_string_static_t_initialize("xxx one", 0, 7),
+    macro_f_string_static_t_initialize("xxx\tone", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0one", 0, 7),
+    macro_f_string_static_t_initialize("xxx  one  ", 0, 10),
+    macro_f_string_static_t_initialize("xxx  one\t ", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0one \0\t", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0 \0one", 0, 9),
+    macro_f_string_static_t_initialize("xxxone\0\0\t", 0, 9),
+
+    // 5.
+    macro_f_string_static_t_initialize("xxx One", 0, 7),
+    macro_f_string_static_t_initialize("xxx\tOne", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0One", 0, 7),
+    macro_f_string_static_t_initialize("xxx  One  ", 0, 10),
+    macro_f_string_static_t_initialize("xxx  One\t ", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0One \0\t", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0 \0One", 0, 9),
+    macro_f_string_static_t_initialize("xxxOne\0\0\t", 0, 9),
+
+    // 6.
+    macro_f_string_static_t_initialize("xxx \0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxx\t\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxx\0\0ne", 0, 7),
+    macro_f_string_static_t_initialize("xxx  \0ne  ", 0, 10),
+    macro_f_string_static_t_initialize("xxx  \0ne\t ", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0\0ne \0\t", 0, 10),
+    macro_f_string_static_t_initialize("xxx\0 \0\0ne", 0, 9),
+    macro_f_string_static_t_initialize("xxx\0ne\0\0\t", 0, 9),
+
+    // 7.
+    macro_f_string_static_t_initialize("xxx o\0ne", 0, 8),
+    macro_f_string_static_t_initialize("xxx\to\0ne", 0, 8),
+    macro_f_string_static_t_initialize("xxx\0o\0ne", 0, 8),
+    macro_f_string_static_t_initialize("xxx  o\0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("xxx  o\0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0o\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0 \0o\0ne", 0, 10),
+    macro_f_string_static_t_initialize("xxxo\0ne\0\0\t", 0, 10),
+
+    // 8.
+    macro_f_string_static_t_initialize("xxx one\0", 0, 8),
+    macro_f_string_static_t_initialize("xxx\tone\0", 0, 8),
+    macro_f_string_static_t_initialize("xxx\0one\0", 0, 8),
+    macro_f_string_static_t_initialize("xxx  one\0  ", 0, 11),
+    macro_f_string_static_t_initialize("xxx  one\0\t ", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0one\0 \0\t", 0, 11),
+    macro_f_string_static_t_initialize("xxx\0 \0one\0", 0, 10),
+    macro_f_string_static_t_initialize("xxxone\0\0\0\t", 0, 10),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("aa", 0, 2),
+    macro_f_string_static_t_initialize("aa1", 0, 3),
+    macro_f_string_static_t_initialize("aaone", 0, 5),
+    macro_f_string_static_t_initialize("aaOne", 0, 5),
+    macro_f_string_static_t_initialize("aa\0ne", 0, 5),
+    macro_f_string_static_t_initialize("aao\0ne", 0, 6),
+    macro_f_string_static_t_initialize("aaone\0", 0, 6),
+  };
+
+  f_string_range_t range_1 = macro_f_string_range_t_initialize(3, 9);
+  f_string_range_t range_2 = macro_f_string_range_t_initialize(2, 0);
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  // First eight are against empty strings for first argument.
+  for (; i < 8; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim_string(utf_string_1.string, utf_string_2, 0, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim_string(utf_string_1.string, utf_string_2, 0, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    range_1.stop = string_1s[i].used - 1;
+
+    if (i % 8 == 0) {
+      status = f_compare_utf_dynamic_partial_trim_string(utf_string_1.string + range_1.start, utf_string_2, (range_1.stop - range_1.start) + 1, f_string_range_empty_c);
+    }
+    else {
+      range_2.stop = string_2s[i].used - 1;
+
+      status = f_compare_utf_dynamic_partial_trim_string(utf_string_1.string + range_1.start, utf_string_2, (range_1.stop - range_1.start) + 1, range_2);
+    }
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_partial_trim_string.h
new file mode 100644 (file)
index 0000000..39509d0
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_partial_trim_string_h
+#define _TEST__F_compare_utf_dynamic_partial_trim_string_h
+
+// f_compare_utf_dynamic_partial_trim_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_partial_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_partial_trim_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_partial_trim_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.c
new file mode 100644 (file)
index 0000000..18565a7
--- /dev/null
@@ -0,0 +1,285 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_string__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_string(utf_string_1.string, utf_string_2, utf_string_1.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_string.h
new file mode 100644 (file)
index 0000000..d799d29
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_string_h
+#define _TEST__F_compare_utf_dynamic_string_h
+
+// f_compare_utf_dynamic_string() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_string()
+ */
+extern void test__f_compare_utf_dynamic_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.c
new file mode 100644 (file)
index 0000000..3cc4739
--- /dev/null
@@ -0,0 +1,434 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_trim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_trim__trims(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize(" ", 0, 1),
+    macro_f_string_static_t_initialize("\t", 0, 1),
+    macro_f_string_static_t_initialize(" \0\t", 0, 3),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  const f_string_static_t string_2s[] = {
+    f_string_empty_s,
+    f_string_empty_s,
+    f_string_empty_s,
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space\tspace", 0, 11),
+    macro_f_string_static_t_initialize("space\t\0 space", 0, 13),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+  };
+
+  const f_status_t expects[] = {
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_1, utf_string_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_2, utf_string_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_1, utf_string_1);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_2, utf_string_2);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+void test__f_compare_utf_dynamic_trim__something_misses_nothing(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_1, f_utf_string_empty_s);
+
+    assert_int_equal(status, F_equal_to_not);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+}
+
+void test__f_compare_utf_dynamic_trim__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim(utf_string_1, utf_string_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim.h
new file mode 100644 (file)
index 0000000..1a5704b
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_trim_h
+#define _TEST__F_compare_utf_dynamic_trim_h
+
+// f_compare_utf_dynamic_trim() only returns memory failures.
+
+/**
+ * Test that function trims.
+ *
+ * @see f_compare_utf_dynamic_trim()
+ */
+extern void test__f_compare_utf_dynamic_trim__trims(void **state);
+
+/**
+ * Test that function doesn't match empty string to a non-empty string.
+ *
+ * @see f_compare_utf_dynamic_trim()
+ */
+extern void test__f_compare_utf_dynamic_trim__something_misses_nothing(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_trim()
+ */
+extern void test__f_compare_utf_dynamic_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_trim_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.c b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.c
new file mode 100644 (file)
index 0000000..65b3e15
--- /dev/null
@@ -0,0 +1,434 @@
+#include "test-compare.h"
+#include "test-compare-utf_dynamic_trim_string.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_dynamic_trim_string__trims(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize(" ", 0, 1),
+    macro_f_string_static_t_initialize("\t", 0, 1),
+    macro_f_string_static_t_initialize(" \0\t", 0, 3),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  const f_string_static_t string_2s[] = {
+    f_string_empty_s,
+    f_string_empty_s,
+    f_string_empty_s,
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space\tspace", 0, 11),
+    macro_f_string_static_t_initialize("space\t\0 space", 0, 13),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+  };
+
+  const f_status_t expects[] = {
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_1.string, utf_string_2, utf_string_1.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_2.string, utf_string_1, utf_string_2.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_1.string, utf_string_1, utf_string_1.used);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_2.string, utf_string_2, utf_string_2.used);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+void test__f_compare_utf_dynamic_trim_string__something_misses_nothing(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_1.string, f_utf_string_empty_s, utf_string_1.used);
+
+    assert_int_equal(status, F_equal_to_not);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+}
+
+void test__f_compare_utf_dynamic_trim_string__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_dynamic_trim_string(utf_string_1.string, utf_string_2, utf_string_1.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.h b/level_0/f_compare/tests/unit/c/test-compare-utf_dynamic_trim_string.h
new file mode 100644 (file)
index 0000000..012e198
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_dynamic_trim_string_h
+#define _TEST__F_compare_utf_dynamic_trim_string_h
+
+// f_compare_utf_dynamic_trim_string() only returns memory failures.
+
+/**
+ * Test that function trims.
+ *
+ * @see f_compare_utf_dynamic_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_trim_string__trims(void **state);
+
+/**
+ * Test that function doesn't match empty string to a non-empty string.
+ *
+ * @see f_compare_utf_dynamic_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_trim_string__something_misses_nothing(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_dynamic_trim_string()
+ */
+extern void test__f_compare_utf_dynamic_trim_string__works(void **state);
+
+#endif // _TEST__F_compare_utf_dynamic_trim_string_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_except.c b/level_0/f_compare/tests/unit/c/test-compare-utf_except.c
new file mode 100644 (file)
index 0000000..3c56f62
--- /dev/null
@@ -0,0 +1,308 @@
+#include "test-compare.h"
+#include "test-compare-utf_except.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_except__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+    macro_f_string_static_t_initialize("SKIP", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+    macro_f_string_static_t_initialize("SKIP1", 0, 5),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+    macro_f_string_static_t_initialize("SKIPone", 0, 7),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+    macro_f_string_static_t_initialize("SKIPOne", 0, 7),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0ne", 0, 7),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIPo\0ne", 0, 8),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+    macro_f_string_static_t_initialize("SKIPone\0", 0, 8),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_except(utf_string_1.string, utf_string_2.string, utf_string_1.used, utf_string_2.used, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_except(utf_string_2.string, utf_string_1.string, utf_string_2.used, utf_string_1.used, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_except.h b/level_0/f_compare/tests/unit/c/test-compare-utf_except.h
new file mode 100644 (file)
index 0000000..c86de86
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_except_h
+#define _TEST__F_compare_utf_except_h
+
+// f_compare_utf_except() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_except()
+ */
+extern void test__f_compare_utf_except__works(void **state);
+
+#endif // _TEST__F_compare_utf_except_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.c
new file mode 100644 (file)
index 0000000..a0198d6
--- /dev/null
@@ -0,0 +1,321 @@
+#include "test-compare.h"
+#include "test-compare-utf_except_trim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_except_trim__works(void **state) {
+
+  // A necessary work-around to to have "\01" with the "\0" being separate from the "1".
+  f_char_t null_before_one_1[] = {
+    'S', 'K', 'I', 'P', '\0', '1'
+  };
+
+  f_char_t null_before_one_2[] = {
+    'S', 'K', 'I', 'P', '\0', '1', ' ', '\0', '\t'
+  };
+
+  f_char_t null_before_one_3[] = {
+    'S', 'K', 'I', 'P', '\0', ' ', '\0', '1'
+  };
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("SKIP ", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\t", 0, 5),
+    macro_f_string_static_t_initialize("SKIP\0", 0, 5),
+    macro_f_string_static_t_initialize("SKIP    ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \t ", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0\t", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0 \0", 0, 7),
+    macro_f_string_static_t_initialize("SKIP\0\0\t", 0, 7),
+
+    // 3.
+    macro_f_string_static_t_initialize("SKIP 1", 0, 6),
+    macro_f_string_static_t_initialize("SKIP\t1", 0, 6),
+    macro_f_string_static_t_initialize(null_before_one_1, 0, 6),
+    macro_f_string_static_t_initialize("SKIP  1  ", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  1\t ", 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_2, 0, 9),
+    macro_f_string_static_t_initialize(null_before_one_3, 0, 8),
+    macro_f_string_static_t_initialize("SKIP1\0\0\t", 0, 8),
+
+    // 4.
+    macro_f_string_static_t_initialize("SKIP one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tone", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0one", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  one  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  one\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0one \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0one", 0, 10),
+    macro_f_string_static_t_initialize("SKIPone\0\0\t", 0, 10),
+
+    // 5.
+    macro_f_string_static_t_initialize("SKIP One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\tOne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0One", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  One  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  One\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0One \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0One", 0, 10),
+    macro_f_string_static_t_initialize("SKIPOne\0\0\t", 0, 10),
+
+    // 6.
+    macro_f_string_static_t_initialize("SKIP \0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\t\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP\0\0ne", 0, 8),
+    macro_f_string_static_t_initialize("SKIP  \0ne  ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP  \0ne\t ", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0\0ne \0\t", 0, 11),
+    macro_f_string_static_t_initialize("SKIP\0 \0\0ne", 0, 10),
+    macro_f_string_static_t_initialize("SKIP\0ne\0\0\t", 0, 10),
+
+    // 7.
+    macro_f_string_static_t_initialize("SKIP o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\to\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  o\0ne  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  o\0ne\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0o\0ne \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0o\0ne", 0, 11),
+    macro_f_string_static_t_initialize("SKIPo\0ne\0\0\t", 0, 11),
+
+    // 8.
+    macro_f_string_static_t_initialize("SKIP one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\tone\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP\0one\0", 0, 9),
+    macro_f_string_static_t_initialize("SKIP  one\0  ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP  one\0\t ", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0one\0 \0\t", 0, 12),
+    macro_f_string_static_t_initialize("SKIP\0 \0one\0", 0, 11),
+    macro_f_string_static_t_initialize("SKIPone\0\0\0\t", 0, 11),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_array_length_t except_1[] = {
+    0, 1, 2, 3,
+  };
+  const f_array_lengths_t excepts_1 = macro_f_array_lengths_t_initialize(except_1, 0, 4);
+  const f_array_lengths_t excepts_2 = f_array_lengths_t_initialize;
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_except_trim(utf_string_1.string, utf_string_2.string, utf_string_1.used, utf_string_2.used, excepts_1, excepts_2);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_except_trim(utf_string_2.string, utf_string_1.string, utf_string_2.used, utf_string_1.used, excepts_2, excepts_1);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_except_trim.h
new file mode 100644 (file)
index 0000000..b02003c
--- /dev/null
@@ -0,0 +1,22 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_except_trim_h
+#define _TEST__F_compare_utf_except_trim_h
+
+// f_compare_utf_except_trim() only returns memory failures.
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_except_trim()
+ */
+extern void test__f_compare_utf_except_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_except_trim_h
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_trim.c b/level_0/f_compare/tests/unit/c/test-compare-utf_trim.c
new file mode 100644 (file)
index 0000000..2465853
--- /dev/null
@@ -0,0 +1,434 @@
+#include "test-compare.h"
+#include "test-compare-utf_trim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_compare_utf_trim__trims(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize(" ", 0, 1),
+    macro_f_string_static_t_initialize("\t", 0, 1),
+    macro_f_string_static_t_initialize(" \0\t", 0, 3),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 13),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  const f_string_static_t string_2s[] = {
+    f_string_empty_s,
+    f_string_empty_s,
+    f_string_empty_s,
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space\tspace", 0, 11),
+    macro_f_string_static_t_initialize("space\t\0 space", 0, 13),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+  };
+
+  const f_status_t expects[] = {
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+  };
+
+  uint8_t i = 0;
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_1.string, utf_string_2.string, utf_string_1.used, utf_string_2.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 13; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_2.string, utf_string_1.string, utf_string_2.used, utf_string_1.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_1.string, utf_string_1.string, utf_string_1.used, utf_string_1.used);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  for (i = 0; i < 10; ++i) {
+
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_2.string, utf_string_2.string, utf_string_2.used, utf_string_2.used);
+
+    assert_int_equal(status, F_equal_to);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+void test__f_compare_utf_trim__something_misses_nothing(void **state) {
+
+  const f_string_static_t string_1s[] = {
+    macro_f_string_static_t_initialize("space", 0, 5),
+    macro_f_string_static_t_initialize(" space", 0, 6),
+    macro_f_string_static_t_initialize("space ", 0, 6),
+    macro_f_string_static_t_initialize(" space ", 0, 7),
+    macro_f_string_static_t_initialize(" \t space \t ", 0, 11),
+    macro_f_string_static_t_initialize("space space", 0, 11),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+    macro_f_string_static_t_initialize(" space\tspace ", 0, 11),
+    macro_f_string_static_t_initialize("\t\0\tspace\t\0 space \0 ", 0, 19),
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 10; ++i) {
+
+    utf_string_1.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_1.string, f_utf_string_empty_s.string, utf_string_1.used, f_utf_string_empty_s.used);
+
+    assert_int_equal(status, F_equal_to_not);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+}
+
+void test__f_compare_utf_trim__works(void **state) {
+
+  const f_string_static_t string_1s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize(0, 0, 0),
+
+    // 2.
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+
+    // 3.
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("1", 0, 1),
+
+    // 4.
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("one", 0, 3),
+
+    // 5.
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+
+    // 6.
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+
+    // 7.
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_string_static_t string_2s[] = {
+
+    // 1.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 2.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 3.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 4.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 5.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 6.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 7.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+
+    // 8.
+    macro_f_string_static_t_initialize(0, 0, 0),
+    macro_f_string_static_t_initialize("", 0, 0),
+    macro_f_string_static_t_initialize("1", 0, 1),
+    macro_f_string_static_t_initialize("one", 0, 3),
+    macro_f_string_static_t_initialize("One", 0, 3),
+    macro_f_string_static_t_initialize("\0ne", 0, 3),
+    macro_f_string_static_t_initialize("o\0ne", 0, 4),
+    macro_f_string_static_t_initialize("one\0", 0, 4),
+  };
+
+  const f_status_t expects[] = {
+
+    // 1.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 2.
+    F_equal_to,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 3.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 4.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 5.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 6.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+
+    // 7.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+
+    // 8.
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to_not,
+    F_equal_to_not,
+    F_equal_to,
+    F_equal_to,
+  };
+
+  f_status_t status = F_none;
+  f_utf_string_dynamic_t utf_string_1 = f_utf_string_dynamic_t_initialize;
+  f_utf_string_dynamic_t utf_string_2 = f_utf_string_dynamic_t_initialize;
+
+  for (uint8_t i = 0; i < 64; ++i) {
+
+    utf_string_1.used = 0;
+    utf_string_2.used = 0;
+
+    status = test_convert_dynamic_to_utf(string_1s[i], &utf_string_1);
+    assert_int_equal(status, F_none);
+
+    status = test_convert_dynamic_to_utf(string_2s[i], &utf_string_2);
+    assert_int_equal(status, F_none);
+
+    status = f_compare_utf_trim(utf_string_1.string, utf_string_2.string, utf_string_1.used, utf_string_2.used);
+
+    assert_int_equal(status, expects[i]);
+  } // for
+
+  f_utf_string_dynamic_resize(0, &utf_string_1);
+  f_utf_string_dynamic_resize(0, &utf_string_2);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_compare/tests/unit/c/test-compare-utf_trim.h b/level_0/f_compare/tests/unit/c/test-compare-utf_trim.h
new file mode 100644 (file)
index 0000000..fb647af
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Compare
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the compare project.
+ */
+#ifndef _TEST__F_compare_utf_trim_h
+#define _TEST__F_compare_utf_trim_h
+
+// f_compare_utf_trim() only returns memory failures.
+
+/**
+ * Test that function trims.
+ *
+ * @see f_compare_utf_trim()
+ */
+extern void test__f_compare_utf_trim__trims(void **state);
+
+/**
+ * Test that function doesn't match empty string to a non-empty string.
+ *
+ * @see f_compare_utf_trim()
+ */
+extern void test__f_compare_utf_trim__something_misses_nothing(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_compare_utf_trim()
+ */
+extern void test__f_compare_utf_trim__works(void **state);
+
+#endif // _TEST__F_compare_utf_trim_h
index 6bf8561748cd9ff454feb67fbf6407cd55be95e7..545910f6986bc04760f48970729693cb56baacaf 100644 (file)
@@ -51,6 +51,37 @@ int main(void) {
     cmocka_unit_test(test__f_compare_trim__something_misses_nothing),
     cmocka_unit_test(test__f_compare_trim__works),
 
+    cmocka_unit_test(test__f_compare_utf__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_dynamic__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except_dynamic__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except_trim__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except_trim_dynamic__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_except_trim_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_trim__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_trim_dynamic__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_partial_trim_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim__trims),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim__something_misses_nothing),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim_string__trims),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim_string__something_misses_nothing),
+    cmocka_unit_test(test__f_compare_utf_dynamic_trim_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_except__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_except_string__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_except_trim__works),
+    cmocka_unit_test(test__f_compare_utf_dynamic_except_trim_string__works),
+    cmocka_unit_test(test__f_compare_utf_except__works),
+    cmocka_unit_test(test__f_compare_utf_except_trim__works),
+    cmocka_unit_test(test__f_compare_utf_trim__trims),
+    cmocka_unit_test(test__f_compare_utf_trim__something_misses_nothing),
+    cmocka_unit_test(test__f_compare_utf_trim__works),
+
     #ifndef _di_level_0_parameter_checking_
       // f_compare() doesn't use parameter checking.
       // f_compare_dynamic() doesn't use parameter checking.
@@ -74,12 +105,51 @@ int main(void) {
       // f_compare_except() doesn't use parameter checking.
       // f_compare_except_trim() doesn't use parameter checking.
       // f_compare_trim() doesn't use parameter checking.
+
+      // f_compare_utf() doesn't use parameter checking.
+      // f_compare_utf_dynamic() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_dynamic() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except_dynamic() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except_trim() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except_trim_dynamic() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_except_trim_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_partial_trim_dynamic() doesn't use parameter checking.
+      // f_compare_utf_dynamic_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_trim() doesn't use parameter checking.
+      // f_compare_utf_dynamic_trim_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_except() doesn't use parameter checking.
+      // f_compare_utf_dynamic_except_string() doesn't use parameter checking.
+      // f_compare_utf_dynamic_except_trim() doesn't use parameter checking.
+      // f_compare_utf_dynamic_except_trim_string() doesn't use parameter checking.
+      // f_compare_utf_except() doesn't use parameter checking.
+      // f_compare_utf_except_trim() doesn't use parameter checking.
+      // f_compare_utf_trim() doesn't use parameter checking.
     #endif // _di_level_0_parameter_checking_
   };
 
   return cmocka_run_group_tests(tests, setup, setdown);
 }
 
+f_status_t test_convert_dynamic_to_utf(const f_string_static_t dynamic, f_utf_string_dynamic_t * const utf) {
+
+  f_status_t status = f_utf_string_dynamic_resize(dynamic.used, utf);
+  if (F_status_is_error(status)) return status;
+
+  utf->used = 0;
+
+  for (f_array_length_t i = 0; i < dynamic.used; ++i, ++utf->used) {
+
+    status = f_utf_char_to_character(dynamic.string + i, dynamic.used - i, &utf->string[i]);
+    if (F_status_is_error(status)) return status;
+  } // for
+
+  return F_none;
+}
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 0c2e692c03e590e70e6e1cf93a4cf2d6574bd88f..2f9a5d7e69ffbe5e4cff167d2944dbdc4bc671af 100644 (file)
@@ -20,6 +20,9 @@
 #include <cmocka.h>
 
 // FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/string.h>
+#include <fll/level_0/utf.h>
 #include <fll/level_0/compare.h>
 
 // Test includes.
 #include "test-compare-except_trim.h"
 #include "test-compare-trim.h"
 
+#include "test-compare-utf.h"
+#include "test-compare-utf_dynamic.h"
+#include "test-compare-utf_dynamic_partial.h"
+#include "test-compare-utf_dynamic_partial_dynamic.h"
+#include "test-compare-utf_dynamic_partial_except.h"
+#include "test-compare-utf_dynamic_partial_except_dynamic.h"
+#include "test-compare-utf_dynamic_partial_except_string.h"
+#include "test-compare-utf_dynamic_partial_except_trim.h"
+#include "test-compare-utf_dynamic_partial_except_trim_dynamic.h"
+#include "test-compare-utf_dynamic_partial_except_trim_string.h"
+#include "test-compare-utf_dynamic_partial_string.h"
+#include "test-compare-utf_dynamic_partial_trim.h"
+#include "test-compare-utf_dynamic_partial_trim_dynamic.h"
+#include "test-compare-utf_dynamic_partial_trim_string.h"
+#include "test-compare-utf_dynamic_string.h"
+#include "test-compare-utf_dynamic_trim.h"
+#include "test-compare-utf_dynamic_trim_string.h"
+#include "test-compare-utf_dynamic_except.h"
+#include "test-compare-utf_dynamic_except_string.h"
+#include "test-compare-utf_dynamic_except_trim.h"
+#include "test-compare-utf_dynamic_except_trim_string.h"
+#include "test-compare-utf_except.h"
+#include "test-compare-utf_except_trim.h"
+#include "test-compare-utf_trim.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -85,6 +113,25 @@ extern int setdown(void **state);
  */
 extern int main(void);
 
+/**
+ * Helper function for converting an entire dynamic string to a complete utf dynamic string.
+ *
+ * @param dynamic
+ *   The source string.
+ * @param utf
+ *   The UTF destination string.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_utf_char_to_character().
+ *   Errors (with error bit) from: f_utf_string_dynamic_resize().
+ *
+ * @see f_utf_char_to_character()
+ * @see f_utf_string_dynamic_resize()
+ */
+extern f_status_t test_convert_dynamic_to_utf(const f_string_static_t dynamic, f_utf_string_dynamic_t * const utf);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif