From 6fb1fa00176bc43d2fb413e77357bddf006a9154 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 8 Nov 2021 20:26:17 -0600 Subject: [PATCH] Update: Fix print function bugs and add missing functions. There are some cases where the logic is flawed and fails to print correctly. Given a bash binary, passing it through the print functions and back to the disk in raw format resulted in a different binary. The binary should be identical to the original and is not. It seems that when I attempted to reduce the number of variables in the print function I failed to account for certain details. This essentially reverts some of the previous logic and puts back the variables. Many off these functions are almost identical but their differences result in requiring slightly different code. This makes the code less manageable and easy to get lost in. The code has been tweaked somewhat to be more consistent across the board, where possible. This might come at a cost of some slight performance. To make the code easier to read, separate the print functions into two groups: 1) The print functions that use file streams. 2) The print functions that use file descriptors. This code is slightly different and while I could use macros to make this simpler, I opted to avoid macros at the cost of duplication. Move these two groups into separate files, significantly improving code readability. There is a mistake in the previous code where errno is being processed for file stream errors. The libc file stream functions do not utilize errno. Change the affected code to just return F_output with the error bit set. I am unable to find a discrete list of error codes returned by ferror(). I will need to additional work to get these codes so I can properly map them to more verbose error codes. The documentation is no longer out of sync. There should be a file descriptor function equivalent for nearly every file stream function. In this regard, several missing functions are now added. This is an unplanned change that is rather large. I am concerned with oversights and regressions. Just keep an eye out for regressions and hope that there are none. --- build/level_0/settings | 4 +- build/monolithic/settings | 4 +- level_0/f_print/c/print.c | 628 +++++---------- level_0/f_print/c/print.h | 1111 +++++-------------------- level_0/f_print/c/print_to.c | 675 ++++++++++++++++ level_0/f_print/c/print_to.h | 1472 ++++++++++++++++++++++++++++++++++ level_0/f_print/c/private-print.c | 1210 +++++++++------------------- level_0/f_print/c/private-print.h | 490 +++-------- level_0/f_print/c/private-print_to.c | 711 ++++++++++++++++ level_0/f_print/c/private-print_to.h | 489 +++++++++++ level_0/f_print/data/build/settings | 4 +- 11 files changed, 4212 insertions(+), 2586 deletions(-) create mode 100644 level_0/f_print/c/print_to.c create mode 100644 level_0/f_print/c/print_to.h create mode 100644 level_0/f_print/c/private-print_to.c create mode 100644 level_0/f_print/c/private-print_to.h diff --git a/build/level_0/settings b/build/level_0/settings index 2f88c85..3690eeb 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -25,14 +25,14 @@ build_libraries-level build_libraries-level_threadless build_libraries_shared build_libraries_static -build_sources_library account.c private-account.c capability.c color.c color-common.c console.c console-common.c control_group.c control_group-common.c conversion.c conversion-common.c private-conversion.c directory.c private-directory.c environment.c private-environment.c execute.c file.c file-common.c private-file.c fss.c private-fss.c fss-common.c fss_named.c fss_nest.c fss_set.c iki.c iki-common.c private-iki.c limit.c memory.c memory_structure.c private-memory.c path.c path-common.c private-path.c pipe.c print.c print-common.c private-print.c serialize.c serialize-common.c private-serialize.c signal.c socket.c string.c string-common.c private-string.c string_dynamic.c string_map.c string_quantity.c string_range.c string_triple.c type_array.c private-type_array.c utf.c utf-common.c private-utf.c utf_dynamic.c utf_map.c utf_triple.c +build_sources_library account.c private-account.c capability.c color.c color-common.c console.c console-common.c control_group.c control_group-common.c conversion.c conversion-common.c private-conversion.c directory.c private-directory.c environment.c private-environment.c execute.c file.c file-common.c private-file.c fss.c private-fss.c fss-common.c fss_named.c fss_nest.c fss_set.c iki.c iki-common.c private-iki.c limit.c memory.c memory_structure.c private-memory.c path.c path-common.c private-path.c pipe.c print.c print_to.c print-common.c private-print.c private-print_to.c serialize.c serialize-common.c private-serialize.c signal.c socket.c string.c string-common.c private-string.c string_dynamic.c string_map.c string_quantity.c string_range.c string_triple.c type_array.c private-type_array.c utf.c utf-common.c private-utf.c utf_dynamic.c utf_map.c utf_triple.c build_sources_library-level thread.c private-thread.c build_sources_library_shared build_sources_library_static build_sources_program build_sources_program_shared build_sources_program_static -build_sources_headers account.h account-common.h capability.h capability-common.h color.h color-common.h console.h console-common.h control_group.h control_group-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h limit.h limit-common.h memory.h memory_structure.h memory-common.h path.h path-common.h pipe.h print.h print-common.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h type.h type_array.h type_array-common.h utf.h utf-common.h utf_dynamic.h utf_map.h utf_triple.h +build_sources_headers account.h account-common.h capability.h capability-common.h color.h color-common.h console.h console-common.h control_group.h control_group-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h execute.h execute-common.h file.h file-common.h fss.h fss-common.h fss_comment.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h limit.h limit-common.h memory.h memory_structure.h memory-common.h path.h path-common.h pipe.h print.h print_to.h print-common.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h string_triple.h type.h type_array.h type_array-common.h utf.h utf-common.h utf_dynamic.h utf_map.h utf_triple.h build_sources_headers-level thread.h thread-common.h build_sources_headers_shared build_sources_headers_static diff --git a/build/monolithic/settings b/build/monolithic/settings index 81b5724..73d48ea 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -25,14 +25,14 @@ build_libraries-monolithic build_libraries-monolithic_threadless build_libraries_shared build_libraries_static -build_sources_library level_0/account.c level_0/private-account.c level_0/capability.c level_0/color.c level_0/color-common.c level_0/console.c level_0/console-common.c level_0/control_group.c level_0/control_group-common.c level_0/conversion.c level_0/conversion-common.c level_0/private-conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/execute.c level_0/file.c level_0/file-common.c level_0/private-file.c level_0/fss.c level_0/private-fss.c level_0/fss-common.c level_0/fss_named.c level_0/fss_nest.c level_0/fss_set.c level_0/iki.c level_0/iki-common.c level_0/private-iki.c level_0/limit.c level_0/memory.c level_0/memory_structure.c level_0/private-memory.c level_0/path.c level_0/path-common.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/print-common.c level_0/private-print.c level_0/serialize.c level_0/serialize-common.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/string.c level_0/string-common.c level_0/private-string.c level_0/string_dynamic.c level_0/string_map.c level_0/string_quantity.c level_0/string_range.c level_0/string_triple.c level_0/type_array.c level_0/private-type_array.c level_0/utf.c level_0/utf-common.c level_0/private-utf.c level_0/utf_dynamic.c level_0/utf_map.c level_0/utf_triple.c level_1/console.c level_1/control_group.c level_1/conversion.c level_1/private-conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/print-common.c level_1/private-print.c level_1/signal.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/control_group.c level_2/error.c level_2/error-common.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/print.c level_2/program.c level_2/status.c +build_sources_library level_0/account.c level_0/private-account.c level_0/capability.c level_0/color.c level_0/color-common.c level_0/console.c level_0/console-common.c level_0/control_group.c level_0/control_group-common.c level_0/conversion.c level_0/conversion-common.c level_0/private-conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/execute.c level_0/file.c level_0/file-common.c level_0/private-file.c level_0/fss.c level_0/private-fss.c level_0/fss-common.c level_0/fss_named.c level_0/fss_nest.c level_0/fss_set.c level_0/iki.c level_0/iki-common.c level_0/private-iki.c level_0/limit.c level_0/memory.c level_0/memory_structure.c level_0/private-memory.c level_0/path.c level_0/path-common.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/print_to.c level_0/print-common.c level_0/private-print.c level_0/private-print_to.c level_0/serialize.c level_0/serialize-common.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/string.c level_0/string-common.c level_0/private-string.c level_0/string_dynamic.c level_0/string_map.c level_0/string_quantity.c level_0/string_range.c level_0/string_triple.c level_0/type_array.c level_0/private-type_array.c level_0/utf.c level_0/utf-common.c level_0/private-utf.c level_0/utf_dynamic.c level_0/utf_map.c level_0/utf_triple.c level_1/console.c level_1/control_group.c level_1/conversion.c level_1/private-conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_embedded_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/print-common.c level_1/private-print.c level_1/signal.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/control_group.c level_2/error.c level_2/error-common.c level_2/private-error.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_embedded_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/print.c level_2/program.c level_2/status.c build_sources_library-monolithic level_0/thread.c level_0/private-thread.c build_sources_library_shared build_sources_library_static build_sources_program build_sources_program_shared build_sources_program_static -build_sources_headers level_0/account.h level_0/account-common.h level_0/capability.h level_0/capability-common.h level_0/color.h level_0/color-common.h level_0/console.h level_0/console-common.h level_0/control_group.h level_0/control_group-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/limit.h level_0/limit-common.h level_0/memory.h level_0/memory_structure.h level_0/memory-common.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/print-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/type_array-common.h level_0/utf.h level_0/utf-common.h level_0/utf_dynamic.h level_0/utf_map.h level_0/utf_triple.h level_1/console.h level_1/control_group.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/print-common.h level_1/signal.h level_1/signal-common.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/control_group.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/print.h level_2/program.h level_2/status.h +build_sources_headers level_0/account.h level_0/account-common.h level_0/capability.h level_0/capability-common.h level_0/color.h level_0/color-common.h level_0/console.h level_0/console-common.h level_0/control_group.h level_0/control_group-common.h level_0/conversion.h level_0/conversion-common.h level_0/directory.h level_0/directory_type.h level_0/directory-common.h level_0/environment.h level_0/environment-common.h level_0/execute.h level_0/execute-common.h level_0/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.h level_0/fss_comment.h level_0/fss_delimit.h level_0/fss_named.h level_0/fss_nest.h level_0/fss_quote.h level_0/fss_set.h level_0/iki.h level_0/iki-common.h level_0/limit.h level_0/limit-common.h level_0/memory.h level_0/memory_structure.h level_0/memory-common.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.h level_0/print_to.h level_0/print-common.h level_0/serialize.h level_0/serialize-common.h level_0/signal.h level_0/signal-common.h level_0/socket.h level_0/socket-common.h level_0/status.h level_0/string.h level_0/string-common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/string_triple.h level_0/type.h level_0/type_array.h level_0/type_array-common.h level_0/utf.h level_0/utf-common.h level_0/utf_dynamic.h level_0/utf_map.h level_0/utf_triple.h level_1/console.h level_1/control_group.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/execute.h level_1/execute-common.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_embedded_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/print-common.h level_1/signal.h level_1/signal-common.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/control_group.h level_2/error.h level_2/error-common.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_embedded_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/print.h level_2/program.h level_2/status.h build_sources_headers-monolithic level_0/thread.h level_0/thread-common.h build_sources_headers_shared build_sources_headers_static diff --git a/level_0/f_print/c/print.c b/level_0/f_print/c/print.c index de7f9fe..53bec2c 100644 --- a/level_0/f_print/c/print.c +++ b/level_0/f_print/c/print.c @@ -25,18 +25,11 @@ extern "C" { if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (fwrite_unlocked(&character, 1, 1, output) != -1) { - return F_none; + if (fwrite_unlocked(&character, 1, 1, output) == -1) { + return F_status_set_error(F_output); } - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); + return F_none; } #endif // _di_f_print_character_ @@ -46,7 +39,28 @@ extern "C" { if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - return private_f_print_character_safely(character, output); + if (character == 0x7f) { + if (fwrite_unlocked(f_print_sequence_delete_s, 1, 3, output) != -1) { + return F_none; + } + } + else if (macro_f_utf_character_t_width_is(character) == 1) { + if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) != -1) { + return F_none; + } + } + else if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) { + if (fwrite_unlocked(&character, 1, 1, output) != -1) { + return F_none; + } + } + else { + if (fwrite_unlocked(f_print_sequence_set_control_s[character], 1, 3, output) != -1) { + return F_none; + } + } + + return F_status_set_error(F_output); } #endif // _di_f_print_character_safely_ @@ -70,34 +84,6 @@ extern "C" { } #endif // _di_f_print_dynamic_ -#ifndef _di_f_print_dynamic_raw_ - f_status_t f_print_dynamic_raw(const f_string_static_t buffer, FILE *output) { - #ifndef _di_level_0_parameter_checking_ - if (!output) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_raw(buffer.string, buffer.used, output); - } -#endif // _di_f_print_dynamic_raw_ - -#ifndef _di_f_print_dynamic_safely_ - f_status_t f_print_dynamic_safely(const f_string_static_t buffer, FILE *output) { - #ifndef _di_level_0_parameter_checking_ - if (!output) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_safely(buffer.string, buffer.used, output); - } -#endif // _di_f_print_dynamic_safely_ - #ifndef _di_f_print_dynamic_partial_ f_status_t f_print_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output) { #ifndef _di_level_0_parameter_checking_ @@ -158,47 +144,47 @@ extern "C" { } #endif // _di_f_print_dynamic_partial_safely_ -#ifndef _di_f_print_except_ - f_status_t f_print_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { +#ifndef _di_f_print_dynamic_raw_ + f_status_t f_print_dynamic_raw(const f_string_static_t buffer, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { + if (!buffer.string || !buffer.used) { return F_data_not; } - return private_f_print_except(string, offset, length, except, output); + return private_f_print_raw(buffer.string, buffer.used, output); } -#endif // _di_f_print_except_ +#endif // _di_f_print_dynamic_raw_ -#ifndef _di_f_print_except_raw_ - f_status_t f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { +#ifndef _di_f_print_dynamic_safely_ + f_status_t f_print_dynamic_safely(const f_string_static_t buffer, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { + if (!buffer.string || !buffer.used) { return F_data_not; } - return private_f_print_except_raw(string, offset, length, except, output); + return private_f_print_safely(buffer.string, buffer.used, output); } -#endif // _di_f_print_except_raw_ +#endif // _di_f_print_dynamic_safely_ -#ifndef _di_f_print_except_safely_ - f_status_t f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { +#ifndef _di_f_print_except_ + f_status_t f_print_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { + if (!string || !length) { return F_data_not; } - return private_f_print_except_safely(string, offset, length, except, output); + return private_f_print_except(string, offset, length, except, output); } -#endif // _di_f_print_except_safely_ +#endif // _di_f_print_except_ #ifndef _di_f_print_except_dynamic_ f_status_t f_print_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { @@ -212,107 +198,115 @@ extern "C" { } #endif // _di_f_print_except_dynamic_ -#ifndef _di_f_print_except_dynamic_raw_ - f_status_t f_print_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { +#ifndef _di_f_print_except_dynamic_partial_ + f_status_t f_print_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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!buffer.string || !buffer.used) return F_data_not; - - return private_f_print_except_raw(buffer.string, 0, buffer.used, except, output); - } -#endif // _di_f_print_except_dynamic_raw_ + if (!buffer.string || !buffer.used || range.start > range.stop || range.start >= buffer.used) { + return F_data_not; + } -#ifndef _di_f_print_except_dynamic_safely_ - f_status_t f_print_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { - #ifndef _di_level_0_parameter_checking_ - if (!output) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + f_array_length_t length = (range.stop - range.start) + 1; - if (!buffer.string || !buffer.used) return F_data_not; + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } - return private_f_print_except_safely(buffer.string, 0, buffer.used, except, output); + return private_f_print_except(buffer.string, range.start, range.start + length, except, output); } -#endif // _di_f_print_except_dynamic_safely_ +#endif // _di_f_print_except_dynamic_partial_ -#ifndef _di_f_print_except_in_ - f_status_t f_print_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_f_print_except_dynamic_partial_raw_ + f_status_t f_print_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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { + if (!buffer.string || !buffer.used || range.start > range.stop || range.start >= buffer.used) { return F_data_not; } - return private_f_print_except_in(string, offset, length, except_at, except_in, output); + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_f_print_except_raw(buffer.string, range.start, range.start + length, except, output); } -#endif // _di_f_print_except_in_ +#endif // _di_f_print_except_dynamic_partial_raw_ -#ifndef _di_f_print_except_in_raw_ - f_status_t f_print_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_f_print_except_dynamic_partial_safely_ + f_status_t f_print_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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { + if (!buffer.string || !buffer.used || range.start > range.stop || range.start >= buffer.used) { return F_data_not; } - return private_f_print_except_in_raw(string, offset, length, except_at, except_in, output); + f_array_length_t length = (range.stop - range.start) + 1; + + if (length + range.start > buffer.used) { + length = buffer.used - range.start; + } + + return private_f_print_except_safely(buffer.string, range.start, range.start + length, except, output); } -#endif // _di_f_print_except_in_raw_ +#endif // _di_f_print_except_dynamic_partial_safely_ -#ifndef _di_f_print_except_in_safely_ - f_status_t f_print_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { +#ifndef _di_f_print_except_dynamic_raw_ + f_status_t f_print_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!string || length == 0) { - return F_data_not; - } + if (!buffer.string || !buffer.used) return F_data_not; - return private_f_print_except_in_safely(string, offset, length, except_at, except_in, output); + return private_f_print_except_raw(buffer.string, 0, buffer.used, except, output); } -#endif // _di_f_print_except_in_safely_ +#endif // _di_f_print_except_dynamic_raw_ -#ifndef _di_f_print_except_in_dynamic_ - f_status_t f_print_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_f_print_except_dynamic_safely_ + f_status_t f_print_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ if (!buffer.string || !buffer.used) return F_data_not; - return private_f_print_except_in(buffer.string, 0, buffer.used, except_at, except_in, output); + return private_f_print_except_safely(buffer.string, 0, buffer.used, except, output); } -#endif // _di_f_print_except_in_dynamic_ +#endif // _di_f_print_except_dynamic_safely_ -#ifndef _di_f_print_except_in_dynamic_raw_ - f_status_t f_print_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_f_print_except_in_ + f_status_t f_print_except_in(const f_string_t string, const f_array_length_t offset, 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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!buffer.string || !buffer.used) return F_data_not; + if (!string || !length) { + return F_data_not; + } - return private_f_print_except_in_raw(buffer.string, 0, buffer.used, except_at, except_in, output); + return private_f_print_except_in(string, offset, length, except_at, except_in, output); } -#endif // _di_f_print_except_in_dynamic_raw_ +#endif // _di_f_print_except_in_ -#ifndef _di_f_print_except_in_dynamic_safely_ - f_status_t f_print_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_f_print_except_in_dynamic_ + f_status_t f_print_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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ if (!buffer.string || !buffer.used) return F_data_not; - return private_f_print_except_in_safely(buffer.string, 0, buffer.used, except_at, except_in, output); + return private_f_print_except_in(buffer.string, 0, buffer.used, except_at, except_in, output); } -#endif // _di_f_print_except_in_dynamic_safely_ +#endif // _di_f_print_except_in_dynamic_ #ifndef _di_f_print_except_in_dynamic_partial_ f_status_t f_print_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) { @@ -374,65 +368,85 @@ extern "C" { } #endif // _di_f_print_except_in_dynamic_partial_safely_ -#ifndef _di_f_print_except_dynamic_partial_ - f_status_t f_print_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_f_print_except_in_dynamic_raw_ + f_status_t f_print_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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!buffer.string || !buffer.used || range.start > range.stop || range.start >= buffer.used) { - return F_data_not; - } + if (!buffer.string || !buffer.used) return F_data_not; - f_array_length_t length = (range.stop - range.start) + 1; + return private_f_print_except_in_raw(buffer.string, 0, buffer.used, except_at, except_in, output); + } +#endif // _di_f_print_except_in_dynamic_raw_ - if (length + range.start > buffer.used) { - length = buffer.used - range.start; - } +#ifndef _di_f_print_except_in_dynamic_safely_ + f_status_t f_print_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_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ - return private_f_print_except(buffer.string, range.start, range.start + length, except, output); + if (!buffer.string || !buffer.used) return F_data_not; + + return private_f_print_except_in_safely(buffer.string, 0, buffer.used, except_at, except_in, output); } -#endif // _di_f_print_except_dynamic_partial_ +#endif // _di_f_print_except_in_dynamic_safely_ -#ifndef _di_f_print_except_dynamic_partial_raw_ - f_status_t f_print_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_f_print_except_in_raw_ + f_status_t f_print_except_in_raw(const f_string_t string, const f_array_length_t offset, 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_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!buffer.string || !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_f_print_except_in_raw(string, offset, length, except_at, except_in, output); + } +#endif // _di_f_print_except_in_raw_ - if (length + range.start > buffer.used) { - length = buffer.used - range.start; +#ifndef _di_f_print_except_in_safely_ + f_status_t f_print_except_in_safely(const f_string_t string, const f_array_length_t offset, 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_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; } - return private_f_print_except_raw(buffer.string, range.start, range.start + length, except, output); + return private_f_print_except_in_safely(string, offset, length, except_at, except_in, output); } -#endif // _di_f_print_except_dynamic_partial_raw_ +#endif // _di_f_print_except_in_safely_ -#ifndef _di_f_print_except_dynamic_partial_safely_ - f_status_t f_print_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_f_print_except_raw_ + f_status_t f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { #ifndef _di_level_0_parameter_checking_ if (!output) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!buffer.string || !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_f_print_except_raw(string, offset, length, except, output); + } +#endif // _di_f_print_except_raw_ - if (length + range.start > buffer.used) { - length = buffer.used - range.start; +#ifndef _di_f_print_except_safely_ + f_status_t f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output) { + #ifndef _di_level_0_parameter_checking_ + if (!output) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; } - return private_f_print_except_safely(buffer.string, range.start, range.start + length, except, output); + return private_f_print_except_safely(string, offset, length, except, output); } -#endif // _di_f_print_except_dynamic_partial_safely_ +#endif // _di_f_print_except_safely_ #ifndef _di_f_print_raw_ f_status_t f_print_raw(const f_string_t string, const f_array_length_t length, FILE *output) { @@ -492,6 +506,8 @@ extern "C" { f_array_length_t start = 0; f_array_length_t total = 0; + f_string_t safe = 0; + uint8_t width = 0; for (register f_array_length_t i = 0; string[i]; ) { @@ -551,13 +567,6 @@ extern "C" { if (total) { if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - return F_status_set_error(F_output); } @@ -566,33 +575,67 @@ extern "C" { if (status == F_true || F_status_set_fine(status) == F_utf) { if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) != -1) { - return F_none; + return F_status_set_error(F_output); } + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + i += width; } else if (status == F_false) { if (fwrite_unlocked(string + start, 1, width, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - return F_status_set_error(F_output); } + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + i += width; } else { - if (string[i]) { - status = private_f_print_character_safely(string[i++], output); - if (F_status_is_error(status)) return status; + safe = private_f_print_character_safely_get(string[i]); + + if (safe) { + if (fwrite_unlocked(safe, 1, 3, output) == -1) { + return F_status_set_error(F_output); + } } else { - ++i; + status = f_utf_is_valid(string + i, width); + + if (F_status_is_error(status) || status == F_false) { + if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { + return F_status_set_error(F_output); + } + + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + } + else { + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + + total = width; + start = i; + i += width; + continue; + } } + + i += width; } start = i; @@ -600,13 +643,6 @@ extern "C" { if (total) { if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - return F_status_set_error(F_output); } } @@ -629,294 +665,6 @@ extern "C" { } #endif // _di_f_print_terminated_ -#ifndef _di_f_print_to_ - f_status_t f_print_to(const f_string_t string, const f_array_length_t length, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to(string, length, id); - } -#endif // _di_f_print_to_ - -#ifndef _di_f_print_to_raw_ - f_status_t f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to_raw(string, length, id); - } -#endif // _di_f_print_to_raw_ - -#ifndef _di_f_print_to_safely_ - f_status_t f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to_safely(string, length, id); - } -#endif // _di_f_print_to_safely_ - -#ifndef _di_f_print_to_dynamic_ - f_status_t f_print_to_dynamic(const f_string_static_t buffer, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to(buffer.string, buffer.used, id); - } -#endif // _di_f_print_to_dynamic_ - -#ifndef _di_f_print_to_dynamic_raw_ - f_status_t f_print_to_dynamic_raw(const f_string_static_t buffer, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to_raw(buffer.string, buffer.used, id); - } -#endif // _di_f_print_to_dynamic_raw_ - -#ifndef _di_f_print_to_dynamic_safely_ - f_status_t f_print_to_dynamic_safely(const f_string_static_t buffer, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to_safely(buffer.string, buffer.used, id); - } -#endif // _di_f_print_to_dynamic_safely_ - -#ifndef _di_f_print_to_dynamic_partial_ - f_status_t f_print_to_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to(buffer.string + range.start, length, id); - } -#endif // _di_f_print_to_dynamic_partial_ - -#ifndef _di_f_print_to_dynamic_partial_raw_ - f_status_t f_print_to_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to_raw(buffer.string + range.start, length, id); - } -#endif // _di_f_print_to_dynamic_partial_raw_ - -#ifndef _di_f_print_to_dynamic_partial_safely_ - f_status_t f_print_to_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to_safely(buffer.string + range.start, length, id); - } -#endif // _di_f_print_to_dynamic_partial_safely_ - -#ifndef _di_f_print_to_except_ - f_status_t f_print_to_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to_except(string, 0, length, except, id); - } -#endif // _di_f_print_to_except_ - -#ifndef _di_f_print_to_except_raw_ - f_status_t f_print_to_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to_except_raw(string, 0, length, except, id); - } -#endif // _di_f_print_to_except_raw_ - -#ifndef _di_f_print_to_except_safely_ - f_status_t f_print_to_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!string || length == 0) { - return F_data_not; - } - - return private_f_print_to_except_safely(string, 0, length, except, id); - } -#endif // _di_f_print_to_except_safely_ - -#ifndef _di_f_print_to_except_dynamic_ - f_status_t f_print_to_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to_except(buffer.string, 0, buffer.used, except, id); - } -#endif // _di_f_print_to_except_dynamic_ - -#ifndef _di_f_print_to_except_dynamic_raw_ - f_status_t f_print_to_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to_except_raw(buffer.string, 0, buffer.used, except, id); - } -#endif // _di_f_print_to_except_dynamic_raw_ - -#ifndef _di_f_print_to_except_dynamic_safely_ - f_status_t f_print_to_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !buffer.used) { - return F_data_not; - } - - return private_f_print_to_except_safely(buffer.string, 0, buffer.used, except, id); - } -#endif // _di_f_print_to_except_dynamic_safely_ - -#ifndef _di_f_print_to_except_dynamic_partial_ - f_status_t f_print_to_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to_except(buffer.string, range.start, range.start + length, except, id); - } -#endif // _di_f_print_to_except_dynamic_partial_ - -#ifndef _di_f_print_to_except_dynamic_partial_raw_ - f_status_t f_print_to_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to_except_raw(buffer.string, range.start, range.start + length, except, id); - } -#endif // _di_f_print_to_except_dynamic_partial_raw_ - -#ifndef _di_f_print_to_except_dynamic_partial_safely_ - f_status_t f_print_to_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { - #ifndef _di_level_0_parameter_checking_ - if (id == -1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!buffer.string || !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_f_print_to_except_safely(buffer.string, range.start, range.start + length, except, id); - } -#endif // _di_f_print_to_except_dynamic_partial_safely_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_print/c/print.h b/level_0/f_print/c/print.h index ba352b0..23799cb 100644 --- a/level_0/f_print/c/print.h +++ b/level_0/f_print/c/print.h @@ -30,6 +30,7 @@ // fll-0 print includes #include +#include #ifdef __cplusplus extern "C" { @@ -67,6 +68,8 @@ extern "C" { /** * Given a single 1-byte character, print the character. * + * This will print NULL characters and is essentially a "raw" print. + * * @param character * The character to verify as safe or not and then print. * @param output @@ -74,6 +77,7 @@ extern "C" { * * @return * F_none on success. + * F_data_not if there is nothing to print. * * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. @@ -100,6 +104,7 @@ extern "C" { * * @return * F_none on success. + * F_data_not if there is nothing to print. * * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. @@ -163,18 +168,18 @@ extern "C" { #endif // _di_f_print_dynamic_ /** - * Similar to a c-library printf, except that this prints a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * Will not stop at NULL. - * Will print NULL. - * Will print up to length 1-byte characters. - * - * All UTF-8 characters, invalid or not, are printed as is. + * Will not print NULL. + * Will print up to the specified range within the buffer. * * 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. * @@ -187,24 +192,25 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_dynamic_raw_ - extern f_status_t f_print_dynamic_raw(const f_string_static_t buffer, FILE *output); -#endif // _di_f_print_dynamic_raw_ +#ifndef _di_f_print_dynamic_partial_ + extern f_status_t f_print_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_f_print_dynamic_partial_ /** - * Similar to a c-library printf, except that this prints a given dynamic string. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * Will not stop at NULL. - * Will not print NULL. + * 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 * 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. * @@ -216,16 +222,17 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() - * - * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_safely_ - extern f_status_t f_print_dynamic_safely(const f_string_static_t buffer, FILE *output); -#endif // _di_f_print_dynamic_safely_ +#ifndef _di_f_print_dynamic_partial_raw_ + extern f_status_t f_print_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_f_print_dynamic_partial_raw_ /** * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * * Will not stop at NULL. * Will not print NULL. * Will print up to the specified range within the buffer. @@ -247,13 +254,15 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() + * + * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_partial_ - extern f_status_t f_print_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, FILE *output); -#endif // _di_f_print_dynamic_partial_ +#ifndef _di_f_print_dynamic_partial_safely_ + extern f_status_t f_print_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output); +#endif // _di_f_print_dynamic_partial_safely_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this prints a given dynamic string. * * Will not stop at NULL. * Will print NULL. @@ -265,8 +274,6 @@ extern "C" { * * @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. * @@ -279,26 +286,24 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_dynamic_partial_raw_ - extern f_status_t f_print_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, FILE *output); -#endif // _di_f_print_dynamic_partial_raw_ +#ifndef _di_f_print_dynamic_raw_ + extern f_status_t f_print_dynamic_raw(const f_string_static_t buffer, FILE *output); +#endif // _di_f_print_dynamic_raw_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this prints a given dynamic string. * * Control characters are converted to the Unicode control character symbols, excluding NULL. * UTF-8 sequences with invalid widths are converted to the unknown character '�'. * * Will not stop at NULL. * Will not print NULL. - * Will print up to the specified range within the buffer. + * Will print up to length 1-byte characters. * * 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. * @@ -313,9 +318,9 @@ extern "C" { * * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_partial_safely_ - extern f_status_t f_print_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, FILE *output); -#endif // _di_f_print_dynamic_partial_safely_ +#ifndef _di_f_print_dynamic_safely_ + extern f_status_t f_print_dynamic_safely(const f_string_static_t buffer, FILE *output); +#endif // _di_f_print_dynamic_safely_ /** * Similar to a c-library printf, except that this will only print a specific range. @@ -355,25 +360,17 @@ extern "C" { #endif // _di_f_print_except_ /** - * Similar to a c-library printf, except that this will only print a specific range. - * - * An offset is provided because the except position is expected to be relative to the start position, without the offset applied. + * Similar to a c-library printf, except that this prints a given dynamic string. * * Will not stop at NULL. - * Will print NULL. + * Will not print NULL. * 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. + * Will print up to the length of the buffer. * * 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 offset - * The inclusive start point to start printing. - * @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. @@ -389,29 +386,24 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_except_raw_ - extern f_status_t f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output); -#endif // _di_f_print_except_raw_ +#ifndef _di_f_print_except_dynamic_ + extern f_status_t f_print_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); +#endif // _di_f_print_except_dynamic_ /** - * Similar to a c-library printf, except that this will only print a specific range. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * 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 up to length 1-byte characters. + * Will print up to the specified range within the buffer. * * 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 offset - * The inclusive start point to start printing. - * @param length - * The total number of characters to print. + * @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. @@ -426,25 +418,63 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() + */ +#ifndef _di_f_print_dynamic_except_partial_ + extern f_status_t f_print_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_f_print_except_dynamic_partial_ + +/** + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * - * @see f_utf_is_valid() + * Will not stop at NULL. + * Will print NULL. + * 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 + * 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 if there is nothing to print. + * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see fwrite_unlocked() */ -#ifndef _di_f_print_except_safely_ - extern f_status_t f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output); -#endif // _di_f_print_except_safely_ +#ifndef _di_f_print_dynamic_except_partial_raw_ + extern f_status_t f_print_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_f_print_except_dynamic_partial_raw_ /** - * Similar to a c-library printf, except that this prints a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. * * 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 up to the length of the buffer. + * Will print up to the specified range within the buffer. * * 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. @@ -459,10 +489,12 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() + * + * @see f_utf_is_valid() */ -#ifndef _di_f_print_except_dynamic_ - extern f_status_t f_print_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, FILE *output); -#endif // _di_f_print_except_dynamic_ +#ifndef _di_f_print_dynamic_except_partial_safely_ + extern f_status_t f_print_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_f_print_except_dynamic_partial_safely_ /** * Similar to a c-library printf, except that this prints a given dynamic string. @@ -575,26 +607,18 @@ extern "C" { #endif // _di_f_print_except_in_ /** - * Similar to a c-library printf, except that this will only print a specific range. - * - * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. + * Similar to a c-library printf, except that this prints a given dynamic string. * * Will not stop at NULL. - * Will print 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 up to length 1-byte characters. - * - * All UTF-8 characters, invalid or not, are printed as is. + * Will print up to the length of the buffer. * * 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 offset - * The inclusive start point to start 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. @@ -613,32 +637,25 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_except_in_raw_ - extern f_status_t f_print_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_f_print_except_in_raw_ +#ifndef _di_f_print_except_in_dynamic_ + extern f_status_t f_print_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_f_print_except_in_dynamic_ /** - * Similar to a c-library printf, except that this will only print a specific range. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * 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 up to length 1-byte characters. + * Will print up to the specified range within the buffer. * * 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 offset - * The inclusive start point to start printing. - * @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. @@ -656,26 +673,28 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() - * - * @see f_utf_is_valid() */ -#ifndef _di_f_print_except_in_safely_ - extern f_status_t f_print_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); -#endif // _di_f_print_except_in_safely_ +#ifndef _di_f_print_dynamic_except_partial_ + extern f_status_t f_print_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_f_print_except_in_dynamic_partial_ /** - * Similar to a c-library printf, except that this prints a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * Will not stop at NULL. - * Will not print 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 up to the length of the buffer. + * 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 * 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. @@ -694,25 +713,25 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_except_in_dynamic_ - extern f_status_t f_print_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_f_print_except_in_dynamic_ +#ifndef _di_f_print_dynamic_except_partial_raw_ + extern f_status_t f_print_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_f_print_except_in_dynamic_partial_raw_ /** - * Similar to a c-library printf, except that this prints a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. * * Will not stop at NULL. - * Will print 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 up to length 1-byte characters. - * - * All UTF-8 characters, invalid or not, are printed as is. + * Will print up to the specified range within the buffer. * * 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_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -730,22 +749,23 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() + * + * @see f_utf_is_valid() */ -#ifndef _di_f_print_except_in_dynamic_raw_ - extern f_status_t f_print_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_f_print_except_in_dynamic_raw_ +#ifndef _di_f_print_dynamic_except_partial_safely_ + extern f_status_t f_print_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_f_print_except_in_dynamic_partial_safely_ /** * Similar to a c-library printf, except that this prints a given dynamic string. * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * * Will not stop at NULL. - * Will not print 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 up to the length of the buffer. + * 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. * @@ -768,28 +788,27 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() - * - * @see f_utf_is_valid() */ -#ifndef _di_f_print_except_in_dynamic_safely_ - extern f_status_t f_print_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_f_print_except_in_dynamic_safely_ +#ifndef _di_f_print_except_in_dynamic_raw_ + extern f_status_t f_print_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_f_print_except_in_dynamic_raw_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this prints a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. * * 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 up to the specified range within the buffer. + * Will print up to the length of the buffer. * * 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_at * An array of locations within the given string to not print. * The array of locations is required/assumed to be in linear order. @@ -807,13 +826,17 @@ extern "C" { * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() + * + * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_except_partial_ - extern f_status_t f_print_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_f_print_except_in_dynamic_partial_ +#ifndef _di_f_print_except_in_dynamic_safely_ + extern f_status_t f_print_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_f_print_except_in_dynamic_safely_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range. + * + * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. * * Will not stop at NULL. * Will print NULL. @@ -825,10 +848,12 @@ extern "C" { * * 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 offset + * The inclusive start point to start 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. @@ -847,25 +872,32 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_dynamic_except_partial_raw_ - extern f_status_t f_print_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_f_print_except_in_dynamic_partial_raw_ +#ifndef _di_f_print_except_in_raw_ + extern f_status_t f_print_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_f_print_except_in_raw_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. * * 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 up to the specified range within the buffer. + * Will print up to length 1-byte characters. * * 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 offset + * The inclusive start point to start 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. @@ -886,127 +918,30 @@ extern "C" { * * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_except_partial_safely_ - extern f_status_t f_print_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_f_print_except_in_dynamic_partial_safely_ - -/** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. - * - * 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 up to the specified range within the buffer. - * - * 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 if there is nothing to print. - * - * F_output (with error bit) on failure. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see fwrite_unlocked() - */ -#ifndef _di_f_print_dynamic_except_partial_ - extern f_status_t f_print_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_f_print_except_dynamic_partial_ - -/** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. - * - * Will not stop at NULL. - * Will print NULL. - * 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 - * 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 if there is nothing to print. - * - * F_output (with error bit) on failure. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see fwrite_unlocked() - */ -#ifndef _di_f_print_dynamic_except_partial_raw_ - extern f_status_t f_print_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_f_print_except_dynamic_partial_raw_ +#ifndef _di_f_print_except_in_safely_ + extern f_status_t f_print_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output); +#endif // _di_f_print_except_in_safely_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. - * - * 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 up to the specified range within the buffer. - * - * 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 if there is nothing to print. - * - * F_output (with error bit) on failure. - * F_parameter (with error bit) if a parameter is invalid. + * Similar to a c-library printf, except that this will only print a specific range. * - * @see fwrite_unlocked() - */ -#ifndef _di_f_print_dynamic_except_partial_ - extern f_status_t f_print_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_f_print_except_dynamic_partial_ - -/** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * An offset is provided because the except position is expected to be relative to the start position, without the offset applied. * * Will not stop at NULL. * Will print NULL. * Will not print any 1-byte character at a location specified in except array. - * Will print up to the specified range within the buffer. + * 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 + * @param string * The string to output. - * @param range - * The range within the provided string to print. + * @param offset + * The inclusive start point to start printing. + * @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. @@ -1022,12 +957,12 @@ extern "C" { * * @see fwrite_unlocked() */ -#ifndef _di_f_print_dynamic_except_partial_raw_ - extern f_status_t f_print_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_f_print_except_dynamic_partial_raw_ +#ifndef _di_f_print_except_raw_ + extern f_status_t f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_f_print_except_raw_ /** - * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * Similar to a c-library printf, except that this will only print a specific range. * * Control characters are converted to the Unicode control character symbols, excluding NULL. * UTF-8 sequences with invalid widths are converted to the unknown character '�'. @@ -1035,14 +970,16 @@ extern "C" { * 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 up to the specified range within the buffer. + * Will print up to length 1-byte characters. * * 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 offset + * The inclusive start point to start printing. + * @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. @@ -1060,9 +997,9 @@ extern "C" { * * @see f_utf_is_valid() */ -#ifndef _di_f_print_dynamic_except_partial_safely_ - extern f_status_t f_print_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_f_print_except_dynamic_partial_safely_ +#ifndef _di_f_print_except_safely_ + extern f_status_t f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except, FILE *output); +#endif // _di_f_print_except_safely_ /** * Similar to a c-library printf, except that this will only print a specific range. @@ -1217,656 +1154,6 @@ extern "C" { extern f_status_t f_print_terminated(const f_string_t string, FILE *output); #endif // _di_f_print_terminated_ -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to length 1-byte characters. - * - * 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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_ - extern f_status_t f_print_to(const f_string_t string, const f_array_length_t length, const int id); -#endif // _di_f_print_to_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * Will not stop at NULL. - * 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 - * The total number of characters to print. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_raw_ - extern f_status_t f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id); -#endif // _di_f_print_to_raw_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to length 1-byte characters. - * - * @param string - * The string to output. - * @param length - * The total number of characters to print. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_safely_ - extern f_status_t f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id); -#endif // _di_f_print_to_safely_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to the length of the buffer. - * - * @param buffer - * The string to output. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_ - extern f_status_t f_print_to_dynamic(const f_string_static_t buffer, const int id); -#endif // _di_f_print_to_dynamic_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * Will not stop at NULL. - * 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 - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_raw_ - extern f_status_t f_print_to_dynamic_raw(const f_string_static_t buffer, const int id); -#endif // _di_f_print_to_dynamic_raw_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to length 1-byte characters. - * - * @param buffer - * The string to output. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_safely_ - extern f_status_t f_print_to_dynamic_safely(const f_string_static_t buffer, const int id); -#endif // _di_f_print_to_dynamic_safely_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to the specified range within the buffer. - * - * @param buffer - * The string to output. - * @param range - * The range within the provided string to print. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_partial_ - extern f_status_t f_print_to_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const int id); -#endif // _di_f_print_to_dynamic_partial_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * Will not stop at NULL. - * 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 - * The range within the provided string to print. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_partial_raw_ - extern f_status_t f_print_to_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const int id); -#endif // _di_f_print_to_dynamic_partial_raw_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * Will not stop at NULL. - * Will not print NULL. - * Will print up to length 1-byte characters. - * - * @param buffer - * The string to output. - * @param range - * The range within the provided string to print. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_dynamic_partial_safely_ - extern f_status_t f_print_to_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const int id); -#endif // _di_f_print_to_dynamic_partial_safely_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * 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 up to length 1-byte characters. - * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_ - extern f_status_t f_print_to_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * Will not stop at NULL. - * Will print NULL. - * 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 - * 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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_raw_ - extern f_status_t f_print_to_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_raw_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * 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 up to length 1-byte characters. - * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_safely_ - extern f_status_t f_print_to_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_safely_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * 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 up to the length of the buffer. - * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_ - extern f_status_t f_print_to_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * Will not stop at NULL. - * Will print NULL. - * 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 - * An array of locations within the given string to not print. - * The array of locations is required/assumed to be in linear order. - * @param id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_raw_ - extern f_status_t f_print_to_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_raw_ - -/** - * Similar to a c-library dprintf, except that this prints a given dynamic string. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * 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 up to the length of the buffer. - * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_safely_ - extern f_status_t f_print_to_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_safely_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * 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 up to the specified range within the buffer. - * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_partial_ - extern f_status_t f_print_to_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_partial_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * Will not stop at NULL. - * Will print NULL. - * 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 - * 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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_partial_raw_ - extern f_status_t f_print_to_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_partial_raw_ - -/** - * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. - * - * Control characters are converted to the Unicode control character symbols, excluding NULL. - * UTF-8 sequences with invalid widths are converted to the unknown character '�'. - * - * 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 up to the specified range within the buffer. - * - * @param id - * The file descriptor to output to. - * @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. - * - * @return - * F_none on success. - * F_data_not if there is nothing to print. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see write() - */ -#ifndef _di_f_print_to_except_dynamic_partial_safely_ - extern f_status_t f_print_to_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); -#endif // _di_f_print_to_except_dynamic_partial_safely_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_print/c/print_to.c b/level_0/f_print/c/print_to.c new file mode 100644 index 0000000..59e6e8c --- /dev/null +++ b/level_0/f_print/c/print_to.c @@ -0,0 +1,675 @@ +#include "print.h" +#include "private-print.h" +#include "private-print_to.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Inline helper function to reduce amount of code typed. + * + * This will process errno based on a write() error. + * + * @return + * The appropriate status. + */ +inline f_status_t private_inline_f_print_to_error() { + if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); + if (errno == EBADF) return F_status_set_error(F_file_descriptor); + if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not); + if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block); + if (errno == EFBIG) return F_status_set_error(F_number_overflow); + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + if (errno == ENOSPC) return F_status_set_error(F_space_not); + if (errno == EPIPE) return F_status_set_error(F_pipe); + + return F_status_set_error(F_output); +} + +#ifndef _di_f_print_to_ + f_status_t f_print_to(const f_string_t string, const f_array_length_t length, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to(string, length, id); + } +#endif // _di_f_print_to_ + +#ifndef _di_f_print_to_character_ + f_status_t f_print_to_character(const char character, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (write(id, &character, 1) == -1) { + return private_inline_f_print_to_error(); + } + + return F_none; + } +#endif // _di_f_print_to_character_ + +#ifndef _di_f_print_to_character_safely_ + f_status_t f_print_to_character_safely(const char character, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + return private_f_print_to_character_safely(character, id); + } +#endif // _di_f_print_to_character_safely_ + +#ifndef _di_f_print_to_dynamic_ + f_status_t f_print_to_dynamic(const f_string_static_t buffer, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to(buffer.string, buffer.used, id); + } +#endif // _di_f_print_to_dynamic_ + +#ifndef _di_f_print_to_dynamic_partial_ + f_status_t f_print_to_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to(buffer.string + range.start, length, id); + } +#endif // _di_f_print_to_dynamic_partial_ + +#ifndef _di_f_print_to_dynamic_partial_raw_ + f_status_t f_print_to_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_raw(buffer.string + range.start, length, id); + } +#endif // _di_f_print_to_dynamic_partial_raw_ + +#ifndef _di_f_print_to_dynamic_partial_safely_ + f_status_t f_print_to_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_safely(buffer.string + range.start, length, id); + } +#endif // _di_f_print_to_dynamic_partial_safely_ + +#ifndef _di_f_print_to_dynamic_raw_ + f_status_t f_print_to_dynamic_raw(const f_string_static_t buffer, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to_raw(buffer.string, buffer.used, id); + } +#endif // _di_f_print_to_dynamic_raw_ + +#ifndef _di_f_print_to_dynamic_safely_ + f_status_t f_print_to_dynamic_safely(const f_string_static_t buffer, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to_safely(buffer.string, buffer.used, id); + } +#endif // _di_f_print_to_dynamic_safely_ + +#ifndef _di_f_print_to_except_ + f_status_t f_print_to_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except(string, 0, length, except, id); + } +#endif // _di_f_print_to_except_ + +#ifndef _di_f_print_to_except_dynamic_ + f_status_t f_print_to_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to_except(buffer.string, 0, buffer.used, except, id); + } +#endif // _di_f_print_to_except_dynamic_ + +#ifndef _di_f_print_to_except_dynamic_partial_ + f_status_t f_print_to_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except(buffer.string, range.start, range.start + length, except, id); + } +#endif // _di_f_print_to_except_dynamic_partial_ + +#ifndef _di_f_print_to_except_dynamic_partial_raw_ + f_status_t f_print_to_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except_raw(buffer.string, range.start, range.start + length, except, id); + } +#endif // _di_f_print_to_except_dynamic_partial_raw_ + +#ifndef _di_f_print_to_except_dynamic_partial_safely_ + f_status_t f_print_to_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except_safely(buffer.string, range.start, range.start + length, except, id); + } +#endif // _di_f_print_to_except_dynamic_partial_safely_ + +#ifndef _di_f_print_to_except_dynamic_raw_ + f_status_t f_print_to_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to_except_raw(buffer.string, 0, buffer.used, except, id); + } +#endif // _di_f_print_to_except_dynamic_raw_ + +#ifndef _di_f_print_to_except_dynamic_safely_ + f_status_t f_print_to_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) { + return F_data_not; + } + + return private_f_print_to_except_safely(buffer.string, 0, buffer.used, except, id); + } +#endif // _di_f_print_to_except_dynamic_safely_ + +#ifndef _di_f_print_to_except_in_ + f_status_t f_print_to_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except_in(string, offset, length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_ + +#ifndef _di_f_print_to_except_in_dynamic_ + f_status_t f_print_to_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) return F_data_not; + + return private_f_print_to_except_in(buffer.string, 0, buffer.used, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_ + +#ifndef _di_f_print_to_except_in_dynamic_partial_ + f_status_t f_print_to_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, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except_in(buffer.string, range.start, range.start + length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_partial_ + +#ifndef _di_f_print_to_except_in_dynamic_partial_raw_ + f_status_t f_print_to_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, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except_in_raw(buffer.string, range.start, range.start + length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_partial_raw_ + +#ifndef _di_f_print_to_except_in_dynamic_partial_safely_ + f_status_t f_print_to_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, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !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_f_print_to_except_in_safely(buffer.string, range.start, range.start + length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_partial_safely_ + +#ifndef _di_f_print_to_except_in_dynamic_raw_ + f_status_t f_print_to_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) return F_data_not; + + return private_f_print_to_except_in_raw(buffer.string, 0, buffer.used, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_raw_ + +#ifndef _di_f_print_to_except_in_dynamic_safely_ + f_status_t f_print_to_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.string || !buffer.used) return F_data_not; + + return private_f_print_to_except_in_safely(buffer.string, 0, buffer.used, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_dynamic_safely_ + +#ifndef _di_f_print_to_except_in_raw_ + f_status_t f_print_to_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except_in_raw(string, offset, length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_raw_ + +#ifndef _di_f_print_to_except_in_safely_ + f_status_t f_print_to_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except_in_safely(string, offset, length, except_at, except_in, id); + } +#endif // _di_f_print_to_except_in_safely_ + +#ifndef _di_f_print_to_except_raw_ + f_status_t f_print_to_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except_raw(string, 0, length, except, id); + } +#endif // _di_f_print_to_except_raw_ + +#ifndef _di_f_print_to_except_safely_ + f_status_t f_print_to_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_except_safely(string, 0, length, except, id); + } +#endif // _di_f_print_to_except_safely_ + +#ifndef _di_f_print_to_raw_ + f_status_t f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_raw(string, length, id); + } +#endif // _di_f_print_to_raw_ + +#ifndef _di_f_print_to_raw_terminated_ + f_status_t f_print_to_raw_terminated(const f_string_t string, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string) { + return F_data_not; + } + + // The f_print_raw_terminated() and f_print_terminated() are functionality identical due to being NULL terminated. + return private_f_print_to_terminated(string, id); + } +#endif // _di_f_print_raw_terminated_ + +#ifndef _di_f_print_to_safely_ + f_status_t f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string || !length) { + return F_data_not; + } + + return private_f_print_to_safely(string, length, id); + } +#endif // _di_f_print_to_safely_ + +#ifndef _di_f_print_to_safely_terminated_ + f_status_t f_print_to_safely_terminated(const f_string_t string, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string) { + return F_data_not; + } + + f_status_t status = F_none; + + f_array_length_t start = 0; + f_array_length_t total = 0; + + f_string_t safe = 0; + + uint8_t width = 0; + + for (register f_array_length_t i = 0; string[i]; ) { + + width = macro_f_utf_character_t_width_is(string[i]); + + if (width) { + if (width > 1) { + if (string[i + 1]) { + if (width > 2) { + if (string[i + 2]) { + if (width > 3) { + if (string[i + 3]) { + status = f_utf_is_control(string + i, 4); + } + else { + status = F_utf; + } + } + else { + status = f_utf_is_control(string + i, 3); + } + } + else { + status = F_utf; + } + } + else { + status = f_utf_is_control(string + i, 2); + } + } + else { + status = F_utf; + } + } + else { + status = f_utf_is_control(string + i, 1); + } + + if (status == F_false && total + width < F_print_write_max_d) { + total += width; + i += width; + + continue; + } + } + else { + if ((string[i] > 0x1f && string[i] != 0x7f) && total < F_print_write_max_d) { + ++total; + ++i; + + continue; + } + + status = F_none; + } + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (status == F_true || F_status_set_fine(status) == F_utf) { + if (write(id, f_print_sequence_unknown_s, 3) == -1) { + return private_inline_f_print_to_error(); + } + + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + + i += width; + } + else if (status == F_false) { + if (write(id, string + start, width) == -1) { + return private_inline_f_print_to_error(); + } + + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + + i += width; + } + else { + safe = private_f_print_character_safely_get(string[i]); + + if (safe) { + if (write(id, safe, 3) == -1) { + return private_inline_f_print_to_error(); + } + } + else { + status = f_utf_is_valid(string + i, width); + + if (F_status_is_error(status) || status == F_false) { + if (write(id, f_print_sequence_unknown_s, 3) == -1) { + return private_inline_f_print_to_error(); + } + + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + } + else { + for (start = 0; string[start] && start < width; ) { + ++start; + } // while + + if (start != width) break; + + total = width; + start = i; + i += width; + continue; + } + } + + i += width; + } + + start = i; + } // for + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // _di_f_print_to_safely_terminated_ + +#ifndef _di_f_print_to_terminated_ + f_status_t f_print_to_terminated(const f_string_t string, const int id) { + #ifndef _di_level_0_parameter_checking_ + if (id == -1) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!string) { + return F_data_not; + } + + return private_f_print_to_terminated(string, id); + } +#endif // _di_f_print_to_terminated_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_print/c/print_to.h b/level_0/f_print/c/print_to.h new file mode 100644 index 0000000..313718b --- /dev/null +++ b/level_0/f_print/c/print_to.h @@ -0,0 +1,1472 @@ +/** + * FLL - Level 0 + * + * Project: Print + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Defines print_to_* variants of print functins to be used for/by project print. + * + * This is auto-included by print.h and should not need to be explicitly included. + */ +#ifndef _F_print_to_h +#define _F_print_to_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to length 1-byte characters. + * + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_ + extern f_status_t f_print_to(const f_string_t string, const f_array_length_t length, const int id); +#endif // _di_f_print_to_ + +/** + * Given a single 1-byte character, print the character. + * + * This will print NULL characters and is essentially a "raw" print. + * + * @param character + * The character to verify as safe or not and then print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_character_ + extern f_status_t f_print_to_character(const char character, const int id); +#endif // _di_f_print_to_character_ + +/** + * Given a single 1-byte character, print the character or a replacement if the character is not considered safe. + * + * Control characters are converted to the Unicode control character symbols, including NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * This can result in the 1-byte character being substituted with a 3-byte character when printing. + * + * This should only be called for the first 1-byte character of a multibyte character. + * + * @param character + * The character to verify as safe or not and then print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_character_safely_ + extern f_status_t f_print_to_character_safely(const char character, const int id); +#endif // _di_f_print_to_character_safely_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to the length of the buffer. + * + * @param buffer + * The string to output. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_ + extern f_status_t f_print_to_dynamic(const f_string_static_t buffer, const int id); +#endif // _di_f_print_to_dynamic_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to the specified range within the buffer. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_partial_ + extern f_status_t f_print_to_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const int id); +#endif // _di_f_print_to_dynamic_partial_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * Will not stop at NULL. + * 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 + * The range within the provided string to print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_partial_raw_ + extern f_status_t f_print_to_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const int id); +#endif // _di_f_print_to_dynamic_partial_raw_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to length 1-byte characters. + * + * @param buffer + * The string to output. + * @param range + * The range within the provided string to print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_partial_safely_ + extern f_status_t f_print_to_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const int id); +#endif // _di_f_print_to_dynamic_partial_safely_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * Will not stop at NULL. + * 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 + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_raw_ + extern f_status_t f_print_to_dynamic_raw(const f_string_static_t buffer, const int id); +#endif // _di_f_print_to_dynamic_raw_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to length 1-byte characters. + * + * @param buffer + * The string to output. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_dynamic_safely_ + extern f_status_t f_print_to_dynamic_safely(const f_string_static_t buffer, const int id); +#endif // _di_f_print_to_dynamic_safely_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * 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 up to length 1-byte characters. + * + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_ + extern f_status_t f_print_to_except(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * 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 up to the length of the buffer. + * + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_ + extern f_status_t f_print_to_except_dynamic(const f_string_static_t buffer, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * 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 up to the specified range within the buffer. + * + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_partial_ + extern f_status_t f_print_to_except_dynamic_partial(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_partial_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * Will not stop at NULL. + * Will print NULL. + * 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_partial_raw_ + extern f_status_t f_print_to_except_dynamic_partial_raw(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_partial_raw_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range in a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * 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 up to the specified range within the buffer. + * + * @param id + * The file descriptor to output to. + * @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. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_partial_safely_ + extern f_status_t f_print_to_except_dynamic_partial_safely(const f_string_static_t buffer, const f_string_range_t range, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_partial_safely_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * Will not stop at NULL. + * Will print NULL. + * 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 + * An array of locations within the given string to not print. + * The array of locations is required/assumed to be in linear order. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_raw_ + extern f_status_t f_print_to_except_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_raw_ + +/** + * Similar to a c-library dprintf, except that this prints a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * 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 up to the length of the buffer. + * + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_dynamic_safely_ + extern f_status_t f_print_to_except_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_dynamic_safely_ + +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. + * + * 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 up to length 1-byte characters. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param offset + * The inclusive start point to start 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. + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_in_ + extern f_status_t f_print_to_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_ + +/** + * Similar to a c-library printf, except that this prints a given dynamic string. + * + * 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 up to the length of the buffer. + * + * 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_in_dynamic_ + extern f_status_t f_print_to_except_in_dynamic(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_dynamic_ + +/** + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * + * 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 up to the specified range within the buffer. + * + * 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_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_dynamic_except_partial_ + extern f_status_t f_print_to_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, const int id); +#endif // _di_f_print_to_except_in_dynamic_partial_ + +/** + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * + * 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 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_dynamic_except_partial_raw_ + extern f_status_t f_print_to_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, const int id); +#endif // _di_f_print_to_except_in_dynamic_partial_raw_ + +/** + * Similar to a c-library printf, except that this will only print a specific range in a given dynamic string. + * + * 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 up to the specified range within the buffer. + * + * 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_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_utf_is_valid() + */ +#ifndef _di_f_print_dynamic_except_partial_safely_ + extern f_status_t f_print_to_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, const int id); +#endif // _di_f_print_to_except_in_dynamic_partial_safely_ + +/** + * Similar to a c-library printf, except that this prints a given dynamic string. + * + * 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 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_in_dynamic_raw_ + extern f_status_t f_print_to_except_in_dynamic_raw(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_dynamic_raw_ + +/** + * Similar to a c-library printf, except that this prints a given dynamic string. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * 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 up to the length of the buffer. + * + * 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_utf_is_valid() + */ +#ifndef _di_f_print_to_except_in_dynamic_safely_ + extern f_status_t f_print_to_except_in_dynamic_safely(const f_string_static_t buffer, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_dynamic_safely_ + +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. + * + * 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 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 + * The string to output. + * @param offset + * The inclusive start point to start 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. + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_in_raw_ + extern f_status_t f_print_to_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_raw_ + +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * An offset is provided because the except_at/except_int positions are expected to be relative to the start position, without the offset applied. + * + * 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 up to length 1-byte characters. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param offset + * The inclusive start point to start 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. + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_utf_is_valid() + */ +#ifndef _di_f_print_to_except_in_safely_ + extern f_status_t f_print_to_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t length, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id); +#endif // _di_f_print_to_except_in_safely_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * Will not stop at NULL. + * Will print NULL. + * 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 + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_raw_ + extern f_status_t f_print_to_except_raw(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_raw_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * 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 up to length 1-byte characters. + * + * @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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_except_safely_ + extern f_status_t f_print_to_except_safely(const f_string_t string, const f_array_length_t length, const f_array_lengths_t except, const int id); +#endif // _di_f_print_to_except_safely_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * Will not stop at NULL. + * 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 + * The total number of characters to print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_raw_ + extern f_status_t f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id); +#endif // _di_f_print_to_raw_ + +/** + * Similar to a c-library printf. + * + * Will stop at NULL. + * Will not print NULL. + * Will print up to length 1-byte characters. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_raw_to_terminated_ + extern f_status_t f_print_to_raw_terminated(const f_string_t string, const int id); +#endif // _di_f_print_raw_to_terminated_ + +/** + * Similar to a c-library dprintf, except that this will only print a specific range. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will not stop at NULL. + * Will not print NULL. + * Will print up to length 1-byte characters. + * + * @param string + * The string to output. + * @param length + * The total number of characters to print. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_safely_ + extern f_status_t f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id); +#endif // _di_f_print_to_safely_ + +/** + * Similar to a c-library printf. + * + * Control characters are converted to the Unicode control character symbols, excluding NULL. + * UTF-8 sequences with invalid widths are converted to the unknown character '�'. + * + * Will stop at NULL. + * Will not print NULL (even 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see fwrite_unlocked() + * + * @see f_utf_is_valid() + */ +#ifndef _di_f_print_to_safely_terminated_ + extern f_status_t f_print_to_safely_terminated(const f_string_t string, const int id); +#endif // _di_f_print_to_safely_terminated_ + +/** + * Similar to a c-library printf. + * + * Will stop at NULL. + * Will not print NULL. + * + * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. + * + * @param string + * The string to output. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + */ +#ifndef _di_f_print_to_terminated_ + extern f_status_t f_print_to_terminated(const f_string_t string, const int id); +#endif // _di_f_print_to_terminated_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_print_to_h diff --git a/level_0/f_print/c/private-print.c b/level_0/f_print/c/private-print.c index ab4abbb..980c2cb 100644 --- a/level_0/f_print/c/private-print.c +++ b/level_0/f_print/c/private-print.c @@ -8,22 +8,18 @@ extern "C" { #if !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_) f_status_t private_f_print(const f_string_t string, const f_array_length_t length, FILE *output) { - f_array_length_t start = 0; f_array_length_t total = 0; for (register f_array_length_t i = 0; i < length; ) { - total = strnlen(string + start, length - start); + total = strnlen(string + i, length - i); if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + if (total > F_print_write_max_d) { + total = F_print_write_max_d; + } + if (fwrite_unlocked(string + i, 1, total, output) == -1) { return F_status_set_error(F_output); } @@ -31,74 +27,18 @@ extern "C" { total = 0; } - start = i; - - if (start < length && !string[start]) { - total = 0; - + if (!string[i]) { do { ++i; - ++total; - } while (i < length && !string[i]); - - start = i; } } // for - if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - return F_none; } #endif // !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_) -#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 == 0x7f) { - if (fwrite_unlocked(f_print_sequence_delete_s, 1, 3, output) != -1) { - return F_none; - } - } - else if (macro_f_utf_character_t_width_is(character) == 1) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) != -1) { - return F_none; - } - } - else if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) { - if (fwrite_unlocked(&character, 1, 1, output) != -1) { - return F_none; - } - } - else { - if (fwrite_unlocked(f_print_sequence_set_control_s[character], 1, 3, output) != -1) { - return F_none; - } - } - - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } -#endif // !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_) - -#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_) +#if !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_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 == 0x7f) { @@ -113,251 +53,15 @@ extern "C" { return (f_string_t) f_print_sequence_set_control_s[character]; } -#endif // !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_) - -#if !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) - f_status_t private_f_print_raw(const f_string_t string, const f_array_length_t length, FILE *output) { - - f_array_length_t start = 0; - f_array_length_t total = 0; - - for (register f_array_length_t i = 0; i < length; ) { - - total = strnlen(string + start, length - start); - - if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - i += total; - total = 0; - } - - start = i; - - if (start < length && !string[start]) { - total = 0; - - do { - ++i; - ++total; - - } while (i < length && !string[i]); - - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - start = i; - } - } // for - - if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - - return F_none; - } -#endif // !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) - -#if !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) - f_status_t private_f_print_safely(const f_string_t string, const f_array_length_t length, FILE *output) { - - f_status_t status = F_none; - - f_array_length_t start = 0; - f_array_length_t total = 0; - - uint8_t width = 0; - - for (register f_array_length_t i = 0; i < length; ) { - - width = macro_f_utf_character_t_width_is(string[i]); - - if (width) { - status = f_utf_is_control(string + i, i + width > length ? length - i : width); - - if (status == F_false && total + width < F_print_write_max_d) { - total += width; - i += width; - - continue; - } - } - else { - if ((string[i] > 0x1f && string[i] != 0x7f) && total < F_print_write_max_d) { - ++total; - ++i; - - continue; - } - - status = F_none; - } - - if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - total = 0; - } - - if (status == F_true || F_status_set_fine(status) == F_utf) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) != -1) { - return F_none; - } - - i += width; - } - else if (status == F_false) { - if (fwrite_unlocked(string + i, 1, width, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - i += width; - } - else { - if (string[i]) { - status = private_f_print_character_safely(string[i++], output); - if (F_status_is_error(status)) return status; - } - else { - ++i; - } - } - - start = i; - } // for - - if (total) { - if (fwrite_unlocked(string + start, 1, total, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - - return F_none; - } -#endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) +#endif // !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_) #if !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) f_status_t private_f_print_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) { - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. - f_array_length_t i = offset; + register f_array_length_t i = offset; f_array_length_t j = 0; - - for (; i < stop; ++i) { - - while (j < except.used && except.array[j] < i) { - ++j; - } // while - - if (j < except.used && except.array[j] == i) continue; - - if (string[i]) { - if (fwrite_unlocked(string + i, 1, 1, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - } // for - - return F_none; - } -#endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) - -#if !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) - f_status_t private_f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) { - - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. - f_array_length_t i = offset; - f_array_length_t j = 0; - - for (; i < stop; ++i) { - - while (j < except.used && except.array[j] < i) { - ++j; - } // while - - if (j < except.used && except.array[j] == i) continue; - - if (fwrite_unlocked(string + i, 1, 1, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } // for - - return F_none; - } -#endif // !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) - -#if !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) - f_status_t private_f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) { - - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. - f_array_length_t i = offset; - f_array_length_t j = 0; - - f_status_t status = F_none; - f_string_t s = 0; + f_array_length_t start = i; + f_array_length_t total = 0; while (i < stop) { @@ -366,88 +70,50 @@ extern "C" { } // while if (j < except.used && except.array[j] == i) { - ++i; - - continue; - } - - s = private_f_print_character_safely_get(string[i]); - - if (s) { - if (fwrite_unlocked(s + i, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - ++i; - } - else { - status = f_utf_is_valid(string + i, stop - i); - - if (F_status_is_error(status) || status == F_false) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i += macro_f_utf_byte_width(string[i]); - continue; + total = 0; } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + start = ++i; + continue; + } + + if (string[i]) { + ++total; + } + if (!string[i] || i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i = stop; - continue; + total = 0; } - if (fwrite_unlocked(string + i, 1, macro_f_utf_byte_width(string[i]), output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - i += macro_f_utf_byte_width(string[i]); + start = ++i; + } + else { + ++i; } } // while return F_none; } -#endif // !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) +#endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) #if !defined(_di_f_print_except_in_) || !defined(_di_f_print_except_in_dynamic_) || !defined(_di_f_print_except_in_dynamic_partial_) f_status_t private_f_print_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. f_array_length_t i = offset; f_array_length_t at = 0; f_array_length_t in = 0; + f_array_length_t start = i; + f_array_length_t total = 0; while (i < stop) { @@ -456,8 +122,15 @@ extern "C" { } // while if (at < except_at.used && except_at.array[at] == i) { - ++i; + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } + total = 0; + } + + start = ++i; continue; } @@ -467,26 +140,38 @@ extern "C" { } // 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 (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } + total = 0; + } + + i = except_in.array[in].stop + 1; + start = i; continue; } } if (string[i]) { - if (fwrite_unlocked(string + i, 1, 1, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + ++total; + } - return F_status_set_error(F_output); + if (!string[i] || i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } + + total = 0; } - } - ++i; + start = ++i; + } + else { + ++i; + } } // while return F_none; @@ -496,10 +181,11 @@ extern "C" { #if !defined(_di_f_print_except_in_raw_) || !defined(_di_f_print_except_in_dynamic_raw_) || !defined(_di_f_print_except_in_dynamic_partial_raw_) f_status_t private_f_print_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. f_array_length_t i = offset; f_array_length_t at = 0; f_array_length_t in = 0; + f_array_length_t start = i; + f_array_length_t total = 0; while (i < stop) { @@ -508,61 +194,15 @@ extern "C" { } // while if (at < except_at.used && except_at.array[at] == i) { - ++i; - - 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 - - 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 (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - continue; + total = 0; } - } - - if (fwrite_unlocked(string + i, 1, 1, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - ++i; - } // while - - return F_none; - } -#endif // !defined(_di_f_print_except_in_raw_) || !defined(_di_f_print_except_in_dynamic_raw_) || !defined(_di_f_print_except_in_dynamic_partial_raw_) - -#if !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_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, FILE *output) { - - // @todo update logic to use fwrite_unlocked() with more than 1 byte at a time. - f_array_length_t i = offset; - f_array_length_t at = 0; - f_array_length_t in = 0; - - f_status_t status = F_none; - f_string_t s = 0; - - 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; + start = ++i; continue; } @@ -572,344 +212,178 @@ extern "C" { } // 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 (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - continue; - } - } - - s = private_f_print_character_safely_get(string[i]); - - if (s) { - if (fwrite_unlocked(s + i, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - ++i; - } - else { - status = f_utf_is_valid(string + i, stop - i); - - if (F_status_is_error(status) || status == F_false) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); + total = 0; } - i += macro_f_utf_byte_width(string[i]); + i = except_in.array[in].stop + 1; + start = i; continue; } + } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + ++total; + if (i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i = stop; - continue; - } - - if (fwrite_unlocked(string + i, 1, macro_f_utf_byte_width(string[i]), output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); + total = 0; } - i += macro_f_utf_byte_width(string[i]); - } - } // while - - return F_none; - } -#endif // !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) - -#if !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) - f_status_t private_f_print_terminated(const f_string_t string, FILE *output) { - - if (fwrite_unlocked(string, 1, strlen(string), output) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - return F_none; - } -#endif // !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) - -#if !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) - f_status_t private_f_print_to(const f_string_t string, const f_array_length_t length, const int id) { - - f_array_length_t i = 0; - f_array_length_t start = 0; - f_array_length_t total = 0; - - while (i < length) { - - if (string[i] && total < F_print_write_max_d) { - ++total; - ++i; - - continue; - } - - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - - if (string[i]) { - start = i++; - total = 1; - } - else { start = ++i; - total = 0; } - } // for - - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); + else { + ++i; } - } + } // while return F_none; } -#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) +#endif // !defined(_di_f_print_except_in_raw_) || !defined(_di_f_print_except_in_dynamic_raw_) || !defined(_di_f_print_except_in_dynamic_partial_raw_) -#if !defined(_di_f_print_to_raw_) || !defined(_di_f_print_dynamic_to_raw_) || !defined(_di_f_print_dynamic_partial_to_raw_) - f_status_t private_f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) { +#if !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_except_in_safely(const f_string_t string, const f_array_length_t offset, 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 = 0; - f_array_length_t start = 0; + f_array_length_t i = offset; + f_array_length_t at = 0; + f_array_length_t in = 0; + f_array_length_t start = i; f_array_length_t total = 0; - while (i < length) { - - if (total < F_print_write_max_d) { - ++total; - ++i; - - continue; - } - - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - - total = 0; - } - - start = ++i; - } // while + f_status_t status = F_none; + f_string_t safe = 0; - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + uint8_t width = 0; - return F_status_set_error(F_output); - } - } + while (i < stop) { - return F_none; - } -#endif // !defined(_di_f_print_to_raw_) || !defined(_di_f_print_dynamic_to_raw_) || !defined(_di_f_print_dynamic_partial_to_raw_) + while (at < except_at.used && except_at.array[at] < i) { + ++at; + } // while -#if !defined(_di_f_print_dynamic_to_safely_) || !defined(_di_f_print_dynamic_partial_to_safely_) || !defined(_di_f_print_to_safely_) - f_status_t private_f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) { + if (at < except_at.used && except_at.array[at] == i) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - f_array_length_t i = 0; - f_array_length_t start = 0; - f_array_length_t total = 0; + total = 0; + } - f_status_t status = F_none; - f_string_t s = 0; + start = ++i; + continue; + } - while (i < length) { + if (in < except_in.used) { + while (in < except_in.used && except_in.array[in].start < i && except_in.array[in].stop < i) { + ++in; + } // while - s = private_f_print_character_safely_get(string[i]); + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - if (s) { - if (total < F_print_write_max_d) { - ++total; - ++i; + total = 0; + } + i = except_in.array[in].stop + 1; + start = i; continue; } } - else { - if (total + macro_f_utf_byte_width(string[i]) < F_print_write_max_d) { - total += macro_f_utf_byte_width(string[i]); - i += macro_f_utf_byte_width(string[i]); - continue; - } + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); + } + else { + safe = 0; } - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } + width = macro_f_utf_character_t_width(string[i]); - total = 0; - } + if (safe) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - if (s) { - if (write(id, s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + total = 0; + } + if (fwrite_unlocked(safe, 1, 3, output) == -1) { return F_status_set_error(F_output); } - start = ++i; + i += width; + start = i; + continue; } - else { - status = f_utf_is_valid(string + i, length - i); - if (F_status_is_error(status) || status == F_false) { - if (write(id, f_print_sequence_unknown_s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + status = f_utf_is_valid(string + i, width); + if (F_status_is_error(status) || status == F_false || i + width >= stop) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i += macro_f_utf_byte_width(string[i]); - start = i; - - continue; + total = 0; } - if (i + macro_f_utf_byte_width(string[i]) >= length) { - if (write(id, f_print_sequence_unknown_s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { + return F_status_set_error(F_output); + } - return F_status_set_error(F_output); - } + if (F_status_is_error(status) || status == F_false) { + i += width; + start = i; + } + else { + i = stop; + start = stop; + } - i = length; - start = length; + continue; + } - continue; + if (total + width >= F_print_write_max_d) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); } - total = macro_f_utf_byte_width(string[i]); + total = 0; start = i; - i += total; } + + total += width; + i += width; } // while if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } } return F_none; } -#endif // !defined(_di_f_print_dynamic_to_safely_) || !defined(_di_f_print_dynamic_partial_to_safely_) || !defined(_di_f_print_to_safely_) +#endif // !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) -#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) - f_status_t private_f_print_to_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { +#if !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) + f_status_t private_f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) { - f_array_length_t i = offset; + register f_array_length_t i = offset; f_array_length_t j = 0; - f_array_length_t start = offset; + f_array_length_t start = i; f_array_length_t total = 0; while (i < stop) { @@ -918,248 +392,282 @@ extern "C" { ++j; } // while - if (j >= except.used || except.array[j] != i) { - if (string[i] && total < F_print_write_max_d) { - ++total; - ++i; + if (j < except.used && except.array[j] == i) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - continue; + total = 0; } + + start = ++i; + continue; } - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + ++total; - return F_status_set_error(F_output); + if (i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } + + total = 0; } - } - if ((j >= except.used || except.array[j] != i) && string[i]) { - start = i++; - total = 1; + start = ++i; } else { - start = ++i; - total = 0; + ++i; } } // while - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - - return F_status_set_error(F_output); - } - } - return F_none; } -#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) +#endif // !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) -#if !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) - f_status_t private_f_print_to_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { +#if !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) + f_status_t private_f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) { f_array_length_t i = offset; f_array_length_t j = 0; - f_array_length_t start = offset; + f_array_length_t start = i; f_array_length_t total = 0; + f_status_t status = F_none; + f_string_t safe = 0; + + uint8_t width = 0; + while (i < stop) { while (j < except.used && except.array[j] < i) { ++j; } // while - if (j >= except.used || except.array[j] != i) { - if (total < F_print_write_max_d) { - ++total; - ++i; + if (j < except.used && except.array[j] == i) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - continue; + total = 0; } - } - - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - return F_status_set_error(F_output); - } + start = ++i; + continue; } - if (j >= except.used || except.array[j] != i) { - start = i++; - total = 1; + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); } else { - start = ++i; - total = 0; + safe = 0; } - } // while - if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + width = macro_f_utf_character_t_width(string[i]); - return F_status_set_error(F_output); - } - } + if (safe) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - return F_none; - } -#endif // !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) + total = 0; + } -#if !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_safely_) - f_status_t private_f_print_to_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { + if (fwrite_unlocked(safe, 1, 3, output) == -1) { + return F_status_set_error(F_output); + } - f_array_length_t i = offset; - f_array_length_t j = 0; - f_array_length_t start = offset; - f_array_length_t total = 0; + i += width; + start = i; + continue; + } - f_status_t status = F_none; - f_string_t s = 0; + status = f_utf_is_valid(string + i, width); - while (i < stop) { + if (F_status_is_error(status) || status == F_false || i + width >= stop) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - while (j < except.used && except.array[j] < i) { - ++j; - } // while + total = 0; + } + + if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { + return F_status_set_error(F_output); + } + + if (F_status_is_error(status) || status == F_false) { + i += width; + start = i; + } + else { + i = stop; + start = stop; + } - if (j < except.used && except.array[j] == i) { - ++i; continue; } - s = private_f_print_character_safely_get(string[i]); - - if (!s && total < F_print_write_max_d) { - ++total; - ++i; + if (total + width >= F_print_write_max_d) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } - continue; + total = 0; + start = i; } + total += width; + i += width; + } // while + + return F_none; + } +#endif // !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) + +#if !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) + f_status_t private_f_print_raw(const f_string_t string, const f_array_length_t length, FILE *output) { + + f_array_length_t start = 0; + f_array_length_t total = 0; + + for (register f_array_length_t i = 0; i < length; ) { + + total = strnlen(string + i, length - i); + if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + if (total > F_print_write_max_d) { + total = F_print_write_max_d; + } + if (fwrite_unlocked(string + i, 1, total, output) == -1) { return F_status_set_error(F_output); } + i += total; total = 0; } - if (s) { - if (write(id, s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + // Print all NULL characters. + if (!string[i]) { + start = i; + + do { + ++i; + ++total; + + } while (i < length && !string[i] && total < F_print_write_max_d); + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } + } + } // for - start = ++i; + return F_none; + } +#endif // !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) + +#if !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) + f_status_t private_f_print_safely(const f_string_t string, const f_array_length_t length, FILE *output) { + + f_status_t status = F_none; + + register f_array_length_t i = 0; + f_array_length_t start = 0; + f_array_length_t total = 0; + + f_string_t safe = 0; + + uint8_t width = 0; + + while (i < length) { + + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); } else { - status = f_utf_is_valid(string + i, stop - i); + safe = 0; + } - if (F_status_is_error(status) || status == F_false) { - if (write(id, f_print_sequence_unknown_s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + width = macro_f_utf_character_t_width(string[i]); + if (safe) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i += macro_f_utf_byte_width(string[i]); - start = i; + total = 0; + } - continue; + if (fwrite_unlocked(safe, 1, 3, output) == -1) { + return F_status_set_error(F_output); } - if (i + macro_f_utf_byte_width(string[i]) >= stop) { - if (write(id, f_print_sequence_unknown_s, 3) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + i += width; + start = i; + continue; + } + + status = f_utf_is_valid(string + i, width); + if (F_status_is_error(status) || status == F_false) { + if (total) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } - i = stop; - start = stop; + total = 0; + } - continue; + if (fwrite_unlocked(f_print_sequence_unknown_s, 1, 3, output) == -1) { + return F_status_set_error(F_output); } - total = macro_f_utf_byte_width(string[i]); + i += width; + start = i; + continue; + } + + if (total + width >= F_print_write_max_d) { + if (fwrite_unlocked(string + start, 1, total, output) == -1) { + return F_status_set_error(F_output); + } + + total = 0; start = i; - i += total; } + + total += width; + i += width; } // while if (total) { - if (write(id, string + start, total) == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); - if (errno == EBADF) return F_status_set_error(F_file_descriptor); - if (errno == EFAULT) return F_status_set_error(F_buffer); - if (errno == EINTR) return F_status_set_error(F_interrupt); - if (errno == EINVAL) return F_status_set_error(F_parameter); - if (errno == EIO) return F_status_set_error(F_input_output); - if (errno == EISDIR) return F_status_set_error(F_file_type_directory); - + if (fwrite_unlocked(string + start, 1, total, output) == -1) { return F_status_set_error(F_output); } } return F_none; } -#endif // !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_safely_) +#endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) + +#if !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) + f_status_t private_f_print_terminated(const f_string_t string, FILE *output) { + + if (fwrite_unlocked(string, 1, strlen(string), output) == -1) { + return F_status_set_error(F_output); + } + + return F_none; + } +#endif // !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_print/c/private-print.h b/level_0/f_print/c/private-print.h index 0d9b516..6a53edc 100644 --- a/level_0/f_print/c/private-print.h +++ b/level_0/f_print/c/private-print.h @@ -29,14 +29,9 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() @@ -50,7 +45,7 @@ extern "C" { #endif // !defined(_di_f_print_) || !defined(_di_f_print_dynamic_) || !defined(_di_f_print_dynamic_partial_) /** - * Private implementation of f_print_character_safely_print(). + * Private implementation of f_print_character_safely(). * * Intended to be shared to each of the different implementation variations. * @@ -61,14 +56,9 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() @@ -104,86 +94,29 @@ extern "C" { * The non-NULL strings returned are the 3-byte characters used as placeholder symbols. * * @see f_print_character_safely_get() - * @see f_print_dynamic_to_safely() - * @see f_print_dynamic_partial_to_safely() - * @see f_print_to_except_dynamic_safely() + * @see f_print_dynamic_partial_safely() + * @see f_print_dynamic_safely() + * @see f_print_except_dynamic_partial_safely() + * @see f_print_except_dynamic_safely() + * @see f_print_except_in_dynamic_safely() + * @see f_print_except_in_dynamic_partial_safely() + * @see f_print_except_in_safely_ + * @see f_print_except_safely() + * @see f_print_safely() + * @see f_print_safely_terminated() + * @see f_print_to_dynamic_partial_safely() + * @see f_print_to_dynamic_safely() * @see f_print_to_except_dynamic_partial_safely() + * @see f_print_to_except_dynamic_safely() + * @see f_print_to_except_in_dynamic_safely() + * @see f_print_to_except_in_dynamic_partial_safely() + * @see f_print_to_except_in_safely_ * @see f_print_to_except_safely() * @see f_print_to_safely() */ -#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_) +#if !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_) extern f_string_t private_f_print_character_safely_get(const char character) F_attribute_visibility_internal_d; -#endif // !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_) -/** - * Private implementation of f_print_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 if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. - * - * - * @see fwrite_unlocked() - * - * @see f_print_raw() - * @see f_print_raw_dynamic() - * @see f_print_raw_dynamic_partial() - */ -#if !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) - extern f_status_t private_f_print_raw(const f_string_t string, const f_array_length_t length, FILE *output) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) - -/** - * Private implementation of f_print_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 if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. - * - * - * @see fwrite_unlocked() - * - * @see f_print_safely() - * @see f_print_safely_dynamic() - * @see f_print_safely_dynamic_partial() - * @see f_utf_is_valid() - */ -#if !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) - extern f_status_t private_f_print_safely(const f_string_t string, const f_array_length_t length, FILE *output) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) +#endif // !defined(_di_f_print_character_safely_get_) || !defined(_di_f_print_dynamic_partial_safely_) || !defined(_di_f_print_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) || !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_safely_) || !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_terminated_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_safely_) /** * Private implementation of f_print_except(). @@ -204,16 +137,10 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. + * F_data_not if there is nothing to print. * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() * @@ -226,87 +153,6 @@ extern "C" { #endif // !defined(_di_f_print_except_) || !defined(_di_f_print_except_dynamic_) || !defined(_di_f_print_except_dynamic_partial_) /** - * Private implementation of f_print_except_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 if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. - * - * - * @see fwrite_unlocked() - * - * @see f_print_except_raw() - * @see f_print_except_dynamic_raw() - * @see f_print_except_dynamic_partial_raw() - */ -#if !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) - extern f_status_t private_f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) - -/** - * Private implementation of f_print_except_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 if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. - * - * - * @see fwrite_unlocked() - * - * @see f_print_except_safely() - * @see f_print_except_dynamic_safely() - * @see f_print_except_dynamic_partial_safely() - * @see f_utf_is_valid() - */ -#if !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) - extern f_status_t private_f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) - -/** * Private implementation of f_print_except_in(). * * Intended to be shared to each of the different implementation variations. @@ -328,16 +174,10 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. + * F_data_not if there is nothing to print. * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() * @@ -371,16 +211,10 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. + * F_data_not if there is nothing to print. * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() * @@ -414,16 +248,10 @@ extern "C" { * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file stream is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_output (with error bit) on any other file output error. - * F_parameter (with error bit) if a parameter is invalid. + * F_data_not if there is nothing to print. * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() * @@ -437,71 +265,76 @@ extern "C" { #endif // !defined(_di_f_print_except_in_safely_) || !defined(_di_f_print_except_dynamic_in_safely_) || !defined(_di_f_print_except_in_dynamic_partial_safely_) /** - * Private implementation of f_print_terminated(). + * Private implementation of f_print_except_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 if length is 0. + * F_data_not if there is nothing to print. * - * F_block (with error bit) if output is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_type_directory (with error bit) if output represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * * @see fwrite_unlocked() * - * @see f_print_terminated() - * @see f_print_raw_terminated() + * @see f_print_except_raw() + * @see f_print_except_dynamic_raw() + * @see f_print_except_dynamic_partial_raw() */ -#if !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) - extern f_status_t private_f_print_terminated(const f_string_t string, FILE *output) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) +#if !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) + extern f_status_t private_f_print_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_except_raw_) || !defined(_di_f_print_except_dynamic_raw_) || !defined(_di_f_print_except_dynamic_partial_raw_) /** - * Private implementation of f_print_to(). + * Private implementation of f_print_except_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 id - * The file descriptor to output to. + * @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 if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * - * @see f_print_to() - * @see f_print_to_dynamic() - * @see f_print_to_dynamic_partial() + * @see fwrite_unlocked() + * + * @see f_print_except_safely() + * @see f_print_except_dynamic_safely() + * @see f_print_except_dynamic_partial_safely() + * @see f_utf_is_valid() */ -#if !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_dynamic_partial_) - extern f_status_t private_f_print_to(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_dynamic_partial_) +#if !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) + extern f_status_t private_f_print_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, FILE *output) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_except_safely_) || !defined(_di_f_print_except_dynamic_safely_) || !defined(_di_f_print_except_dynamic_partial_safely_) /** - * Private implementation of f_print_to_raw(). + * Private implementation of f_print_raw(). * * Intended to be shared to each of the different implementation variations. * @@ -509,32 +342,28 @@ extern "C" { * The string to output. * @param length * The total number of characters to print. - * @param id - * The file descriptor to output to. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * - * @see f_print_to_raw() - * @see f_print_to_dynamic_raw() - * @see f_print_to_dynamic_partial_raw() + * @see fwrite_unlocked() + * + * @see f_print_raw() + * @see f_print_raw_dynamic() + * @see f_print_raw_dynamic_partial() */ -#if !defined(_di_f_print_to_raw_) || !defined(_di_f_print_to_dynamic_raw_) || !defined(_di_f_print_to_dynamic_partial_raw_) - extern f_status_t private_f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_raw_) || !defined(_di_f_print_to_dynamic_raw_) || !defined(_di_f_print_to_dynamic_partial_raw_) +#if !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) + extern f_status_t private_f_print_raw(const f_string_t string, const f_array_length_t length, FILE *output) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_raw_) || !defined(_di_f_print_raw_dynamic_) || !defined(_di_f_print_raw_dynamic_partial_) /** - * Private implementation of f_print_to_safely(). + * Private implementation of f_print_safely(). * * Intended to be shared to each of the different implementation variations. * @@ -542,145 +371,52 @@ extern "C" { * The string to output. * @param length * The total number of characters to print. - * @param id - * The file descriptor to output to. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * - * @see f_print_to_safely() - * @see f_print_to_dynamic_safely() - * @see f_print_to_dynamic_partial_safely() + * @see fwrite_unlocked() + * + * @see f_print_safely() + * @see f_print_safely_dynamic() + * @see f_print_safely_dynamic_partial() * @see f_utf_is_valid() */ -#if !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_dynamic_partial_safely_) - extern f_status_t private_f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_dynamic_partial_safely_) +#if !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) + extern f_status_t private_f_print_safely(const f_string_t string, const f_array_length_t length, FILE *output) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_safely_) || !defined(_di_f_print_safely_dynamic_) || !defined(_di_f_print_safely_dynamic_partial_) /** - * Private implementation of f_print_to(). + * Private implementation of f_print_terminated(). * * 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 id - * The file descriptor to output to. + * @param output + * The file stream to output to, including standard streams such as stdout and stderr. * * @return * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. - * - * @see f_print_to_except() - * @see f_print_to_except_dynamic() - * @see f_print_to_except_dynamic_partial() - */ -#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) - extern f_status_t private_f_print_to_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) - -/** - * Private implementation of f_print_to_raw(). - * - * Intended to be shared to each of the different implementation variations. + * F_data_not if there is nothing to print. * - * @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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. + * F_output (with error bit) on failure. * F_parameter (with error bit) if a parameter is invalid. * - * @see f_print_to_except_raw() - * @see f_print_to_except_dynamic_raw() - * @see f_print_to_except_dynamic_partial_raw() - */ -#if !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) - extern f_status_t private_f_print_to_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) - -/** - * Private implementation of f_print_to_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 id - * The file descriptor to output to. - * - * @return - * F_none on success. - * F_data_not if length is 0. - * - * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. - * F_buffer (with error bit) if the buffer is invalid. - * F_file_closed (with error bit) if file is not open. - * F_file_descriptor (with error bit) if the file descriptor is invalid. - * F_file_type_directory (with error bit) if file descriptor represents a directory. - * F_input_output (with error bit) on I/O error. - * F_interrupt (with error bit) if interrupt was received. - * F_parameter (with error bit) if a parameter is invalid. + * @see fwrite_unlocked() * - * @see f_print_to_except_safely() - * @see f_print_to_except_dynamic_safely() - * @see f_print_to_except_dynamic_partial_safely() - * @see f_utf_is_valid() + * @see f_print_terminated() + * @see f_print_raw_terminated() */ -#if !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) - extern f_status_t private_f_print_to_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) +#if !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) + extern f_status_t private_f_print_terminated(const f_string_t string, FILE *output) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_terminated_) || !defined(_di_f_print_raw_terminated_) #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_print/c/private-print_to.c b/level_0/f_print/c/private-print_to.c new file mode 100644 index 0000000..30d2dce --- /dev/null +++ b/level_0/f_print/c/private-print_to.c @@ -0,0 +1,711 @@ +#include "print.h" +#include "private-print.h" +#include "private-print_to.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Inline helper function to reduce amount of code typed. + * + * This will process errno based on a write() error. + * + * @return + * The appropriate status. + */ +inline f_status_t private_inline_f_print_to_error() { + if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block); + if (errno == EBADF) return F_status_set_error(F_file_descriptor); + if (errno == EDESTADDRREQ) return F_status_set_error(F_socket_not); + if (errno == EDQUOT) return F_status_set_error(F_filesystem_quota_block); + if (errno == EFBIG) return F_status_set_error(F_number_overflow); + if (errno == EFAULT) return F_status_set_error(F_buffer); + if (errno == EINTR) return F_status_set_error(F_interrupt); + if (errno == EINVAL) return F_status_set_error(F_parameter); + if (errno == EIO) return F_status_set_error(F_input_output); + if (errno == EISDIR) return F_status_set_error(F_file_type_directory); + if (errno == ENOSPC) return F_status_set_error(F_space_not); + if (errno == EPIPE) return F_status_set_error(F_pipe); + + return F_status_set_error(F_output); +} + +#if !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + f_status_t private_f_print_to(const f_string_t string, const f_array_length_t length, const int id) { + + f_array_length_t total = 0; + + for (register f_array_length_t i = 0; i < length; ) { + + total = strnlen(string + i, length - i); + + if (total) { + if (total > F_print_write_max_d) { + total = F_print_write_max_d; + } + + if (write(id, string + i, total) == -1) { + return private_inline_f_print_to_error(); + } + + i += total; + total = 0; + } + + if (!string[i]) { + do { + ++i; + } while (i < length && !string[i]); + } + } // for + + return F_none; + } +#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_dynamic_to_) || !defined(_di_f_print_dynamic_partial_to_) + +#if !defined(_di_f_print_to_character_safely_) || !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_safely_dynamic_) || !defined(_di_f_print_to_safely_dynamic_partial_) || !defined(_di_f_print_to_safely_terminated_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + f_status_t private_f_print_to_character_safely(const char character, const int id) { + + if (character == 0x7f) { + if (write(id, f_print_sequence_delete_s, 3) != -1) { + return F_none; + } + } + else if (macro_f_utf_character_t_width_is(character) == 1) { + if (write(id, f_print_sequence_unknown_s, 3) != -1) { + return F_none; + } + } + else if (macro_f_utf_character_t_width_is(character) > 1 || character > 0x1f) { + if (write(id, &character, 1) != -1) { + return F_none; + } + } + else { + if (write(id, f_print_sequence_set_control_s, 3) != -1) { + return F_none; + } + } + + return private_inline_f_print_to_error(); + } +#endif // !defined(_di_f_print_to_character_safely_) || !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_safely_dynamic_) || !defined(_di_f_print_to_safely_dynamic_partial_) || !defined(_di_f_print_to_safely_terminated_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + +#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + f_status_t private_f_print_to_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { + + f_array_length_t i = offset; + f_array_length_t j = 0; + f_array_length_t start = offset; + f_array_length_t total = 0; + + while (i < stop) { + + while (j < except.used && except.array[j] < i) { + ++j; + } // while + + if (j >= except.used || except.array[j] != i) { + if (string[i] && total < F_print_write_max_d) { + ++total; + ++i; + + continue; + } + } + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + if ((j >= except.used || except.array[j] != i) && string[i]) { + start = i++; + total = 1; + } + else { + start = ++i; + total = 0; + } + } // while + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + +#if !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) + f_status_t private_f_print_to_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { + + f_array_length_t i = offset; + f_array_length_t j = 0; + f_array_length_t start = offset; + f_array_length_t total = 0; + + while (i < stop) { + + while (j < except.used && except.array[j] < i) { + ++j; + } // while + + if (j >= except.used || except.array[j] != i) { + if (total < F_print_write_max_d) { + ++total; + ++i; + + continue; + } + } + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + if (j >= except.used || except.array[j] != i) { + start = i++; + total = 1; + } + else { + start = ++i; + total = 0; + } + } // while + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) + +#if !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_safely_) + f_status_t private_f_print_to_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) { + + f_array_length_t i = offset; + f_array_length_t j = 0; + f_array_length_t start = offset; + f_array_length_t total = 0; + + f_status_t status = F_none; + f_string_t safe = 0; + + uint8_t width = 0; + + while (i < stop) { + + while (j < except.used && except.array[j] < i) { + ++j; + } // while + + if (j < except.used && except.array[j] == i) { + ++i; + continue; + } + + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); + } + else { + safe = 0; + } + + if (safe) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, safe, 3) == -1) { + return private_inline_f_print_to_error(); + } + + start = ++i; + continue; + } + + width = macro_f_utf_character_t_width(string[i]); + + status = f_utf_is_valid(string + i, width); + + if (F_status_is_error(status) || status == F_false || i + width >= stop) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, f_print_sequence_unknown_s, 3) == -1) { + return private_inline_f_print_to_error(); + } + + if (F_status_is_error(status) || status == F_false) { + i += width; + start = i; + } + else { + i = stop; + start = stop; + } + + continue; + } + + total += width; + i += width; + + if (total >= F_print_write_max_d) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + start = i; + } + } // while + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_safely_) + +#if !defined(_di_f_print_to_except_in_) || !defined(_di_f_print_to_except_in_dynamic_) || !defined(_di_f_print_to_except_in_dynamic_partial_) + f_status_t private_f_print_to_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + + f_array_length_t i = offset; + f_array_length_t at = 0; + f_array_length_t in = 0; + f_array_length_t start = i; + f_array_length_t total = 0; + + 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) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + start = ++i; + 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 + + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + i = except_in.array[in].stop + 1; + start = i; + continue; + } + } + + if (string[i]) { + ++total; + } + + if (!string[i] || i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + start = ++i; + } + else { + ++i; + } + } // while + + return F_none; + } +#endif // !defined(_di_f_print_to_except_in_) || !defined(_di_f_print_to_except_in_dynamic_) || !defined(_di_f_print_to_except_in_dynamic_partial_) + +#if !defined(_di_f_print_to_except_in_raw_) || !defined(_di_f_print_to_except_in_dynamic_raw_) || !defined(_di_f_print_to_except_in_dynamic_partial_raw_) + f_status_t private_f_print_to_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + + f_array_length_t i = offset; + f_array_length_t at = 0; + f_array_length_t in = 0; + f_array_length_t start = i; + f_array_length_t total = 0; + + 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) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + start = ++i; + 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 + + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + i = except_in.array[in].stop + 1; + start = i; + continue; + } + } + + ++total; + + if (i + 1 == stop || total == F_print_write_max_d) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + start = ++i; + } + else { + ++i; + } + } // while + + return F_none; + } +#endif // !defined(_di_f_print_to_except_in_raw_) || !defined(_di_f_print_to_except_in_dynamic_raw_) || !defined(_di_f_print_to_except_in_dynamic_partial_raw_) + +#if !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + f_status_t private_f_print_to_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, const f_string_ranges_t except_in, const int id) { + + f_array_length_t i = offset; + f_array_length_t at = 0; + f_array_length_t in = 0; + f_array_length_t start = i; + f_array_length_t total = 0; + + f_status_t status = F_none; + f_string_t safe = 0; + + uint8_t width = 0; + + 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) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + start = ++i; + 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 + + if (in < except_in.used && except_in.array[in].start <= i && except_in.array[in].stop >= i) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + i = except_in.array[in].stop + 1; + start = i; + continue; + } + } + + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); + } + else { + safe = 0; + } + + if (safe) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, safe, 3) == -1) { + return private_inline_f_print_to_error(); + } + + start = ++i; + continue; + } + + width = macro_f_utf_character_t_width(string[i]); + + status = f_utf_is_valid(string + i, width); + + if (F_status_is_error(status) || status == F_false || i + width >= stop) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, f_print_sequence_unknown_s, 3) == -1) { + return private_inline_f_print_to_error(); + } + + if (F_status_is_error(status) || status == F_false) { + i += width; + start = i; + } + else { + i = stop; + start = stop; + } + + continue; + } + + total += width; + i += width; + + if (total >= F_print_write_max_d) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + start = i; + } + } // while + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + +#if !defined(_di_f_print_to_raw_) || !defined(_di_f_print_dynamic_to_raw_) || !defined(_di_f_print_dynamic_partial_to_raw_) + f_status_t private_f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) { + + f_array_length_t start = 0; + f_array_length_t total = 0; + + for (register f_array_length_t i = 0; i < length; ) { + + total = strnlen(string + i, length - i); + + if (total) { + if (total > F_print_write_max_d) { + total = F_print_write_max_d; + } + + if (write(id, string + i, total) == -1) { + return private_inline_f_print_to_error(); + } + + i += total; + total = 0; + } + + // Print all NULL characters. + if (!string[i]) { + start = i; + + do { + ++i; + ++total; + + } while (i < length && !string[i] && total < F_print_write_max_d); + + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + } // for + + return F_none; + } +#endif // !defined(_di_f_print_to_raw_) || !defined(_di_f_print_dynamic_to_raw_) || !defined(_di_f_print_dynamic_partial_to_raw_) + +#if !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_dynamic_partial_safely_) || !defined(_di_f_print_to_safely_) + f_status_t private_f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) { + + f_status_t status = F_none; + + register f_array_length_t i = 0; + f_array_length_t start = 0; + f_array_length_t total = 0; + + f_string_t safe = 0; + + uint8_t width = 0; + + while (i < length) { + + if (string[i]) { + safe = private_f_print_character_safely_get(string[i]); + } + else { + safe = 0; + } + + if (safe) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, safe, 3) == -1) { + return private_inline_f_print_to_error(); + } + + start = ++i; + continue; + } + + width = macro_f_utf_character_t_width(string[i]); + + status = f_utf_is_valid(string + i, width); + + if (F_status_is_error(status) || status == F_false || i + width >= length) { + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + } + + if (write(id, f_print_sequence_unknown_s, 3) == -1) { + return private_inline_f_print_to_error(); + } + + if (F_status_is_error(status) || status == F_false) { + i += width; + start = i; + } + else { + i = length; + start = length; + } + + continue; + } + + total += width; + i += width; + + if (total >= F_print_write_max_d) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + + total = 0; + start = i; + } + } // while + + if (total) { + if (write(id, string + start, total) == -1) { + return private_inline_f_print_to_error(); + } + } + + return F_none; + } +#endif // !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_dynamic_partial_to_safely_) || !defined(_di_f_print_to_safely_) + +#if !defined(_di_f_print_to_terminated_) || !defined(_di_f_print_to_raw_terminated_) + f_status_t private_f_print_to_terminated(const f_string_t string, const int id) { + + if (write(id, string, strlen(string)) == -1) { + return private_inline_f_print_to_error(); + } + + return F_none; + } +#endif // !defined(_di_f_print_to_terminated_) || !defined(_di_f_print_to_raw_terminated_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_print/c/private-print_to.h b/level_0/f_print/c/private-print_to.h new file mode 100644 index 0000000..a2382d1 --- /dev/null +++ b/level_0/f_print/c/private-print_to.h @@ -0,0 +1,489 @@ +/** + * FLL - Level 0 + * + * Project: Print + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_print_to_h +#define _PRIVATE_F_print_to_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation of f_print_to(). + * + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to() + * @see f_print_to_dynamic() + * @see f_print_to_dynamic_partial() + */ +#if !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_dynamic_partial_) + extern f_status_t private_f_print_to(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_) || !defined(_di_f_print_to_dynamic_) || !defined(_di_f_print_to_dynamic_partial_) + +/** + * Private implementation of f_print_to_character_safely(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param character + * The character to verify as safe or not. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_character_safely() + * @see f_print_to_safely() + * @see f_print_to_safely_dynamic() + * @see f_print_to_safely_dynamic_partial() + * @see f_print_to_safely_terminated() + * @see f_print_to_except_safely() + * @see f_print_to_except_dynamic_safely() + * @see f_print_to_except_dynamic_partial_safely() + * @see f_print_to_except_in_safely() + * @see f_print_to_except_in_dynamic_safely() + * @see f_print_to_except_in_dynamic_partial_safely() + */ +#if !defined(_di_f_print_to_character_safely_) || !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_safely_dynamic_) || !defined(_di_f_print_to_safely_dynamic_partial_) || !defined(_di_f_print_to_safely_terminated_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + extern f_status_t private_f_print_to_character_safely(const char character, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_character_safely_) || !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_safely_dynamic_) || !defined(_di_f_print_to_safely_dynamic_partial_) || !defined(_di_f_print_to_safely_terminated_) || !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) || !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + +/** + * Private implementation of f_print_to(). + * + * 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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_except() + * @see f_print_to_except_dynamic() + * @see f_print_to_except_dynamic_partial() + */ +#if !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) + extern f_status_t private_f_print_to_except(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_) || !defined(_di_f_print_to_except_dynamic_) || !defined(_di_f_print_to_except_dynamic_partial_) +/** + * Private implementation of f_print_to_except_in(). + * + * 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_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + * + * @see f_print_to_except_in() + * @see f_print_to_except_in_dynamic() + * @see f_print_to_except_in_dynamic_partial() + */ +#if !defined(_di_f_print_to_except_in_) || !defined(_di_f_print_to_except_dynamic_in_) || !defined(_di_f_print_to_except_in_dynamic_partial_) + extern f_status_t private_f_print_to_except_in(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, f_string_ranges_t except_in, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_in_) || !defined(_di_f_print_to_except_dynamic_in_) || !defined(_di_f_print_to_except_in_dynamic_partial_) + +/** + * Private implementation of f_print_to_except_in_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_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + * + * @see f_print_to_except_in_raw() + * @see f_print_to_except_in_dynamic_raw() + * @see f_print_to_except_in_dynamic_partial_raw() + */ +#if !defined(_di_f_print_to_except_in_raw_) || !defined(_di_f_print_to_except_dynamic_in_raw_) || !defined(_di_f_print_to_except_in_dynamic_partial_raw_) + extern f_status_t private_f_print_to_except_in_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, f_string_ranges_t except_in, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_in_raw_) || !defined(_di_f_print_to_except_dynamic_in_raw_) || !defined(_di_f_print_to_except_in_dynamic_partial_raw_) + +/** + * Private implementation of f_print_to_except_in_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_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_output (with error bit) on failure. + * F_parameter (with error bit) if a parameter is invalid. + * + * @see write() + * + * @see f_print_to_except_in_safely() + * @see f_print_to_except_in_dynamic_safely() + * @see f_print_to_except_in_dynamic_partial_safely() + * @see f_utf_is_valid() + */ +#if !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_dynamic_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + extern f_status_t private_f_print_to_except_in_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except_at, f_string_ranges_t except_in, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_in_safely_) || !defined(_di_f_print_to_except_dynamic_in_safely_) || !defined(_di_f_print_to_except_in_dynamic_partial_safely_) + +/** + * Private implementation of f_print_to_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_except_raw() + * @see f_print_to_except_dynamic_raw() + * @see f_print_to_except_dynamic_partial_raw() + */ +#if !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) + extern f_status_t private_f_print_to_except_raw(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_raw_) || !defined(_di_f_print_to_except_dynamic_raw_) || !defined(_di_f_print_to_except_dynamic_partial_raw_) + +/** + * Private implementation of f_print_to_except_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_except_safely() + * @see f_print_to_except_dynamic_safely() + * @see f_print_to_except_dynamic_partial_safely() + * @see f_utf_is_valid() + */ +#if !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) + extern f_status_t private_f_print_to_except_safely(const f_string_t string, const f_array_length_t offset, const f_array_length_t stop, const f_array_lengths_t except, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_except_safely_) || !defined(_di_f_print_to_except_dynamic_safely_) || !defined(_di_f_print_to_except_dynamic_partial_safely_) + +/** + * Private implementation of f_print_to_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_raw() + * @see f_print_to_dynamic_raw() + * @see f_print_to_dynamic_partial_raw() + */ +#if !defined(_di_f_print_to_raw_) || !defined(_di_f_print_to_dynamic_raw_) || !defined(_di_f_print_to_dynamic_partial_raw_) + extern f_status_t private_f_print_to_raw(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_raw_) || !defined(_di_f_print_to_dynamic_raw_) || !defined(_di_f_print_to_dynamic_partial_raw_) + +/** + * Private implementation of f_print_to_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 id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_safely() + * @see f_print_to_dynamic_safely() + * @see f_print_to_dynamic_partial_safely() + * @see f_utf_is_valid() + */ +#if !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_dynamic_partial_safely_) + extern f_status_t private_f_print_to_safely(const f_string_t string, const f_array_length_t length, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_safely_) || !defined(_di_f_print_to_dynamic_safely_) || !defined(_di_f_print_to_dynamic_partial_safely_) + +/** + * Private implementation of f_print_to_terminated(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param string + * The string to output. + * @param id + * The file descriptor to output to. + * + * @return + * F_none on success. + * F_data_not if there is nothing to print. + * + * F_block (with error bit) if file descriptor is set to non-block and the write would result in a blocking operation. + * F_buffer (with error bit) if the buffer is invalid. + * F_file_closed (with error bit) if file is not open. + * F_file_descriptor (with error bit) if the file descriptor is invalid. + * F_file_type_directory (with error bit) if file descriptor represents a directory. + * F_filesystem_quota_block (with error bit) if quota is reached or exceeded. + * F_input_output (with error bit) on I/O error. + * F_interrupt (with error bit) if interrupt was received. + * F_number_overflow (with error bit) if maximum size reached while writing or attempting to write beyond maximum allowed offset. + * F_parameter (with error bit) if a parameter is invalid. + * F_pipe (with error bit) if a connected pipe or socket is closed. + * F_space_not (with error bit) cannot write, out of space. + * F_socket_not (with error bit) if socket is not connected. + * + * F_output (with error bit) on any other failure. + * + * @see write() + * + * @see f_print_to_terminated() + * @see f_print_to_raw_terminated() + */ +#if !defined(_di_f_print_to_terminated_) || !defined(_di_f_print_to_raw_terminated_) + extern f_status_t private_f_print_to_terminated(const f_string_t string, const int id) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_print_to_terminated_) || !defined(_di_f_print_to_raw_terminated_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_print_to_h diff --git a/level_0/f_print/data/build/settings b/level_0/f_print/data/build/settings index c6be3b0..2a47310 100644 --- a/level_0/f_print/data/build/settings +++ b/level_0/f_print/data/build/settings @@ -24,13 +24,13 @@ build_libraries -lc build_libraries-individual -lf_memory -lf_string -lf_utf build_libraries_shared build_libraries_static -build_sources_library print.c print-common.c private-print.c +build_sources_library print.c print_to.c print-common.c private-print.c private-print_to.c build_sources_library_shared build_sources_library_static build_sources_program build_sources_program_shared build_sources_program_static -build_sources_headers print.h print-common.h +build_sources_headers print.h print_to.h print-common.h build_sources_headers_shared build_sources_headers_static build_sources_script -- 1.8.3.1