From 0236e19d89db8d4ce83b3992b10cade8489adc1d Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 27 Jul 2021 22:15:41 -0500 Subject: [PATCH] Progress: Continue work on printing. Use ";" and ":" for ignore_index and ignore_range. I intend to reserve "<", ">", "(", ")", "{", and "}" for context related matters, which currently is only color context. The handling of UTF-8 character codes with ignore indexes and ranges needs to be carefully considered and documented. Print safely functions will need to convert, but what if the bits are being ignored? Print raw functions should print as-is, even if invalid. Print normally functions should validate and return error. For now I just added some comments. Oops! I include space as a "control" character. I started to convert byte_dump printing as a way of testing the current state of the code. I intend to slowly convert each level 3 project one at a time and test for problems. This quickly convinced me to not follow the fprintf() standards practice and I moved the FILE * after the string rather than before. Finish the trim functions. This is done very quickly so I am confident that there is some logic bug somewhere. This is just another reason for me to implement testing support. There are several utf_character trim functions in fl_print. Remove these for now. The print is getting big and I believe that I now need an fl_utf_print and an fll_utf_print just like is done with how fl_string has fl_utf_string. I want to get all of the bugs out of the print functions before I move to working on the utf_print functions. This will likely get addressed during a unicode development pass. This converts some of the fll_program print functions. Looking at the color print functions, I now plan on merging a lot of the color printing functionality into the print functions. Specifically, the fl_print_string() and related should support color context printing. This will allow me to simplify some of the code. The idea so far is that I can use "[" and "]" to accept an "f_color_set_t" and the "[" represents the "before" pointer and the "]" represents the "after" pointer. For example the following: fl_print_string(" %q%s%q%c", output.stream, *context.set.title.before, name, *context.set.title.after, f_string_eol_s[0]); would be changed to: fl_print_string(" %[%s%]%c", output.stream, context.set.title, name, context.set.title, f_string_eol_s[0]); --- level_0/f_print/c/print-common.h | 4 +- level_0/f_print/c/print.h | 32 + level_0/f_print/c/private-print.c | 11 +- level_1/fl_print/c/print.c | 335 ++++-- level_1/fl_print/c/print.h | 813 ++++++++++---- level_1/fl_print/c/private-print.c | 1555 ++++++++------------------- level_1/fl_print/c/private-print.h | 279 +---- level_2/fll_print/c/print.c | 352 +++++- level_2/fll_print/c/print.h | 729 ++++++++++++- level_2/fll_program/c/program.c | 75 +- level_2/fll_program/c/program.h | 77 +- level_2/fll_program/data/build/dependencies | 2 + level_2/fll_program/data/build/settings | 2 +- 13 files changed, 2538 insertions(+), 1728 deletions(-) diff --git a/level_0/f_print/c/print-common.h b/level_0/f_print/c/print-common.h index fb9fa78..65d9e34 100644 --- a/level_0/f_print/c/print-common.h +++ b/level_0/f_print/c/print-common.h @@ -117,8 +117,8 @@ extern "C" { * f_print_format_flag_*: * - align_left: "-", Use left-justification. * - convert: "#", Use alternate form conversion (prefixing 0b/0B, 0o/0O, 0t/0T, 0d/0D, 0x/0X). - * - ignore_index: "(", Ignore characters in the given positions from a f_array_length_t (only applies to string arguments but not character arguments). - * - ignore_range: ")", Ignore characters in the given ranges from a f_string_range_t (only applies to string arguments but not character arguments). + * - ignore_index: ";", Ignore characters in the given positions from a f_array_length_t (only applies to string arguments but not character arguments). + * - ignore_range: ":", Ignore characters in the given ranges from a f_string_range_t (only applies to string arguments but not character arguments). * - precision: Designates that a precision is in use. * - sign_always: "+", Always show the signs (+ or -). * - sign_pad: " ", Add a space where a sign would be if the sign is not displayed. diff --git a/level_0/f_print/c/print.h b/level_0/f_print/c/print.h index 5b9d415..a3fe2d9 100644 --- a/level_0/f_print/c/print.h +++ b/level_0/f_print/c/print.h @@ -147,6 +147,8 @@ extern "C" { * Will print NULL. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -235,6 +237,8 @@ extern "C" { * Will print NULL. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -332,6 +336,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param string @@ -434,6 +440,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -539,6 +547,8 @@ extern "C" { * Will not print any 1-byte character within the ranges specified in except_in array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param string @@ -653,6 +663,8 @@ extern "C" { * Will not print any 1-byte character within the ranges specified in except_in array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -765,6 +777,8 @@ extern "C" { * Will not print any 1-byte character within the ranges specified in except_in array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -873,6 +887,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to the specified range within the buffer. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -939,6 +955,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to the specified range within the buffer. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -1009,6 +1027,8 @@ extern "C" { * Will print NULL. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param string @@ -1195,6 +1215,8 @@ extern "C" { * Will print NULL. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param string * The string to output. * @param length @@ -1295,6 +1317,8 @@ extern "C" { * Will print NULL. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param buffer * The string to output. * @param id @@ -1393,6 +1417,8 @@ extern "C" { * Will print NULL. * Will print up to the specified range within the buffer. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param buffer * The string to output. * @param range @@ -1500,6 +1526,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to length 1-byte characters. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param string * The string to output. * @param length @@ -1612,6 +1640,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to the length of the buffer. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param buffer * The string to output. * @param except @@ -1722,6 +1752,8 @@ extern "C" { * Will not print any 1-byte character at a location specified in except array. * Will print up to the specified range within the buffer. * + * All UTF-8 characters, invalid or not, are printed as is. + * * @param buffer * The string to output. * @param range diff --git a/level_0/f_print/c/private-print.c b/level_0/f_print/c/private-print.c index d066463..6c1400f 100644 --- a/level_0/f_print/c/private-print.c +++ b/level_0/f_print/c/private-print.c @@ -24,7 +24,7 @@ extern "C" { #if !defined(_di_f_print_character_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) f_status_t private_f_print_character_safely(const char character, FILE *output) { - if (character > 32 && character != 127) { + if (character > 31 && character != 127) { if (!fputc_unlocked(character, output)) { return F_status_set_error(F_output); } @@ -128,9 +128,6 @@ extern "C" { else if (character == 31) { string = f_print_sequence_unit_separator_s; } - else if (character == 32) { - string = f_print_sequence_space_s; - } else { // character == 127. @@ -156,7 +153,7 @@ extern "C" { #if !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_to_safely_) || !defined(_di_f_print_dynamic_partial_to_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_) f_string_t private_f_print_character_safely_get(const char character) { - if (character > 32 && character != 127) { + if (character > 31 && character != 127) { return 0; } @@ -288,10 +285,6 @@ extern "C" { return f_print_sequence_unit_separator_s; } - if (character == 32) { - return f_print_sequence_space_s; - } - // character == 127. return f_print_sequence_delete_s; } diff --git a/level_1/fl_print/c/print.c b/level_1/fl_print/c/print.c index 94ad5e6..11c0f88 100644 --- a/level_1/fl_print/c/print.c +++ b/level_1/fl_print/c/print.c @@ -6,24 +6,24 @@ extern "C" { #endif #ifndef _di_fl_print_string_ - f_status_t fl_print_string(FILE *output, const f_string_t string, ...) { + f_status_t fl_print_string(const f_string_t string, FILE *output, ...) { #ifndef _di_level_1_parameter_checking_ - if (!output) return F_status_set_error(F_parameter); if (!string) return F_status_set_error(F_parameter); + if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status_t status = F_none; va_list ap; - va_start(ap, string); + va_start(ap, output); for (char *current = string; *current; current = current + 1) { if (*current == f_string_ascii_percent_s[0]) { current = current + 1; - status = private_fl_print_string_convert(current, &ap, output); + status = private_fl_print_string_convert(current, output, &ap); if (F_status_is_error(status)) break; if (!*current) break; @@ -40,23 +40,24 @@ extern "C" { #endif // _di_fl_print_string_ #ifndef _di_fl_print_string_convert_ - f_status_t fl_print_string_convert(FILE *output, char *current, va_list *ap) { + f_status_t fl_print_string_convert(char *current, FILE *output, va_list *ap) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); + if (!ap) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - return private_fl_print_string_convert(current, ap, output); + return private_fl_print_string_convert(current, output, ap); } #endif // _di_fl_print_string_convert_ #ifndef _di_fl_print_string_va_ - f_status_t fl_print_string_va(FILE *output, const f_string_t string, va_list ap) { + f_status_t fl_print_string_va(const f_string_t string, FILE *output, va_list *ap) { #ifndef _di_level_1_parameter_checking_ - if (!output) return F_status_set_error(F_parameter); if (!string) return F_status_set_error(F_parameter); + if (!output) return F_status_set_error(F_parameter); + if (!ap) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - uint8_t width = 0; uint8_t i = 0; char *current = string; @@ -64,20 +65,18 @@ extern "C" { while (*current) { - width = macro_f_utf_byte_width_is(*current); - - if (width) { - if (width == 1) { + if (macro_f_utf_byte_width_is(*current)) { + if (macro_f_utf_byte_width_is(*current) == 1) { if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { return F_status_set_error(F_output); } } else { - for (i = 0; i < width && current[i]; ++i) { + for (i = 0; i < macro_f_utf_byte_width_is(*current) && current[i]; ++i) { // do nothing. } // for - if (i < width) { + if (i < macro_f_utf_byte_width_is(*current)) { if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { return F_status_set_error(F_output); } @@ -85,14 +84,14 @@ extern "C" { break; } - for (i = 0; i < width; ++i) { + for (i = 0; i < macro_f_utf_byte_width_is(*current); ++i) { if (!fputc_unlocked(current[i], output)) { return F_status_set_error(F_output); } } // for - current = current + (width - 1); + current = current + (macro_f_utf_byte_width_is(*current) - 1); } } else { @@ -225,6 +224,34 @@ extern "C" { } #endif // _di_fl_print_trim_ +#ifndef _di_fl_print_trim_raw_ + f_status_t fl_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_fl_print_trim_raw(string, length, output); + } +#endif // _di_fl_print_trim_raw_ + +#ifndef _di_fl_print_trim_safely_ + f_status_t fl_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_fl_print_trim_safely(string, length, output); + } +#endif // _di_fl_print_trim_safely_ + #ifndef _di_fl_print_trim_dynamic_ f_status_t fl_print_trim_dynamic(const f_string_static_t buffer, FILE *output) { #ifndef _di_level_1_parameter_checking_ @@ -239,6 +266,34 @@ extern "C" { } #endif // _di_fl_print_trim_dynamic_ +#ifndef _di_fl_print_trim_dynamic_raw_ + f_status_t fl_print_trim_dynamic_raw(const f_string_static_t buffer, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!buffer.used) { + return F_data_not; + } + + return private_fl_print_trim_raw(buffer.string, buffer.used, output); + } +#endif // _di_fl_print_trim_dynamic_raw_ + +#ifndef _di_fl_print_trim_dynamic_safely_ + f_status_t fl_print_trim_dynamic_safely(const f_string_static_t buffer, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!buffer.used) { + return F_data_not; + } + + return private_fl_print_trim_safely(buffer.string, buffer.used, output); + } +#endif // _di_fl_print_trim_dynamic_safely_ + #ifndef _di_fl_print_trim_dynamic_partial_ f_status_t fl_print_trim_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { #ifndef _di_level_1_parameter_checking_ @@ -259,6 +314,46 @@ extern "C" { } #endif // _di_fl_print_trim_dynamic_partial_ +#ifndef _di_fl_print_trim_dynamic_partial_raw_ + f_status_t fl_print_trim_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + return F_data_not; + } + + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_fl_print_trim_raw(buffer.string + range.start, length, output); + } +#endif // _di_fl_print_trim_dynamic_partial_raw_ + +#ifndef _di_fl_print_trim_dynamic_partial_safely_ + f_status_t fl_print_trim_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + return F_data_not; + } + + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_fl_print_trim_safely(buffer.string + range.start, length, output); + } +#endif // _di_fl_print_trim_dynamic_partial_safely_ + #ifndef _di_fl_print_trim_except_ f_status_t fl_print_trim_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ @@ -271,28 +366,28 @@ extern "C" { const f_string_ranges_t except_in = f_string_ranges_t_initialize; - return private_fl_print_trim_except_in(string, 0, length, except, except_in, output); + return private_fl_print_trim_except_in(string, length, except, except_in, output); } #endif // _di_fl_print_trim_except_ -#ifndef _di_fl_print_trim_except_dynamic_ - f_status_t fl_print_trim_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { +#ifndef _di_fl_print_trim_except_raw_ + f_status_t fl_print_trim_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!buffer.used) { + if (!string || !length) { return F_data_not; } const f_string_ranges_t except_in = f_string_ranges_t_initialize; - return private_fl_print_trim_except_in(buffer.string, 0, buffer.used, except, except_in, output); + return private_fl_print_trim_except_in_raw(string, length, except, except_in, output); } -#endif // _di_fl_print_trim_except_dynamic_ +#endif // _di_fl_print_trim_except_raw_ -#ifndef _di_fl_print_trim_except_in_ - f_status_t fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_safely_ + f_status_t fl_print_trim_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -301,12 +396,14 @@ extern "C" { return F_data_not; } - return private_fl_print_trim_except_in(string, 0, length, except_at, except_in, output); + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in_safely(string, length, except, except_in, output); } -#endif // _di_fl_print_trim_except_in_ +#endif // _di_fl_print_trim_except_safely_ -#ifndef _di_fl_print_trim_except_in_dynamic_ - f_status_t fl_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_dynamic_ + f_status_t fl_print_trim_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -315,54 +412,74 @@ extern "C" { return F_data_not; } - return private_fl_print_trim_except_in(buffer.string, 0, buffer.used, except_at, except_in, output); + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in(buffer.string, buffer.used, except, except_in, output); } -#endif // _di_fl_print_trim_except_in_dynamic_ +#endif // _di_fl_print_trim_except_dynamic_ -#ifndef _di_fl_print_trim_except_in_dynamic_partial_ - f_status_t fl_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_dynamic_raw_ + f_status_t fl_print_trim_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + if (!buffer.used) { return F_data_not; } - f_array_length_t length = (range.stop - range.start) + 1; + const f_string_ranges_t except_in = f_string_ranges_t_initialize; - if (length + range.start > buffer.used) { - length = buffer.used - range.start; + return private_fl_print_trim_except_in_raw(buffer.string, buffer.used, except, except_in, output); + } +#endif // _di_fl_print_trim_except_dynamic_raw_ + +#ifndef _di_fl_print_trim_except_dynamic_safely_ + f_status_t fl_print_trim_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ + + if (!buffer.used) { + return F_data_not; } - return private_fl_print_trim_except_in(buffer.string, range.start, range.start + length, except_at, except_in, output); + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in_safely(buffer.string, buffer.used, except, except_in, output); } -#endif // _di_fl_print_trim_except_in_dynamic_partial_ +#endif // _di_fl_print_trim_except_dynamic_safely_ -#ifndef _di_fl_print_trim_except_dynamic_partial_ - f_status_t fl_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { +#ifndef _di_fl_print_trim_except_in_ + f_status_t fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + if (!string || !length) { return F_data_not; } - f_array_length_t length = (range.stop - range.start) + 1; + return private_fl_print_trim_except_in(string, length, except_at, except_in, output); + } +#endif // _di_fl_print_trim_except_in_ - if (length + range.start > buffer.used) { - length = buffer.used - range.start; - } +#ifndef _di_fl_print_trim_except_in_raw_ + f_status_t fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ - const f_string_ranges_t except_in = f_string_ranges_t_initialize; + if (!string || !length) { + return F_data_not; + } - return private_fl_print_trim_except_in(buffer.string, range.start, range.start + length, except, except_in, output); + return private_fl_print_trim_except_in_raw(string, length, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_dynamic_partial_ +#endif // _di_fl_print_trim_except_in_raw_ -#ifndef _di_fl_print_trim_except_utf_ - f_status_t fl_print_trim_except_utf(const f_utf_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { +#ifndef _di_fl_print_trim_except_in_safely_ + f_status_t fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -371,14 +488,12 @@ extern "C" { return F_data_not; } - const f_string_ranges_t except_in = f_string_ranges_t_initialize; - - return private_fl_print_trim_except_in_utf(string, 0, length, except, except_in, output); + return private_fl_print_trim_except_in_safely(string, length, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_utf_ +#endif // _di_fl_print_trim_except_in_safely_ -#ifndef _di_fl_print_trim_except_utf_dynamic_ - f_status_t fl_print_trim_except_utf_dynamic(const f_utf_string_static_t buffer, const f_array_lengths_t except, FILE *output) { +#ifndef _di_fl_print_trim_except_in_dynamic_ + f_status_t fl_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -387,28 +502,26 @@ extern "C" { return F_data_not; } - const f_string_ranges_t except_in = f_string_ranges_t_initialize; - - return private_fl_print_trim_except_in_utf(buffer.string, 0, buffer.used, except, except_in, output); + return private_fl_print_trim_except_in(buffer.string, buffer.used, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_utf_dynamic_ +#endif // _di_fl_print_trim_except_in_dynamic_ -#ifndef _di_fl_print_trim_except_in_utf_ - f_status_t fl_print_trim_except_in_utf(const f_utf_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_in_dynamic_raw_ + f_status_t fl_print_trim_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!string || !length) { + if (!buffer.used) { return F_data_not; } - return private_fl_print_trim_except_in_utf(string, 0, length, except_at, except_in, output); + return private_fl_print_trim_except_in_raw(buffer.string, buffer.used, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_in_utf_ +#endif // _di_fl_print_trim_except_in_dynamic_raw_ -#ifndef _di_fl_print_trim_except_in_utf_dynamic_ - f_status_t fl_print_trim_except_in_utf_dynamic(const f_utf_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_in_dynamic_safely_ + f_status_t fl_print_trim_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -417,12 +530,12 @@ extern "C" { return F_data_not; } - return private_fl_print_trim_except_in_utf(buffer.string, 0, buffer.used, except_at, except_in, output); + return private_fl_print_trim_except_in_safely(buffer.string, buffer.used, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_in_utf_dynamic_ +#endif // _di_fl_print_trim_except_in_dynamic_safely_ -#ifndef _di_fl_print_trim_except_in_utf_dynamic_partial_ - f_status_t fl_print_trim_except_in_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_fl_print_trim_except_in_dynamic_partial_ + f_status_t fl_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -437,12 +550,12 @@ extern "C" { length = buffer.used - range.start; } - return private_fl_print_trim_except_in_utf(buffer.string, range.start, range.start + length, except_at, except_in, output); + return private_fl_print_trim_except_in(buffer.string + range.start, length, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_in_utf_dynamic_partial_ +#endif // _di_fl_print_trim_except_in_dynamic_partial_ -#ifndef _di_fl_print_trim_except_utf_dynamic_partial_ - f_status_t fl_print_trim_except_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { +#ifndef _di_fl_print_trim_except_in_dynamic_partial_raw_ + f_status_t fl_print_trim_except_in_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -457,42 +570,76 @@ extern "C" { length = buffer.used - range.start; } - const f_string_ranges_t except_in = f_string_ranges_t_initialize; + return private_fl_print_trim_except_in_raw(buffer.string + range.start, length, except_at, except_in, output); + } +#endif // _di_fl_print_trim_except_in_dynamic_partial_raw_ + +#ifndef _di_fl_print_trim_except_in_dynamic_partial_safely_ + f_status_t fl_print_trim_except_in_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + #ifndef _di_level_1_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_1_parameter_checking_ - return private_fl_print_trim_except_in_utf(buffer.string, range.start, range.start + length, except, except_in, output); + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + return F_data_not; + } + + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_fl_print_trim_except_in_safely(buffer.string + range.start, length, except_at, except_in, output); } -#endif // _di_fl_print_trim_except_utf_dynamic_partial_ +#endif // _di_fl_print_trim_except_in_dynamic_partial_safely_ -#ifndef _di_fl_print_trim_utf_ - f_status_t fl_print_trim_utf(const f_utf_string_t string, const f_array_length_t length, FILE *output) { +#ifndef _di_fl_print_trim_except_dynamic_partial_ + f_status_t fl_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!string || !length) { + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { return F_data_not; } - return private_fl_print_trim_utf(string, length, output); + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in(buffer.string + range.start, length, except, except_in, output); } -#endif // _di_fl_print_trim_utf_ +#endif // _di_fl_print_trim_except_dynamic_partial_ -#ifndef _di_fl_print_trim_utf_dynamic_ - f_status_t fl_print_trim_utf_dynamic(const f_utf_string_static_t buffer, FILE *output) { +#ifndef _di_fl_print_trim_except_dynamic_partial_raw_ + f_status_t fl_print_trim_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (!buffer.used) { + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { return F_data_not; } - return private_fl_print_trim_utf(buffer.string, buffer.used, output); + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in_raw(buffer.string + range.start, length, except, except_in, output); } -#endif // _di_fl_print_trim_utf_dynamic_ +#endif // _di_fl_print_trim_except_dynamic_partial_raw_ -#ifndef _di_fl_print_trim_utf_dynamic_partial_ - f_status_t fl_print_trim_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, FILE *output) { +#ifndef _di_fl_print_trim_except_dynamic_partial_safely_ + f_status_t fl_print_trim_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_1_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -507,9 +654,11 @@ extern "C" { length = buffer.used - range.start; } - return private_fl_print_trim_utf(buffer.string + range.start, length, output); + const f_string_ranges_t except_in = f_string_ranges_t_initialize; + + return private_fl_print_trim_except_in_safely(buffer.string + range.start, length, except, except_in, output); } -#endif // _di_fl_print_trim_utf_dynamic_partial_ +#endif // _di_fl_print_trim_except_dynamic_partial_safely_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_print/c/print.h b/level_1/fl_print/c/print.h index 1c08801..6110bd9 100644 --- a/level_1/fl_print/c/print.h +++ b/level_1/fl_print/c/print.h @@ -8,6 +8,8 @@ * Provides some standard printing functions not available in a libc. * * Functions provided here are UTF-8 aware. + * + * @fixme: the except_in and except_at only apply to 1-byte characters, so what happens if a single except byte is only a part of a single multibyte character? */ #ifndef _FL_print_h #define _FL_print_h @@ -35,14 +37,11 @@ extern "C" { * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * This function violates this FLL projects' standard practice of having a parameter with '*' before const parameters. - * This is done as an exception case to achieve similar arguments structure with the fprintf() family of functions. - * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param string * The formatted string to process and output. * This is a NULL terminated string. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ... * Additional arguments relating to the string. * @@ -53,6 +52,7 @@ extern "C" { * F_valid_not (with error bit) on invalid syntax (such as terminating the string on a single '%'). * * Success from: f_print_dynamic(). + * Success from: f_print_dynamic_raw(). * Success from: f_print_dynamic_safely(). * Success from: f_print_safely(). * Success from: f_print_terminated(). @@ -60,6 +60,7 @@ extern "C" { * Errors (with error bit) from: f_conversion_number_signed_to_file(). * Errors (with error bit) from: f_conversion_number_unsigned_to_file(). * Errors (with error bit) from: f_print_dynamic(). + * Errors (with error bit) from: f_print_dynamic_raw(). * Errors (with error bit) from: f_print_dynamic_safely(). * Errors (with error bit) from: f_print_safely(). * Errors (with error bit) from: f_print_terminated(). @@ -71,12 +72,13 @@ extern "C" { * @see f_conversion_number_signed_to_file() * @see f_conversion_number_unsigned_to_file() * @see f_print_dynamic() + * @see f_print_dynamic_raw() * @see f_print_dynamic_safely() * @see f_print_safely() * @see f_print_terminated() */ #ifndef _di_fl_print_string_ - extern f_status_t fl_print_string(FILE *output, const f_string_t string, ...); + extern f_status_t fl_print_string(const f_string_t string, FILE *output, ...); #endif // _di_fl_print_string_ /** @@ -87,13 +89,11 @@ extern "C" { * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * This function violates this FLL projects' standard practice of having a parameter with '*' before const parameters. - * This is done as an exception case to achieve similar arguments structure with the fprintf() family of functions. - * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param current * The current character position within the string. + * This pointer might be updated by this function. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ap * The variable arguments list. * @@ -104,6 +104,7 @@ extern "C" { * F_valid_not (with error bit) on invalid syntax (such as terminating the string on a single '%'). * * Success from: f_print_dynamic(). + * Success from: f_print_dynamic_raw(). * Success from: f_print_dynamic_safely(). * Success from: f_print_safely(). * Success from: f_print_terminated(). @@ -111,6 +112,7 @@ extern "C" { * Errors (with error bit) from: f_conversion_number_signed_to_file(). * Errors (with error bit) from: f_conversion_number_unsigned_to_file(). * Errors (with error bit) from: f_print_dynamic(). + * Errors (with error bit) from: f_print_dynamic_raw(). * Errors (with error bit) from: f_print_dynamic_safely(). * Errors (with error bit) from: f_print_safely(). * Errors (with error bit) from: f_print_terminated(). @@ -120,12 +122,13 @@ extern "C" { * @see f_conversion_number_signed_to_file() * @see f_conversion_number_unsigned_to_file() * @see f_print_dynamic() + * @see f_print_dynamic_raw() * @see f_print_dynamic_safely() * @see f_print_safely() * @see f_print_terminated() */ #ifndef _di_fl_print_string_convert_ - extern f_status_t fl_print_string_convert(FILE *output, char *current, va_list *ap); + extern f_status_t fl_print_string_convert(char *current, FILE *output, va_list *ap); #endif // _di_fl_print_string_convert_ /** @@ -135,13 +138,10 @@ extern "C" { * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * This function violates this FLL projects' standard practice of having a parameter with '*' before const parameters. - * This is done as an exception case to achieve similar arguments structure with the fprintf() family of functions. - * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param string * The formatted string to process and output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ap * The variable list. * The va_start(ap, string) and va_end(ap) is required to be called outside this function. @@ -153,6 +153,7 @@ extern "C" { * F_valid_not (with error bit) on invalid syntax (such as terminating the string on a single '%'). * * Success from: f_print_dynamic(). + * Success from: f_print_dynamic_raw(). * Success from: f_print_dynamic_safely(). * Success from: f_print_safely(). * Success from: f_print_terminated(). @@ -160,6 +161,7 @@ extern "C" { * Errors (with error bit) from: f_conversion_number_signed_to_file(). * Errors (with error bit) from: f_conversion_number_unsigned_to_file(). * Errors (with error bit) from: f_print_dynamic(). + * Errors (with error bit) from: f_print_dynamic_raw(). * Errors (with error bit) from: f_print_dynamic_safely(). * Errors (with error bit) from: f_print_safely(). * Errors (with error bit) from: f_print_terminated(). @@ -171,12 +173,13 @@ extern "C" { * @see f_conversion_number_signed_to_file() * @see f_conversion_number_unsigned_to_file() * @see f_print_dynamic() + * @see f_print_dynamic_raw() * @see f_print_dynamic_safely() * @see f_print_safely() * @see f_print_terminated() */ #ifndef _di_fl_print_string_va_ - extern f_status_t fl_print_string_va(FILE *output, const f_string_t string, va_list ap); + extern f_status_t fl_print_string_va(const f_string_t string, FILE *output, va_list *ap); #endif // _di_fl_print_string_va_ /** @@ -184,8 +187,8 @@ extern "C" { * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * @@ -200,11 +203,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -214,14 +218,87 @@ extern "C" { #endif // _di_fl_print_trim_ /** + * Print a string, stripping leading and trailing whitespace. + * + * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will print NULL. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_raw_ + extern f_status_t fl_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output); +#endif // _di_fl_print_trim_raw_ + +/** + * Print a string, stripping leading and trailing whitespace. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_safely_ + extern f_status_t fl_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output); +#endif // _di_fl_print_trim_safely_ + +/** * Print a dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will print the entire dynamic string, except for leading/trailing whitespace. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -233,11 +310,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -247,14 +325,89 @@ extern "C" { #endif // _di_fl_print_trim_dynamic_ /** + * Print a dynamic string, stripping leading and trailing whitespace. + * + * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will print NULL. + * Will print the entire dynamic string, except for leading/trailing whitespace. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param buffer + * The string to output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_dynamic_raw_ + extern f_status_t fl_print_trim_dynamic_raw(const f_string_static_t buffer, FILE *output); +#endif // _di_fl_print_trim_dynamic_raw_ + +/** + * Print a dynamic string, stripping leading and trailing whitespace. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will print the entire dynamic string, except for leading/trailing whitespace. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param buffer + * The string to output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_dynamic_safely_ + extern f_status_t fl_print_trim_dynamic_safely(const f_string_static_t buffer, FILE *output); +#endif // _di_fl_print_trim_dynamic_safely_ + +/** * Print a partial dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will print the only the buffer range specified by range, except for leading/trailing whitespace. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -268,11 +421,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -282,14 +436,93 @@ extern "C" { #endif // _di_fl_print_trim_dynamic_partial_ /** + * Print a partial dynamic string, stripping leading and trailing whitespace. + * + * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will print NULL. + * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_dynamic_partial_raw_ + extern f_status_t fl_print_trim_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_fl_print_trim_dynamic_partial_raw_ + +/** + * Print a partial dynamic string, stripping leading and trailing whitespace. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_dynamic_partial_safely_ + extern f_status_t fl_print_trim_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_fl_print_trim_dynamic_partial_safely_ + +/** * Print a string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will not print any 1-byte character at a location specified in except array. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param string @@ -306,11 +539,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -320,15 +554,100 @@ extern "C" { #endif // _di_fl_print_trim_except_ /** + * Print a string, stripping leading and trailing whitespace. + * + * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * + * Will not stop at NULL. + * Will print NULL. + * Will not print any 1-byte character at a location specified in except array. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_except_raw_ + extern f_status_t fl_print_trim_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_raw_ + +/** + * Print a string, stripping leading and trailing whitespace. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will not print any 1-byte character at a location specified in except array. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_except_safely_ + extern f_status_t fl_print_trim_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_safely_ + +/** * Print a dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will print the entire dynamic string, except for leading/trailing whitespace. * Will not print any 1-byte character at a location specified in except array. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -343,11 +662,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -357,27 +677,27 @@ extern "C" { #endif // _di_fl_print_trim_except_dynamic_ /** - * Print a string, stripping leading and trailing whitespace. + * Print a dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1-byte character at a location specified in except_at array. - * Will not print any 1-byte character within the ranges specified in except_in array. + * Will not stop at NULL. + * Will print NULL. + * Will print the entire dynamic string, except for leading/trailing whitespace. + * Will not print any 1-byte character at a location specified in except array. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * @param string + * @param buffer * The string to output. - * @param length - * The total number of characters to print. - * @param except_at + * @param except * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. - * @param except_in - * An array of ranges within the string to not print. - * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -385,40 +705,38 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_ - extern f_status_t fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_ +#ifndef _di_fl_print_trim_except_dynamic_raw_ + extern f_status_t fl_print_trim_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_dynamic_raw_ /** * Print a dynamic string, stripping leading and trailing whitespace. * - * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will print NULL (as a control character symbol). * Will print the entire dynamic string, except for leading/trailing whitespace. - * Will not print any 1-byte character at a location specified in except_at array. - * Will not print any 1-byte character within the ranges specified in except_in array. + * Will not print any 1-byte character at a location specified in except array. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer * The string to output. - * @param except_at + * @param except * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. - * @param except_in - * An array of ranges within the string to not print. - * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -426,36 +744,37 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_dynamic_ - extern f_status_t fl_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_dynamic_ +#ifndef _di_fl_print_trim_except_dynamic_safely_ + extern f_status_t fl_print_trim_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_dynamic_safely_ /** - * Print a partial dynamic string, stripping leading and trailing whitespace. + * Print a string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will not print NULL. * Will not print any 1-byte character at a location specified in except_at array. * Will not print any 1-byte character within the ranges specified in except_in array. - * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * @param buffer + * @param string * The string to output. - * @param range - * The range within the provided string to print. + * @param length + * The total number of characters to print. * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -469,38 +788,47 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_dynamic_partial_ - extern f_status_t fl_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_dynamic_partial_ +#ifndef _di_fl_print_trim_except_in_ + extern f_status_t fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_ /** - * Print a partial dynamic string, stripping leading and trailing whitespace. + * Print a string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1-byte character at a location specified in except array. - * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * Will not stop at NULL. + * Will print NULL. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * @param buffer + * @param string * The string to output. - * @param range - * The range within the provided string to print. - * @param except + * @param length + * The total number of characters to print. + * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -508,27 +836,30 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_dynamic_partial_ - extern f_status_t fl_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); -#endif // _di_fl_print_trim_except_dynamic_partial_ +#ifndef _di_fl_print_trim_except_in_raw_ + extern f_status_t fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_raw_ /** * Print a string, stripping leading and trailing whitespace. * - * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except array. + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * @@ -536,9 +867,12 @@ extern "C" { * The string to output. * @param length * The total number of characters to print. - * @param except + * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -546,36 +880,42 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_utf_ - extern f_status_t fl_print_trim_except_utf(const f_utf_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); -#endif // _di_fl_print_trim_except_utf_ +#ifndef _di_fl_print_trim_except_in_safely_ + extern f_status_t fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_safely_ /** * Print a dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except array. + * Will not stop at NULL. + * Will not print NULL. * Will print the entire dynamic string, except for leading/trailing whitespace. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer * The string to output. - * @param except + * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -583,35 +923,40 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_utf_dynamic_ - extern f_status_t fl_print_trim_except_utf_dynamic(const f_utf_string_static_t buffer, const f_array_lengths_t except, FILE *output); -#endif // _di_fl_print_trim_except_utf_dynamic_ +#ifndef _di_fl_print_trim_except_in_dynamic_ + extern f_status_t fl_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_ /** - * Print a string, stripping leading and trailing whitespace. + * Print a dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except_at array. - * Will not print any 1 UTF character within the ranges specified in except_in array. + * Will not stop at NULL. + * Will print NULL. + * Will print the entire dynamic string, except for leading/trailing whitespace. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * @param string + * @param buffer * The string to output. - * @param length - * The total number of characters to print. * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -625,29 +970,31 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_utf_ - extern f_status_t fl_print_trim_except_in_utf(const f_utf_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_utf_ +#ifndef _di_fl_print_trim_except_in_dynamic_raw_ + extern f_status_t fl_print_trim_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_raw_ /** * Print a dynamic string, stripping leading and trailing whitespace. * - * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except_at array. - * Will not print any 1 UTF character within the ranges specified in except_in array. + * Will not stop at NULL. + * Will print NULL (as a control character symbol). * Will print the entire dynamic string, except for leading/trailing whitespace. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * @@ -666,30 +1013,32 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_utf_dynamic_ - extern f_status_t fl_print_trim_except_in_utf_dynamic(const f_utf_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_utf_dynamic_ +#ifndef _di_fl_print_trim_except_in_dynamic_safely_ + extern f_status_t fl_print_trim_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_safely_ /** * Print a partial dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except_at array. - * Will not print any 1 UTF character within the ranges specified in except_in array. + * Will not stop at NULL. + * Will not print NULL. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. * Will print the only the buffer range specified by range, except for leading/trailing whitespace. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer @@ -709,38 +1058,48 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_in_utf_dynamic_partial_ - extern f_status_t fl_print_trim_except_in_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_fl_print_trim_except_in_utf_dynamic_partial_ +#ifndef _di_fl_print_trim_except_in_dynamic_partial_ + extern f_status_t fl_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_partial_ /** * Print a partial dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will not print any 1 UTF character at a location specified in except array. + * Will not stop at NULL. + * Will print NULL. + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. * Will print the only the buffer range specified by range, except for leading/trailing whitespace. * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer * The string to output. * @param range * The range within the provided string to print. - * @param except + * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -748,33 +1107,44 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_except_utf_dynamic_partial_ - extern f_status_t fl_print_trim_except_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); -#endif // _di_fl_print_trim_except_utf_dynamic_partial_ +#ifndef _di_fl_print_trim_except_in_dynamic_partial_raw_ + extern f_status_t fl_print_trim_except_in_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_partial_raw_ /** - * Print a string, stripping leading and trailing whitespace. + * Print a partial dynamic string, stripping leading and trailing whitespace. * - * Except for leading/trailing whitespace, the string is printed as-is without interpretation. + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will not print any 1-byte character at a location specified in except_at array. + * Will not print any 1-byte character within the ranges specified in except_in array. + * Will print the only the buffer range specified by range, except for leading/trailing whitespace. * - * Will not stop at \0. - * Will not print \0. + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * - * @param string + * @param buffer * The string to output. - * @param length - * The total number of characters to print. + * @param range + * The range within the provided string to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -782,32 +1152,40 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_utf_ - extern f_status_t fl_print_trim_utf(const f_utf_string_t string, const f_array_length_t length, FILE *output); -#endif // _di_fl_print_trim_utf_ +#ifndef _di_fl_print_trim_except_in_dynamic_partial_safely_ + extern f_status_t fl_print_trim_except_in_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fl_print_trim_except_in_dynamic_partial_safely_ /** - * Print a dynamic string, stripping leading and trailing whitespace. + * Print a partial dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. - * Will print the entire dynamic string, except for leading/trailing whitespace. + * Will not stop at NULL. + * Will not print NULL. + * Will not print any 1-byte character at a location specified in except array. + * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * + * NULL characters are treated as whitespace for the purpose of trimming. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -815,34 +1193,85 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_utf_dynamic_ - extern f_status_t fl_print_trim_utf_dynamic(const f_utf_string_static_t buffer, FILE *output); -#endif // _di_fl_print_trim_utf_dynamic_ +#ifndef _di_fl_print_trim_except_dynamic_partial_ + extern f_status_t fl_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_dynamic_partial_ /** * Print a partial dynamic string, stripping leading and trailing whitespace. * * Except for leading/trailing whitespace, the string is printed as-is without interpretation. * - * Will not stop at \0. - * Will not print \0. + * Will not stop at NULL. + * Will print NULL. + * Will not print any 1-byte character at a location specified in except array. + * Will print the only the buffer range specified by range, except for leading/trailing whitespace. + * + * All UTF-8 characters, invalid or not, are printed as is, except for trimmed characters. + * Invalid UTF-8 characters are not considered whitespace for the purpose of trimming. + * + * NULL characters are treated as whitespace for the purpose of trimming. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * F_none on success. + * F_data_not on success but there is nothing to print. + * + * F_output (with error bit) on error when printing to output. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. + * + * Errors (with error bit) from: f_utf_is_whitespace(). + * + * @see fputc_unlocked() + */ +#ifndef _di_fl_print_trim_except_dynamic_partial_raw_ + extern f_status_t fl_print_trim_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_dynamic_partial_raw_ + +/** + * Print a partial dynamic string, stripping leading and trailing whitespace. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will print NULL (as a control character symbol). + * Will not print any 1-byte character at a location specified in except array. * Will print the only the buffer range specified by range, except for leading/trailing whitespace. * + * NULL characters are treated as whitespace for the purpose of trimming. + * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * * @param buffer * The string to output. * @param range * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. * @param output * The file stream to output to, including standard streams such as stdout and stderr. * @@ -850,18 +1279,18 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on error when printing to output. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * - * Errors (with error bit) from: f_utf_character_is_whitespace(). + * Errors (with error bit) from: f_utf_is_valid() + * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() */ -#ifndef _di_fl_print_trim_utf_dynamic_partial_ - extern f_status_t fl_print_trim_utf_dynamic_partial(const f_utf_string_static_t buffer, const f_string_range_t range, FILE *output); -#endif // _di_fl_print_trim_utf_dynamic_partial_ +#ifndef _di_fl_print_trim_except_dynamic_partial_safely_ + extern f_status_t fl_print_trim_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fl_print_trim_except_dynamic_partial_safely_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_print/c/private-print.c b/level_1/fl_print/c/private-print.c index 2abfab2..86b385c 100644 --- a/level_1/fl_print/c/private-print.c +++ b/level_1/fl_print/c/private-print.c @@ -6,7 +6,7 @@ extern "C" { #endif #if !defined(_di_fl_print_string_convert_) || !defined(_di_fl_print_string_) - f_status_t private_fl_print_string_convert(char *current, va_list *ap, FILE *output) { + f_status_t private_fl_print_string_convert(char *current, FILE *output, va_list *ap) { // An unpaired '%' character must not be at the end of the string. if (!*current) { @@ -28,10 +28,10 @@ extern "C" { else if (*current == f_string_ascii_pound_s[0]) { flag |= f_print_format_flag_convert; } - else if (*current == f_string_ascii_parenthesis_open_s[0]) { + else if (*current == f_string_ascii_colon_semi_s[0]) { flag |= f_print_format_flag_ignore_index; // @todo } - else if (*current == f_string_ascii_parenthesis_close_s[0]) { + else if (*current == f_string_ascii_colon_s[0]) { flag |= f_print_format_flag_ignore_range; // @todo } else if (*current == f_string_ascii_plus_s[0]) { @@ -211,14 +211,15 @@ extern "C" { } else if (*current == f_string_ascii_S_s[0]) { - // NULL terminated static/dynamic string. - const f_string_static_t value = va_arg(*ap, f_string_static_t); + // NULL terminated safe string. + const f_string_t value = va_arg(*ap, f_string_t); if (flag & f_print_format_flag_trim) { - return private_fl_print_trim(value.string, value.used, output); + // @todo: implement a: private_fl_print_trim_safely_teminated(). + //return private_fl_print_trim_teminated(value, output); } - return f_print_dynamic(value, output); + return f_print_safely_terminated(value, output); } else if (*current == f_string_ascii_u_s[0]) { type = f_print_format_type_unsigned; @@ -467,10 +468,9 @@ extern "C" { #endif // !defined(_di_fl_print_string_convert_) || !defined(_di_fl_print_string_) #if !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_) || !defined(_di_fl_print_trim_except_in_) || !defined(_di_fl_print_trim_except_in_dynamic_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_) - f_status_t private_fl_print_trim_except_in(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + f_status_t private_fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - // @todo resume converting this function. - f_array_length_t i = start; + f_array_length_t i = 0; f_array_length_t j = 0; f_array_length_t at = 0; f_array_length_t at2 = 0; @@ -480,7 +480,7 @@ extern "C" { f_status_t status = F_none; // skip past leading whitespace. - while (i < stop) { + while (i < length) { if (!string[i]) { ++i; @@ -508,7 +508,7 @@ extern "C" { continue; } - status = f_utf_is_whitespace(string + i, (stop - i) + 1); + status = f_utf_is_whitespace(string + i, (length - i) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -525,13 +525,7 @@ extern "C" { f_string_t s = 0; - while (i < stop) { - - if (!string[i]) { - ++i; - - continue; - } + while (i < length) { while (at < except_at.used && except_at.array[at] < i) { ++at; @@ -555,7 +549,7 @@ extern "C" { } } - status = f_utf_is_whitespace(string + i, (stop - i) + 1); + status = f_utf_is_whitespace(string + i, (length - i) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -565,10 +559,12 @@ extern "C" { return status; } - if (status == F_true) { + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - while (j < stop) { + while (j < length) { if (!string[j]) { ++j; @@ -596,7 +592,7 @@ extern "C" { continue; } - status = f_utf_is_whitespace(string + j, (stop - j) + 1); + status = f_utf_is_whitespace(string + j, (length - j) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -606,10 +602,10 @@ extern "C" { return status; } - if (status == F_false) break; + if (status == F_false && string[i]) break; } // while - if (j == stop || status == F_true) break; + if (j == length) break; // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). while (i < j) { @@ -640,22 +636,8 @@ extern "C" { continue; } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i = stop; - status = F_none; - break; + if (i + macro_f_utf_byte_width(string[i]) >= length) { + return F_status_set_error(F_complete_not_utf_stop); } if (!fputc_unlocked(string[i], output)) { @@ -683,10 +665,16 @@ extern "C" { i += macro_f_utf_byte_width(string[i]); } // while - if (i >= stop) break; + if (i >= length) break; + + if (!string[i]) { + ++i; + + continue; + } } - status = f_utf_is_valid(string + i, stop - i); + status = f_utf_is_valid(string + i, length - i); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -696,38 +684,12 @@ extern "C" { return status; } - if (F_status_is_error(status) || status == F_false) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i += macro_f_utf_byte_width(string[i]); - continue; + if (i + macro_f_utf_byte_width(string[i]) >= length) { + return F_status_set_error(F_complete_not_utf_stop); } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i = stop; - continue; + if (status == F_false) { + return F_status_set_error(F_utf_not); } if (!fputc_unlocked(string[i], output)) { @@ -754,13 +716,15 @@ extern "C" { i += macro_f_utf_byte_width(string[i]); } // while + + return F_none; } #endif // !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_) || !defined(_di_fl_print_trim_except_in_) || !defined(_di_fl_print_trim_except_in_dynamic_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_) #if !defined(_di_fl_print_trim_except_raw_) || !defined(_di_fl_print_trim_except_dynamic_raw_) || !defined(_di_fl_print_trim_except_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_in_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_raw_) - f_status_t private_fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + f_status_t private_fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - f_array_length_t i = start; + f_array_length_t i = 0; f_array_length_t j = 0; f_array_length_t at = 0; f_array_length_t at2 = 0; @@ -768,10 +732,15 @@ extern "C" { f_array_length_t in2 = 0; f_status_t status = F_none; - uint8_t width_max = 0; // skip past leading whitespace. - while (i < stop) { + while (i < length) { + + if (!string[i]) { + ++i; + + continue; + } while (at < except_at.used && except_at.array[at] < i) { ++at; @@ -793,23 +762,17 @@ extern "C" { continue; } - width_max = (stop - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } + status = f_utf_is_whitespace(string + i, (length - i) + 1); - if (status == F_false) break; + // consider invalid data not-whitespace. + if (F_status_is_error(status) || status == F_false) break; i += macro_f_utf_byte_width(string[i]); } // while - while (i < stop) { + f_string_t s = 0; + + while (i < length) { while (at < except_at.used && except_at.array[at] < i) { ++at; @@ -821,37 +784,32 @@ extern "C" { continue; } - while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { - ++in; - } // while - - if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { - i = except_in.array[in].stop + 1; - - continue; - } + if (in < except_in.used) { + while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { + ++in; + } // while - width_max = (stop - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + i = except_in.array[in].stop + 1; - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); + continue; } - - return status; } - if (status == F_true) { + status = f_utf_is_whitespace(string + i, (length - i) + 1); + + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - if (j == stop) { - return F_none; - } + while (j < length) { - at2 = at; + if (!string[j]) { + ++j; - while (j < stop) { + continue; + } while (at2 < except_at.used && except_at.array[at2] < j) { ++at2; @@ -863,7 +821,7 @@ extern "C" { continue; } - while (in2 < except_in.used && except_in.array[in2].start < j && except_in.array[in2].stop <= j) { + while (in2 < except_in.used && except_in.array[in2].start < j && except_in.array[in2].stop < j) { ++in2; } // while @@ -873,67 +831,87 @@ extern "C" { continue; } - width_max = (stop - j) + 1; - status = f_utf_is_whitespace(string + j, width_max); + status = f_utf_is_whitespace(string + j, (length - j) + 1); - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + if (F_status_is_error(status) || status == F_false && string[i]) break; + } // while - return status; - } + if (j == length) break; - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - while (i < j) { + // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). + while (i < j) { - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while + while (at < except_at.used && except_at.array[at] < i) { + ++at; + } // while - if (at < except_at.used && except_at.array[at] == i) { - ++i; + if (at < except_at.used && except_at.array[at] == i) { + ++i; - continue; - } + continue; + } - while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { - ++in; - } // while + while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { + ++in; + } // while - if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { - i = except_in.array[in].stop + 1; + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + i = except_in.array[in].stop + 1; - continue; - } + continue; + } + + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } + + if (macro_f_utf_byte_width(string[i]) > 1 && i + 1 < length) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); + } - if (!fputc_unlocked(string[i], output)) { + if (macro_f_utf_byte_width(string[i]) > 2 && i + 2 < length) { + if (!fputc_unlocked(string[i + 2], output)) { return F_status_set_error(F_output); } - ++i; - } // while - - break; + if (macro_f_utf_byte_width(string[i]) > 3 && i + 3 < length) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } } - j += macro_f_utf_byte_width(string[j]); + i += macro_f_utf_byte_width(string[i]); } // while - if (status == F_true) break; + if (i >= length) break; } - width_max = macro_f_utf_byte_width(string[i]); - - for (j = 0; j < width_max; ++j) { + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } - if (!fputc_unlocked(string[i + j], output)) { + if (macro_f_utf_byte_width(string[i]) > 1 && i + 1 < length) { + if (!fputc_unlocked(string[i + 1], output)) { return F_status_set_error(F_output); } - } // for - i += width_max; + if (macro_f_utf_byte_width(string[i]) > 2 && i + 2 < length) { + if (!fputc_unlocked(string[i + 2], output)) { + return F_status_set_error(F_output); + } + + if (macro_f_utf_byte_width(string[i]) > 3 && i + 3 < length) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } + } + + i += macro_f_utf_byte_width(string[i]); } // while return F_none; @@ -941,9 +919,9 @@ extern "C" { #endif // !defined(_di_fl_print_trim_except_raw_) || !defined(_di_fl_print_trim_except_dynamic_raw_) || !defined(_di_fl_print_trim_except_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_in_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_raw_) #if !defined(_di_fl_print_trim_except_safely_) || !defined(_di_fl_print_trim_except_dynamic_safely_) || !defined(_di_fl_print_trim_except_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_in_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_safely_) - f_status_t private_fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + f_status_t private_fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - f_array_length_t i = start; + f_array_length_t i = 0; f_array_length_t j = 0; f_array_length_t at = 0; f_array_length_t at2 = 0; @@ -952,10 +930,11 @@ extern "C" { f_status_t status = F_none; + f_string_t s = 0; + // skip past leading whitespace. - while (i < stop) { + while (i < length) { - // Consider NULL whitespace for the purposes of trimming (@todo update documentation to describe this behavior). if (!string[i]) { ++i; @@ -982,24 +961,15 @@ extern "C" { continue; } - status = f_utf_is_whitespace(string + i, (stop - i) + 1); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + status = f_utf_is_whitespace(string + i, (length - i) + 1); - return status; - } - - if (status == F_false) break; + // invalid UTF will not be treated as whitespace. + if (F_status_is_error(status) || status == F_false) break; i += macro_f_utf_byte_width(string[i]); } // while - f_string_t s = 0; - - while (i < stop) { + while (i < length) { while (at < except_at.used && except_at.array[at] < i) { ++at; @@ -1023,33 +993,16 @@ extern "C" { } } - status = f_utf_is_whitespace(string + i, (stop - i) + 1); - - // invalid UTF-8 characters will be considered non-whitespace. - if (F_status_is_error(status)) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i += macro_f_utf_byte_width(string[i]); - continue; - } + status = f_utf_is_whitespace(string + i, (length - i) + 1); - if (status == F_true) { // @todo: update to handle NULL as whitespace in this condition. + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - while (j < stop) { + while (j < length) { - // Consider NULL whitespace for the purposes of trimming (@todo update documentation to describe this behavior). - if (!string[i]) { + if (!string[j]) { ++j; continue; @@ -1075,13 +1028,12 @@ extern "C" { continue; } - status = f_utf_is_whitespace(string + j, (stop - j) + 1); - if (F_status_is_error(status)) break; + status = f_utf_is_whitespace(string + j, (length - j) + 1); - if (status == F_false) break; + if (F_status_is_error(status) || status == F_false && string[i]) break; } // while - if (j == stop || status == F_true) break; + if (j == length || status == F_true || !string[i]) break; // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). while (i < j) { @@ -1106,7 +1058,7 @@ extern "C" { continue; } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { + if (i + macro_f_utf_byte_width(string[i]) >= length) { if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { return F_status_set_error(F_output); } @@ -1119,12 +1071,31 @@ extern "C" { return F_status_set_error(F_output); } - i = stop; + i = length; status = F_none; break; } - if (string[i]) { + if (!string[i]) { + if (!fputc_unlocked(f_print_sequence_null_s[0], output)) { + return F_status_set_error(F_output); + } + + if (!fputc_unlocked(f_print_sequence_null_s[1], output)) { + return F_status_set_error(F_output); + } + + if (!fputc_unlocked(f_print_sequence_null_s[2], output)) { + return F_status_set_error(F_output); + } + + ++i; + continue; + } + + status = f_utf_is_valid(string + i, length - i); + + if (status == F_true) { if (!fputc_unlocked(string[i], output)) { return F_status_set_error(F_output); } @@ -1146,166 +1117,107 @@ extern "C" { } } } - - i += macro_f_utf_byte_width(string[i]); } else { - if (!fputc_unlocked(f_print_sequence_null_s[0], output)) { + if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { return F_status_set_error(F_output); } - if (!fputc_unlocked(f_print_sequence_null_s[1], output)) { + if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { return F_status_set_error(F_output); } - if (!fputc_unlocked(f_print_sequence_null_s[2], output)) { + if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { return F_status_set_error(F_output); } - - ++i; } - } // while - // at this point the invalid character found while looping with j shall be safely printed. - if (F_status_is_error(status)) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } + i += macro_f_utf_byte_width(string[i]); + } // while - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } + if (i >= length) break; + } - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } + status = f_utf_is_valid(string + i, length - i); - i += macro_f_utf_byte_width(string[i]); - continue; + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_maybe) { + return F_status_set_error(F_utf); } - if (i >= stop) break; + return status; } - s = f_print_character_safely_get(string[i]); - - if (s) { - if (!fputc_unlocked(s[i], output)) { + if (status == F_false || i + macro_f_utf_byte_width(string[i]) >= length) { + if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { return F_status_set_error(F_output); } - if (!fputc_unlocked(s[i + 1], output)) { + if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { return F_status_set_error(F_output); } - if (!fputc_unlocked(s[i + 2], output)) { + if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { return F_status_set_error(F_output); } - ++i; + if (status == F_false) { + i += macro_f_utf_byte_width(string[i]); + } + else { + i = length; + } + + continue; } - else { - status = f_utf_is_valid(string + i, stop - i); - if (F_status_is_error(status) || status == F_false) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i += macro_f_utf_byte_width(string[i]); - continue; - } - - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { - return F_status_set_error(F_output); - } - - if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { - return F_status_set_error(F_output); - } - - i = stop; - continue; - } - - if (!fputc_unlocked(string[i], output)) { + if (macro_f_utf_byte_width(string[i]) > 1) { + if (!fputc_unlocked(string[i + 1], output)) { return F_status_set_error(F_output); } - if (macro_f_utf_byte_width(string[i]) > 1) { - if (!fputc_unlocked(string[i + 1], output)) { + if (macro_f_utf_byte_width(string[i]) > 2) { + if (!fputc_unlocked(string[i + 2], output)) { return F_status_set_error(F_output); } - if (macro_f_utf_byte_width(string[i]) > 2) { - if (!fputc_unlocked(string[i + 2], output)) { + if (macro_f_utf_byte_width(string[i]) > 3) { + if (!fputc_unlocked(string[i + 3], output)) { return F_status_set_error(F_output); } - - if (macro_f_utf_byte_width(string[i]) > 3) { - if (!fputc_unlocked(string[i + 3], output)) { - return F_status_set_error(F_output); - } - } } } - - i += macro_f_utf_byte_width(string[i]); } + + i += macro_f_utf_byte_width(string[i]); } // while return F_none; } #endif // !defined(_di_fl_print_trim_except_safely_) || !defined(_di_fl_print_trim_except_dynamic_safely_) || !defined(_di_fl_print_trim_except_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_in_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_safely_) -#if !defined(_di_fl_print_trim_except_in_utf_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_) || !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_) - f_status_t private_fl_print_trim_except_in_utf(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#if !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_) + f_status_t private_fl_print_trim(const f_string_t string, const f_array_length_t length, FILE *output) { - f_array_length_t i = start; + f_array_length_t i = 0; f_array_length_t j = 0; - f_array_length_t at = 0; - f_array_length_t at2 = 0; - f_array_length_t in = 0; - f_array_length_t in2 = 0; f_status_t status = F_none; - while (i < stop) { - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while + // skip past leading whitespace. + while (i < length) { - if (at < except_at.used && except_at.array[at] == i) { + if (!string[i]) { ++i; continue; } - while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { - ++in; - } // while - - if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { - i = except_in.array[in].stop + 1; - - continue; - } - - status = f_utf_character_is_whitespace(string[i]); + status = f_utf_is_whitespace(string + i, (length - i) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -1317,28 +1229,14 @@ extern "C" { if (status == F_false) break; - ++i; + i += macro_f_utf_byte_width(string[i]); } // while - while (i < stop) { - - if (!string[i]) { - ++i; - - continue; - } - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while - - if (at < except_at.used && except_at.array[at] == i) { - ++i; + f_string_t s = 0; - continue; - } + while (i < length) { - status = f_utf_character_is_whitespace(string[i]); + status = f_utf_is_whitespace(string + i, (length - i) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -1348,38 +1246,20 @@ extern "C" { return status; } - if (status == F_true) { - j = i + 1; - - if (j == stop) { - return F_none; - } - - at2 = at; - - while (j < stop) { + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { + j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - while (at2 < except_at.used && except_at.array[at2] < j) { - ++at2; - } // while + while (j < length) { - if (at2 < except_at.used && except_at.array[at2] == j) { + if (!string[j]) { ++j; continue; } - while (in2 < except_in.used && except_in.array[in2].start < j && except_in.array[in2].stop <= j) { - ++in2; - } // while - - if (in2 < except_in.used && except_in.array[in2].start <= j && except_in.array[in2].stop >= j) { - j = except_in.array[in2].stop + 1; - - continue; - } - - status = f_utf_character_is_whitespace(string[j]); + status = f_utf_is_whitespace(string + j, (length - j) + 1); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -1389,818 +1269,351 @@ extern "C" { return status; } - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - while (i < j) { + if (status == F_false && string[i]) break; + } // while - if (!string[i]) { - ++i; + if (j == length) break; - continue; - } + // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). + while (i < j) { + + if (!string[i]) { + ++i; + + continue; + } - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while + if (i + macro_f_utf_byte_width(string[i]) >= length) { + return F_status_set_error(F_complete_not_utf_stop); + } - if (at < except_at.used && except_at.array[at] == i) { - ++i; + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } - continue; - } + if (macro_f_utf_byte_width(string[i]) > 1) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); + } - if (!fputc_unlocked(string[i], output)) { + if (macro_f_utf_byte_width(string[i]) > 2) { + if (!fputc_unlocked(string[i + 2], output)) { return F_status_set_error(F_output); } - ++i; - } // while - - break; + if (macro_f_utf_byte_width(string[i]) > 3) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } } - ++j; + i += macro_f_utf_byte_width(string[i]); } // while - if (status == F_true) break; - } - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - - ++i; - } // while + if (i >= length) break; - return F_none; - } -#endif // !defined(_di_fl_print_trim_except_in_utf_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_) || !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_) + if (!string[i]) { + ++i; -#if !defined(_di_fl_print_trim_except_in_utf_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_utf_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_raw_) - f_status_t private_fl_print_trim_except_in_utf_raw(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + continue; + } + } - f_array_length_t i = start; - f_array_length_t j = 0; - f_array_length_t at = 0; - f_array_length_t at2 = 0; - f_array_length_t in = 0; - f_array_length_t in2 = 0; + status = f_utf_is_valid(string + i, length - i); - f_status_t status = F_none; + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_maybe) { + return F_status_set_error(F_utf); + } - while (i < stop) { + return status; + } - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while + if (i + macro_f_utf_byte_width(string[i]) >= length) { + return F_status_set_error(F_complete_not_utf_stop); + } - if (at < except_at.used && except_at.array[at] == i) { - ++i; + if (status == F_false) { + return F_status_set_error(F_utf_not); + } - continue; + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); } - while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { - ++in; - } // while + if (macro_f_utf_byte_width(string[i]) > 1) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); + } - if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { - i = except_in.array[in].stop + 1; + if (macro_f_utf_byte_width(string[i]) > 2) { + if (!fputc_unlocked(string[i + 2], output)) { + return F_status_set_error(F_output); + } - continue; + if (macro_f_utf_byte_width(string[i]) > 3) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } } - status = f_utf_character_is_whitespace(string[i]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + i += macro_f_utf_byte_width(string[i]); + } // while - return status; - } + return F_none; + } +#endif // !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_) - if (status == F_false) break; +#if !defined(_di_fl_print_trim_raw_) || !defined(_di_fl_print_trim_dynamic_raw_) || !defined(_di_fl_print_trim_dynamic_partial_raw_) + f_status_t private_fl_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output) { - ++i; - } // while + f_array_length_t i = 0; + f_array_length_t j = 0; - while (i < stop) { + f_status_t status = F_none; - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while + // skip past leading whitespace. + while (i < length) { - if (at < except_at.used && except_at.array[at] == i) { + if (!string[i]) { ++i; continue; } - status = f_utf_character_is_whitespace(string[i]); + status = f_utf_is_whitespace(string + i, (length - i) + 1); - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + // consider invalid data not-whitespace. + if (F_status_is_error(status) || status == F_false) break; - return status; - } + i += macro_f_utf_byte_width(string[i]); + } // while - if (status == F_true) { - j = i + 1; + f_string_t s = 0; - if (j == stop) { - return F_none; - } + while (i < length) { - at2 = at; + status = f_utf_is_whitespace(string + i, (length - i) + 1); - while (j < stop) { + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { + j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - while (at2 < except_at.used && except_at.array[at2] < j) { - ++at2; - } // while + while (j < length) { - if (at2 < except_at.used && except_at.array[at2] == j) { + if (!string[j]) { ++j; continue; } - while (in2 < except_in.used && except_in.array[in2].start < j && except_in.array[in2].stop <= j) { - ++in2; - } // while - - if (in2 < except_in.used && except_in.array[in2].start <= j && except_in.array[in2].stop >= j) { - j = except_in.array[in2].stop + 1; + status = f_utf_is_whitespace(string + j, (length - j) + 1); - continue; - } + if (F_status_is_error(status) || status == F_false && string[i]) break; + } // while - status = f_utf_character_is_whitespace(string[j]); + if (j == length) break; - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). + while (i < j) { - return status; + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); } - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - while (i < j) { - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while - - if (at < except_at.used && except_at.array[at] == i) { - ++i; - - continue; - } + if (macro_f_utf_byte_width(string[i]) > 1 && i + 1 < length) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); + } - if (!fputc_unlocked(string[i], output)) { + if (macro_f_utf_byte_width(string[i]) > 2 && i + 2 < length) { + if (!fputc_unlocked(string[i + 2], output)) { return F_status_set_error(F_output); } - ++i; - } // while - - break; + if (macro_f_utf_byte_width(string[i]) > 3 && i + 3 < length) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } } - ++j; + i += macro_f_utf_byte_width(string[i]); } // while - if (status == F_true) break; + if (i >= length) break; } if (!fputc_unlocked(string[i], output)) { return F_status_set_error(F_output); } - ++i; - } // while - - return F_none; - } -#endif // !defined(_di_fl_print_trim_except_in_utf_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_utf_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_raw_) - -#if !defined(_di_fl_print_trim_except_in_utf_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_utf_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_safely_) - f_status_t private_fl_print_trim_except_in_utf_safely(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - - f_array_length_t i = start; - f_array_length_t j = 0; - f_array_length_t at = 0; - f_array_length_t at2 = 0; - f_array_length_t in = 0; - f_array_length_t in2 = 0; - - f_status_t status = F_none; - - while (i < stop) { - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while - - if (at < except_at.used && except_at.array[at] == i) { - ++i; - - continue; - } - - while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { - ++in; - } // while - - if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { - i = except_in.array[in].stop + 1; - - continue; - } - - status = f_utf_character_is_whitespace(string[i]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_false) break; - - ++i; - } // while - - while (i < stop) { - - if (!string[i]) { // @todo each of these needs to be replaced with a get safe check. - ++i; - - continue; - } - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while - - if (at < except_at.used && except_at.array[at] == i) { - ++i; - - continue; - } - - status = f_utf_character_is_whitespace(string[i]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_true) { - j = i + 1; - - if (j == stop) { - return F_none; - } - - at2 = at; - - while (j < stop) { - - while (at2 < except_at.used && except_at.array[at2] < j) { - ++at2; - } // while - - if (at2 < except_at.used && except_at.array[at2] == j) { - ++j; - - continue; - } - - while (in2 < except_in.used && except_in.array[in2].start < j && except_in.array[in2].stop <= j) { - ++in2; - } // while - - if (in2 < except_in.used && except_in.array[in2].start <= j && except_in.array[in2].stop >= j) { - j = except_in.array[in2].stop + 1; - - continue; - } - - status = f_utf_character_is_whitespace(string[j]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - while (i < j) { - - if (!string[i]) { - ++i; - - continue; - } - - while (at < except_at.used && except_at.array[at] < i) { - ++at; - } // while - - if (at < except_at.used && except_at.array[at] == i) { - ++i; - - continue; - } - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - - ++i; - } // while - - break; - } - - ++j; - } // while - - if (status == F_true) break; - } - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - - ++i; - } // while - - return F_none; - } -#endif // !defined(_di_fl_print_trim_except_in_utf_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_utf_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_safely_) - -#if !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_) - f_status_t private_fl_print_trim(const f_string_t string, const f_array_length_t length, FILE *output) { - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_status_t status = F_none; - uint8_t width_max = 0; - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_false) break; - } // for - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - if (!string[i]) continue; - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_true) { - j = i + macro_f_utf_byte_width(string[i]); - - if (j == length) { - return F_none; - } - - for (; j < length; j += macro_f_utf_byte_width(string[j])) { - - width_max = (length - j) + 1; - status = f_utf_is_whitespace(string + j, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { - - if (!string[i]) continue; - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for - - break; - } - } // for - - if (status == F_true) break; - } - - width_max = macro_f_utf_byte_width(string[i]); - - for (j = 0; j < width_max; ++j) { - - if (!fputc_unlocked(string[i + j], output)) { - return F_status_set_error(F_output); - } - } // for - } // for - - return F_none; - } -#endif // !defined(_di_fl_print_trim_) || !defined(_di_fl_print_trim_dynamic_) || !defined(_di_fl_print_trim_dynamic_partial_) - -#if !defined(_di_fl_print_trim_raw_) || !defined(_di_fl_print_trim_dynamic_raw_) || !defined(_di_fl_print_trim_dynamic_partial_raw_) - f_status_t private_fl_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output) { - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_status_t status = F_none; - uint8_t width_max = 0; - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_false) break; - } // for - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_true) { - j = i + macro_f_utf_byte_width(string[i]); - - if (j == length) { - return F_none; - } - - for (; j < length; j += macro_f_utf_byte_width(string[j])) { - - width_max = (length - j) + 1; - status = f_utf_is_whitespace(string + j, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for - - break; - } - } // for - - if (status == F_true) break; - } - - width_max = macro_f_utf_byte_width(string[i]); - - for (j = 0; j < width_max; ++j) { - - if (!fputc_unlocked(string[i + j], output)) { - return F_status_set_error(F_output); - } - } // for - } // for - - return F_none; - } -#endif // !defined(_di_fl_print_trim_raw_) || !defined(_di_fl_print_trim_dynamic_raw_) || !defined(_di_fl_print_trim_dynamic_partial_raw_) - -#if !defined(_di_fl_print_trim_safely_) || !defined(_di_fl_print_trim_dynamic_safely_) || !defined(_di_fl_print_trim_dynamic_partial_safely_) - f_status_t private_fl_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output) { - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_status_t status = F_none; - uint8_t width_max = 0; - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_false) break; - } // for - - for (; i < length; i += macro_f_utf_byte_width(string[i])) { - - if (!string[i]) continue; // @todo each of these needs to be replaced with a get safe check. - - width_max = (length - i) + 1; - status = f_utf_is_whitespace(string + i, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_true) { - j = i + macro_f_utf_byte_width(string[i]); - - if (j == length) { - return F_none; + if (macro_f_utf_byte_width(string[i]) > 1 && i + 1 < length) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); } - for (; j < length; j += macro_f_utf_byte_width(string[j])) { - - width_max = (length - j) + 1; - status = f_utf_is_whitespace(string + j, width_max); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; + if (macro_f_utf_byte_width(string[i]) > 2 && i + 2 < length) { + if (!fputc_unlocked(string[i + 2], output)) { + return F_status_set_error(F_output); } - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { - - if (!string[i]) continue; - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for - - break; + if (macro_f_utf_byte_width(string[i]) > 3 && i + 3 < length) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } } - } // for - - if (status == F_true) break; + } } - width_max = macro_f_utf_byte_width(string[i]); - - for (j = 0; j < width_max; ++j) { - - if (!fputc_unlocked(string[i + j], output)) { - return F_status_set_error(F_output); - } - } // for - } // for + i += macro_f_utf_byte_width(string[i]); + } // while return F_none; } -#endif // !defined(_di_fl_print_trim_safely_) || !defined(_di_fl_print_trim_dynamic_safely_) || !defined(_di_fl_print_trim_dynamic_partial_safely_) +#endif // !defined(_di_fl_print_trim_raw_) || !defined(_di_fl_print_trim_dynamic_raw_) || !defined(_di_fl_print_trim_dynamic_partial_raw_) -#if !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_) - f_status_t private_fl_print_trim_utf(const f_utf_string_t string, const f_array_length_t length, FILE *output) { +#if !defined(_di_fl_print_trim_safely_) || !defined(_di_fl_print_trim_dynamic_safely_) || !defined(_di_fl_print_trim_dynamic_partial_safely_) + f_status_t private_fl_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output) { f_array_length_t i = 0; f_array_length_t j = 0; f_status_t status = F_none; - for (; i < length; ++i) { - - status = f_utf_character_is_whitespace(string[i]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; - } - - if (status == F_false) break; - } // for - - for (; i < length; ++i) { - - if (!string[i]) continue; + f_string_t s = 0; - status = f_utf_character_is_whitespace(string[i]); + // skip past leading whitespace. + while (i < length) { - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + if (!string[i]) { + ++i; - return status; + continue; } - if (status == F_true) { - j = i + 1; + status = f_utf_is_whitespace(string + i, (length - i) + 1); - if (j == length) { - return F_none; - } + // invalid UTF will not be treated as whitespace. + if (F_status_is_error(status) || status == F_false) break; - for (; j < length; ++j) { - - status = f_utf_character_is_whitespace(string[j]); + i += macro_f_utf_byte_width(string[i]); + } // while - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + while (i < length) { - return status; - } + status = f_utf_is_whitespace(string + i, (length - i) + 1); - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { + // determine if this is an end of string whitespace that needs to be trimmed. + if (status == F_true || !string[i]) { + j = i + macro_f_utf_byte_width(string[i]); + status = F_none; - if (!string[i]) continue; + while (j < length) { - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for + if (!string[j]) { + ++j; - break; + continue; } - } // for - - if (status == F_true) break; - } - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for - - return F_none; - } -#endif // !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_) -#if !defined(_di_fl_print_trim_utf_raw_) || !defined(_di_fl_print_trim_utf_dynamic_raw_) || !defined(_di_fl_print_trim_utf_dynamic_partial_raw_) - f_status_t private_fl_print_trim_utf_raw(const f_utf_string_t string, const f_array_length_t length, FILE *output) { + status = f_utf_is_whitespace(string + j, (length - j) + 1); - f_array_length_t i = 0; - f_array_length_t j = 0; + if (F_status_is_error(status) || status == F_false && string[i]) break; + } // while - f_status_t status = F_none; + if (j == length || status == F_true || !string[i]) break; - for (; i < length; ++i) { + // print all processed whitespace (note: control characters are not whitespace so no checks for this are needed). + while (i < j) { - status = f_utf_character_is_whitespace(string[i]); + if (i + macro_f_utf_byte_width(string[i]) >= length) { + if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { + return F_status_set_error(F_output); + } - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { + return F_status_set_error(F_output); + } - return status; - } + if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { + return F_status_set_error(F_output); + } - if (status == F_false) break; - } // for + i = length; + status = F_none; + break; + } - for (; i < length; ++i) { + if (!string[i]) { + if (!fputc_unlocked(f_print_sequence_null_s[0], output)) { + return F_status_set_error(F_output); + } - status = f_utf_character_is_whitespace(string[i]); + if (!fputc_unlocked(f_print_sequence_null_s[1], output)) { + return F_status_set_error(F_output); + } - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } + if (!fputc_unlocked(f_print_sequence_null_s[2], output)) { + return F_status_set_error(F_output); + } - return status; - } + ++i; + continue; + } - if (status == F_true) { - j = i + 1; + status = f_utf_is_valid(string + i, length - i); - if (j == length) { - return F_none; - } + if (status == F_true) { + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } - for (; j < length; ++j) { + if (macro_f_utf_byte_width(string[i]) > 1) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); + } - status = f_utf_character_is_whitespace(string[j]); + if (macro_f_utf_byte_width(string[i]) > 2) { + if (!fputc_unlocked(string[i + 2], output)) { + return F_status_set_error(F_output); + } - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); + if (macro_f_utf_byte_width(string[i]) > 3) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } + } + } } - - return status; } + else { + if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { + return F_status_set_error(F_output); + } - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for + if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { + return F_status_set_error(F_output); + } - break; + if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { + return F_status_set_error(F_output); + } } - } // for - if (status == F_true) break; - } + i += macro_f_utf_byte_width(string[i]); + } // while - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); + if (i >= length) break; } - } // for - - return F_none; - } -#endif // !defined(_di_fl_print_trim_utf_raw_) || !defined(_di_fl_print_trim_utf_dynamic_raw_) || !defined(_di_fl_print_trim_utf_dynamic_partial_raw_) - -#if !defined(_di_fl_print_trim_utf_safely_) || !defined(_di_fl_print_trim_utf_dynamic_safely_) || !defined(_di_fl_print_trim_utf_dynamic_partial_safely_) - f_status_t private_fl_print_trim_utf_safely(const f_utf_string_t string, const f_array_length_t length, FILE *output) { - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_status_t status = F_none; - - f_string_t s = 0; - for (; i < length; ++i) { - - status = f_utf_character_is_whitespace(string[i]); + status = f_utf_is_valid(string + i, length - i); if (F_status_is_error(status)) { if (F_status_set_fine(status) == F_maybe) { @@ -2210,83 +1623,57 @@ extern "C" { return status; } - if (status == F_false) break; - } // for + if (status == F_false || i + macro_f_utf_byte_width(string[i]) >= length) { + if (!fputc_unlocked(f_print_sequence_unknown_s[0], output)) { + return F_status_set_error(F_output); + } - for (; i < length; ++i) { + if (!fputc_unlocked(f_print_sequence_unknown_s[1], output)) { + return F_status_set_error(F_output); + } - status = f_utf_character_is_whitespace(string[i]); + if (!fputc_unlocked(f_print_sequence_unknown_s[2], output)) { + return F_status_set_error(F_output); + } - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); + if (status == F_false) { + i += macro_f_utf_byte_width(string[i]); + } + else { + i = length; } - return status; + continue; } - if (status == F_true) { - j = i + 1; + if (!fputc_unlocked(string[i], output)) { + return F_status_set_error(F_output); + } - if (j == length) { - return F_none; + if (macro_f_utf_byte_width(string[i]) > 1) { + if (!fputc_unlocked(string[i + 1], output)) { + return F_status_set_error(F_output); } - for (; j < length; ++j) { - - status = f_utf_character_is_whitespace(string[j]); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_maybe) { - return F_status_set_error(F_utf); - } - - return status; + if (macro_f_utf_byte_width(string[i]) > 2) { + if (!fputc_unlocked(string[i + 2], output)) { + return F_status_set_error(F_output); } - // all whitespaces found so far must be printed when a non-whitespace is found. - if (status == F_false) { - for (; i < j; ++i) { - - - /* @todo - s = f_print_character_safely_get(string[i]); // @todo: in addition to this, the width of the character at string[i] needs to be taken into consideration. - - if (s) { - // - status = F_false; - } - */ - - if (!string[i]) continue; - - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for - - break; + if (macro_f_utf_byte_width(string[i]) > 3) { + if (!fputc_unlocked(string[i + 3], output)) { + return F_status_set_error(F_output); + } } - } // for - - if (status == F_true) break; - } - - s = f_print_character_safely_get(string[i]); // @todo: in addition to this, the width of the character at string[i] needs to be taken into consideration. - - if (s) { - // - status = F_false; + } } - if (!fputc_unlocked(string[i], output)) { - return F_status_set_error(F_output); - } - } // for + i += macro_f_utf_byte_width(string[i]); + } // while return F_none; } -#endif // !defined(_di_fl_print_trim_utf_safely_) || !defined(_di_fl_print_trim_utf_dynamic_safely_) || !defined(_di_fl_print_trim_utf_dynamic_partial_safely_) +#endif // !defined(_di_fl_print_trim_safely_) || !defined(_di_fl_print_trim_dynamic_safely_) || !defined(_di_fl_print_trim_dynamic_partial_safely_) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_print/c/private-print.h b/level_1/fl_print/c/private-print.h index 38645b3..8a9ced0 100644 --- a/level_1/fl_print/c/private-print.h +++ b/level_1/fl_print/c/private-print.h @@ -23,18 +23,17 @@ extern "C" { * * @param current * The current character position within the string. - * @param ap - * The variable arguments list. * @param output * The file stream to output to, including standard streams such as stdout and stderr. + * @param ap + * The variable arguments list. * * @return * F_none on success. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * F_valid_not (with error bit) on invalid syntax (such as terminating the string on a single '%'). * * Success from: f_print_dynamic(). @@ -65,7 +64,7 @@ extern "C" { * @see private_fl_print_convert_number() */ #if !defined(_di_fl_print_string_convert_) || !defined(_di_fl_print_string_) - extern f_status_t private_fl_print_string_convert(char *current, va_list *ap, FILE *output) f_attribute_visibility_internal; + extern f_status_t private_fl_print_string_convert(char *current, FILE *output, va_list *ap) f_attribute_visibility_internal; #endif // !defined(_di_fl_print_string_convert_) || !defined(_di_fl_print_string_) /** @@ -97,10 +96,8 @@ extern "C" { * * @param string * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. + * @param length + * The total number of characters to print. * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -114,11 +111,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -131,7 +129,7 @@ extern "C" { * @see fl_print_trim_except_in_dynamic_partial() */ #if !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_) || !defined(_di_fl_print_trim_except_in_) || !defined(_di_fl_print_trim_except_in_dynamic_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_) - extern f_status_t private_fl_print_trim_except_in(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; + extern f_status_t private_fl_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; #endif // !defined(_di_fl_print_trim_except_) || !defined(_di_fl_print_trim_except_dynamic_) || !defined(_di_fl_print_trim_except_dynamic_partial_) || !defined(_di_fl_print_trim_except_in_) || !defined(_di_fl_print_trim_except_in_dynamic_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_) /** @@ -141,10 +139,8 @@ extern "C" { * * @param string * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. + * @param length + * The total number of characters to print. * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -158,10 +154,9 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * * Errors (with error bit) from: f_utf_is_whitespace(). * @@ -175,7 +170,7 @@ extern "C" { * @see fl_print_trim_except_in_dynamic_partial_raw() */ #if !defined(_di_fl_print_trim_except_raw_) || !defined(_di_fl_print_trim_except_dynamic_raw_) || !defined(_di_fl_print_trim_except_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_in_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_raw_) - extern f_status_t private_fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; + extern f_status_t private_fl_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; #endif // !defined(_di_fl_print_trim_except_raw_) || !defined(_di_fl_print_trim_except_dynamic_raw_) || !defined(_di_fl_print_trim_except_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_in_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_raw_) /** @@ -185,10 +180,8 @@ extern "C" { * * @param string * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. + * @param length + * The total number of characters to print. * @param except_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -202,11 +195,11 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -219,133 +212,10 @@ extern "C" { * @see fl_print_trim_except_in_dynamic_partial_safely() */ #if !defined(_di_fl_print_trim_except_safely_) || !defined(_di_fl_print_trim_except_dynamic_safely_) || !defined(_di_fl_print_trim_except_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_in_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_safely_) - extern f_status_t private_fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; + extern f_status_t private_fl_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; #endif // !defined(_di_fl_print_trim_except_safely_) || !defined(_di_fl_print_trim_except_dynamic_safely_) || !defined(_di_fl_print_trim_except_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_in_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_dynamic_partial_safely_) /** - * Private implementation of fl_print_trim_except_utf(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. - * @param except - * An array of locations within the given string to not print. - * The array of locations is required/assumed to be in linear order. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_except_in_utf() - * @see fl_print_trim_except_in_utf_dynamic() - * @see fl_print_trim_except_in_utf_dynamic_partial() - * @see fl_print_trim_except_utf() - * @see fl_print_trim_except_utf_dynamic() - * @see fl_print_trim_except_utf_dynamic_partial() - */ -#if !defined(_di_fl_print_trim_except_in_utf_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_) || !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_) - extern f_status_t private_fl_print_trim_except_in_utf(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_except_in_utf_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_) || !defined(_di_fl_print_trim_except_utf_) || !defined(_di_fl_print_trim_except_utf_dynamic_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_) - -/** - * Private implementation of fl_print_trim_except_utf_raw(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. - * @param except - * An array of locations within the given string to not print. - * The array of locations is required/assumed to be in linear order. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_except_in_utf_raw() - * @see fl_print_trim_except_in_utf_dynamic_raw() - * @see fl_print_trim_except_in_utf_dynamic_partial_raw() - * @see fl_print_trim_except_utf_raw() - * @see fl_print_trim_except_utf_dynamic_raw() - * @see fl_print_trim_except_utf_dynamic_partial_raw() - */ -#if !defined(_di_fl_print_trim_except_in_utf_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_utf_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_raw_) - extern f_status_t private_fl_print_trim_except_in_utf_raw(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_except_in_utf_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_raw_) || !defined(_di_fl_print_trim_except_utf_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_raw_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_raw_) - -/** - * Private implementation of fl_print_trim_except_utf_safely(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param offset - * The inclusive start point to start printing. - * @param stop - * The exclusive stop point to stop printing. - * @param except - * An array of locations within the given string to not print. - * The array of locations is required/assumed to be in linear order. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_except_in_utf_safely() - * @see fl_print_trim_except_in_utf_dynamic_safely() - * @see fl_print_trim_except_in_utf_dynamic_partial_safely() - * @see fl_print_trim_except_utf_safely() - * @see fl_print_trim_except_utf_dynamic_safely() - * @see fl_print_trim_except_utf_dynamic_partial_safely() - */ -#if !defined(_di_fl_print_trim_except_in_utf_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_utf_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_safely_) - extern f_status_t private_fl_print_trim_except_in_utf_safely(const f_utf_string_t string, const f_array_length_t start, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_except_in_utf_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_in_utf_dynamic_partial_safely_) || !defined(_di_fl_print_trim_except_utf_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_safely_) || !defined(_di_fl_print_trim_except_utf_dynamic_partial_safely_) - -/** * Private implementation of fl_print_trim(). * * Intended to be shared to each of the different implementation variations. @@ -361,11 +231,12 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_complete_not_utf_stop (with error bit) if character is an incomplete UTF-8 fragment at end of the string. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -394,10 +265,9 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * * Errors (with error bit) from: f_utf_is_whitespace(). * @@ -427,11 +297,11 @@ extern "C" { * F_none on success. * F_data_not on success but there is nothing to print. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_output (with error bit) on failure to print to the output file. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_not (with error bit) if character is an invalid UTF-8 character. * + * Errors (with error bit) from: f_utf_is_valid() * Errors (with error bit) from: f_utf_is_whitespace(). * * @see fputc_unlocked() @@ -444,105 +314,6 @@ extern "C" { extern f_status_t private_fl_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output) f_attribute_visibility_internal; #endif // !defined(_di_fl_print_trim_safely_) || !defined(_di_fl_print_trim_dynamic_safely_) || !defined(_di_fl_print_trim_dynamic_partial_safely_) -/** - * Private implementation of fl_print_trim_utf(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param length - * The total number of characters to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_utf() - * @see fl_print_trim_utf_dynamic() - * @see fl_print_trim_utf_dynamic_partial() - */ -#if !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_) - extern f_status_t private_fl_print_trim_utf(const f_utf_string_t string, const f_array_length_t length, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_utf_) || !defined(_di_fl_print_trim_utf_dynamic_) || !defined(_di_fl_print_trim_utf_dynamic_partial_) - -/** - * Private implementation of fl_print_trim_utf_raw(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param length - * The total number of characters to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_utf_raw() - * @see fl_print_trim_utf_dynamic_raw() - * @see fl_print_trim_utf_dynamic_partial_raw() - */ -#if !defined(_di_fl_print_trim_utf_raw_) || !defined(_di_fl_print_trim_utf_dynamic_raw_) || !defined(_di_fl_print_trim_utf_dynamic_partial_raw_) - extern f_status_t private_fl_print_trim_utf_raw(const f_utf_string_t string, const f_array_length_t length, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_utf_raw_) || !defined(_di_fl_print_trim_utf_dynamic_raw_) || !defined(_di_fl_print_trim_utf_dynamic_partial_raw_) - -/** - * Private implementation of fl_print_trim_utf_safely(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param string - * The string to output. - * @param length - * The total number of characters to print. - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. - * - * @return - * F_none on success. - * F_data_not on success but there is nothing to print. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_output (with error bit) on failure to print to the output file. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. - * - * Errors (with error bit) from: f_utf_character_is_whitespace(). - * - * @see fputc_unlocked() - * - * @see fl_print_trim_utf_safely() - * @see fl_print_trim_utf_dynamic_safely() - * @see fl_print_trim_utf_dynamic_partial_safely() - */ -#if !defined(_di_fl_print_trim_utf_safely_) || !defined(_di_fl_print_trim_utf_dynamic_safely_) || !defined(_di_fl_print_trim_utf_dynamic_partial_safely_) - extern f_status_t private_fl_print_trim_utf_safely(const f_utf_string_t string, const f_array_length_t length, FILE *output) f_attribute_visibility_internal; -#endif // !defined(_di_fl_print_trim_utf_safely_) || !defined(_di_fl_print_trim_utf_dynamic_safely_) || !defined(_di_fl_print_trim_utf_dynamic_partial_safely_) - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_2/fll_print/c/print.c b/level_2/fll_print/c/print.c index bab5909..b9092d3 100644 --- a/level_2/fll_print/c/print.c +++ b/level_2/fll_print/c/print.c @@ -395,15 +395,15 @@ extern "C" { #endif // _di_fll_print_safely_terminated_ #ifndef _di_fll_print_string_ - f_status_t fll_print_string(FILE *output, const f_string_t string, ...) { + f_status_t fll_print_string(const f_string_t string, FILE *output, ...) { flockfile(output); va_list ap; - va_start(ap, string); + va_start(ap, output); - const f_status_t status = fl_print_string_va(output, string, ap); + const f_status_t status = fl_print_string_va(string, output, &ap); va_end(ap); @@ -412,11 +412,11 @@ extern "C" { #endif // _di_fll_print_string_ #ifndef _di_fll_print_string_convert_ - f_status_t fll_print_string_convert(FILE *output, char *current, va_list *ap) { + f_status_t fll_print_string_convert(char *current, FILE *output, va_list *ap) { flockfile(output); - const f_status_t status = fl_print_string_convert(output, current, ap); + const f_status_t status = fl_print_string_convert(current, output, ap); funlockfile(output); @@ -425,11 +425,11 @@ extern "C" { #endif // _di_fll_print_string_convert_ #ifndef _di_fll_print_string_va_ - f_status_t fll_print_string_va(FILE *output, const f_string_t string, va_list ap) { + f_status_t fll_print_string_va(const f_string_t string, FILE *output, va_list *ap) { flockfile(output); - const f_status_t status = fl_print_string_va(output, string, ap); + const f_status_t status = fl_print_string_va(string, output, ap); funlockfile(output); @@ -450,6 +450,344 @@ extern "C" { } #endif // _di_fll_print_terminated_ +#ifndef _di_fll_print_trim_raw_ + f_status_t fll_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_raw(string, length, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_raw_ + +#ifndef _di_fll_print_trim_safely_ + f_status_t fll_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_safely(string, length, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_safely_ + +#ifndef _di_fll_print_trim_dynamic_ + f_status_t fll_print_trim_dynamic(const f_string_static_t buffer, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic(buffer, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_ + +#ifndef _di_fll_print_trim_dynamic_raw_ + f_status_t fll_print_trim_dynamic_raw(const f_string_static_t buffer, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic_raw(buffer, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_raw_ + +#ifndef _di_fll_print_trim_dynamic_safely_ + f_status_t fll_print_trim_dynamic_safely(const f_string_static_t buffer, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic_safely(buffer, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_safely_ + +#ifndef _di_fll_print_trim_dynamic_partial_ + f_status_t fll_print_trim_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic_partial(buffer, range, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_partial_ + +#ifndef _di_fll_print_trim_dynamic_partial_raw_ + f_status_t fll_print_trim_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic_partial_raw(buffer, range, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_partial_raw_ + +#ifndef _di_fll_print_trim_dynamic_partial_safely_ + f_status_t fll_print_trim_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_dynamic_partial_safely(buffer, range, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_dynamic_partial_safely_ + +#ifndef _di_fll_print_trim_except_ + f_status_t fll_print_trim_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except(string, length, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_ + +#ifndef _di_fll_print_trim_except_raw_ + f_status_t fll_print_trim_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_raw(string, length, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_raw_ + +#ifndef _di_fll_print_trim_except_safely_ + f_status_t fll_print_trim_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_safely(string, length, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_safely_ + +#ifndef _di_fll_print_trim_except_dynamic_ + f_status_t fll_print_trim_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic(buffer, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_ + +#ifndef _di_fll_print_trim_except_dynamic_raw_ + f_status_t fll_print_trim_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic_raw(buffer, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_raw_ + +#ifndef _di_fll_print_trim_except_dynamic_safely_ + f_status_t fll_print_trim_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic_safely(buffer, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_safely_ + +#ifndef _di_fll_print_trim_except_in_ + f_status_t fll_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in(string, length, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_ + +#ifndef _di_fll_print_trim_except_in_raw_ + f_status_t fll_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_raw(string, length, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_raw_ + +#ifndef _di_fll_print_trim_except_in_safely_ + f_status_t fll_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_safely(string, length, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_safely_ + +#ifndef _di_fll_print_trim_except_in_dynamic_ + f_status_t fll_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic(buffer, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_ + +#ifndef _di_fll_print_trim_except_in_dynamic_raw_ + f_status_t fll_print_trim_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic_raw(buffer, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_raw_ + +#ifndef _di_fll_print_trim_except_in_dynamic_safely_ + f_status_t fll_print_trim_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic_safely(buffer, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_safely_ + +#ifndef _di_fll_print_trim_except_in_dynamic_partial_ + f_status_t fll_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic_partial(buffer, range, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_partial_ + +#ifndef _di_fll_print_trim_except_in_dynamic_partial_raw_ + f_status_t fll_print_trim_except_in_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic_partial_raw(buffer, range, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_partial_raw_ + +#ifndef _di_fll_print_trim_except_in_dynamic_partial_safely_ + f_status_t fll_print_trim_except_in_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_in_dynamic_partial_safely(buffer, range, except_at, except_in, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_in_dynamic_partial_safely_ + +#ifndef _di_fll_print_trim_except_dynamic_partial_ + f_status_t fll_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic_partial(buffer, range, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_partial_ + +#ifndef _di_fll_print_trim_except_dynamic_partial_raw_ + f_status_t fll_print_trim_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic_partial_raw(buffer, range, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_partial_raw_ + +#ifndef _di_fll_print_trim_except_dynamic_partial_safely_ + f_status_t fll_print_trim_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output) { + + flockfile(output); + + const f_status_t status = fl_print_trim_except_dynamic_partial_safely(buffer, range, except, output); + + funlockfile(output); + + return status; + } +#endif // _di_fll_print_trim_except_dynamic_partial_safely_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_2/fll_print/c/print.h b/level_2/fll_print/c/print.h index bc33f4c..d1f0170 100644 --- a/level_2/fll_print/c/print.h +++ b/level_2/fll_print/c/print.h @@ -865,11 +865,11 @@ extern "C" { /** * This is a variation of fl_print_string() that uses locking. * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param string * The formatted string to process and output. * This is a NULL terminated string. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ... * Additional arguments relating to the string. * @@ -886,16 +886,16 @@ extern "C" { * @see fl_print_string() */ #ifndef _di_fll_print_string_ - extern f_status_t fll_print_string(FILE *output, const f_string_t string, ...); + extern f_status_t fll_print_string(const f_string_t string, FILE *output, ...); #endif // _di_fll_print_string_ /** * This is a variation of fl_print_string_convert() that uses locking. * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param current * The current character position within the string. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ap * The variable arguments list. * @@ -910,16 +910,16 @@ extern "C" { * @see fl_print_string_convert() */ #ifndef _di_fll_print_string_convert_ - extern f_status_t fll_print_string_convert(FILE *output, char *current, va_list *ap); + extern f_status_t fll_print_string_convert(char *current, FILE *output, va_list *ap); #endif // _di_fll_print_string_convert_ /** * This is a variation of fl_print_string_va() that uses locking. * - * @param output - * The file stream to output to, including standard streams such as stdout and stderr. * @param string * The formatted string to process and output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * @param ap * The variable list. * The va_start(ap, string) and va_end(ap) is required to be called outside this function. @@ -935,7 +935,7 @@ extern "C" { * @see fl_print_string_va() */ #ifndef _di_fll_print_string_va_ - extern f_status_t fll_print_string_va(FILE *output, const f_string_t string, va_list ap); + extern f_status_t fll_print_string_va(const f_string_t string, FILE *output, va_list *ap); #endif // _di_fll_print_string_va_ /** @@ -960,6 +960,717 @@ extern "C" { extern f_status_t fll_print_terminated(const f_string_t string, FILE *output); #endif // _di_fll_print_terminated_ +/** + * This is a variation of fl_print_trim() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim(). + * + * Errors (with error bit) from: fl_print_trim(). + * + * @see flockfile() + * @see funlockfile() + * + * @see f_print_except_dynamic_partial() + */ +#ifndef _di_fll_print_trim_ + extern f_status_t fll_print_trim(const f_string_t string, const f_array_length_t length, FILE *output); +#endif // _di_fll_print_trim_ + +/** + * This is a variation of fl_print_trim_raw() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_raw(). + * + * Errors (with error bit) from: fl_print_trim_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_raw() + */ +#ifndef _di_fll_print_trim_raw_ + extern f_status_t fll_print_trim_raw(const f_string_t string, const f_array_length_t length, FILE *output); +#endif // _di_fll_print_trim_raw_ + +/** + * This is a variation of fl_print_trim_safely() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_safely(). + * + * Errors (with error bit) from: fl_print_trim_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_safely() + */ +#ifndef _di_fll_print_trim_safely_ + extern f_status_t fll_print_trim_safely(const f_string_t string, const f_array_length_t length, FILE *output); +#endif // _di_fll_print_trim_safely_ + +/** + * This is a variation of fl_print_trim_dynamic() that uses locking. + * + * @param buffer + * The string to output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_dynamic(). + * + * Errors (with error bit) from: fl_print_trim_dynamic(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_dynamic() + */ +#ifndef _di_fll_print_trim_dynamic_ + extern f_status_t fll_print_trim_dynamic(const f_string_static_t buffer, FILE *output); +#endif // _di_fll_print_trim_dynamic_ + +/** + * This is a variation of fl_print_trim_dynamic_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_dynamic_raw(). + * + * Errors (with error bit) from: fl_print_trim_dynamic_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_dynamic_raw() + */ +#ifndef _di_fll_print_trim_dynamic_raw_ + extern f_status_t fll_print_trim_dynamic_raw(const f_string_static_t buffer, FILE *output); +#endif // _di_fll_print_trim_dynamic_raw_ + +/** + * This is a variation of fl_print_trim_dynamic_safely() that uses locking. + * + * @param buffer + * The string to output. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_dynamic_safely(). + * + * Errors (with error bit) from: fl_print_trim_dynamic_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_dynamic_safely() + */ +#ifndef _di_fll_print_trim_dynamic_safely_ + extern f_status_t fll_print_trim_dynamic_safely(const f_string_static_t buffer, FILE *output); +#endif // _di_fll_print_trim_dynamic_safely_ + +/** + * This is a variation of fl_print_trim_dynamic_partial() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_dynamic_partial(). + * + * Errors (with error bit) from: fl_print_trim_dynamic_partial(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_dynamic_partial() + */ +#ifndef _di_fll_print_trim_dynamic_partial_ + extern f_status_t fll_print_trim_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_fll_print_trim_dynamic_partial_ + +/** + * This is a variation of fl_print_trim_dynamic_partial_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_dynamic_partial_raw(). + * + * Errors (with error bit) from: fl_print_trim_dynamic_partial_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_dynamic_partial_raw() + */ +#ifndef _di_fll_print_trim_dynamic_partial_raw_ + extern f_status_t fll_print_trim_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_fll_print_trim_dynamic_partial_raw_ + +/** + * This is a variation of f_print_except_dynamic_partial() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: f_print_except_dynamic_partial(). + * + * Errors (with error bit) from: f_print_except_dynamic_partial(). + * + * @see flockfile() + * @see funlockfile() + * + * @see f_print_except_dynamic_partial() + */ +#ifndef _di_fll_print_trim_dynamic_partial_safely_ + extern f_status_t fll_print_trim_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_fll_print_trim_dynamic_partial_safely_ + +/** + * This is a variation of fl_print_trim_except() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except(). + * + * Errors (with error bit) from: fl_print_trim_except(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except() + */ +#ifndef _di_fll_print_trim_except_ + extern f_status_t fll_print_trim_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_ + +/** + * This is a variation of fl_print_trim_except_raw() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_raw() + */ +#ifndef _di_fll_print_trim_except_raw_ + extern f_status_t fll_print_trim_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_raw_ + +/** + * This is a variation of fl_print_trim_except_safely() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_safely() + */ +#ifndef _di_fll_print_trim_except_safely_ + extern f_status_t fll_print_trim_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_safely_ + +/** + * This is a variation of fl_print_trim_except_dynamic() that uses locking. + * + * @param buffer + * The string to output. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic() + */ +#ifndef _di_fll_print_trim_except_dynamic_ + extern f_status_t fll_print_trim_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_ + +/** + * This is a variation of fl_print_trim_except_dynamic_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic_raw() + */ +#ifndef _di_fll_print_trim_except_dynamic_raw_ + extern f_status_t fll_print_trim_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_raw_ + +/** + * This is a variation of fl_print_trim_except_dynamic_safely() that uses locking. + * + * @param buffer + * The string to output. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic_safely() + */ +#ifndef _di_fll_print_trim_except_dynamic_safely_ + extern f_status_t fll_print_trim_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_safely_ + +/** + * This is a variation of fl_print_trim_except_in() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in(). + * + * Errors (with error bit) from: fl_print_trim_except_in(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in() + */ +#ifndef _di_fll_print_trim_except_in_ + extern f_status_t fll_print_trim_except_in(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_ + +/** + * This is a variation of fl_print_trim_except_in_raw() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_in_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_raw() + */ +#ifndef _di_fll_print_trim_except_in_raw_ + extern f_status_t fll_print_trim_except_in_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_raw_ + +/** + * This is a variation of fl_print_trim_except_in_safely() that uses locking. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_in_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_safely() + */ +#ifndef _di_fll_print_trim_except_in_safely_ + extern f_status_t fll_print_trim_except_in_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_safely_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic() that uses locking. + * + * @param buffer + * The string to output. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_dynamic() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_ + extern f_status_t fll_print_trim_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_dynamic_raw() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_raw_ + extern f_status_t fll_print_trim_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_raw_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic_safely() that uses locking. + * + * @param buffer + * The string to output. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_dynamic_safely() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_safely_ + extern f_status_t fll_print_trim_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_safely_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic_partial() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic_partial(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic_partial(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_in_dynamic_partial() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_partial_ + extern f_status_t fll_print_trim_except_in_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_partial_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic_partial_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic_partial_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic_partial_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see f_print_except_dynamic_partial() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_partial_raw_ + extern f_status_t fll_print_trim_except_in_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_partial_raw_ + +/** + * This is a variation of fl_print_trim_except_in_dynamic_partial_safely() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except_at + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param except_in + * An array of ranges within the string to not print. + * The array of ranges is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_in_dynamic_partial_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_in_dynamic_partial_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see f_print_except_dynamic_partial() + */ +#ifndef _di_fll_print_trim_except_in_dynamic_partial_safely_ + extern f_status_t fll_print_trim_except_in_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_fll_print_trim_except_in_dynamic_partial_safely_ + +/** + * This is a variation of fl_print_trim_except_dynamic_partial() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic_partial(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic_partial(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic_partial() + */ +#ifndef _di_fll_print_trim_except_dynamic_partial_ + extern f_status_t fll_print_trim_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_partial_ + +/** + * This is a variation of fl_print_trim_except_dynamic_partial_raw() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic_partial_raw(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic_partial_raw(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic_partial_raw() + */ +#ifndef _di_fll_print_trim_except_dynamic_partial_raw_ + extern f_status_t fll_print_trim_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_partial_raw_ + +/** + * This is a variation of fl_print_trim_except_dynamic_partial_safely() that uses locking. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param except + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. + * + * @return + * Success from: fl_print_trim_except_dynamic_partial_safely(). + * + * Errors (with error bit) from: fl_print_trim_except_dynamic_partial_safely(). + * + * @see flockfile() + * @see funlockfile() + * + * @see fl_print_trim_except_dynamic_partial_safely() + */ +#ifndef _di_fll_print_trim_except_dynamic_partial_safely_ + extern f_status_t fll_print_trim_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, FILE *output); +#endif // _di_fll_print_trim_except_dynamic_partial_safely_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_2/fll_program/c/program.c b/level_2/fll_program/c/program.c index 1df8eab..8861940 100644 --- a/level_2/fll_program/c/program.c +++ b/level_2/fll_program/c/program.c @@ -5,93 +5,80 @@ extern "C" { #endif #ifndef _di_fll_program_print_help_header_ - f_status_t fll_program_print_help_header(const f_file_t file, const f_color_context_t context, const f_string_t name, const f_string_t version) { + f_status_t fll_program_print_help_header(const f_file_t output, const f_color_context_t context, const f_string_t name, const f_string_t version) { - fprintf(file.stream, "%c", f_string_eol_s[0]); - f_color_print(file.stream, context.set.title, " %s", name); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %q%s%q%c", output.stream, *context.set.title.before, name, *context.set.title.after, f_string_eol_s[0]); + fl_print_string(" %qVersion %s%q%c", output.stream, *context.set.notable.before, version, *context.set.notable.after, f_string_eol_s[0]); - fprintf(file.stream, "%c", f_string_eol_s[0]); - f_color_print(file.stream, context.set.notable, " Version %s", version); - - fprintf(file.stream, "%c%c", f_string_eol_s[0], f_string_eol_s[0]); - f_color_print(file.stream, context.set.important, " Available Options: "); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %qAvailable Options:%q ", output.stream, *context.set.important.before, *context.set.important.after); return F_none; } #endif // _di_fll_program_print_help_header_ #ifndef _di_fll_program_print_help_option_ - f_status_t fll_program_print_help_option(const f_file_t file, const f_color_context_t context, const f_string_t option_short, const f_string_t option_long, const f_string_t symbol_short, const f_string_t symbol_long, const f_string_t description) { - - fprintf(file.stream, "%c %s", f_string_eol_s[0], symbol_short); - f_color_print(file.stream, context.set.standout, option_short); + f_status_t fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_t option_short, const f_string_t option_long, const f_string_t symbol_short, const f_string_t symbol_long, const f_string_t description) { - fprintf(file.stream, ", %s", symbol_long); - f_color_print(file.stream, context.set.standout, option_long); - - fprintf(file.stream, " %s", description); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %s%q%s%q", output.stream, symbol_short, *context.set.standout.before, option_short, *context.set.standout.after); + fl_print_string(", %s%q%s%q", output.stream, symbol_long, *context.set.standout.before, option_long, *context.set.standout.after); + fl_print_string(" %S", output.stream, description); return F_none; } #endif // _di_fll_program_print_help_option_ #ifndef _di_fll_program_print_help_option_long_ - f_status_t fll_program_print_help_option_long(const f_file_t file, const f_color_context_t context, const f_string_t option_long, const f_string_t symbol_long, const f_string_t description) { - - fprintf(file.stream, "%c %s", f_string_eol_s[0], symbol_long); - f_color_print(file.stream, context.set.standout, option_long); + f_status_t fll_program_print_help_option_long(const f_file_t output, const f_color_context_t context, const f_string_t option_long, const f_string_t symbol_long, const f_string_t description) { - fprintf(file.stream, " %s", description); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %s%q%s%q", output.stream, symbol_long, *context.set.standout.before, option_long, *context.set.standout.after); + fl_print_string(" %S", output.stream, description); return F_none; } #endif // _di_fll_program_print_help_option_long_ #ifndef _di_fll_program_print_help_option_other_ - f_status_t fll_program_print_help_option_other(const f_file_t file, const f_color_context_t context, const f_string_t option_other, const f_string_t description) { + f_status_t fll_program_print_help_option_other(const f_file_t output, const f_color_context_t context, const f_string_t option_other, const f_string_t description) { - fprintf(file.stream, "%c ", f_string_eol_s[0]); - f_color_print(file.stream, context.set.standout, option_other); - - fprintf(file.stream, " %s", description); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %q%s%q", output.stream, *context.set.standout.before, option_other, *context.set.standout.after); + fl_print_string(" %S", output.stream, description); return F_none; } #endif // _di_fll_program_print_help_option_other_ #ifndef _di_fll_program_print_help_usage_ - f_status_t fll_program_print_help_usage(const f_file_t file, const f_color_context_t context, const f_string_t name, const f_string_t parameters) { - - fprintf(file.stream, "%c%c", f_string_eol_s[0], f_string_eol_s[0]); - f_color_print(file.stream, context.set.important, " Usage:"); + f_status_t fll_program_print_help_usage(const f_file_t output, const f_color_context_t context, const f_string_t name, const f_string_t parameters) { - fprintf(file.stream, "%c ", f_string_eol_s[0]); - f_color_print(file.stream, context.set.standout, name); + f_print_terminated(f_string_eol_s, output.stream); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %qUsage:%q", output.stream, *context.set.important.before, *context.set.important.after); - fprintf(file.stream, "%s", f_string_space_s); - f_color_print(file.stream, context.set.notable, "["); + f_print_terminated(f_string_eol_s, output.stream); + fl_print_string(" %q%S%q", output.stream, *context.set.standout.before, name, *context.set.standout.after); - fprintf(file.stream, " options "); - f_color_print(file.stream, context.set.notable, "]"); + fl_print_string(" %q[%q options %q]%q", output.stream, *context.set.notable.before, *context.set.notable.after, *context.set.notable.before, *context.set.notable.after); if (parameters[0] != '\0') { - fprintf(file.stream, "%s", f_string_space_s); - f_color_print(file.stream, context.set.notable, "["); - - fprintf(file.stream, " %s ", parameters); - f_color_print(file.stream, context.set.notable, "]"); + fl_print_string(" %q[%q%S%q]%q", output.stream, *context.set.notable.before, *context.set.notable.after, parameters, *context.set.notable.before, *context.set.notable.after); } - fprintf(file.stream, "%c%c", f_string_eol_s[0], f_string_eol_s[0]); + f_print_terminated(f_string_eol_s, output.stream); + f_print_terminated(f_string_eol_s, output.stream); return F_none; } #endif // _di_fll_program_print_help_usage_ #ifndef _di_fll_program_print_version_ - f_status_t fll_program_print_version(const f_file_t file, const f_string_t version) { + f_status_t fll_program_print_version(const f_file_t output, const f_string_t version) { - fprintf(file.stream, "%s%c", version, f_string_eol_s[0]); + fl_print_string("%S%c", output.stream, version, f_string_eol_s[0]); return F_none; } diff --git a/level_2/fll_program/c/program.h b/level_2/fll_program/c/program.h index d0d0b2e..4805eba 100644 --- a/level_2/fll_program/c/program.h +++ b/level_2/fll_program/c/program.h @@ -22,9 +22,11 @@ #include #include #include +#include // fll-1 includes #include +#include #ifdef __cplusplus extern "C" { @@ -33,8 +35,10 @@ extern "C" { /** * Print standard help header. * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param context * The color context. * @param name @@ -45,19 +49,20 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: f_color_print(). - * - * @param f_color_print() + * @see f_print_terminated() + * @see fl_print_string() */ #ifndef _di_fll_program_print_help_header_ - extern f_status_t fll_program_print_help_header(const f_file_t file, const f_color_context_t context, const f_string_t name, const f_string_t version); + extern f_status_t fll_program_print_help_header(const f_file_t output, const f_color_context_t context, const f_string_t name, const f_string_t version); #endif // _di_fll_program_print_help_header_ /** * Print standard help option. * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param context * The color context. * @param option_short @@ -74,19 +79,20 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: f_color_print(). - * - * @param f_color_print() + * @see f_print_terminated() + * @see fl_print_string() */ #ifndef _di_fll_program_print_help_option_ - extern f_status_t fll_program_print_help_option(const f_file_t file, const f_color_context_t context, const f_string_t option_short, const f_string_t option_long, const f_string_t symbol_short, const f_string_t symbol_long, const f_string_t description); + extern f_status_t fll_program_print_help_option(const f_file_t output, const f_color_context_t context, const f_string_t option_short, const f_string_t option_long, const f_string_t symbol_short, const f_string_t symbol_long, const f_string_t description); #endif // _di_fll_program_print_help_option_ /** * Print standard help option (long option only). * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param context * The color context. * @param option_long @@ -99,19 +105,20 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: f_color_print(). - * - * @param f_color_print() + * @see f_print_terminated() + * @see fl_print_string() */ #ifndef _di_fll_program_print_help_option_long_ - extern f_status_t fll_program_print_help_option_long(const f_file_t file, const f_color_context_t context, const f_string_t option_long, const f_string_t symbol_long, const f_string_t description); + extern f_status_t fll_program_print_help_option_long(const f_file_t output, const f_color_context_t context, const f_string_t option_long, const f_string_t symbol_long, const f_string_t description); #endif // _di_fll_program_print_help_option_long_ /** * Print standard help option (other option only). * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param context * The color context. * @param option_other @@ -122,19 +129,20 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: f_color_print(). - * - * @param f_color_print() + * @see f_print_terminated() + * @see fl_print_string() */ #ifndef _di_fll_program_print_help_option_other_ - extern f_status_t fll_program_print_help_option_other(const f_file_t file, const f_color_context_t context, const f_string_t option_other, const f_string_t description); + extern f_status_t fll_program_print_help_option_other(const f_file_t output, const f_color_context_t context, const f_string_t option_other, const f_string_t description); #endif // _di_fll_program_print_help_option_other_ /** * Print standard help usage. * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param context * The color context. * @param name @@ -146,27 +154,30 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: f_color_print(). - * - * @param f_color_print() + * @see f_print_terminated() + * @see fl_print_string() */ #ifndef _di_fll_program_print_help_usage_ - extern f_status_t fll_program_print_help_usage(const f_file_t file, const f_color_context_t context, const f_string_t name, const f_string_t parameters); + extern f_status_t fll_program_print_help_usage(const f_file_t output, const f_color_context_t context, const f_string_t name, const f_string_t parameters); #endif // _di_fll_program_print_help_usage_ /** * Print the program version. * - * @param file - * The file to output to. + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param output + * The file stream to output to. * @param version * The version number of the program. * * @return * F_none on success. + * + * @see fl_print_string() */ #ifndef _di_fll_program_print_version_ - extern f_status_t fll_program_print_version(const f_file_t file, const f_string_t version); + extern f_status_t fll_program_print_version(const f_file_t output, const f_string_t version); #endif // _di_fll_program_print_version_ /** diff --git a/level_2/fll_program/data/build/dependencies b/level_2/fll_program/data/build/dependencies index 3b0c180..aacb4b0 100644 --- a/level_2/fll_program/data/build/dependencies +++ b/level_2/fll_program/data/build/dependencies @@ -8,4 +8,6 @@ f_utf f_color f_console f_file +f_print fl_string +fl_print diff --git a/level_2/fll_program/data/build/settings b/level_2/fll_program/data/build/settings index 76a20e4..4e31a67 100644 --- a/level_2/fll_program/data/build/settings +++ b/level_2/fll_program/data/build/settings @@ -20,7 +20,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -build_libraries-individual -lfl_string -lf_color -lf_console -lf_file -lf_memory -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_print -lf_string -lf_type_array -lf_utf build_sources_library program.c build_sources_program build_sources_headers program.h -- 1.8.3.1