From 5cfe0e8295a2cdf854bffb1475aa1a4311c71277 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 2 May 2020 18:42:44 -0500 Subject: [PATCH] Update: simplify and rework string functions The rip and append functions are functionally identical. Remove the rip function. With the rip functions gone, the rip_trim functions are renamed to rip. This way "rip" functions operate like a theoretical append_trim function, but with fewer words. Make the string functions use start and stop ranges instead of lengths. This eliminates the needs for the partial functions. Add new nulless functions that check for and remove nulls from source strings while transferring them to the destination string. This allows for converting the strings that may have nulls to nulless strings such that they can be used in null-sensitive functions such as those found in the standard C libraries. Make sure the utf_string functions match correspond to the string functions. --- level_1/fl_string/c/private-string.c | 283 ++++++----- level_1/fl_string/c/private-string.h | 130 ++--- level_1/fl_string/c/string.c | 287 ++++++++--- level_1/fl_string/c/string.h | 451 ++++++++++++----- level_1/fl_utf/c/private-utf.c | 238 +++++++-- level_1/fl_utf/c/private-utf.h | 129 ++++- level_1/fl_utf/c/utf.c | 296 ++++++++++- level_1/fl_utf/c/utf.h | 561 +++++++++++++++++++-- level_2/fll_program/c/program.c | 114 ++--- level_2/fll_program/c/program.h | 60 +-- .../c/private-fss_basic_list_read.c | 4 +- level_3/fss_basic_read/c/private-fss_basic_read.c | 4 +- .../c/private-fss_extended_list_read.c | 4 +- .../c/private-fss_extended_read.c | 4 +- 14 files changed, 1960 insertions(+), 605 deletions(-) diff --git a/level_1/fl_string/c/private-string.c b/level_1/fl_string/c/private-string.c index 6729436..5f4f931 100644 --- a/level_1/fl_string/c/private-string.c +++ b/level_1/fl_string/c/private-string.c @@ -5,26 +5,92 @@ extern "C" { #endif -#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_) - f_return_status private_fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) { - f_status status = f_none; +#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) + f_return_status private_fl_string_append(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. + f_string_length source_length = (stop - start) + 1; - f_string_length total = destination->used + source_length; + if (destination->used + source_length > f_string_max_size) return f_status_set_error(f_string_too_large); + + f_status status = f_none; - if (total > f_string_max_size) return f_status_set_error(f_string_too_large); + const f_string_length total = destination->used + source_length; if (total > destination->size) { f_macro_string_dynamic_resize(status, (*destination), total); if (f_status_is_error(status)) return status; } - memcpy(destination->string + destination->used, source, source_length); - + memcpy(destination->string + destination->used, source + start, source_length); destination->used = total; return f_none; } -#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_) +#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) + +#if !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) + f_return_status private_fl_string_append_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. + f_string_length source_length = (stop - start) + 1; + + if (destination->used + source_length > f_string_max_size) return f_status_set_error(f_string_too_large); + + f_status status = f_none; + + f_string_length first = 0; + + for (f_string_length i = 0; i <= source_length; i++) { + if (i == source_length) { + if (i > first) { + f_string_length length = i - first; + + if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large); + + f_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, length); + destination->used = total; + } + + break; + } + + if (source[i] == f_string_eos) { + if (i > 0) { + if (i > first) { + f_string_length length = i - first; + + if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large); + + f_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, length); + destination->used = total; + } + } + + while (i + 1 < source_length && source[i + 1] == f_string_eos) { + i++; + } // while + + first = i + 1; + continue; + } + } // for + + return f_none; + } +#endif // !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) #if !defined(_di_fl_string_compare_) || !defined(_di_fl_string_dynamic_compare_) || !defined(_di_fl_string_dynamic_partial_compare_) f_return_status private_fl_string_compare(const f_string string1, const f_string string2, const f_string_length offset1, const f_string_length offset2, const f_string_length stop1, const f_string_length stop2) { @@ -72,9 +138,7 @@ extern "C" { width_max = (stop1 - i1) + 1; status = f_utf_is_whitespace(string1 + i1, width_max); if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_maybe) { - return f_status_set_error(f_invalid_utf); - } + if (f_status_set_fine(status) == f_maybe) return f_status_set_error(f_invalid_utf); return status; } @@ -122,9 +186,7 @@ extern "C" { width_max = (stop1 - j) + 1; status = f_utf_is_whitespace(string1 + j, width_max); if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_maybe) { - return f_status_set_error(f_invalid_utf); - } + if (f_status_set_fine(status) == f_maybe) return f_status_set_error(f_invalid_utf); return status; } @@ -146,9 +208,7 @@ extern "C" { width_max = (stop2 - j) + 1; status = f_utf_is_whitespace(string2 + j, width_max); if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_maybe) { - return f_status_set_error(f_invalid_utf); - } + if (f_status_set_fine(status) == f_maybe) return f_status_set_error(f_invalid_utf); return status; } @@ -191,50 +251,16 @@ extern "C" { } #endif // !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_) -#if !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_) - f_return_status private_fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) { - f_status status = f_none; - - if (destination->used == 0) { - if (source_length > f_string_max_size) return f_status_set_error(f_string_too_large); - - f_macro_string_dynamic_resize(status, (*destination), source_length); - if (f_status_is_error(status)) return status; - - memcpy(destination->string, source, source_length); - - destination->used = source_length; - } - else { - f_string_length total = destination->used + source_length + glue_length; - - if (total > f_string_max_size) return f_status_set_error(f_string_too_large); - - if (total > destination->size) { - f_macro_string_dynamic_resize(status, (*destination), total); - if (f_status_is_error(status)) return status; - } - - for (f_string_length i = 0; i < glue_length; i++) { - destination->string[destination->used + i] = glue[i]; - } // for - - memcpy(destination->string + destination->used + glue_length, source, source_length); - - destination->used = total; - } +#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) + f_return_status private_fl_string_prepend(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. + f_string_length source_length = (stop - start) + 1; - return f_none; - } -#endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_) + if (destination->used + source_length > f_string_max_size) return f_status_set_error(f_string_too_large); -#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_) - f_return_status private_fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) { f_status status = f_none; - f_string_length total = destination->used + source_length; - - if (total > f_string_max_size) return f_status_set_error(f_string_too_large); + const f_string_length total = destination->used + source_length; if (total > destination->size) { f_macro_string_dynamic_resize(status, (*destination), total); @@ -243,120 +269,151 @@ extern "C" { if (destination->used > 0) { memmove(destination->string + source_length, destination->string, destination->used); - memcpy(destination->string, source, source_length); + memcpy(destination->string, source + start, source_length); } else { - memcpy(destination->string, source, source_length); + memcpy(destination->string, source + start, source_length); } destination->used = total; - return f_none; } -#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_) +#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) -#if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) - f_return_status private_fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) { +#if !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_) + f_return_status private_fl_string_prepend_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. - f_string_length size = (stop - start) + 1; + f_string_length source_length = (stop - start) + 1; - if (size == 0) return f_no_data; + if (destination->used + source_length > f_string_max_size) return f_status_set_error(f_string_too_large); f_status status = f_none; - if (size > result->size) { - f_macro_string_dynamic_resize(status, (*result), size); - } + f_string_length first = 0; + f_string_length offset = 0; - if (f_status_is_error(status)) return status; + for (f_string_length i = 0; i <= source_length; i++) { + if (i == source_length) { + if (i > first) { + f_string_length length = i - first; - memcpy(result->string, string + start, size); - result->used = size; + if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large); - return f_none; - } -#endif // !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) + f_string_length total = destination->used + length; -#if !defined(_di_fl_string_rip_trim_) || !defined(_di_fl_string_dynamic_rip_trim_) - f_return_status private_fl_string_rip_trim(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) { - // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. - f_string_length size = (stop - start) + 1; + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } - if (size == 0) return f_no_data; + memmove(destination->string + offset + length, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, length); - f_status status = f_none; + destination->used = total; + offset += length; + } - if (size > result->size) { - f_macro_string_dynamic_resize(status, (*result), size); - } + break; + } + + if (source[i] == f_string_eos) { + if (i > 0) { + if (i > first) { + f_string_length length = i - first; + + if (destination->used + length > f_string_max_size) return f_status_set_error(f_string_too_large); + + f_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); - if (f_status_is_error(status)) return status; + if (f_status_is_error(status)) return status; + } - f_string_length begin = start; - f_string_length end = stop; + memmove(destination->string + offset + length, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, length); + + destination->used = total; + offset += length; + } + } + + while (i + 1 < source_length && source[i + 1] == f_string_eos) { + i++; + } // while + + first = i + 1; + continue; + } + } // for + + return f_none; + } +#endif // !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_) + +#if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) || !defined(_di_fl_string_rip_nulless_) || !defined(_di_fl_string_dynamic_rip_nulless_) + f_return_status private_fl_string_rip_find_range(const f_string source, f_string_length *start, f_string_length *stop) { + f_string_length stop_original = *stop; + + f_status status = f_none; uint8_t width = 0; // skip past leading whitespace. - for (; begin <= end; begin += width) { + for (; *start <= *stop; *start += width) { // skip past NULL. - while (begin < end && string[begin] == f_string_eos) begin++; - if (begin > end) break; + while (*start < *stop && source[*start] == f_string_eos) (*start)++; + if (*start > *stop) break; - status = f_utf_is_whitespace(string + begin, (end - begin) + 1); + status = f_utf_is_whitespace(source + *start, (*stop - *start) + 1); if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_maybe) { - return f_status_set_error(f_invalid_utf); - } + if (f_status_set_fine(status) == f_maybe) return f_status_set_error(f_invalid_utf); return status; } if (status == f_false) break; - width = f_macro_utf_byte_width(string[begin]); + width = f_macro_utf_byte_width(source[*start]); } // for - for (; end > begin; end--) { + for (; *stop > *start; (*stop)--) { + // skip past NULL. - while (end > begin && string[end] == f_string_eos) end--; - if (string[end] == f_string_eos) continue; - if (end == begin) break; + while (*stop > *start && source[*stop] == f_string_eos) (*stop)--; + + if (source[*stop] == f_string_eos) continue; + if (*stop == *start) break; - // each UTF-8 character of width 8 is an incomplete part. + // each UTF-8 character of width 1 is an incomplete part. // go left until either width is 0 (ascii, or > 1) to determine the character. for (;;) { - width = f_macro_utf_byte_width_is(string[end]); + width = f_macro_utf_byte_width_is(source[*stop]); + if (width == 1) { - end--; + (*stop)--; - if (end == begin) break; + if (*stop == *start) break; } else break; } // for - if (end == begin) break; + if (*stop == *start) break; - status = f_utf_is_whitespace(string + end, (stop - end) + 1); + status = f_utf_is_whitespace(source + *stop, (stop_original - *stop) + 1); if (f_status_is_error(status)) { - if (f_status_set_fine(status) == f_maybe) { - return f_status_set_error(f_invalid_utf); - } + if (f_status_set_fine(status) == f_maybe) return f_status_set_error(f_invalid_utf); return status; } if (status == f_false) break; - - width = f_macro_utf_byte_width(string[end]); } // for - memcpy(result->string, string + begin, (end - begin) + 1); - result->used = (end - begin) + 1; - return f_none; } -#endif // !defined(_di_fl_string_rip_trim_) || !defined(_di_fl_string_dynamic_rip_trim_) +#endif // !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) || !defined(_di_fl_string_rip_nulless_) || !defined(_di_fl_string_dynamic_rip_nulless_) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_string/c/private-string.h b/level_1/fl_string/c/private-string.h index e5ce484..77994d7 100644 --- a/level_1/fl_string/c/private-string.h +++ b/level_1/fl_string/c/private-string.h @@ -24,8 +24,10 @@ extern "C" { * * @param source * The source string to append. - * @param source_length - * Total number of bytes to copy from source string. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. * @param destination * The destination string the source and glue are appended onto. * @@ -37,12 +39,43 @@ extern "C" { * f_error_reallocation (with error bit) on memory reallocation error. * * @see fl_string_append() + * @see fl_string_mash() * @see fl_string_dynamic_append() - * @see fl_string_dynamic_partial_append() + * @see fl_string_dynamic_mash() */ -#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_) - extern f_return_status private_fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_dynamic_partial_append_) +#if !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) + extern f_return_status private_fl_string_append(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_string_append_) || !defined(_di_fl_string_dynamic_append_) || !defined(_di_fl_string_append_mash_) || !defined(_di_fl_string_dynamic_mash_) + +/** + * Private implementation of fl_string_append_nulless(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append_nulless() + * @see fl_string_mash_nulless() + * @see fl_string_dynamic_append_nulless() + * @see fl_string_dynamic_mash_nulless() + */ +#if !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) + extern f_return_status private_fl_string_append_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_string_append_nulless_) || !defined(_di_fl_string_dynamic_append_nulless_) || !defined(_di_fl_string_mash_nulless_) || !defined(_di_fl_string_dynamic_mash_nulless_) /** * Private implementation of fl_string_compare(). @@ -107,45 +140,16 @@ extern "C" { #endif // !defined(_di_fl_string_compare_trim_) || !defined(_di_fl_string_dynamic_compare_trim_) || !defined(_di_fl_string_dynamic_partial_compare_trim_) /** - * Private implementation of fl_string_mash(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param source_length - * Total number of bytes to copy from source string. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * f_none on success. - * f_string_max_size (with error bit) if the combined string is too large. - * f_invalid_parameter (with error bit) if a parameter is invalid. - * f_error_allocation (with error bit) on memory allocation error. - * f_error_reallocation (with error bit) on memory reallocation error. - * - * @see fl_string_mash() - * @see fl_string_dynamic_mash() - * @see fl_string_dynamic_partial_mash() - */ -#if !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_) - extern f_return_status private_fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_string_mash_) || !defined(_di_fl_string_dynamic_mash_) || !defined(_di_fl_string_dynamic_partial_mash_) - -/** * Private implementation of fl_string_prepend(). * * Intended to be shared to each of the different implementation variations. * * @param source * The source string to prepend. - * @param source_length - * Total number of bytes to copy from source string. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. * @param destination * The destination string the source and glue are prepended onto. * @@ -158,57 +162,55 @@ extern "C" { * * @see fl_string_prepend() * @see fl_string_dynamic_prepend() - * @see fl_string_dynamic_partial_prepend() */ -#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_) - extern f_return_status private_fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_dynamic_partial_prepend_) +#if !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_append_mish_) || !defined(_di_fl_string_dynamic_mish_) + extern f_return_status private_fl_string_prepend(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_string_prepend_) || !defined(_di_fl_string_dynamic_prepend_) || !defined(_di_fl_string_append_mish_) || !defined(_di_fl_string_dynamic_mish_) /** - * Private implementation of fl_string_rip(). + * Private implementation of fl_string_prepend_nulless(). * * Intended to be shared to each of the different implementation variations. * - * @param string - * The string to rip from. + * @param source + * The source string to prepend. * @param start - * Inclusive start point of string to rip. + * Inclusive start point of string to append. * @param stop - * Inclusive stop point of string to rip. - * @param result - * The new string, which will be allocated or reallocated as necessary. + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are prepended onto. * * @return * f_none on success. - * f_no_data if nothing to rip, no allocations or reallocations are performed. + * f_string_max_size (with error bit) if the combined string is too large. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_dynamic_rip() - * @see fl_string_rip() + * @see fl_string_prepend_nulless() + * @see fl_string_dynamic_prepend_nulless() */ -#if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) - extern f_return_status private_fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) +#if !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_) || !defined(_di_fl_string_append_mish_) || !defined(_di_fl_string_dynamic_mish_) + extern f_return_status private_fl_string_prepend_nulless(const f_string source, f_string_length start, const f_string_length stop, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_string_prepend_nulless_) || !defined(_di_fl_string_dynamic_prepend_nulless_) || !defined(_di_fl_string_append_mish_) || !defined(_di_fl_string_dynamic_mish_) /** - * Private implementation of fl_string_rip_trim(). + * Private implementation of fl_string_rip(), but only the part for finding the start/stop range. * * Intended to be shared to each of the different implementation variations. * - * @param string + * @param source * The string to rip from. * @param start * Inclusive start point of string to rip. + * Will be updated to reflect the new start range. * @param stop * Inclusive stop point of string to rip. - * @param result - * The new string, which will be allocated or reallocated as necessary. + * Will be updated to reflect the new stop range. * * @return * f_none on success. - * f_no_data if nothing to rip, no allocations or reallocations are performed. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. @@ -216,9 +218,9 @@ extern "C" { * @see fl_string_dynamic_rip() * @see fl_string_rip() */ -#if !defined(_di_fl_string_rip_trim_) || !defined(_di_fl_string_dynamic_rip_trim_) - extern f_return_status private_fl_string_rip_trim(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_string_rip_trim_) || !defined(_di_fl_string_dynamic_rip_trim_) +#if !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) || !defined(_di_fl_string_rip_nulless_) || !defined(_di_fl_string_dynamic_rip_nulless_) + extern f_return_status private_fl_string_rip_find_range(const f_string source, f_string_length *start, f_string_length *stop) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_string_rip_) || !defined(_di_fl_string_dynamic_rip_) || !defined(_di_fl_string_rip_nulless_) || !defined(_di_fl_string_dynamic_rip_nulless_) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_string/c/string.c b/level_1/fl_string/c/string.c index 7edb64f..e59f5e8 100644 --- a/level_1/fl_string/c/string.c +++ b/level_1/fl_string/c/string.c @@ -6,16 +6,27 @@ extern "C" { #endif #ifndef _di_fl_string_append_ - f_return_status fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination) { + f_return_status fl_string_append(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (source_length < 1) return f_status_set_error(f_invalid_parameter); + if (start > stop) return f_status_set_error(f_invalid_parameter); if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_append(source, source_length, destination); + return private_fl_string_append(source, start, stop, destination); } #endif // _di_fl_string_append_ +#ifndef _di_fl_string_append_nulless_ + f_return_status fl_string_append_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (start > stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_string_append_nulless(source, start, stop, destination); + } +#endif // _di_fl_string_append_nulless_ + #ifndef _di_fl_string_compare_ f_return_status fl_string_compare(const f_string string1, const f_string string2, const f_string_length length1, const f_string_length length2) { #ifndef _di_level_1_parameter_checking_ @@ -67,7 +78,7 @@ extern "C" { if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_append(source.string, source.used, destination); + return private_fl_string_append(source.string, 0, source.used - 1, destination); } #endif // _di_fl_string_dynamic_append_ @@ -79,10 +90,78 @@ extern "C" { if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_mash(glue, glue_length, source.string, source.used, destination); + if (destination->used > 0) { + f_status status = private_fl_string_append(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_append(source.string, 0, source.used - 1, destination); } #endif // _di_fl_string_dynamic_mash_ +#ifndef _di_fl_string_dynamic_mash_nulless_ + f_return_status fl_string_dynamic_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_append_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_append_nulless(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_string_dynamic_mash_nulless_ + +#ifndef _di_fl_string_dynamic_mish_ + f_return_status fl_string_dynamic_mish(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_prepend(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_prepend(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_string_dynamic_mish_ + +#ifndef _di_fl_string_dynamic_mish_nulless_ + f_return_status fl_string_dynamic_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_prepend_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_prepend_nulless(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_string_dynamic_mish_nulless_ + #ifndef _di_fl_string_dynamic_partial_compare_ f_return_status fl_string_dynamic_partial_compare(const f_string_dynamic string1, const f_string_dynamic string2, const f_string_location offset1, const f_string_location offset2) { #ifndef _di_level_1_parameter_checking_ @@ -117,49 +196,6 @@ extern "C" { } #endif // _di_fl_string_dynamic_partial_compare_trim_ -#ifndef _di_fl_string_dynamic_partial_append_ - f_return_status fl_string_dynamic_partial_append(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) { - #ifndef _di_level_1_parameter_checking_ - if (source.used < 1) return f_status_set_error(f_invalid_parameter); - if (destination == 0) return f_status_set_error(f_invalid_parameter); - - if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter); - if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); - #endif // _di_level_1_parameter_checking_ - - return private_fl_string_append(source.string + offset.start, (offset.stop - offset.start) + 1, destination); - } -#endif // _di_fl_string_dynamic_partial_append_ - -#ifndef _di_fl_string_dynamic_partial_mash_ - f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) { - #ifndef _di_level_1_parameter_checking_ - if (glue_length < 1) return f_status_set_error(f_invalid_parameter); - if (source.used < 1) return f_status_set_error(f_invalid_parameter); - if (destination == 0) return f_status_set_error(f_invalid_parameter); - - if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter); - if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); - #endif // _di_level_1_parameter_checking_ - - return private_fl_string_mash(glue, glue_length, source.string + offset.start, (offset.stop - offset.start) + 1, destination); - } -#endif // _di_fl_string_dynamic_partial_mash_ - -#ifndef _di_fl_string_dynamic_partial_prepend_ - f_return_status fl_string_dynamic_partial_prepend(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) { - #ifndef _di_level_1_parameter_checking_ - if (source.used < 1) return f_status_set_error(f_invalid_parameter); - if (destination == 0) return f_status_set_error(f_invalid_parameter); - - if (offset.start > offset.stop) return f_status_set_error(f_invalid_parameter); - if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); - #endif // _di_level_1_parameter_checking_ - - return private_fl_string_prepend(source.string + offset.start, (offset.stop - offset.start) + 1, destination); - } -#endif // _di_fl_string_dynamic_partial_prepend_ - #ifndef _di_fl_string_dynamic_prepend_ f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ @@ -167,37 +203,37 @@ extern "C" { if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_prepend(source.string, source.used, destination); + return private_fl_string_prepend(source.string, 0, source.used - 1, destination); } #endif // _di_fl_string_dynamic_prepend_ #ifndef _di_fl_string_dynamic_rip_ - f_return_status fl_string_dynamic_rip(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result) { + f_return_status fl_string_dynamic_rip(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (location.start < 0) return f_status_set_error(f_invalid_parameter); - if (location.stop < location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.stop) return f_status_set_error(f_invalid_parameter); + if (offset.stop < offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= 0) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_rip(buffer.string, location.start, location.stop, result); + return private_fl_string_append(source.string, offset.start, offset.stop, destination); } #endif // _di_fl_string_dynamic_rip_ -#ifndef _di_fl_string_dynamic_rip_trim_ - f_return_status fl_string_dynamic_rip_trim(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result) { +#ifndef _di_fl_string_dynamic_rip_nulless_ + f_return_status fl_string_dynamic_rip_nulless(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (location.start < 0) return f_status_set_error(f_invalid_parameter); - if (location.stop < location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.stop) return f_status_set_error(f_invalid_parameter); + if (offset.stop < offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= 0) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_rip_trim(buffer.string, location.start, location.stop, result); + return private_fl_string_append_nulless(source.string, offset.start, offset.stop, destination); } -#endif // _di_fl_string_dynamic_rip_trim_ +#endif // _di_fl_string_dynamic_rip_nulless_ #ifndef _di_fl_string_dynamic_seek_line_to_ f_return_status fl_string_dynamic_seek_line_to(const f_string_dynamic buffer, f_string_location *location, const int8_t seek_to_this) { @@ -502,49 +538,142 @@ extern "C" { #endif // _di_fl_string_dynamic_seek_to_utf_character_ #ifndef _di_fl_string_mash_ - f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination) { + f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ if (glue_length < 1) return f_status_set_error(f_invalid_parameter); - if (source_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_mash(glue, glue_length, source, source_length, destination); + if (destination->used > 0) { + f_status status = private_fl_string_append(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_append(source, start, stop, destination); } #endif // _di_fl_string_mash_ +#ifndef _di_fl_string_mash_nulless_ + f_return_status fl_string_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_append_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_append_nulless(source, start, stop, destination); + } +#endif // _di_fl_string_mash_nulless_ + +#ifndef _di_fl_string_mish_ + f_return_status fl_string_mish(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_prepend(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_prepend(source, start, stop, destination); + } +#endif // _di_fl_string_mish_ + +#ifndef _di_fl_string_mish_nulless_ + f_return_status fl_string_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_string_prepend_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_string_prepend_nulless(source, start, stop, destination); + } +#endif // _di_fl_string_mish_nulless_ + #ifndef _di_fl_string_prepend_ - f_return_status fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination) { + f_return_status fl_string_prepend(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (source_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_prepend(source, source_length, destination); + return private_fl_string_prepend(source, start, stop, destination); } #endif // _di_fl_string_prepend_ +#ifndef _di_fl_string_prepend_nulless_ + f_return_status fl_string_prepend_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_string_prepend_nulless(source, start, stop, destination); + } +#endif // _di_fl_string_prepend_nulless_ + #ifndef _di_fl_string_rip_ - f_return_status fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) { + f_return_status fl_string_rip(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ if (start > stop) return f_status_set_error(f_invalid_parameter); - if (result == 0) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_rip(string, start, stop, result); + f_string_length begin = start; + f_string_length end = stop; + + f_status status = private_fl_string_rip_find_range(source, &begin, &end); + + if (f_status_is_error(status)) return status; + + return private_fl_string_append(source, begin, end, destination); } #endif // _di_fl_string_rip_ -#ifndef _di_fl_string_rip_trim_ - f_return_status fl_string_rip_trim(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result) { +#ifndef _di_fl_string_rip_nulless_ + f_return_status fl_string_rip_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ if (start > stop) return f_status_set_error(f_invalid_parameter); - if (result == 0) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_string_rip_trim(string, start, stop, result); + f_string_length begin = start; + f_string_length end = stop; + + f_status status = private_fl_string_rip_find_range(source, &begin, &end); + + if (f_status_is_error(status)) return status; + + return private_fl_string_append_nulless(source, begin, end, destination); } -#endif // _di_fl_string_rip_trim_ +#endif // _di_fl_string_rip_nulless_ #ifndef _di_fl_string_seek_line_to_ f_return_status fl_string_seek_line_to(const f_string string, f_string_location *location, const int8_t seek_to_this) { diff --git a/level_1/fl_string/c/string.h b/level_1/fl_string/c/string.h index 58f078a..0d681b2 100644 --- a/level_1/fl_string/c/string.h +++ b/level_1/fl_string/c/string.h @@ -39,8 +39,10 @@ extern "C" { * * @param source * The source string to append. - * @param source_length - * Total number of bytes to copy from source string. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. * @param destination * The destination string the source is appended onto. * @@ -53,13 +55,40 @@ extern "C" { * * @see fl_string_append() * @see fl_string_dynamic_append() - * @see fl_string_dynamic_partial_append() */ #ifndef _di_fl_string_append_ - extern f_return_status fl_string_append(const f_string source, const f_string_length source_length, f_string_dynamic *destination); + extern f_return_status fl_string_append(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); #endif // _di_fl_string_append_ /** + * Append the source string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append_nulless() + * @see fl_string_dynamic_append_nulless() + */ +#ifndef _di_fl_string_append_nulless_ + extern f_return_status fl_string_append_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_append_nulless_ + +/** * Compare two strings, similar to strncmp(). * * This does not stop on NULL. @@ -135,13 +164,36 @@ extern "C" { * * @see fl_string_append() * @see fl_string_dynamic_append() - * @see fl_string_dynamic_partial_append() */ #ifndef _di_fl_string_dynamic_append_ extern f_return_status fl_string_dynamic_append(const f_string_dynamic source, f_string_dynamic *destination); #endif // _di_fl_string_dynamic_append_ /** + * Append the source string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append_nulless() + * @see fl_string_dynamic_append_nulless() + */ +#ifndef _di_fl_string_dynamic_append_nulless_ + extern f_return_status fl_string_dynamic_append_nulless(const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_append_nulless_ + +/** * Compare two strings, similar to strncmp(). * * This does not stop on NULL. @@ -215,13 +267,100 @@ extern "C" { * * @see fl_string_mash() * @see fl_string_dynamic_mash() - * @see fl_string_dynamic_partial_mash() */ #ifndef _di_fl_string_dynamic_mash_ extern f_return_status fl_string_dynamic_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination); #endif // _di_fl_string_dynamic_mash_ /** + * Append the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mash_nulless() + * @see fl_string_dynamic_mash_nulless() + */ +#ifndef _di_fl_string_dynamic_mash_nulless_ + extern f_return_status fl_string_dynamic_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_mash_nulless_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mish() + * @see fl_string_dynamic_mish() + */ +#ifndef _di_fl_string_dynamic_mish_ + extern f_return_status fl_string_dynamic_mish(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_mish_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mish_nulless() + * @see fl_string_dynamic_mish_nulless() + */ +#ifndef _di_fl_string_dynamic_mish_nulless_ + extern f_return_status fl_string_dynamic_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_mish_nulless_ + +/** * Compare two strings, similar to strncmp(), but restricted to the given ranges. * * This does not stop on NULL. @@ -281,70 +420,12 @@ extern "C" { #endif // _di_fl_string_dynamic_partial_compare_trim_ /** - * Append the source string onto the destination. - * - * @param source - * The source string to append. - * @param offset - * A range within the source to restrict the append from. - * @param destination - * The destination string the source is appended onto. - * - * @return - * f_none on success. - * f_string_max_size (with error bit) if the combined string is too large. - * f_invalid_parameter (with error bit) if a parameter is invalid. - * f_error_allocation (with error bit) on memory allocation error. - * f_error_reallocation (with error bit) on memory reallocation error. - * - * @see fl_string_append() - * @see fl_string_dynamic_append() - * @see fl_string_dynamic_partial_append() - */ -#ifndef _di_fl_string_dynamic_partial_append_ - extern f_return_status fl_string_dynamic_partial_append(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination); -#endif // _di_fl_string_dynamic_partial_append_ - -/** - * Append the source string onto the destination with the glue in between. - * - * If the destination string is empty, then no glue is appended. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param offset - * A range within the source to restrict the append from. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * f_none on success. - * f_string_max_size (with error bit) if the combined string is too large. - * f_invalid_parameter (with error bit) if a parameter is invalid. - * f_error_allocation (with error bit) on memory allocation error. - * f_error_reallocation (with error bit) on memory reallocation error. - * - * @see fl_string_mash() - * @see fl_string_dynamic_mash() - * @see fl_string_dynamic_partial_mash() - */ -#ifndef _di_fl_string_dynamic_partial_mash_ - extern f_return_status fl_string_dynamic_partial_mash(const f_string glue, const f_string_length glue_length, const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination); -#endif // _di_fl_string_dynamic_partial_mash_ - -/** * Prepend the source string onto the destination. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. * * @param source * The source string to prepend. - * @param offset - * A range within the source to restrict the prepend from. * @param destination * The destination string the source is prepended onto. * @@ -355,15 +436,11 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_append() * @see fl_string_prepend() - * @see fl_string_dynamic_append() - * @see fl_string_dynamic_prepend() - * @see fl_string_dynamic_partial_append() */ -#ifndef _di_fl_string_dynamic_partial_append_ - extern f_return_status fl_string_dynamic_partial_prepend(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination); -#endif // _di_fl_string_dynamic_partial_append_ +#ifndef _di_fl_string_dynamic_prepend_ + extern f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_prepend_ /** * Prepend the source string onto the destination. @@ -382,24 +459,23 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_append() - * @see fl_string_prepend() - * @see fl_string_dynamic_append() - * @see fl_string_dynamic_partial_append() - * @see fl_string_dynamic_partial_prepend() + * @see fl_string_prepend_nulless() */ -#ifndef _di_fl_string_dynamic_prepend_ - extern f_return_status fl_string_dynamic_prepend(const f_string_dynamic source, f_string_dynamic *destination); -#endif // _di_fl_string_dynamic_prepend_ +#ifndef _di_fl_string_dynamic_prepend_nulless_ + extern f_return_status fl_string_dynamic_prepend_nulless(const f_string_dynamic source, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_prepend_nulless_ /** * Allocate a new string from the provided range in the buffer. * - * @param buffer + * Ignores leading and trailing whitespace. + * As a result, resulting size may be smaller than requested range. + * + * @param source * The buffer to rip from. - * @param location + * @param offset * A range within the buffer representing the string to rip. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return @@ -409,12 +485,12 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_dynamic_rip_trim() - * @see fl_string_rip() - * @see fl_string_rip_trim() + * @see fl_string_append() + * @see fl_string_dynamic_append() + * @see fl_string_dynamic_rip() */ #ifndef _di_fl_string_dynamic_rip_ - extern f_return_status fl_string_dynamic_rip(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result); + extern f_return_status fl_string_dynamic_rip(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination); #endif // _di_fl_string_dynamic_rip_ /** @@ -423,11 +499,13 @@ extern "C" { * Ignores leading and trailing whitespace. * As a result, resulting size may be smaller than requested range. * - * @param buffer - * The buffer to rip from. - * @param location + * Skips over NULL characters from source when appending. + * + * @param source + * The string to rip from. + * @param offset * A range within the buffer representing the string to rip. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return @@ -437,13 +515,13 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_dynamic_rip() - * @see fl_string_dynamic_rip_trim() - * @see fl_string_rip() + * @see fl_string_append_nulless() + * @see fl_string_dynamic_append_nulless() + * @see fl_string_dynamic_rip_nulless() */ -#ifndef _di_fl_string_dynamic_rip_trim_ - extern f_return_status fl_string_dynamic_rip_trim(const f_string_dynamic buffer, const f_string_location location, f_string_dynamic *result); -#endif // _di_fl_string_dynamic_rip_trim_ +#ifndef _di_fl_string_dynamic_rip_nulless_ + extern f_return_status fl_string_dynamic_rip_nulless(const f_string_dynamic source, const f_string_location offset, f_string_dynamic *destination); +#endif // _di_fl_string_dynamic_rip_nulless_ /** * Seek the buffer location forward until the character (1-byte wide) or EOL is reached. @@ -621,8 +699,10 @@ extern "C" { * The number of bytes the glue takes up. * @param source * The source string to append. - * @param source_length - * Total number of bytes to copy from source string. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. * @param destination * The destination string the source and glue are appended onto. * @@ -635,21 +715,122 @@ extern "C" { * * @see fl_string_mash() * @see fl_string_dynamic_mash() - * @see fl_string_dynamic_partial_mash() */ #ifndef _di_fl_string_mash_ - extern f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length source_length, f_string_dynamic *destination); + extern f_return_status fl_string_mash(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); #endif // _di_fl_string_mash_ /** + * Append the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mash_nulless() + * @see fl_string_dynamic_mash_nulless() + */ +#ifndef _di_fl_string_mash_nulless_ + extern f_return_status fl_string_mash_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_mash_nulless_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mish() + * @see fl_string_dynamic_mish() + */ +#ifndef _di_fl_string_mish_ + extern f_return_status fl_string_mish(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_mish_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_mish_nulless() + * @see fl_string_dynamic_mish_nulless() + */ +#ifndef _di_fl_string_mish_nulless_ + extern f_return_status fl_string_mish_nulless(const f_string glue, const f_string_length glue_length, const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_mish_nulless_ + +/** * Prepend the source string onto the destination. * * Prepend operations require memory move operations and are therefore likely more expensive than append operations. * * @param source * The source string to prepend. - * @param source_length - * Total number of bytes to copy from source string. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. * @param destination * The destination string the source is prepended onto. * @@ -660,26 +841,54 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_append() - * @see fl_string_dynamic_append() * @see fl_string_dynamic_prepend() - * @see fl_string_dynamic_partial_append() - * @see fl_string_dynamic_partial_prepend() */ #ifndef _di_fl_string_prepend_ - extern f_return_status fl_string_prepend(const f_string source, const f_string_length source_length, f_string_dynamic *destination); + extern f_return_status fl_string_prepend(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); #endif // _di_fl_string_prepend_ /** + * Prepend the source string onto the destination. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_dynamic_prepend_nulless() + */ +#ifndef _di_fl_string_prepend_nulless_ + extern f_return_status fl_string_prepend_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_prepend_nulless_ + +/** * Allocate a new string from the provided range in the string. * - * @param string + * Ignores leading and trailing whitespace. + * As a result, resulting size may be smaller than requested range. + * + * @param source * The string to rip from. * @param start * An inclusive start location within string. * @param stop * An inclusive stop location within string. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return @@ -689,12 +898,11 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_dynamic_rip() - * @see fl_string_dynamic_rip_trim() - * @see fl_string_rip_trim() + * @see fl_string_append() + * @see fl_string_dynamic_append() */ #ifndef _di_fl_string_rip_ - extern f_return_status fl_string_rip(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result); + extern f_return_status fl_string_rip(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); #endif // _di_fl_string_rip_ /** @@ -703,13 +911,15 @@ extern "C" { * Ignores leading and trailing whitespace. * As a result, resulting size may be smaller than requested range. * - * @param string + * Skips over NULL characters from source when ripping. + * + * @param source * The string to rip from. * @param start * An inclusive start location within string. * @param stop * An inclusive stop location within string. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return @@ -719,13 +929,12 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_string_dynamic_rip() - * @see fl_string_rip() - * @see fl_string_rip_trim() + * @see fl_string_append_nulless() + * @see fl_string_dynamic_rip_nulless() */ -#ifndef _di_fl_string_rip_trim_ - extern f_return_status fl_string_rip_trim(const f_string string, const f_string_length start, const f_string_length stop, f_string_dynamic *result); -#endif // _di_fl_string_rip_trim_ +#ifndef _di_fl_string_rip_nulless_ + extern f_return_status fl_string_rip_nulless(const f_string source, const f_string_length start, const f_string_length stop, f_string_dynamic *destination); +#endif // _di_fl_string_rip_nulless_ /** * Seek the string location forward until the character (1-byte wide) or EOL is reached. diff --git a/level_1/fl_utf/c/private-utf.c b/level_1/fl_utf/c/private-utf.c index 68d79ca..cfd223a 100644 --- a/level_1/fl_utf/c/private-utf.c +++ b/level_1/fl_utf/c/private-utf.c @@ -5,6 +5,93 @@ extern "C" { #endif +#if !defined(_di_fl_utf_string_append_) || !defined(_di_fl_utf_string_dynamic_append_) || !defined(_di_fl_utf_string_append_mash_) || !defined(_di_fl_utf_string_dynamic_mash_) + f_return_status private_fl_utf_string_append(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. + f_utf_string_length source_length = (stop - start) + 1; + + if (destination->used + source_length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_status status = f_none; + + const f_utf_string_length total = destination->used + source_length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + start, source_length); + destination->used = total; + + return f_none; + } +#endif // !defined(_di_fl_utf_string_append_) || !defined(_di_fl_utf_string_dynamic_append_) || !defined(_di_fl_utf_string_append_mash_) || !defined(_di_fl_utf_string_dynamic_mash_) + +#if !defined(_di_fl_utf_string_append_nulless_) || !defined(_di_fl_utf_string_dynamic_append_nulless_) || !defined(_di_fl_utf_string_mash_nulless_) || !defined(_di_fl_utf_string_dynamic_mash_nulless_) + f_return_status private_fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. + f_utf_string_length source_length = (stop - start) + 1; + + if (destination->used + source_length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_status status = f_none; + + f_utf_string_length first = 0; + + for (f_utf_string_length i = 0; i <= source_length; i++) { + if (i == source_length) { + if (i > first) { + f_utf_string_length length = i - first; + + if (destination->used + length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_utf_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, length); + destination->used = total; + } + + break; + } + + if (source[i] == f_utf_character_eos) { + if (i > 0) { + if (i > first) { + f_utf_string_length length = i - first; + + if (destination->used + length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_utf_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, length); + destination->used = total; + } + } + + while (i + 1 < source_length && source[i + 1] == f_utf_character_eos) { + i++; + } // while + + first = i + 1; + continue; + } + } // for + + return f_none; + } +#endif // !defined(_di_fl_utf_string_append_nulless_) || !defined(_di_fl_utf_string_dynamic_append_nulless_) || !defined(_di_fl_utf_string_mash_nulless_) || !defined(_di_fl_utf_string_dynamic_mash_nulless_) + #if !defined(_di_fl_utf_string_compare_) || !defined(_di_fl_utf_string_dynamic_compare_) || !defined(_di_fl_utf_string_dynamic_partial_compare_) f_return_status private_fl_utf_string_compare(const f_utf_string string1, const f_utf_string string2, const f_utf_string_length offset1, const f_utf_string_length offset2, const f_utf_string_length stop1, const f_utf_string_length stop2) { f_utf_string_length i1 = offset1; @@ -150,91 +237,150 @@ extern "C" { } #endif // !defined(_di_fl_utf_string_compare_trim_) || !defined(_di_fl_utf_string_dynamic_compare_trim_) || !defined(_di_fl_utf_string_dynamic_partial_compare_trim_) -#if !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) - f_return_status private_fl_utf_string_rip(const f_utf_string string, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *result) { +#if !defined(_di_fl_utf_string_prepend_) || !defined(_di_fl_utf_string_dynamic_prepend_) + f_return_status private_fl_utf_string_prepend(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. - f_utf_string_length size = (stop - start) + 1; + f_utf_string_length source_length = (stop - start) + 1; - if (size == 0) return f_no_data; + if (destination->used + source_length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); f_status status = f_none; - if (result == 0) { - f_macro_string_dynamic_new(status, (*result), size); + const f_utf_string_length total = destination->used + source_length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + if (destination->used > 0) { + memmove(destination->string + source_length, destination->string, destination->used); + memcpy(destination->string, source + start, source_length); } else { - f_macro_string_dynamic_resize(status, (*result), size); + memcpy(destination->string, source + start, source_length); } - if (f_status_is_error(status)) return status; - - memcpy(result->string, string + start, size); - result->used = size; - + destination->used = total; return f_none; } -#endif // !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) +#endif // !defined(_di_fl_utf_string_prepend_) || !defined(_di_fl_utf_string_dynamic_prepend_) -#if !defined(_di_fl_utf_string_rip_trim_) || !defined(_di_fl_utf_string_dynamic_rip_trim_) - f_return_status private_fl_utf_string_rip_trim(const f_utf_string string, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *result) { +#if !defined(_di_fl_utf_string_prepend_nulless_) || !defined(_di_fl_utf_string_dynamic_prepend_nulless_) + f_return_status private_fl_utf_string_prepend_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { // The start and stop point are inclusive locations, and therefore start - stop is actually 1 too few locations. - f_utf_string_length size = (stop - start) + 1; + f_utf_string_length source_length = (stop - start) + 1; - if (size == 0) return f_no_data; + if (destination->used + source_length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); f_status status = f_none; - if (result == 0) { - f_macro_string_dynamic_new(status, (*result), size); - } - else { - f_macro_string_dynamic_resize(status, (*result), size); - } + f_utf_string_length first = 0; + f_utf_string_length offset = 0; + + for (f_utf_string_length i = 0; i <= source_length; i++) { + if (i == source_length) { + if (i > first) { + f_utf_string_length length = i - first; + + if (destination->used + length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_utf_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + if (f_status_is_error(status)) return status; + } + + memmove(destination->string + offset + length, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, length); + + destination->used = total; + offset += length; + } + + break; + } + + if (source[i] == f_utf_character_eos) { + if (i > 0) { + if (i > first) { + f_utf_string_length length = i - first; + + if (destination->used + length > f_utf_string_max_size) return f_status_set_error(f_string_too_large); + + f_utf_string_length total = destination->used + length; + + if (total > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), total); + + if (f_status_is_error(status)) return status; + } + + memmove(destination->string + offset + length, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, length); + + destination->used = total; + offset += length; + } + } + + while (i + 1 < source_length && source[i + 1] == f_utf_character_eos) { + i++; + } // while - if (f_status_is_error(status)) return status; + first = i + 1; + continue; + } + } // for - f_utf_string_length begin = start; - f_utf_string_length end = stop; + return f_none; + } +#endif // !defined(_di_fl_utf_string_prepend_nulless_) || !defined(_di_fl_utf_string_dynamic_prepend_nulless_) + +#if !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) || !defined(_di_fl_utf_string_rip_nulless_) || !defined(_di_fl_utf_string_dynamic_rip_nulless_) + f_return_status private_fl_utf_string_rip_find_range(const f_utf_string source, f_utf_string_length *start, f_utf_string_length *stop) { + f_utf_string_length stop_original = *stop; + + f_status status = f_none; // skip past leading whitespace. - for (; begin <= end; begin++) { + for (; *start <= *stop; (*start)++) { // skip past NULL. - while (begin < size && string[begin] == f_string_eos) begin++; - if (begin > end) break; + while (*start < *stop && source[*start] == f_string_eos) (*start)++; + if (*start > *stop) break; - status = f_utf_character_is_whitespace(string[begin]); + status = f_utf_character_is_whitespace(source[*start]); 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_maybe) return f_status_set_error(f_invalid_utf); + + return status; } if (status == f_false) break; } // for - for (; end > begin; end--) { + for (; *stop > *start; (*stop)--) { + // skip past NULL. - if (string[end] == f_string_eos) continue; - if (end == begin) break; + while (*stop > *start && source[*stop] == f_string_eos) (*stop)--; + + if (source[*stop] == f_string_eos) continue; + if (*stop == *start) break; - status = f_utf_character_is_whitespace(string[end]); + status = f_utf_character_is_whitespace(source[*stop]); 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_maybe) return f_status_set_error(f_invalid_utf); + + return status; } if (status == f_false) break; } // for - memcpy(result->string, string + begin, (end - begin) + 1); - result->used = (end - begin) + 1; - return f_none; } -#endif // !defined(_di_fl_utf_string_rip_trim_) || !defined(_di_fl_utf_string_dynamic_rip_trim_) +#endif // !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) || !defined(_di_fl_utf_string_rip_nulless_) || !defined(_di_fl_utf_string_dynamic_rip_nulless_) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_utf/c/private-utf.h b/level_1/fl_utf/c/private-utf.h index d6ce958..6e0d215 100644 --- a/level_1/fl_utf/c/private-utf.h +++ b/level_1/fl_utf/c/private-utf.h @@ -18,6 +18,66 @@ extern "C" { #endif /** + * Private implementation of fl_utf_string_append(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append() + * @see fl_utf_string_mash() + * @see fl_utf_string_dynamic_append() + * @see fl_utf_string_dynamic_mash() + */ +#if !defined(_di_fl_utf_string_append_) || !defined(_di_fl_utf_string_dynamic_append_) || !defined(_di_fl_utf_string_append_mash_) || !defined(_di_fl_utf_string_dynamic_mash_) + extern f_return_status private_fl_utf_string_append(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_utf_string_append_) || !defined(_di_fl_utf_string_dynamic_append_) || !defined(_di_fl_utf_string_append_mash_) || !defined(_di_fl_utf_string_dynamic_mash_) + +/** + * Private implementation of fl_utf_string_append_nulless(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append_nulless() + * @see fl_utf_string_mash_nulless() + * @see fl_utf_string_dynamic_append_nulless() + * @see fl_utf_string_dynamic_mash_nulless() + */ +#if !defined(_di_fl_utf_string_append_nulless_) || !defined(_di_fl_utf_string_dynamic_append_nulless_) || !defined(_di_fl_utf_string_mash_nulless_) || !defined(_di_fl_utf_string_dynamic_mash_nulless_) + extern f_return_status private_fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_utf_string_append_nulless_) || !defined(_di_fl_utf_string_dynamic_append_nulless_) || !defined(_di_fl_utf_string_mash_nulless_) || !defined(_di_fl_utf_string_dynamic_mash_nulless_) + +/** * Private implementation of fl_utf_string_compare(). * * Intended to be shared to each of the different implementation variations. @@ -80,50 +140,77 @@ extern "C" { #endif // !defined(_di_fl_utf_string_compare_trim_) || !defined(_di_fl_utf_string_dynamic_compare_trim_) || !defined(_di_fl_utf_string_dynamic_partial_compare_trim_) /** - * Private implementation of fl_utf_string_rip(). + * Private implementation of fl_utf_string_prepend(). * * Intended to be shared to each of the different implementation variations. * - * @param string - * The string to rip from. + * @param source + * The source string to prepend. * @param start - * Inclusive start point of string to rip. + * Inclusive start point of string to append. * @param stop - * Inclusive stop point of string to rip. - * @param result - * The new string, which will be allocated or reallocated as necessary. + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are prepended onto. * * @return * f_none on success. - * f_no_data if nothing to rip, no allocations or reallocations are performed. + * f_string_max_size (with error bit) if the combined string is too large. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_utf_string_dynamic_rip() - * @see fl_utf_string_rip() + * @see fl_utf_string_prepend() + * @see fl_utf_string_dynamic_prepend() + */ +#if !defined(_di_fl_utf_string_prepend_) || !defined(_di_fl_utf_string_dynamic_prepend_) || !defined(_di_fl_utf_string_append_mish_) || !defined(_di_fl_utf_string_dynamic_mish_) + extern f_return_status private_fl_utf_string_prepend(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_utf_string_prepend_) || !defined(_di_fl_utf_string_dynamic_prepend_) || !defined(_di_fl_utf_string_append_mish_) || !defined(_di_fl_utf_string_dynamic_mish_) + +/** + * Private implementation of fl_utf_string_prepend_nulless(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source and glue are prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_prepend_nulless() + * @see fl_utf_string_dynamic_prepend_nulless() */ -#if !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) - extern f_return_status private_fl_utf_string_rip(const f_utf_string string, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *result) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) +#if !defined(_di_fl_utf_string_prepend_nulless_) || !defined(_di_fl_utf_string_dynamic_prepend_nulless_) || !defined(_di_fl_utf_string_append_mish_) || !defined(_di_fl_utf_string_dynamic_mish_) + extern f_return_status private_fl_utf_string_prepend_nulless(const f_utf_string source, f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_utf_string_prepend_nulless_) || !defined(_di_fl_utf_string_dynamic_prepend_nulless_) || !defined(_di_fl_utf_string_append_mish_) || !defined(_di_fl_utf_string_dynamic_mish_) /** - * Private implementation of fl_string_rip_trim(). + * Private implementation of fl_utf_string_rip(), but only the part for finding the start/stop range. * * Intended to be shared to each of the different implementation variations. * - * @param string + * @param source * The string to rip from. * @param start * Inclusive start point of string to rip. + * Will be updated to reflect the new start range. * @param stop * Inclusive stop point of string to rip. - * @param result - * The new string, which will be allocated or reallocated as necessary. + * Will be updated to reflect the new stop range. * * @return * f_none on success. - * f_no_data if nothing to rip, no allocations or reallocations are performed. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. @@ -131,9 +218,9 @@ extern "C" { * @see fl_utf_string_dynamic_rip() * @see fl_utf_string_rip() */ -#if !defined(_di_fl_utf_string_rip_trim_) || !defined(_di_fl_utf_string_dynamic_rip_trim_) - extern f_return_status private_fl_utf_string_rip_trim(const f_utf_string string, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *result) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_utf_string_rip_trim_) || !defined(_di_fl_utf_string_dynamic_rip_trim_) +#if !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) || !defined(_di_fl_utf_string_rip_nulless_) || !defined(_di_fl_utf_string_dynamic_rip_nulless_) + extern f_return_status private_fl_utf_string_rip_find_range(const f_utf_string source, f_utf_string_length *start, f_utf_string_length *stop) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_utf_string_rip_) || !defined(_di_fl_utf_string_dynamic_rip_) || !defined(_di_fl_utf_string_rip_nulless_) || !defined(_di_fl_utf_string_dynamic_rip_nulless_) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_utf/c/utf.c b/level_1/fl_utf/c/utf.c index e1ac61e..1e9ef87 100644 --- a/level_1/fl_utf/c/utf.c +++ b/level_1/fl_utf/c/utf.c @@ -5,6 +5,28 @@ extern "C" { #endif +#ifndef _di_fl_utf_string_append_ + f_return_status fl_utf_string_append(const f_utf_string source, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (start > stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_append(source, start, stop, destination); + } +#endif // _di_fl_utf_string_append_ + +#ifndef _di_fl_utf_string_append_nulless_ + f_return_status fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (start > stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_append_nulless(source, start, stop, destination); + } +#endif // _di_fl_utf_string_append_nulless_ + #ifndef _di_fl_utf_string_compare_ f_return_status fl_utf_string_compare(const f_utf_string string1, const f_utf_string string2, const f_utf_string_length length1, const f_utf_string_length length2) { #ifndef _di_level_1_parameter_checking_ @@ -27,6 +49,97 @@ extern "C" { } #endif // _di_fl_utf_string_compare_trim_ +#ifndef _di_fl_utf_string_dynamic_append_ + f_return_status fl_utf_string_dynamic_append(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_append(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_append_ + +#ifndef _di_fl_utf_string_dynamic_mash_ + f_return_status fl_utf_string_dynamic_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_append(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_append(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_mash_ + +#ifndef _di_fl_utf_string_dynamic_mash_nulless_ + f_return_status fl_utf_string_dynamic_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_append_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_append_nulless(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_mash_nulless_ + +#ifndef _di_fl_utf_string_dynamic_mish_ + f_return_status fl_utf_string_dynamic_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_prepend(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_prepend(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_mish_ + +#ifndef _di_fl_utf_string_dynamic_mish_nulless_ + f_return_status fl_utf_string_dynamic_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_prepend_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_prepend_nulless(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_mish_nulless_ + #ifndef _di_fl_utf_string_dynamic_compare_ f_return_status fl_utf_string_dynamic_compare(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2) { #ifndef _di_level_1_parameter_checking_ @@ -49,7 +162,7 @@ extern "C" { } #endif // _di_f_utf_string_dynamic_compare_trim_ -#ifndef _di_fl_string_dynamic_partial_compare_ +#ifndef _di_fl_utf_string_dynamic_partial_compare_ f_return_status fl_utf_string_dynamic_partial_compare(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2, const f_utf_string_location offset1, const f_utf_string_location offset2) { #ifndef _di_level_1_parameter_checking_ if (string1.used <= 0) return f_status_set_error(f_invalid_parameter); @@ -64,9 +177,9 @@ extern "C" { return private_fl_utf_string_compare(string1.string, string2.string, offset1.start, offset2.start, offset1.stop + 1, offset2.stop + 1); } -#endif // _di_fl_string_dynamic_partial_compare_ +#endif // _di_fl_utf_string_dynamic_partial_compare_ -#ifndef _di_fl_string_dynamic_partial_compare_trim_ +#ifndef _di_fl_utf_string_dynamic_partial_compare_trim_ f_return_status fl_utf_string_dynamic_partial_comparetrim(const f_utf_string_dynamic string1, const f_utf_string_dynamic string2, const f_utf_string_location offset1, const f_utf_string_location offset2) { #ifndef _di_level_1_parameter_checking_ if (string1.used <= 0) return f_status_set_error(f_invalid_parameter); @@ -81,35 +194,46 @@ extern "C" { return private_fl_utf_string_compare_trim(string1.string, string2.string, offset1.start, offset2.start, offset1.stop + 1, offset2.stop + 1); } -#endif // _di_fl_string_dynamic_partial_comparetrim_ +#endif // _di_fl_utf_string_dynamic_partial_compare_trim_ + +#ifndef _di_fl_utf_string_dynamic_prepend_ + f_return_status fl_utf_string_dynamic_prepend(const f_utf_string_dynamic source, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (source.used < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_prepend(source.string, 0, source.used - 1, destination); + } +#endif // _di_fl_utf_string_dynamic_prepend_ #ifndef _di_fl_utf_string_dynamic_rip_ - f_return_status fl_utf_string_dynamic_rip(const f_utf_string_dynamic buffer, const f_utf_string_location location, f_utf_string_dynamic *result) { + f_return_status fl_utf_string_dynamic_rip(const f_utf_string_dynamic source, const f_utf_string_location offset, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (location.start < 0) return f_status_set_error(f_invalid_parameter); - if (location.stop < location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.stop) return f_status_set_error(f_invalid_parameter); + if (offset.stop < offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= 0) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_utf_string_rip(buffer.string, location.start, location.stop, result); + return private_fl_utf_string_append(source.string, offset.start, offset.stop, destination); } #endif // _di_fl_utf_string_dynamic_rip_ -#ifndef _di_fl_utf_string_dynamic_rip_trim_ - f_return_status fl_utf_string_dynamic_rip_trim(const f_utf_string_dynamic buffer, const f_utf_string_location location, f_utf_string_dynamic *result) { +#ifndef _di_fl_utf_string_dynamic_rip_nulless_ + f_return_status fl_utf_string_dynamic_rip_nulless(const f_utf_string_dynamic source, const f_utf_string_location offset, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (location.start < 0) return f_status_set_error(f_invalid_parameter); - if (location.stop < location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= 0) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.start) return f_status_set_error(f_invalid_parameter); - if (buffer.used <= location.stop) return f_status_set_error(f_invalid_parameter); + if (offset.stop < offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= 0) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.start) return f_status_set_error(f_invalid_parameter); + if (source.used <= offset.stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_utf_string_rip_trim(buffer.string, location.start, location.stop, result); + return private_fl_utf_string_append_nulless(source.string, offset.start, offset.stop, destination); } -#endif // _di_fl_utf_string_dynamic_rip_trim_ +#endif // _di_fl_utf_string_dynamic_rip_nulless_ #ifndef _di_fl_utf_string_dynamic_seek_line_to_ f_return_status fl_utf_string_dynamic_seek_line_to(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character seek_to_this) { @@ -323,25 +447,143 @@ extern "C" { } #endif // _di_fl_utf_string_dynamic_seek_to_char_ +#ifndef _di_fl_utf_string_mash_ + f_return_status fl_utf_string_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_append(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_append(source, start, stop, destination); + } +#endif // _di_fl_utf_string_mash_ + +#ifndef _di_fl_utf_string_mash_nulless_ + f_return_status fl_utf_string_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_append_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_append_nulless(source, start, stop, destination); + } +#endif // _di_fl_utf_string_mash_nulless_ + +#ifndef _di_fl_utf_string_mish_ + f_return_status fl_utf_string_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_prepend(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_prepend(source, start, stop, destination); + } +#endif // _di_fl_utf_string_mish_ + +#ifndef _di_fl_utf_string_mish_nulless_ + f_return_status fl_utf_string_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (destination->used > 0) { + f_status status = private_fl_utf_string_prepend_nulless(glue, 0, glue_length - 1, destination); + + if (f_status_is_error(status)) { + return status; + } + } + + return private_fl_utf_string_prepend_nulless(source, start, stop, destination); + } +#endif // _di_fl_utf_string_mish_nulless_ + +#ifndef _di_fl_utf_string_prepend_ + f_return_status fl_utf_string_prepend(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_prepend(source, start, stop, destination); + } +#endif // _di_fl_utf_string_prepend_ + +#ifndef _di_fl_utf_string_prepend_nulless_ + f_return_status fl_utf_string_prepend_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { + #ifndef _di_level_1_parameter_checking_ + if (stop > start) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + return private_fl_utf_string_prepend_nulless(source, start, stop, destination); + } +#endif // _di_fl_utf_string_prepend_nulless_ + #ifndef _di_fl_utf_string_rip_ - f_return_status fl_utf_string_rip(const f_utf_string string, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *result) { + f_return_status fl_utf_string_rip(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ if (start > stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_utf_string_rip(string, start, stop, result); + f_utf_string_length begin = start; + f_utf_string_length end = stop; + + f_status status = private_fl_utf_string_rip_find_range(source, &begin, &end); + + if (f_status_is_error(status)) return status; + + return private_fl_utf_string_append(source, begin, end, destination); } #endif // _di_fl_utf_string_rip_ -#ifndef _di_fl_utf_string_rip_trim_ - f_return_status fl_utf_string_rip_trim(const f_utf_string string, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *result) { +#ifndef _di_fl_utf_string_rip_nulless_ + f_return_status fl_utf_string_rip_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ if (start > stop) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_utf_string_rip_trim(string, start, stop, result); + f_utf_string_length begin = start; + f_utf_string_length end = stop; + + f_status status = private_fl_utf_string_rip_find_range(source, &begin, &end); + + if (f_status_is_error(status)) return status; + + return private_fl_utf_string_append_nulless(source, begin, end, destination); } -#endif // _di_fl_utf_string_rip_trim_ +#endif // _di_fl_utf_string_rip_nulless_ #ifndef _di_fl_utf_string_seek_line_to_ f_return_status fl_utf_string_seek_line_to(const f_utf_string string, f_utf_string_location *location, const f_utf_character seek_to_this) { @@ -496,7 +738,7 @@ extern "C" { return f_none; } -#endif // _di_fl_string_seek_to_ +#endif // _di_fl_utf_string_seek_to_ #ifndef _di_fl_utf_string_seek_to_char_ f_return_status fl_utf_string_seek_to_char(const f_utf_string string, f_utf_string_location *location, const int8_t seek_to_this) { diff --git a/level_1/fl_utf/c/utf.h b/level_1/fl_utf/c/utf.h index ebe5b27..b08365b 100644 --- a/level_1/fl_utf/c/utf.h +++ b/level_1/fl_utf/c/utf.h @@ -35,6 +35,60 @@ extern "C" { #endif /** + * Append the source UTF-8 string onto the destination. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append() + * @see fl_utf_string_dynamic_append() + */ +#ifndef _di_fl_utf_string_append_ + extern f_return_status fl_utf_string_append(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_append_ + +/** + * Append the source UTF-8 string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to append. + * @param stop + * Inclusive stop point of string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append_nulless() + * @see fl_utf_string_dynamic_append_nulless() + */ +#ifndef _di_fl_utf_string_append_nulless_ + extern f_return_status fl_utf_string_append_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_append_nulless_ + +/** * Compare two UTF-8 strings, similar to strncmp(). * * This does not stop on NULL. @@ -96,6 +150,52 @@ extern "C" { #endif // _di_fl_utf_string_compare_trim_ /** + * Append the source UTF-8 string onto the destination. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append() + * @see fl_utf_string_dynamic_append() + */ +#ifndef _di_fl_utf_string_dynamic_append_ + extern f_return_status fl_utf_string_dynamic_append(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_append_ + +/** + * Append the source UTF-8 string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_append_nulless() + * @see fl_utf_string_dynamic_append_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_append_nulless_ + extern f_return_status fl_utf_string_dynamic_append_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_append_nulless_ + +/** * Compare two UTF-8 strings, similar to strncmp(). * * This does not stop on NULL. @@ -149,6 +249,122 @@ extern "C" { #endif // _di_f_utf_string_dynamic_compare_trim_ /** + * Append the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mash() + * @see fl_utf_string_dynamic_mash() + */ +#ifndef _di_fl_utf_string_dynamic_mash_ + extern f_return_status fl_utf_string_dynamic_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_mash_ + +/** + * Append the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mash_nulless() + * @see fl_utf_string_dynamic_mash_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_mash_nulless_ + extern f_return_status fl_utf_string_dynamic_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_mash_nulless_ + +/** + * Prepend the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mish() + * @see fl_utf_string_dynamic_mish() + */ +#ifndef _di_fl_utf_string_dynamic_mish_ + extern f_return_status fl_utf_string_dynamic_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_mish_ + +/** + * Prepend the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mish_nulless() + * @see fl_utf_string_dynamic_mish_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_mish_nulless_ + extern f_return_status fl_utf_string_dynamic_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_mish_nulless_ + +/** * Compare two UTF-8 strings, similar to strncmp(), but restricted to the given ranges. * * This does not stop on NULL. @@ -210,59 +426,108 @@ extern "C" { #endif // _di_fl_utf_string_dynamic_partial_compare_trim_ /** - * Allocated a new UTF-8 string from the provided range in the buffer. + * Prepend the source string onto the destination. * - * @param buffer + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_prepend() + */ +#ifndef _di_fl_utf_string_dynamic_prepend_ + extern f_return_status fl_utf_string_dynamic_prepend(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_prepend_ + +/** + * Prepend the source string onto the destination. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * @param source + * The source string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_prepend_nulless() + */ +#ifndef _di_fl_utf_string_dynamic_prepend_nulless_ + extern f_return_status fl_utf_string_dynamic_prepend_nulless(const f_utf_string_dynamic source, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_prepend_nulless_ + +/** + * Allocate a new string from the provided range in the buffer. + * + * Ignores leading and trailing whitespace. + * As a result, resulting size may be smaller than requested range. + * + * @param source * The buffer to rip from. - * @param location + * @param offset * A range within the buffer representing the string to rip. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. - * f_invalid_utf (with error bit) if a character in the string is an invalid UTF-8 character. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_utf_string_dynamic_rip_trim() - * @see fl_utf_string_rip() - * @see fl_utf_string_rip_trim() + * @see fl_utf_string_append() + * @see fl_utf_string_dynamic_append() + * @see fl_utf_string_dynamic_rip() */ #ifndef _di_fl_utf_string_dynamic_rip_ - extern f_return_status fl_utf_string_dynamic_rip(const f_utf_string_dynamic buffer, const f_utf_string_location location, f_utf_string_dynamic *result); + extern f_return_status fl_utf_string_dynamic_rip(const f_utf_string_dynamic source, const f_utf_string_location offset, f_utf_string_dynamic *destination); #endif // _di_fl_utf_string_dynamic_rip_ /** - * Allocate a new UTF-8 string from the provided range in the buffer. + * Allocate a new string from the provided range in the buffer. * * Ignores leading and trailing whitespace. * As a result, resulting size may be smaller than requested range. * - * @param buffer - * The buffer to rip from. - * @param location + * Skips over NULL characters from source when appending. + * + * @param source + * The string to rip from. + * @param offset * A range within the buffer representing the string to rip. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. - * f_invalid_utf (with error bit) if a character in the string is an invalid UTF-8 character. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see: fl_utf_string_dynamic_rip() - * @see: fl_utf_string_rip() - * @see: fl_utf_string_rip_trim() + * @see fl_utf_string_append_nulless() + * @see fl_utf_string_dynamic_append_nulless() + * @see fl_utf_string_dynamic_rip_nulless() */ -#ifndef _di_fl_utf_string_dynamic_rip_trim_ - extern f_return_status fl_utf_string_dynamic_rip_trim(const f_utf_string_dynamic buffer, const f_utf_string_location location, f_utf_string_dynamic *result); -#endif // _di_fl_utf_string_dynamic_rip_trim_ +#ifndef _di_fl_utf_string_dynamic_rip_nulless_ + extern f_return_status fl_utf_string_dynamic_rip_nulless(const f_utf_string_dynamic source, const f_utf_string_location offset, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_dynamic_rip_nulless_ /** * Seek the buffer location forward until the UTF-8 character or EOL is reached. @@ -415,63 +680,281 @@ extern "C" { #endif // _di_fl_utf_string_dynamic_seek_to_char_ /** - * Allocated a new UTF-8 string from the provided range in the buffer. + * Seek the buffer location forward until the UTF-8 character (up to 4-byte wide) is reached. * * @param buffer - * The buffer to rip from. + * The buffer to traverse. + * @param location + * A range within the buffer representing the start and stop locations. + * The start location will be incremented by seek. + * @param seek_to_this + * A 1-width, 2-width, 3-width, or 4-width character representing a character to seek to. + * + * @return + * f_none on success. + * f_none_on_eos on success, but stopped at end of buffer. + * f_none_on_stop on success, but stopped stop location. + * f_invalid_utf (with error bit) if character is an invalid UTF-8 character. + * f_incomplete_utf (with error bit) if character is an incomplete UTF-8 fragment. + * f_incomplete_utf_on_stop (with error bit) if the stop location is reached before the complete UTF-8 character can be processed. + * f_incomplete_utf_on_eos (with error bit) if end of string is reached before a complete UTF-8 character can be processed. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * + * @see fl_utf_string_dynamic_seek_to() + * @see fl_utf_string_seek_to() + * @see fl_utf_string_seek_to_character() + */ +#ifndef _di_fl_utf_string_dynamic_seek_to_utf_character_ + extern f_return_status fl_utf_string_dynamic_seek_to_utf_character(const f_utf_string_dynamic buffer, f_utf_string_location *location, const f_utf_character seek_to_this); +#endif // _di_fl_utf_string_dynamic_seek_to_utf_character_ + +/** + * Append the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mash() + * @see fl_utf_string_dynamic_mash() + */ +#ifndef _di_fl_utf_string_mash_ + extern f_return_status fl_utf_string_mash(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_mash_ + +/** + * Append the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mash_nulless() + * @see fl_utf_string_dynamic_mash_nulless() + */ +#ifndef _di_fl_utf_string_mash_nulless_ + extern f_return_status fl_utf_string_mash_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_mash_nulless_ + +/** + * Prepend the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mish() + * @see fl_utf_string_dynamic_mish() + */ +#ifndef _di_fl_utf_string_mish_ + extern f_return_status fl_utf_string_mish(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_mish_ + +/** + * Prepend the UTF-8 source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_mish_nulless() + * @see fl_utf_string_dynamic_mish_nulless() + */ +#ifndef _di_fl_utf_string_mish_nulless_ + extern f_return_status fl_utf_string_mish_nulless(const f_utf_string glue, const f_utf_string_length glue_length, const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_mish_nulless_ + +/** + * Prepend the UTF-8 source string onto the destination. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_prepend() + */ +#ifndef _di_fl_utf_string_prepend_ + extern f_return_status fl_utf_string_prepend(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_prepend_ + +/** + * Prepend the UTF-8 source string onto the destination. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param start + * Inclusive start point of string to prepend. + * @param stop + * Inclusive stop point of string to prepend. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * f_none on success. + * f_string_max_size (with error bit) if the combined string is too large. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_error_allocation (with error bit) on memory allocation error. + * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_utf_string_dynamic_prepend_nulless() + */ +#ifndef _di_fl_utf_string_prepend_nulless_ + extern f_return_status fl_utf_string_prepend_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_prepend_nulless_ + +/** + * Allocate a new UTF-8 string from the provided range in the string. + * + * Ignores leading and trailing whitespace. + * As a result, resulting size may be smaller than requested range. + * + * @param source + * The string to rip from. * @param start * An inclusive start location within string. * @param stop * An inclusive stop location within string. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. - * f_invalid_utf (with error bit) if a character in the string is an invalid UTF-8 character. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_utf_string_dynamic_rip() - * @see fl_utf_string_dynamic_rip_trim() - * @see fl_utf_string_rip_trim() + * @see fl_utf_string_append() + * @see fl_utf_string_dynamic_append() */ #ifndef _di_fl_utf_string_rip_ - extern f_return_status fl_utf_string_rip(const f_utf_string string, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *result); + extern f_return_status fl_utf_string_rip(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); #endif // _di_fl_utf_string_rip_ /** - * Allocate a new string from the provided range in the string. + * Allocate a new UTF-8 string from the provided range in the string. * * Ignores leading and trailing whitespace. * As a result, resulting size may be smaller than requested range. * - * @param string + * Skips over NULL characters from source when ripping. + * + * @param source * The string to rip from. * @param start * An inclusive start location within string. * @param stop * An inclusive stop location within string. - * @param result + * @param destination * The new string, which will be allocated or reallocated as necessary. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. - * f_invalid_utf (with error bit) if a character in the string is an invalid UTF-8 character. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. * - * @see fl_utf_string_dynamic_rip() - * @see fl_utf_string_dynamic_rip_trim() - * @see fl_utf_string_rip() + * @see fl_utf_string_append_nulless() + * @see fl_utf_string_dynamic_rip_nulless() */ -#ifndef _di_fl_utf_string_rip_trim_ - extern f_return_status fl_utf_string_rip_trim(const f_utf_string string, const f_string_length start, const f_string_length stop, f_utf_string_dynamic *result); -#endif // _di_fl_utf_string_rip_trim_ +#ifndef _di_fl_utf_string_rip_nulless_ + extern f_return_status fl_utf_string_rip_nulless(const f_utf_string source, const f_utf_string_length start, const f_utf_string_length stop, f_utf_string_dynamic *destination); +#endif // _di_fl_utf_string_rip_nulless_ /** * Seek the string location forward until the UTF-8 character or EOL is reached. diff --git a/level_2/fll_program/c/program.c b/level_2/fll_program/c/program.c index 654502d..e309927 100644 --- a/level_2/fll_program/c/program.c +++ b/level_2/fll_program/c/program.c @@ -150,11 +150,10 @@ extern "C" { } #endif // _di_fll_program_parameter_process_ -#ifndef _di_fll_program_parameter_additional_mash_ - f_return_status fll_program_parameter_additional_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination) { +#ifndef _di_fll_program_parameter_additional_append_ + f_return_status fll_program_parameter_additional_append(const f_string *argv, const f_string_lengths additional, f_string_dynamics *destination) { #ifndef _di_level_2_parameter_checking_ if (argv == 0) return f_status_set_error(f_invalid_parameter); - if (glue_length < 1) return f_status_set_error(f_invalid_parameter); if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_2_parameter_checking_ @@ -167,9 +166,25 @@ extern "C" { length = strnlen(argv[additional.array[i]], f_console_max_size); if (length > 0) { - status = fl_string_mash(glue, glue_length, argv[additional.array[i]], length, destination); + f_string_dynamic ripped = f_string_dynamic_initialize; - if (f_status_is_error(status)) return f_status_set_error(f_string_too_large); + status = fl_string_append(argv[additional.array[i]], 0, length - 1, &ripped); + + if (f_status_is_error(status)) return status; + + if (status == f_no_data) { + status = f_none; + } + else { + if (destination->used >= destination->size) { + f_macro_string_dynamics_resize(status, (*destination), destination->size + f_console_default_allocation_step); + + if (f_status_is_error(status)) return status; + } + + destination->array[destination->used] = ripped; + destination->used++; + } } } // for @@ -179,10 +194,10 @@ extern "C" { return status; } -#endif // _di_fll_program_parameter_additional_mash_ +#endif // _di_fll_program_parameter_additional_append_ -#ifndef _di_fll_program_parameter_additional_mash_trim_ - f_return_status fll_program_parameter_additional_mash_trim(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination) { +#ifndef _di_fll_program_parameter_additional_mash_ + f_return_status fll_program_parameter_additional_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination) { #ifndef _di_level_2_parameter_checking_ if (argv == 0) return f_status_set_error(f_invalid_parameter); if (glue_length < 1) return f_status_set_error(f_invalid_parameter); @@ -193,53 +208,35 @@ extern "C" { f_string_length length = 0; f_string_length start = destination->used; - f_string_dynamic ripped = f_string_dynamic_initialize; for (f_string_length i = 0; i < additional.used; i++) { length = strnlen(argv[additional.array[i]], f_console_max_size); if (length > 0) { - status = fl_string_rip_trim(argv[additional.array[i]], 0, length - 1, &ripped); - - if (f_status_is_error(status)) { - f_macro_string_dynamic_delete_simple(ripped); - return status; - } - - if (ripped.used > 0) { - status = fl_string_dynamic_mash(glue, glue_length, ripped, destination); + status = fl_string_mash(glue, glue_length, argv[additional.array[i]], 0, length - 1, destination); - if (f_status_is_error(status)) { - f_macro_string_dynamic_delete_simple(ripped); - return f_status_set_error(f_string_too_large); - } - } + if (f_status_is_error(status)) return f_status_set_error(f_string_too_large); } } // for - if (ripped.size) { - f_macro_string_dynamic_delete(status, ripped); - } - if (status == f_none && start == destination->used) { return f_no_data; } return status; } -#endif // _di_fll_program_parameter_additional_mash_trim_ +#endif // _di_fll_program_parameter_additional_mash_ #ifndef _di_fll_program_parameter_additional_rip_ - f_return_status fll_program_parameter_additional_rip(const f_string *argv, const f_string_lengths additional, f_string_dynamics *result) { + f_return_status fll_program_parameter_additional_rip(const f_string *argv, const f_string_lengths additional, f_string_dynamics *destination) { #ifndef _di_level_2_parameter_checking_ if (argv == 0) return f_status_set_error(f_invalid_parameter); - if (result == 0) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_2_parameter_checking_ f_status status = f_none; - f_string_length length = 0; - f_string_length start = result->used; + f_string_length start = destination->used; for (f_string_length i = 0; i < additional.used; i++) { length = strnlen(argv[additional.array[i]], f_console_max_size); @@ -255,19 +252,19 @@ extern "C" { status = f_none; } else { - if (result->used >= result->size) { - f_macro_string_dynamics_resize(status, (*result), result->size + f_console_default_allocation_step); + if (destination->used >= destination->size) { + f_macro_string_dynamics_resize(status, (*destination), destination->size + f_console_default_allocation_step); if (f_status_is_error(status)) return status; } - result->array[result->used] = ripped; - result->used++; + destination->array[destination->used] = ripped; + destination->used++; } } } // for - if (status == f_none && start == result->used) { + if (status == f_none && start == destination->used) { return f_no_data; } @@ -275,50 +272,53 @@ extern "C" { } #endif // _di_fll_program_parameter_additional_rip_ -#ifndef _di_fll_program_parameter_additional_rip_trim_ - f_return_status fll_program_parameter_additional_rip_trim(const f_string *argv, const f_string_lengths additional, f_string_dynamics *result) { +#ifndef _di_fll_program_parameter_additional_rip_mash_ + f_return_status fll_program_parameter_additional_rip_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination) { #ifndef _di_level_2_parameter_checking_ if (argv == 0) return f_status_set_error(f_invalid_parameter); - if (result == 0) return f_status_set_error(f_invalid_parameter); + if (glue_length < 1) return f_status_set_error(f_invalid_parameter); + if (destination == 0) return f_status_set_error(f_invalid_parameter); #endif // _di_level_2_parameter_checking_ f_status status = f_none; + f_string_length length = 0; - f_string_length start = result->used; + f_string_length start = destination->used; + f_string_dynamic ripped = f_string_dynamic_initialize; for (f_string_length i = 0; i < additional.used; i++) { length = strnlen(argv[additional.array[i]], f_console_max_size); if (length > 0) { - f_string_dynamic ripped = f_string_dynamic_initialize; - - status = fl_string_rip_trim(argv[additional.array[i]], 0, length - 1, &ripped); - - if (f_status_is_error(status)) return status; + status = fl_string_rip(argv[additional.array[i]], 0, length - 1, &ripped); - if (status == f_no_data) { - status = f_none; + if (f_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(ripped); + return status; } - else { - if (result->used >= result->size) { - f_macro_string_dynamics_resize(status, (*result), result->size + f_console_default_allocation_step); - if (f_status_is_error(status)) return status; - } + if (ripped.used > 0) { + status = fl_string_dynamic_mash(glue, glue_length, ripped, destination); - result->array[result->used] = ripped; - result->used++; + if (f_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(ripped); + return f_status_set_error(f_string_too_large); + } } } } // for - if (status == f_none && start == result->used) { + if (ripped.size) { + f_macro_string_dynamic_delete(status, ripped); + } + + if (status == f_none && start == destination->used) { return f_no_data; } return status; } -#endif // _di_fll_program_parameter_additional_rip_trim_ +#endif // _di_fll_program_parameter_additional_rip_mash_ #ifdef __cplusplus } // extern "C" diff --git a/level_2/fll_program/c/program.h b/level_2/fll_program/c/program.h index aaa637b..26dd647 100644 --- a/level_2/fll_program/c/program.h +++ b/level_2/fll_program/c/program.h @@ -160,35 +160,35 @@ extern "C" { #endif // _di_fll_program_parameter_process_ /** - * Mash together all additional arguments associated with a given console parameter. + * Allocate new strings from all of the provided locations. + * + * These new strings are appended onto the destination. + * + * Empty console parameters are ignored. * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. * @param argv * The program argument array to parse. * @param additional * The string locations where the console parameters are found. * @param destination - * The destination string the source and glue are appended onto. + * An array of dynamic strings each representing a console parameter. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. - * f_string_max_size (with error bit) if the combined string is too large. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. + * + * @see fl_string_append() */ -#ifndef _di_fll_program_parameter_additional_mash_ - extern f_return_status fll_program_parameter_additional_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination); -#endif // _di_fll_program_parameter_additional_mash_ +#ifndef _di_fll_program_parameter_additional_append_ + extern f_return_status fll_program_parameter_additional_append(const f_string *argv, const f_string_lengths additional, f_string_dynamics *destination); +#endif // _di_fll_program_parameter_additional_append_ + /** * Mash together all additional arguments associated with a given console parameter. * - * The console parameter is trimmed before mashing. - * * @param glue * A string to append between the source and destination, such as a space: ' '. * @param glue_length @@ -208,20 +208,20 @@ extern "C" { * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. */ -#ifndef _di_fll_program_parameter_additional_mash_trim_ - extern f_return_status fll_program_parameter_additional_mash_trim(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination); -#endif // _di_fll_program_parameter_additional_mash_trim_ +#ifndef _di_fll_program_parameter_additional_mash_ + extern f_return_status fll_program_parameter_additional_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination); +#endif // _di_fll_program_parameter_additional_mash_ /** * Allocate new strings from all of the provided locations. * - * Empty console parameters are ignored. + * The console parameters are trimmed. * * @param argv * The program argument array to parse. * @param additional * The string locations where the console parameters are found. - * @param result + * @param destination * An array of dynamic strings each representing a console parameter. * * @return @@ -232,37 +232,37 @@ extern "C" { * f_error_reallocation (with error bit) on memory reallocation error. * * @see fl_string_rip() - * @see fll_program_parameter_additional_rip_trim() */ #ifndef _di_fll_program_parameter_additional_rip_ - extern f_return_status fll_program_parameter_additional_rip(const f_string *argv, const f_string_lengths additional, f_string_dynamics *result); + extern f_return_status fll_program_parameter_additional_rip(const f_string *argv, const f_string_lengths additional, f_string_dynamics *destination); #endif // _di_fll_program_parameter_additional_rip_ - /** - * Allocate new strings from all of the provided locations. + * Mash together all additional arguments associated with a given console parameter. * - * The console parameters are trimmed. + * The console parameter is trimmed before mashing. * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. * @param argv * The program argument array to parse. * @param additional * The string locations where the console parameters are found. - * @param result - * An array of dynamic strings each representing a console parameter. + * @param destination + * The destination string the source and glue are appended onto. * * @return * f_none on success. * f_no_data if nothing to rip, no allocations or reallocations are performed. + * f_string_max_size (with error bit) if the combined string is too large. * f_invalid_parameter (with error bit) if a parameter is invalid. * f_error_allocation (with error bit) on memory allocation error. * f_error_reallocation (with error bit) on memory reallocation error. - * - * @see fl_string_rip() - * @see fll_program_parameter_additional_rip() */ -#ifndef _di_fll_program_parameter_additional_rip_trim_ - extern f_return_status fll_program_parameter_additional_rip_trim(const f_string *argv, const f_string_lengths additional, f_string_dynamics *result); -#endif // _di_fll_program_parameter_additional_rip_trim_ +#ifndef _di_fll_program_parameter_additional_rip_mash_ + extern f_return_status fll_program_parameter_additional_rip_mash(const f_string glue, const f_string_length glue_length, const f_string *argv, const f_string_lengths additional, f_string_dynamic *destination); +#endif // _di_fll_program_parameter_additional_rip_mash_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c index 93d51a6..11d63e8 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c @@ -162,10 +162,10 @@ extern "C" { depths->array[i].index_name = data.parameters[fss_basic_list_read_parameter_name].additional.array[position_name]; if (data.parameters[fss_basic_list_read_parameter_trim].result == f_console_result_found) { - fl_string_rip_trim(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } else { - fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_append(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } if (depths->array[i].value_name.used == 0) { diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c index 0df2238..1eacbd0 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-fss_basic_read.c @@ -162,10 +162,10 @@ extern "C" { depths->array[i].index_name = data.parameters[fss_basic_read_parameter_name].additional.array[position_name]; if (data.parameters[fss_basic_read_parameter_trim].result == f_console_result_found) { - fl_string_rip_trim(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } else { - fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_append(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } if (depths->array[i].value_name.used == 0) { diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index f0f98aa..fb19fcf 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -162,10 +162,10 @@ extern "C" { depths->array[i].index_name = data.parameters[fss_extended_list_read_parameter_name].additional.array[position_name]; if (data.parameters[fss_extended_list_read_parameter_trim].result == f_console_result_found) { - fl_string_rip_trim(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } else { - fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_append(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } if (depths->array[i].value_name.used == 0) { diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c index 8742f02..72fbce5 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-fss_extended_read.c @@ -162,10 +162,10 @@ extern "C" { depths->array[i].index_name = data.parameters[fss_extended_read_parameter_name].additional.array[position_name]; if (data.parameters[fss_extended_read_parameter_trim].result == f_console_result_found) { - fl_string_rip_trim(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } else { - fl_string_rip(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); + fl_string_append(arguments.argv[depths->array[i].index_name], 0, strlen(arguments.argv[depths->array[i].index_name]), &depths->array[i].value_name); } if (depths->array[i].value_name.used == 0) { -- 1.8.3.1