From 37897eed7a894d08219f793104b90dfca6f80c51 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Wed, 29 Mar 2023 23:53:20 -0500 Subject: [PATCH] Update: Add missing utf string functions and fix existing ones. These utf string functions not up to date with the latest design and are missing several functions. Update every single existing function. Add the missing functions. --- level_0/f_compare/c/compare.c | 14 +- level_0/f_compare/c/compare.h | 118 +++--- level_0/f_compare/c/compare/private-utf.c | 469 +++++++++++++++++++++-- level_0/f_compare/c/compare/private-utf.h | 97 ++++- level_0/f_compare/c/compare/utf.c | 268 ++++++++++++- level_0/f_compare/c/compare/utf.h | 605 ++++++++++++++++++++++++++++++ level_0/f_compare/c/private-compare.h | 8 +- 7 files changed, 1453 insertions(+), 126 deletions(-) diff --git a/level_0/f_compare/c/compare.c b/level_0/f_compare/c/compare.c index f2918de..fb1cb57 100644 --- a/level_0/f_compare/c/compare.c +++ b/level_0/f_compare/c/compare.c @@ -26,13 +26,6 @@ extern "C" { } #endif // _di_f_compare_except_trim_ -#ifndef _di_f_compare_trim_ - f_status_t f_compare_trim(const f_string_t string1, const f_string_t string2, const f_array_length_t length1, const f_array_length_t length2) { - - return private_f_compare_trim(string1, string2, 0, 0, length1, length2); - } -#endif // _di_f_compare_trim_ - #ifndef _di_f_compare_dynamic_ f_status_t f_compare_dynamic(const f_string_static_t string1, const f_string_static_t string2) { @@ -301,6 +294,13 @@ extern "C" { } #endif // _di_f_compare_dynamic_partial_trim_string_ +#ifndef _di_f_compare_trim_ + f_status_t f_compare_trim(const f_string_t string1, const f_string_t string2, const f_array_length_t length1, const f_array_length_t length2) { + + return private_f_compare_trim(string1, string2, 0, 0, length1, length2); + } +#endif // _di_f_compare_trim_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_compare/c/compare.h b/level_0/f_compare/c/compare.h index 6ddf9c0..7f8df9c 100644 --- a/level_0/f_compare/c/compare.h +++ b/level_0/f_compare/c/compare.h @@ -112,8 +112,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -127,38 +127,6 @@ extern "C" { * * This does not stop on NULL. * NULL characters are ignored. - * Ignores leading and trailing whitespace. - * - * @param string1 - * String to compare. - * @param string2 - * String to compare. - * @param length1 - * Length of string1. - * @param length2 - * Length of string2. - * - * @return - * F_equal_to when both strings equal. - * F_equal_to_not when both strings do not equal. - * - * F_parameter (with error bit) if a parameter is invalid. - * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). - * - * @see f_utf_is_combining() - * @see f_utf_is_whitespace() - */ -#ifndef _di_f_compare_trim_ - extern f_status_t f_compare_trim(const f_string_t string1, const f_string_t string2, const f_array_length_t length1, const f_array_length_t length2); -#endif // _di_f_compare_trim_ - -/** - * Compare two strings, similar to strncmp(). - * - * This does not stop on NULL. - * NULL characters are ignored. * * @param string1 * String to compare. @@ -210,7 +178,6 @@ extern "C" { * * This does not stop on NULL. * NULL characters are ignored. - * Ignores leading and trailing whitespace. * All 1-byte characters in except1 and except2 are ignored. * * @param string1 @@ -232,8 +199,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -267,8 +234,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -306,8 +273,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -323,7 +290,6 @@ extern "C" { * * This does not stop on NULL. * NULL characters are ignored. - * Ignores leading and trailing whitespace. * * @param string1 * String to compare. @@ -338,8 +304,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -366,8 +332,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -398,8 +364,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -581,8 +547,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -618,8 +584,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -659,8 +625,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -718,8 +684,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -748,8 +714,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -782,8 +748,8 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -792,6 +758,38 @@ extern "C" { extern f_status_t f_compare_dynamic_partial_trim_string(const f_string_t string1, const f_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2); #endif // _di_f_compare_dynamic_partial_trim_string_ +/** + * Compare two strings, similar to strncmp(). + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * Length of string1. + * @param length2 + * Length of string2. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see f_utf_is_combining() + * @see f_utf_is_whitespace() + */ +#ifndef _di_f_compare_trim_ + extern f_status_t f_compare_trim(const f_string_t string1, const f_string_t string2, const f_array_length_t length1, const f_array_length_t length2); +#endif // _di_f_compare_trim_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_compare/c/compare/private-utf.c b/level_0/f_compare/c/compare/private-utf.c index 3cd67b0..9abf068 100644 --- a/level_0/f_compare/c/compare/private-utf.c +++ b/level_0/f_compare/c/compare/private-utf.c @@ -5,7 +5,7 @@ extern "C" { #endif -#if !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_partial_) +#if !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_string_) || !defined(_di_f_compare_utf_dynamic_partial_) || !defined(_di_f_compare_utf_dynamic_partial_dynamic_) f_status_t private_f_compare_utf(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2) { f_array_length_t i1 = offset1; @@ -35,14 +35,83 @@ extern "C" { return F_equal_to; } -#endif // !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_partial_) +#endif // !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_string_) || !defined(_di_f_compare_utf_dynamic_partial_) || !defined(_di_f_compare_utf_dynamic_partial_dynamic_) -#if !defined(_di_f_compare_utf_trim_) || !defined(_di_f_compare_utf_dynamic_trim_) || !defined(_di_f_compare_utf_dynamic_partial_trim_) - f_status_t private_f_compare_utf_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2) { +#if !defined(_di_f_compare_utf_except_) || !defined(_di_f_compare_utf_dynamic_except_) || !defined(_di_f_compare_utf_dynamic_partial_except_) + f_status_t private_f_compare_utf_except(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + f_array_length_t i1 = offset1; + f_array_length_t i2 = offset2; + + f_array_length_t e1 = 0; + f_array_length_t e2 = 0; + + while (i1 < stop1 && i2 < stop2) { + + // Skip past NULL in string1. + while (i1 < stop1 && !string1[i1]) ++i1; + if (i1 == stop1) break; + + // Skip past NULL in string2. + while (i2 < stop2 && !string2[i2]) ++i2; + if (i2 == stop2) break; + + // Skip past except characters in string1. + while (e1 < except1.used && except1.array[e1] < i1) ++e1; + if (e1 < except1.used && except1.array[e1] == i1) { + ++i1; + + continue; + } + + // Skip past except characters in string2. + while (e2 < except2.used && except2.array[e2] < i2) ++e2; + if (e2 < except2.used && except2.array[e2] == i2) { + ++i2; + + continue; + } + + if (string1[i1] != string2[i2]) return F_equal_to_not; + + ++i1; + ++i2; + } // while + + // Only return F_equal_to if all remaining characters are NULL or are designated to be ignored. + for (; i1 < stop1; i1++) { + + // Skip past except characters in string1. + while (e1 < except1.used && except1.array[e1] < i1) ++e1; + if (e1 < except1.used && except1.array[e1] == i1) continue; + + if (string1[i1]) return F_equal_to_not; + } // for + + for (; i2 < stop2; ++i2) { + + // Skip past except characters in string2. + while (e2 < except2.used && except2.array[e2] < i2) ++e2; + if (e2 < except2.used && except2.array[e2] == i2) continue; + + if (string2[i2]) return F_equal_to_not; + } // for + + return F_equal_to; + } +#endif // !defined(_di_f_compare_utf_except_) || !defined(_di_f_compare_utf_dynamic_except_) || !defined(_di_f_compare_utf_dynamic_partial_except_) + +#if !defined(_di_f_compare_utf_except_trim_) || !defined(_di_f_compare_utf_dynamic_except_trim_) || !defined(_di_f_compare_utf_dynamic_partial_except_trim_) + f_status_t private_f_compare_utf_except_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2, const f_array_lengths_t except1, const f_array_lengths_t except2) { f_array_length_t i1 = offset1; f_array_length_t i2 = offset2; + f_array_length_t e1 = 0; + f_array_length_t e2 = 0; + + f_array_length_t previous = 0; + f_status_t status = F_none; // Skip past leading whitespace in string1. @@ -52,47 +121,87 @@ extern "C" { while (i1 < stop1 && !string1[i1]) ++i1; if (i1 == stop1) break; + // Skip past except characters in string1. + while (e1 < except1.used && except1.array[e1] < i1) ++e1; + if (e1 < except1.used && except1.array[e1] == i1) continue; + status = f_utf_character_is_whitespace(string1[i1], F_false); if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; - // Ignore possibly invalid UTF-8 codes. - if (F_status_set_fine(status) != F_maybe) { - return status; - } + break; } if (status == F_false) break; + + status = f_utf_character_is_combining(string1[i1]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + i1 = previous; + + break; + } + + previous = i1; } // for // Skip past leading whitespace in string2. - for (; i2 < stop2; i2++) { + for (; i2 < stop2; ++i2) { // Skip past NULL in string2. while (i2 < stop2 && !string2[i2]) ++i2; if (i2 == stop2) break; + // Skip past except characters in string2. + while (e2 < except2.used && except2.array[e2] < i2) ++e2; + if (e2 < except2.used && except2.array[e2] == i2) continue; + status = f_utf_character_is_whitespace(string2[i2], F_false); if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; - // Ignore possibly invalid UTF-8 codes. - if (F_status_set_fine(status) != F_maybe) { - return status; - } + break; } if (status == F_false) break; + + status = f_utf_character_is_combining(string2[i2]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + i2 = previous; + + break; + } + + previous = i2; } // for f_array_length_t last1 = i1; f_array_length_t last2 = i2; { - // The size1 and size2 are to represent to total number of characters after trim. + // The size1 and size2 are to represent to total number of characters after trim that are not ignored via "except". f_array_length_t size1 = 0; f_array_length_t size2 = 0; + f_array_length_t j = 0; + f_array_length_t ej = e1; // Determine where the last non-whitespace is in string1. for (j = i1; j < stop1; ++j) { @@ -101,21 +210,48 @@ extern "C" { while (j < stop1 && !string1[j]) ++j; if (j == stop1) break; + // Skip past except characters in string1. + while (ej < except1.used && except1.array[ej] < j) ++ej; + if (ej < except1.used && except1.array[ej] == j) continue; + status = f_utf_character_is_whitespace(string1[j], F_false); if (F_status_is_error(status)) { - // ignore possibly invalid UTF-8 codes. - if (F_status_set_fine(status) != F_maybe) { - return status; - } + if (F_status_set_fine(status) == F_parameter) return status; } if (status == F_false) { + status = f_utf_character_is_combining(string1[j]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + if (last1 != previous) { + size1 -= macro_f_utf_byte_width(string1[last1]); + last1 = previous; + } + } + else { + last1 = j; + ++size1; + previous = j; + } + } + else if (F_status_is_error(status)) { last1 = j; ++size1; + previous = j; + } + else { + previous = j; } } // for + ej = e2; + // Determine where the last non-whitespace is in string2. for (j = i2; j < stop2; ++j) { @@ -123,14 +259,16 @@ extern "C" { while (j < stop2 && !string2[j]) ++j; if (j == stop2) break; + // Skip past except characters in string2. + while (ej < except2.used && except2.array[ej] < j) ++ej; + if (ej < except2.used && except2.array[ej] == j) continue; + status = f_utf_character_is_whitespace(string2[j], F_false); if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_maybe) return F_status_set_error(F_utf_not); - // Ignore possibly invalid UTF-8 codes. - if (F_status_set_fine(status) != F_maybe) { - return status; - } + return status; } if (status == F_false) { @@ -139,37 +277,294 @@ extern "C" { } } // for - if (size1 != size2) { - return F_equal_to_not; - } + if (size1 != size2) return F_equal_to_not; } - for (; i1 < last1 && i2 < last2; ++i1, ++i2) { + if (last1 < stop1 && last2 < stop2) { + while (i1 <= last1 && i2 <= last2) { + + // Skip past NULL in string1. + while (i1 <= last1 && !string1[i1]) ++i1; + if (i1 > last1) break; + + // Skip past NULL in string2. + while (i2 <= last2 && !string2[i2]) ++i2; + if (i2 > last2) break; + + // Skip past except characters in string1. + while (e1 < except1.used && except1.array[e1] < i1) ++e1; + + if (e1 < except1.used && except1.array[e1] == i1) { + ++i1; + + continue; + } + + // Skip past except characters in string2. + while (e2 < except2.used && except2.array[e2] < i2) ++e2; + + if (e2 < except2.used && except2.array[e2] == i2) { + ++i2; + + continue; + } + + if (string1[i1] != string2[i2]) return F_equal_to_not; + + ++i1; + ++i2; + } // while + } + + // Only return F_equal_to if all remaining characters are NULL. + if (last1 < stop1) { + for (; i1 <= last1; ++i1) { + + if (string1[i1] != 0) { + + // Skip past except characters in string1. + while (e1 < except1.used && except1.array[e1] < i1) ++e1; + if (e1 < except1.used && except1.array[e1] == i1) continue; + + return F_equal_to_not; + } + } // for + } + + if (last2 < stop2) { + for (; i2 <= last2; ++i2) { + + if (string2[i2] != 0) { + + // Skip past except characters in string1. + while (e2 < except2.used && except2.array[e2] < i2) ++e2; + if (e2 < except2.used && except2.array[e2] == i2) continue; + + return F_equal_to_not; + } + } // for + } + + return F_equal_to; + } +#endif // !defined(_di_f_compare_utf_except_trim_) || !defined(_di_f_compare_utf_dynamic_except_trim_) || !defined(_di_f_compare_utf_dynamic_partial_except_trim_) + +#if !defined(_di_f_compare_utf_trim_) || !defined(_di_f_compare_utf_dynamic_trim_) || !defined(_di_f_compare_utf_dynamic_partial_trim_) + f_status_t private_f_compare_utf_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2) { + + f_array_length_t i1 = offset1; + f_array_length_t i2 = offset2; + f_array_length_t previous = 0; + f_status_t status = F_none; + + // Skip past leading whitespace in string1. + for (; i1 < stop1; i1 += macro_f_utf_byte_width(string1[i1])) { // Skip past NULL in string1. - while (i1 < last1 && !string1[i1]) ++i1; - if (i1 == last1) break; + while (i1 < stop1 && !string1[i1]) ++i1; + if (i1 == stop1) break; + + status = f_utf_character_is_whitespace(string1[i1], F_false); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + if (status == F_false) break; + + status = f_utf_character_is_combining(string1[i1]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + i1 = previous; + + break; + } + + previous = i1; + } // for + + // Skip past leading whitespace in string2. + for (; i2 < stop2; i2 += macro_f_utf_byte_width(string2[i2])) { // Skip past NULL in string2. - while (i2 < last2 && !string2[i2]) ++i2; - if (i2 == last2) break; + while (i2 < stop2 && !string2[i2]) ++i2; + if (i2 == stop2) break; - if (string1[i1] != string2[i2]) return F_equal_to_not; + status = f_utf_character_is_whitespace(string2[i2], F_false); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + if (status == F_false) break; + + status = f_utf_character_is_combining(string2[i2]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + i2 = previous; + + break; + } + + previous = i2; } // for + f_array_length_t last1 = i1; + f_array_length_t last2 = i2; + + { + // Size1 and size2 are to represent to total number of characters after trim. + f_array_length_t size1 = 0; + f_array_length_t size2 = 0; + + previous = i1; + + // Determine where the last non-whitespace is in string1. + for (f_array_length_t j = i1; j < stop1; j += macro_f_utf_byte_width(string1[j])) { + + // Skip past NULL in string1. + while (j < stop1 && !string1[j]) ++j; + if (j == stop1) break; + + status = f_utf_character_is_whitespace(string1[j], F_false); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + if (status == F_false) { + status = f_utf_character_is_combining(string1[j]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + if (last1 != previous) { + size1 -= macro_f_utf_byte_width(string1[last1]); + last1 = previous; + } + } + else { + last1 = j; + size1 += macro_f_utf_byte_width(string1[last1]); + previous = j; + } + } + else if (F_status_is_error(status)) { + last1 = j; + size1 += macro_f_utf_byte_width(string1[last1]); + previous = j; + } + else { + previous = j; + } + } // for + + previous = i2; + + // Determine where the last non-whitespace is in string2. + for (f_array_length_t j = i2; j < stop2; j += macro_f_utf_byte_width(string2[j])) { + + // Skip past NULL in string2. + while (j < stop2 && !string2[j]) ++j; + if (j == stop2) break; + + status = f_utf_character_is_whitespace(string2[j], F_false); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + + break; + } + + if (status == F_false) { + status = f_utf_character_is_combining(string2[j]); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_parameter) return status; + } + + // This is a combining character, so the previous character is no longer considered a space. + if (status == F_true) { + if (last2 != previous) { + size2 -= macro_f_utf_byte_width(string2[last2]); + last2 = previous; + } + } + else { + last2 = j; + size2 += macro_f_utf_byte_width(string2[last2]); + previous = j; + } + } + else if (F_status_is_error(status)) { + last2 = j; + size2 += macro_f_utf_byte_width(string2[last2]); + previous = j; + } + else { + previous = j; + } + } // for + + if (size1 != size2) return F_equal_to_not; + } + + if (last1 < stop1 && last2 < stop2) { + for (; i1 < last1 && i2 < last2; ++i1, ++i2) { + + // Skip past NULL in string1. + while (i1 < last1 && !string1[i1]) ++i1; + if (i1 == last1) break; + + // Skip past NULL in string2. + while (i2 < last2 && !string2[i2]) ++i2; + if (i2 == last2) break; + + if (string1[i1] != string2[i2]) return F_equal_to_not; + } // for + } + // Only return F_equal_to if all remaining characters are NULL. - for (; i1 < last1; ++i1) { - if (string1[i1] != 0) return F_equal_to_not; - } // for + if (last1 < stop1) { + for (; i1 < last1; ++i1) { + if (string1[i1] != 0) return F_equal_to_not; + } // for + } - for (; i2 < last2; ++i2) { - if (string2[i2] != 0) return F_equal_to_not; - } // for + if (last2 < stop2) { + for (; i2 < last2; ++i2) { + if (string2[i2] != 0) return F_equal_to_not; + } // for + } return F_equal_to; } #endif // !defined(_di_f_compare_utf_trim_) || !defined(_di_f_compare_utf_dynamic_trim_) || !defined(_di_f_compare_utf_dynamic_partial_trim_) + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_compare/c/compare/private-utf.h b/level_0/f_compare/c/compare/private-utf.h index cd2f0b1..7bcd069 100644 --- a/level_0/f_compare/c/compare/private-utf.h +++ b/level_0/f_compare/c/compare/private-utf.h @@ -16,7 +16,7 @@ extern "C" { #endif /** - * Private implementation of fl_utf_compare(). + * Private implementation of f_compare(). * * Intended to be shared to each of the different implementation variations. * @@ -37,15 +37,95 @@ extern "C" { * F_equal_to when both strings equal. * F_equal_to_not when both strings do not equal. * - * F_parameter (with error bit) if a parameter is invalid. - * * @see f_compare_utf() * @see f_compare_utf_dynamic() + * @see f_compare_utf_dynamic_string() * @see f_compare_utf_dynamic_partial() + * @see f_compare_utf_dynamic_partial_dynamic() */ -#if !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_partial_) +#if !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_string_) || !defined(_di_f_compare_utf_dynamic_partial_) || !defined(_di_f_compare_utf_dynamic_partial_dynamic_) extern f_status_t private_f_compare_utf(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_partial_) +#endif // !defined(_di_f_compare_utf_) || !defined(_di_f_compare_utf_dynamic_) || !defined(_di_f_compare_utf_dynamic_string_) || !defined(_di_f_compare_utf_dynamic_partial_) || !defined(_di_f_compare_utf_dynamic_partial_dynamic_) + +/** + * Private implementation of f_compare_utf_except(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param offset1 + * Offset of string1 to start at. + * @param offset2 + * Offset of string2 to start at. + * @param stop1 + * Exclusive stop position for string1. + * @param stop2 + * Exclusive stop position for string2. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * @see f_compare_utf_except() + * @see f_compare_utf_dynamic_except() + * @see f_compare_utf_dynamic_partial_except() + */ +#if !defined(_di_f_compare_utf_except_) || !defined(_di_f_compare_utf_dynamic_except_) || !defined(_di_f_compare_utf_dynamic_partial_except_) + extern f_status_t private_f_compare_utf_except(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2, const f_array_lengths_t except1, const f_array_lengths_t except2) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_compare_utf_except_) || !defined(_di_f_compare_utf_dynamic_except_) || !defined(_di_f_compare_utf_dynamic_partial_except_) + +/** + * Private implementation of f_compare_utf_except_trim(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param offset1 + * Offset of string1 to start at. + * @param offset2 + * Offset of string2 to start at. + * @param stop1 + * Exclusive stop position for string1. + * @param stop2 + * Exclusive stop position for string2. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_utf_not (with error bit) if a character is not valid UTF-8. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + * + * @see f_compare_utf_except_trim() + * @see f_compare_utf_dynamic_except_trim() + * @see f_compare_utf_dynamic_partial_except_trim() + */ +#if !defined(_di_f_compare_utf_except_trim_) || !defined(_di_f_compare_utf_dynamic_except_trim_) || !defined(_di_f_compare_utf_dynamic_partial_except_trim_) + extern f_status_t private_f_compare_utf_except_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t offset1, const f_array_length_t offset2, const f_array_length_t stop1, const f_array_length_t stop2, const f_array_lengths_t except1, const f_array_lengths_t except2) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_compare_utf_except_trim_) || !defined(_di_f_compare_utf_dynamic_except_trim_) || !defined(_di_f_compare_utf_dynamic_partial_except_trim_) /** * Private implementation of f_compare_utf_trim(). @@ -69,11 +149,14 @@ extern "C" { * F_equal_to when both strings equal. * F_equal_to_not when both strings do not equal. * - * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if a character is not valid UTF-8. * - * Errors (with error bit) from: f_utf_character_is_whitespace() + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). * + * @see f_utf_character_is_combining() * @see f_utf_character_is_whitespace() + * * @see f_compare_utf_trim() * @see f_compare_utf_dynamic_trim() * @see f_compare_utf_dynamic_partial_trim() diff --git a/level_0/f_compare/c/compare/utf.c b/level_0/f_compare/c/compare/utf.c index b4ff316..3780439 100644 --- a/level_0/f_compare/c/compare/utf.c +++ b/level_0/f_compare/c/compare/utf.c @@ -12,6 +12,20 @@ extern "C" { } #endif // _di_f_compare_utf_ +#ifndef _di_f_compare_utf_except_ + f_status_t f_compare_utf_except(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t length1, const f_array_length_t length2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except(string1, string2, 0, 0, length1, length2, except1, except2); + } +#endif // _di_f_compare_utf_except_ + +#ifndef _di_f_compare_utf_except_trim_ + f_status_t f_compare_utf_except_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t length1, const f_array_length_t length2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim(string1, string2, 0, 0, length1, length2, except1, except2); + } +#endif // _di_f_compare_utf_except_trim_ + #ifndef _di_f_compare_utf_dynamic_ f_status_t f_compare_utf_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2) { @@ -19,6 +33,41 @@ extern "C" { } #endif // _di_f_compare_utf_dynamic_ +#ifndef _di_f_compare_utf_dynamic_except_ + f_status_t f_compare_utf_dynamic_except(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except(string1.string, string2.string, 0, 0, string1.used, string2.used, except1, except2); + } +#endif // _di_f_compare_utf_dynamic_except_ + +#ifndef _di_f_compare_utf_dynamic_except_string_ + f_status_t f_compare_utf_dynamic_except_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except(string1, string2.string, 0, 0, length1, string2.used, except1, except2); + } +#endif // _di_f_compare_utf_dynamic_except_string_ + +#ifndef _di_f_compare_utf_dynamic_except_trim_ + f_status_t f_compare_utf_dynamic_except_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim(string1.string, string2.string, 0, 0, string1.used, string2.used, except1, except2); + } +#endif // _di_f_compare_utf_dynamic_except_trim_ + +#ifndef _di_f_compare_utf_dynamic_except_trim_string_ + f_status_t f_compare_utf_dynamic_except_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim(string1, string2.string, 0, 0, length1, string2.used, except1, except2); + } +#endif // _di_f_compare_utf_dynamic_except_trim_string_ + +#ifndef _di_f_compare_utf_dynamic_string_ + f_status_t f_compare_utf_dynamic_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1) { + + return private_f_compare_utf(string1, string2.string, 0, 0, length1, string2.used); + } +#endif // _di_f_compare_utf_dynamic_string_ + #ifndef _di_f_compare_utf_dynamic_trim_ f_status_t f_compare_utf_dynamic_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2) { @@ -26,27 +75,224 @@ extern "C" { } #endif // _di_f_compare_utf_dynamic_trim_ +#ifndef _di_f_compare_utf_dynamic_trim_string_ + f_status_t f_compare_utf_dynamic_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1) { + + return private_f_compare_utf_trim(string1, string2.string, 0, 0, length1, string2.used); + } +#endif // _di_f_compare_utf_dynamic_trim_string_ + #ifndef _di_f_compare_utf_dynamic_partial_ f_status_t f_compare_utf_dynamic_partial(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2) { - #ifndef _di_level_0_parameter_checking_ - if (string1.used <= range1.stop) return F_status_set_error(F_parameter); - if (string2.used <= range2.stop) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - return private_f_compare_utf(string1.string, string2.string, range1.start, range2.start, range1.stop + 1, range2.stop + 1); + return private_f_compare_utf( + string1.string, + string2.string, + range1.start, + range2.start, + string1.used <= range1.stop + ? string1.used + : range1.stop + 1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1 + ); } #endif // _di_f_compare_utf_dynamic_partial_ +#ifndef _di_f_compare_utf_dynamic_partial_dynamic_ + f_status_t f_compare_utf_dynamic_partial_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2) { + + return private_f_compare_utf( + string1.string, + string2.string, + 0, + range2.start, + string1.used, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_dynamic_ + +#ifndef _di_f_compare_utf_dynamic_partial_string_ + f_status_t f_compare_utf_dynamic_partial_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2) { + + return private_f_compare_utf( + string1, + string2.string, + 0, + range2.start, + length1, + string2.used < range2.stop + ? string2.used + : range2.stop + 1 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_string_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_ + f_status_t f_compare_utf_dynamic_partial_except(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except( + string1.string, + string2.string, + range1.start, + range2.start, + string1.used < range1.stop + ? string1.used + : range1.stop + 1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_dynamic_ + f_status_t f_compare_utf_dynamic_partial_except_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except( + string1.string, + string2.string, + 0, + range2.start, + string1.used, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_dynamic_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_string_ + f_status_t f_compare_utf_dynamic_partial_except_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except( + string1, + string2.string, + 0, + range2.start, + length1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_string_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_ + f_status_t f_compare_utf_dynamic_partial_except_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim( + string1.string, + string2.string, + range1.start, + range2.start, + string1.used <= range1.stop + ? string1.used + : range1.stop + 1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_trim_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_dynamic_ + f_status_t f_compare_utf_dynamic_partial_except_trim_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim( + string1.string, + string2.string, + 0, + range2.start, + string1.used, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_trim_dynamic_ + +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_string_ + f_status_t f_compare_utf_dynamic_partial_except_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2) { + + return private_f_compare_utf_except_trim( + string1, + string2.string, + 0, + range2.start, + length1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1, + except1, + except2 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_except_trim_string_ + #ifndef _di_f_compare_utf_dynamic_partial_trim_ f_status_t f_compare_utf_dynamic_partial_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2) { - #ifndef _di_level_0_parameter_checking_ - if (string1.used <= range1.stop) return F_status_set_error(F_parameter); - if (string2.used <= range2.stop) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - return private_f_compare_utf_trim(string1.string, string2.string, range1.start, range2.start, range1.stop + 1, range2.stop + 1); + return private_f_compare_utf_trim( + string1.string, + string2.string, + range1.start, + range2.start, + string1.used <= range1.stop + ? string1.used + : range1.stop + 1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1 + ); + } +#endif // _di_f_compare_utf_utf_dynamic_partial_trim_ + +#ifndef _di_f_compare_utf_dynamic_partial_trim_dynamic_ + f_status_t f_compare_utf_dynamic_partial_trim_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2) { + + return private_f_compare_utf_trim( + string1.string, + string2.string, + 0, + range2.start, + string1.used, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1 + ); + } +#endif // _di_f_compare_utf_dynamic_partial_trim_dynamic_ + +#ifndef _di_f_compare_utf_dynamic_partial_trim_string_ + f_status_t f_compare_utf_dynamic_partial_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2) { + + return private_f_compare_utf_trim( + string1, + string2.string, + 0, + range2.start, + length1, + string2.used <= range2.stop + ? string2.used + : range2.stop + 1 + ); } -#endif // _di_f_compare_utf_dynamic_partial_trim_ +#endif // _di_f_compare_utf_dynamic_partial_trim_string_ #ifndef _di_f_compare_utf_trim_ f_status_t f_compare_utf_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t length1, const f_array_length_t length2) { diff --git a/level_0/f_compare/c/compare/utf.h b/level_0/f_compare/c/compare/utf.h index ffec18a..415d69c 100644 --- a/level_0/f_compare/c/compare/utf.h +++ b/level_0/f_compare/c/compare/utf.h @@ -44,6 +44,77 @@ extern "C" { * * This does not stop on NULL. * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * Length of string1. + * @param length2 + * Length of string2. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_except_ + extern f_status_t f_compare_utf_except(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t length1, const f_array_length_t length2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_except_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * Length of string1. + * @param length2 + * Length of string2. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_except_trim_ + extern f_status_t f_compare_utf_except_trim(const f_utf_string_t string1, const f_utf_string_t string2, const f_array_length_t length1, const f_array_length_t length2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_except_trim_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This does not stop on NULL. + * NULL characters are ignored. * * @param string1 * String to compare. @@ -66,6 +137,177 @@ extern "C" { * * This does not stop on NULL. * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_except_ + extern f_status_t f_compare_utf_dynamic_except(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_except_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_except_string_ + extern f_status_t f_compare_utf_dynamic_except_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_except_string_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_except_trim_ + extern f_status_t f_compare_utf_dynamic_except_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_except_trim_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_except_trim_string_ + extern f_status_t f_compare_utf_dynamic_except_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_except_trim_string_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_string_ + extern f_status_t f_compare_utf_dynamic_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1); +#endif // _di_f_compare_utf_dynamic_string_ + +/** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This does not stop on NULL. + * NULL characters are ignored. * Ignores leading and trailing whitespace. * * @param string1 @@ -80,8 +322,10 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * F_utf_fragment (with error bit) if character is a UTF-8 fragment. * + * Errors (with error bit) from: f_utf_character_is_combining(). * Errors (with error bit) from: f_utf_character_is_whitespace(). * + * @see f_utf_character_is_combining() * @see f_utf_character_is_whitespace() */ #ifndef _di_f_compare_utf_dynamic_trim_ @@ -89,6 +333,38 @@ extern "C" { #endif // _di_f_compare_utf_dynamic_trim_ /** + * Compare two UTF-8 strings, similar to strncmp(). + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_trim_string_ + extern f_status_t f_compare_utf_dynamic_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1); +#endif // _di_f_compare_utf_dynamic_trim_string_ + +/** * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given ranges. * * This does not stop on NULL. @@ -114,6 +390,269 @@ extern "C" { #endif // _di_f_compare_utf_dynamic_partial_ /** + * Compare two strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range2 + * A range within the string2 to restrict the comparison to. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_partial_dynamic_ + extern f_status_t f_compare_utf_dynamic_partial_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2); +#endif // _di_f_compare_utf_dynamic_partial_dynamic_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given ranges. + * + * This does not stop on NULL. + * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range1 + * A range within the string1 to restrict the comparison to. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_ + extern f_status_t f_compare_utf_dynamic_partial_except(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_ + +/** + * Compare two strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_dynamic_ + extern f_status_t f_compare_utf_dynamic_partial_except_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_dynamic_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_string_ + extern f_status_t f_compare_utf_dynamic_partial_except_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_string_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given ranges. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range1 + * A range within the string1 to restrict the comparison to. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_ + extern f_status_t f_compare_utf_dynamic_partial_except_trim(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_trim_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_dynamic_ + extern f_status_t f_compare_utf_dynamic_partial_except_trim_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_trim_dynamic_ + +/** + * Compare two strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * All 1-byte characters in except1 and except2 are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param range2 + * A range within the string2 to restrict the comparison to. + * @param except1 + * A set of locations within string1 to ignore. + * This assumes/requires that the locations be in linear order. + * @param except2 + * A set of locations within string2 to ignore. + * This assumes/requires that the locations be in linear order. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_partial_except_trim_string_ + extern f_status_t f_compare_utf_dynamic_partial_except_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2, const f_array_lengths_t except1, const f_array_lengths_t except2); +#endif // _di_f_compare_utf_dynamic_partial_except_trim_string_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param range2 + * A range within the string2 to restrict the comparison to. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_compare_utf_dynamic_partial_string_ + extern f_status_t f_compare_utf_dynamic_partial_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2); +#endif // _di_f_compare_utf_dynamic_partial_string_ + +/** * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given ranges. * * This does not stop on NULL. @@ -135,8 +674,10 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_utf_character_is_combining(). * Errors (with error bit) from: f_utf_character_is_whitespace(). * + * @see f_utf_character_is_combining() * @see f_utf_character_is_whitespace() */ #ifndef _di_f_compare_utf_dynamic_partial_trim_ @@ -144,6 +685,70 @@ extern "C" { #endif // _di_f_compare_utf_dynamic_partial_trim_ /** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param range2 + * A range within the string2 to restrict the comparison to. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_partial_trim_dynamic_ + extern f_status_t f_compare_utf_dynamic_partial_trim_dynamic(const f_utf_string_static_t string1, const f_utf_string_static_t string2, const f_string_range_t range2); +#endif // _di_f_compare_utf_dynamic_partial_trim_dynamic_ + +/** + * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given range for the second string. + * + * This operates with the first string being a traditional string. + * + * This does not stop on NULL. + * NULL characters are ignored. + * Ignores leading and trailing whitespace. + * + * @param string1 + * String to compare. + * @param string2 + * String to compare. + * @param length1 + * The length of string1. + * @param range2 + * A range within the string2 to restrict the comparison to. + * + * @return + * F_equal_to when both strings equal. + * F_equal_to_not when both strings do not equal. + * + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_character_is_combining(). + * Errors (with error bit) from: f_utf_character_is_whitespace(). + * + * @see f_utf_character_is_combining() + * @see f_utf_character_is_whitespace() + */ +#ifndef _di_f_compare_utf_dynamic_partial_trim_string_ + extern f_status_t f_compare_utf_dynamic_partial_trim_string(const f_utf_string_t string1, const f_utf_string_static_t string2, const f_array_length_t length1, const f_string_range_t range2); +#endif // _di_f_compare_utf_dynamic_partial_trim_string_ + +/** * Compare two UTF-8 strings, similar to strncmp(). * * This does not stop on NULL. diff --git a/level_0/f_compare/c/private-compare.h b/level_0/f_compare/c/private-compare.h index fa189fa..9d61caf 100644 --- a/level_0/f_compare/c/private-compare.h +++ b/level_0/f_compare/c/private-compare.h @@ -113,8 +113,8 @@ extern "C" { * * F_utf_not (with error bit) if a character is not valid UTF-8. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() @@ -151,8 +151,8 @@ extern "C" { * * F_utf_not (with error bit) if a character is not valid UTF-8. * - * F_parameter (with error bit) from: f_utf_is_combining(). - * F_parameter (with error bit) from: f_utf_is_whitespace(). + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see f_utf_is_combining() * @see f_utf_is_whitespace() -- 1.8.3.1