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.
}
#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) {
}
#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
*
* 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()
*
* 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.
*
* 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
*
* 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()
*
* 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()
*
* 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()
*
* This does not stop on NULL.
* NULL characters are ignored.
- * Ignores leading and trailing whitespace.
*
* @param string1
* String to compare.
*
* 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()
*
* 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()
*
* 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()
*
* 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()
*
* 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()
*
* 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()
*
* 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()
*
* 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()
*
* 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()
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
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;
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.
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) {
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) {
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) {
}
} // 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
#endif
/**
- * Private implementation of fl_utf_compare().
+ * Private implementation of f_compare().
*
* Intended to be shared to each of the different implementation variations.
*
* 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().
* 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()
}
#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) {
}
#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) {
}
#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) {
*
* 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.
*
* 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
* 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_
#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.
#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.
*
* 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_
#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.
*
* 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()
*
* 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()