From 240aceb2d24db1d4a59b73a74107bd94deae2124 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Fri, 19 Nov 2021 21:26:18 -0600 Subject: [PATCH] Progress: Major UTF-8 changes and optimization, begin updating byte_dump and utf8, and miscellaneous changes. A previous commit accidentally include the utf8 level 3 program while it was being heavily developed. As it is already committed, commit the latest changes. The utf8 program is still not done. While working on the utf program, I noticed that there are some things in the UTF-8 code that is not yet done or correct and is needed. I also noticed that the byte_dump program needs to handle the narrow and wide widths to assure consistent column line ups. Such a change requires new functionality in the UTF-8 code for processing the widths. These two significant needs resulted in me finally getting around to some of the UTF-8 cleanup that I have been needing to do. - Get rid of the width parameter, and calculate the width as needed (bitwise is chip and allocated a variable and then passing it along parameters is not as cheap). - Swap some of the conditions to avoid using "!", saving a single operation though structural changes. - Break out the utf string functions into its own utf_string.c, utf_string.h, private-utf_string.c, and private-utf_string.h. - Numerous documentation comment cleanups and update (I think there is still more to do). - Provide F_utf_fragment and F_utf_fragment_not for improved communication of UTF-8 fragments in error responses (rather than re-using F_utf). - Provide f_utf_unicode_string_from() (I have not yet written a f_utf_unicode_string_to() but I plan to). - Update endianess detection to use macros (I am include , but I may also provide custom macros to disable and explicitly designate endianess). The UTF-8 is wide functions are drafted out, but there are a lot of wide character codes that I need to add. This will be grunt work that will take a notable amount of time. For now, just add a comment and I will get back to this. The byte_dump program is depending on the is wide functions and so currently incompletely implements the narrow and wide support. Try to use present tense in error message. There are likely many more places, but this is a start. Add F_first, F_first_not, F_last, F_last_not, F_next, F_next_not, F_previous, and F_previous_not for providing position return codes. Fix a bug where width is being define by a uint8_t but the calculates are f_array_length_t. How did this ever work before, by accident? --- build/level_0/settings | 4 +- build/monolithic/settings | 4 +- level_0/f_file/c/file.h | 10 +- level_0/f_status/c/status.h | 10 + level_0/f_utf/c/private-utf.c | 736 ++----- level_0/f_utf/c/private-utf.h | 712 +------ level_0/f_utf/c/private-utf_string.c | 496 +++++ level_0/f_utf/c/private-utf_string.h | 529 +++++ level_0/f_utf/c/utf-common.c | 1 + level_0/f_utf/c/utf-common.h | 24 + level_0/f_utf/c/utf.c | 2032 +++++++++----------- level_0/f_utf/c/utf.h | 709 +++---- level_0/f_utf/c/utf_dynamic.c | 1 + level_0/f_utf/c/utf_dynamic.h | 15 +- level_0/f_utf/c/utf_map.c | 1 + level_0/f_utf/c/utf_map.h | 4 +- level_0/f_utf/c/utf_string.c | 377 ++++ level_0/f_utf/c/utf_string.h | 423 ++++ level_0/f_utf/c/utf_triple.c | 1 + level_0/f_utf/c/utf_triple.h | 4 +- level_0/f_utf/data/build/settings | 4 +- level_1/fl_conversion/c/conversion.c | 4 +- level_1/fl_status/c/status.c | 30 + level_1/fl_status/c/status.h | 20 + level_1/fl_string/c/private-string.c | 48 +- level_2/fll_status/c/status.c | 60 + level_3/byte_dump/c/byte_dump.c | 16 +- level_3/byte_dump/c/byte_dump.h | 37 +- level_3/byte_dump/data/build/settings | 2 +- level_3/control/data/build/settings | 2 +- level_3/controller/c/controller.c | 6 +- level_3/controller/c/private-rule.c | 1 + level_3/fake/c/private-build.c | 2 +- level_3/fake/c/private-print.c | 2 +- level_3/fss_basic_list_read/data/build/settings | 2 +- .../fss_basic_list_write/c/fss_basic_list_write.c | 2 +- .../c/private-fss_basic_list_write.c | 2 +- level_3/fss_basic_list_write/data/build/settings | 2 +- level_3/fss_basic_read/data/build/settings | 2 +- level_3/fss_basic_write/c/fss_basic_write.c | 2 +- .../fss_basic_write/c/private-fss_basic_write.c | 2 +- level_3/fss_basic_write/data/build/settings | 2 +- level_3/fss_embedded_list_read/data/build/settings | 2 +- .../c/fss_embedded_list_write.c | 2 +- .../c/private-fss_embedded_list_write.c | 2 +- .../fss_embedded_list_write/data/build/settings | 2 +- level_3/fss_extended_list_read/data/build/settings | 2 +- .../c/fss_extended_list_write.c | 2 +- .../c/private-fss_extended_list_write.c | 2 +- .../fss_extended_list_write/data/build/settings | 2 +- level_3/fss_extended_read/data/build/settings | 2 +- level_3/fss_extended_write/c/fss_extended_write.c | 2 +- .../c/private-fss_extended_write.c | 2 +- level_3/fss_extended_write/data/build/settings | 2 +- level_3/fss_identify/data/build/settings | 2 +- level_3/fss_status_code/data/build/settings | 2 +- level_3/iki_write/c/iki_write.c | 6 +- level_3/iki_write/data/build/settings | 2 +- level_3/status_code/data/build/settings | 2 +- level_3/utf8/c/private-common.c | 147 +- level_3/utf8/c/private-common.h | 170 +- level_3/utf8/c/private-print.c | 192 ++ level_3/utf8/c/private-print.h | 164 ++ level_3/utf8/c/private-utf8.c | 347 +--- level_3/utf8/c/private-utf8.h | 142 +- level_3/utf8/c/private-utf8_binary.c | 158 ++ level_3/utf8/c/private-utf8_binary.h | 67 + level_3/utf8/c/private-utf8_codepoint.c | 260 +++ level_3/utf8/c/private-utf8_codepoint.h | 88 + level_3/utf8/c/utf8.c | 137 +- level_3/utf8/c/utf8.h | 42 +- level_3/utf8/data/build/settings | 2 +- 72 files changed, 4585 insertions(+), 3712 deletions(-) create mode 100644 level_0/f_utf/c/private-utf_string.c create mode 100644 level_0/f_utf/c/private-utf_string.h create mode 100644 level_0/f_utf/c/utf_string.c create mode 100644 level_0/f_utf/c/utf_string.h create mode 100644 level_3/utf8/c/private-print.c create mode 100644 level_3/utf8/c/private-print.h create mode 100644 level_3/utf8/c/private-utf8_binary.c create mode 100644 level_3/utf8/c/private-utf8_binary.h create mode 100644 level_3/utf8/c/private-utf8_codepoint.c create mode 100644 level_3/utf8/c/private-utf8_codepoint.h diff --git a/build/level_0/settings b/build/level_0/settings index 3690eeb..eb9ca4b 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_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 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 utf_dynamic.c utf_map.c utf_string.c utf_triple.c private-utf.c private-utf_string.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_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 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_string.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 73d48ea..0d2ae20 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_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 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/utf_dynamic.c level_0/utf_map.c level_0/utf_string.c level_0/utf_triple.c level_0/private-utf.c level_0/private-utf_string.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_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 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_string.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_file/c/file.h b/level_0/f_file/c/file.h index 0a7696e..e2af559 100644 --- a/level_0/f_file/c/file.h +++ b/level_0/f_file/c/file.h @@ -1967,9 +1967,17 @@ extern "C" { * @param path * The file path * @param mode - * The file modes do use when opening. + * The file modes do use when opening, as an fopen() file mode string. * Set to 0 to determine mode from file.flags (falling back to read only as a failsafe). * If neither truncate nor append are not specified in write only mode, then the failsafe is to append. + * + * File Modes (fopen() file modes vs open file modes): + * - "r": O_RDONLY. + * - "w": O_WRONLY | O_CREAT | O_TRUNC. + * - "a": O_WRONLY | O_CREAT | O_APPEND. + * - "r+": O_RDWR. + * - "w+": O_RDWR | O_CREAT | O_TRUNC. + * - "a+": O_RDWR | O_CREAT | O_APPEND. * @param file * The file information. * The file.stream is updated if necessary. diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index 0df5d77..622517f 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -205,6 +205,8 @@ extern "C" { F_exist_not, F_failure, F_failure_not, + F_first, + F_first_not, F_fork, F_fork_not, F_format, @@ -226,6 +228,8 @@ extern "C" { F_interrupt_not, F_known, F_known_not, + F_last, + F_last_not, F_limit, F_limit_not, F_link, @@ -248,6 +252,8 @@ extern "C" { F_mount_not, F_name, F_name_not, + F_next, + F_next_not, F_nice, F_nice_not, F_optional, @@ -262,6 +268,8 @@ extern "C" { F_pipe_not, F_port, F_port_not, + F_previous, + F_previous_not, F_processor, F_processor_not, F_prohibited, @@ -312,6 +320,8 @@ extern "C" { F_user, F_user_not, F_utf, + F_utf_fragment, + F_utf_fragment_not, F_utf_not, F_valid, F_valid_not, diff --git a/level_0/f_utf/c/private-utf.c b/level_0/f_utf/c/private-utf.c index beed62c..9917dae 100644 --- a/level_0/f_utf/c/private-utf.c +++ b/level_0/f_utf/c/private-utf.c @@ -5,39 +5,38 @@ extern "C" { #endif -#if !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) +#if !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_wide_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) f_status_t private_f_utf_char_to_character(const f_string_t character, const f_array_length_t width_max, f_utf_character_t *character_utf) { - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { + if (!macro_f_utf_byte_width_is(*character)) { *character_utf = macro_f_utf_character_t_from_char_1(character[0]); return F_none; } - else if (width == 1) { - return F_status_is_error(F_utf); + + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - if (width > width_max) { + if (macro_f_utf_byte_width_is(*character) > width_max) { return F_status_set_error(F_failure); } *character_utf = macro_f_utf_character_t_from_char_1(character[0]); - if (width < 2) { + if (macro_f_utf_byte_width_is(*character) < 2) { return F_none; } *character_utf |= macro_f_utf_character_t_from_char_2(character[1]); - if (width == 2) { + if (macro_f_utf_byte_width_is(*character) == 2) { return F_none; } *character_utf |= macro_f_utf_character_t_from_char_3(character[2]); - if (width == 3) { + if (macro_f_utf_byte_width_is(*character) == 3) { return F_none; } @@ -45,49 +44,49 @@ extern "C" { return F_none; } -#endif // !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) +#endif // !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_wide_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) #if !defined(_di_f_utf_character_is_alpha_) || !defined(_di_f_utf_is_alpha_) - f_status_t private_f_utf_character_is_alpha(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_alpha(const f_utf_character_t character) { - if (private_f_utf_character_is_zero_width(character, width)) { + if (private_f_utf_character_is_zero_width(character)) { return F_false; } // is_control() handles both is_control_code() and is_control_format(). - if (private_f_utf_character_is_control(character, width)) { + if (private_f_utf_character_is_control(character)) { return F_false; } - if (private_f_utf_character_is_control_picture(character, width)) { + if (private_f_utf_character_is_control_picture(character)) { return F_false; } - if (private_f_utf_character_is_combining(character, width)) { + if (private_f_utf_character_is_combining(character)) { return F_false; } - if (private_f_utf_character_is_whitespace(character, width)) { + if (private_f_utf_character_is_whitespace(character)) { return F_false; } - if (private_f_utf_character_is_whitespace_modifier(character, width)) { + if (private_f_utf_character_is_whitespace_modifier(character)) { return F_false; } - if (private_f_utf_character_is_numeric(character, width)) { + if (private_f_utf_character_is_numeric(character)) { return F_false; } - if (private_f_utf_character_is_punctuation(character, width)) { + if (private_f_utf_character_is_punctuation(character)) { return F_false; } - if (private_f_utf_character_is_symbol(character, width)) { + if (private_f_utf_character_is_symbol(character)) { return F_false; } - if (private_f_utf_character_is_phonetic(character, width)) { + if (private_f_utf_character_is_phonetic(character)) { return F_false; } @@ -96,46 +95,46 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_alpha_) || !defined(_di_f_utf_is_alpha_) #if !defined(_di_f_utf_character_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_digit_) - f_status_t private_f_utf_character_is_alpha_digit(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_alpha_digit(const f_utf_character_t character) { - if (private_f_utf_character_is_digit(character, width)) { + if (private_f_utf_character_is_digit(character)) { return F_true; } - if (private_f_utf_character_is_zero_width(character, width)) { + if (private_f_utf_character_is_zero_width(character)) { return F_false; } // is_control() handles both is_control_code() and is_control_format(). - if (private_f_utf_character_is_control(character, width)) { + if (private_f_utf_character_is_control(character)) { return F_false; } - if (private_f_utf_character_is_control_picture(character, width)) { + if (private_f_utf_character_is_control_picture(character)) { return F_false; } - if (private_f_utf_character_is_whitespace(character, width)) { + if (private_f_utf_character_is_whitespace(character)) { return F_false; } - if (private_f_utf_character_is_whitespace_modifier(character, width)) { + if (private_f_utf_character_is_whitespace_modifier(character)) { return F_false; } - if (private_f_utf_character_is_numeric(character, width)) { + if (private_f_utf_character_is_numeric(character)) { return F_false; } - if (private_f_utf_character_is_punctuation(character, width)) { + if (private_f_utf_character_is_punctuation(character)) { return F_false; } - if (private_f_utf_character_is_symbol(character, width)) { + if (private_f_utf_character_is_symbol(character)) { return F_false; } - if (private_f_utf_character_is_phonetic(character, width)) { + if (private_f_utf_character_is_phonetic(character)) { return F_false; } @@ -144,42 +143,42 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_digit_) #if !defined(_di_f_utf_character_is_alpha_numeric_) || !defined(_di_f_utf_is_alpha_numeric_) - f_status_t private_f_utf_character_is_alpha_numeric(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_alpha_numeric(const f_utf_character_t character) { - if (private_f_utf_character_is_numeric(character, width)) { + if (private_f_utf_character_is_numeric(character)) { return F_true; } - if (private_f_utf_character_is_zero_width(character, width)) { + if (private_f_utf_character_is_zero_width(character)) { return F_false; } // is_control() handles both is_control_code() and is_control_format(). - if (private_f_utf_character_is_control(character, width)) { + if (private_f_utf_character_is_control(character)) { return F_false; } - if (private_f_utf_character_is_control_picture(character, width)) { + if (private_f_utf_character_is_control_picture(character)) { return F_false; } - if (private_f_utf_character_is_whitespace(character, width)) { + if (private_f_utf_character_is_whitespace(character)) { return F_false; } - if (private_f_utf_character_is_whitespace_modifier(character, width)) { + if (private_f_utf_character_is_whitespace_modifier(character)) { return F_false; } - if (private_f_utf_character_is_punctuation(character, width)) { + if (private_f_utf_character_is_punctuation(character)) { return F_false; } - if (private_f_utf_character_is_symbol(character, width)) { + if (private_f_utf_character_is_symbol(character)) { return F_false; } - if (private_f_utf_character_is_phonetic(character, width)) { + if (private_f_utf_character_is_phonetic(character)) { return F_false; } @@ -188,9 +187,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_alpha_numeric_) || !defined(_di_f_utf_is_alpha_numeric_) #if !defined(_di_f_utf_character_is_ascii_) || !defined(_di_f_utf_is_ascii_) - f_status_t private_f_utf_character_is_ascii(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_ascii(const f_utf_character_t character) { - if (width < 2) { + if (macro_f_utf_character_t_width_is(character) < 2) { const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); if (byte_first >= 0x00 && byte_first <= 0x7f) { @@ -203,9 +202,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_ascii_) || !defined(_di_f_utf_is_ascii_) #if !defined(_di_f_utf_character_is_combining_) || !defined(_di_f_utf_is_combining_) - f_status_t private_f_utf_character_is_combining(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_combining(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Diacritical Marks: U+0300 to U+036F. if (character >= 0xcc800000 && character <= 0xcdaf0000) { @@ -214,7 +213,8 @@ extern "C" { return F_false; } - else if (width == 3) { + + if (macro_f_utf_character_t_width_is(character) == 3) { // Diacritical Marks Extended: U+1AB0 to U+1AC0. if (character >= 0xe1aab000 && character <= 0xe1ab8000) { @@ -247,9 +247,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_combining_) || !defined(_di_f_utf_is_combining_) #if !defined(_di_f_utf_character_is_control_) || !defined(_di_f_utf_is_control_) - f_status_t private_f_utf_character_is_control(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_control(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Control Codes. @@ -280,7 +280,7 @@ extern "C" { return F_true; } } - else if (width == 3) { + else if (macro_f_utf_character_t_width_is(character) == 3) { // Control Formats. @@ -324,7 +324,7 @@ extern "C" { return F_true; } } - else if (width == 4) { + else if (macro_f_utf_character_t_width_is(character) == 4) { // Control Formats. @@ -364,9 +364,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_control_) || !defined(_di_f_utf_is_control_) #if !defined(_di_f_utf_character_is_control_code_) || !defined(_di_f_utf_is_control_code_) - f_status_t private_f_utf_character_is_control_code(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_control_code(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Latin-1 Supplement: U+0080 to U+009F. if (character >= 0xc2800000 && character <= 0xc29f0000) { @@ -379,9 +379,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_control_code_) || !defined(_di_f_utf_is_contro_codel_) #if !defined(_di_f_utf_character_is_control_format_) || !defined(_di_f_utf_is_control_format_) - f_status_t private_f_utf_character_is_control_format(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_control_format(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Latin-1 Supplement: U+00AD. if (character == 0xc2ad0000) { @@ -403,7 +403,7 @@ extern "C" { return F_true; } } - else if (width == 3) { + else if (macro_f_utf_character_t_width_is(character) == 3) { // Arabic Extended-A: U+08E2. if (character == 0xe0a3a200) { @@ -445,7 +445,7 @@ extern "C" { return F_true; } } - else if (width == 4) { + else if (macro_f_utf_character_t_width_is(character) == 4) { // Kaithi: U+110BD, U+110CD. if (character == 0xf09182bd || character == 0xf091838d) { @@ -483,9 +483,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_control_format_) || !defined(_di_f_utf_is_control_format_) #if !defined(_di_f_utf_character_is_control_picture_) || !defined(_di_f_utf_is_control_picture_) - f_status_t private_f_utf_character_is_control_picture(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_control_picture(const f_utf_character_t character) { - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // Control Pictures: U+2400 to U+2426. if (character >= 0xe2908000 && character <= 0xe290a600) { return F_true; @@ -502,9 +502,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_control_picture_) || !defined(_di_f_utf_is_control_picture_) #if !defined(_di_f_utf_character_is_digit_) || !defined(_di_f_utf_is_digit_) - f_status_t private_f_utf_character_is_digit(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_digit(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { uint16_t bytes = (uint16_t) ((character & 0xffff0000) >> 16); // Arabic: U+0660 to U+0669. @@ -528,7 +528,7 @@ extern "C" { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { uint16_t bytes = (uint16_t) ((character & 0x00ffff00) >> 8); if (byte_first == 0xe0) { @@ -711,7 +711,7 @@ extern "C" { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_second = macro_f_utf_character_t_to_char_2(character); - if (width == 4) { + if (macro_f_utf_character_t_width_is(character) == 4) { uint16_t bytes = (uint16_t) ((character & 0xffff0000) >> 16); if (byte_first == 0xf0) { @@ -875,9 +875,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_digit_) || !defined(_di_f_utf_is_digit_) #if !defined(_di_f_utf_character_is_emoji_) || !defined(_di_f_utf_is_emoji_) - f_status_t private_f_utf_character_is_emoji(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_emoji(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Latin-1 Supplement: U+00A9, U+00AE. if (character == 0xc2a90000 || character == 0xc2ae0000) { @@ -887,7 +887,7 @@ extern "C" { return F_false; } - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // General Punctuation: U+203C, U+2049. if (character == 0xe280bc00 || character == 0xe2818900) { @@ -1122,7 +1122,7 @@ extern "C" { return F_false; } - if (width == 4) { + if (macro_f_utf_character_t_width_is(character) == 4) { // U+1F0CF to U+1F171. if (character >= 0xf09f8084 && character <= 0xf09f85b1) { @@ -1365,23 +1365,23 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_emoji_) || !defined(_di_f_utf_is_emoji_) #if !defined(_di_f_utf_character_is_numeric_) || !defined(_di_f_utf_is_numeric_) - f_status_t private_f_utf_character_is_numeric(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_numeric(const f_utf_character_t character) { - if (private_f_utf_character_is_digit(character, width)) { + if (private_f_utf_character_is_digit(character)) { return F_true; } // @todo add letter UTF-8 numbers. // @todo add other UTF-8 numbers. - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // Number Forms: U+2150 to U+218B. if (character >= 0xe2859000 && character <= 0xe2868b00) { return F_true; } } - else if (width == 4) { + else if (macro_f_utf_character_t_width_is(character) == 4) { // Coptic Epact Numbers: U+102E1 to U+102FB. if (character >= 0xf0908ba1 && character <= 0xf0908bbb) { @@ -1394,9 +1394,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_numeric_) || !defined(_di_f_utf_is_numeric_) #if !defined(_di_f_utf_character_is_phonetic_) || !defined(_di_f_utf_is_phonetic_) - f_status_t private_f_utf_character_is_phonetic(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_phonetic(const f_utf_character_t character) { - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // Phonetic Extensions: U+1D00 to U+1D7F. if (character >= 0xe1b48000 && character <= 0xe1b5bf00) { @@ -1414,9 +1414,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_phonetic_) || !defined(_di_f_utf_is_phonetic_) #if !defined(_di_f_utf_character_is_private_) || !defined(_di_f_utf_is_private_) - f_status_t private_f_utf_character_is_private(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_private(const f_utf_character_t character) { - if (width < 3) { + if (macro_f_utf_character_t_width_is(character) < 3) { return F_false; } @@ -1425,7 +1425,7 @@ extern "C" { const uint8_t byte_second = macro_f_utf_character_t_to_char_2(character); const uint8_t byte_third = macro_f_utf_character_t_to_char_3(character); - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { if (byte_first >= 0xe0 && byte_first <= 0xef) { if (byte_second >= 0x80 && byte_second <= 0x8f) { @@ -1441,7 +1441,7 @@ extern "C" { const uint8_t byte_fourth = macro_f_utf_character_t_to_char_4(character); - if (width == 4) { + if (macro_f_utf_character_t_width_is(character) == 4) { if (byte_first == 0xf3) { if (byte_second >= 0x80 && byte_second <= 0xbf) { if (byte_third >= 0x80 && byte_third <= 0xbf) { @@ -1472,12 +1472,12 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_private_) || !defined(_di_f_utf_is_private_) #if !defined(_di_f_utf_character_is_punctuation_) || !defined(_di_f_utf_is_punctuation_) - f_status_t private_f_utf_character_is_punctuation(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_punctuation(const f_utf_character_t character) { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { if (byte_first == 0xc2) { // Latin-1 Supplement: U+00A1, U+00A7, U+00B6, U+00B7. @@ -1564,7 +1564,7 @@ extern "C" { } } } - else if (width == 3) { + else if (macro_f_utf_character_t_width_is(character) == 3) { if (byte_first == 0xe0) { @@ -1899,7 +1899,7 @@ extern "C" { } } } - else if (width == 4) { + else if (macro_f_utf_character_t_width_is(character) == 4) { uint8_t byte_second = macro_f_utf_character_t_to_char_2(character); if (byte_first == 0xf0) { @@ -2139,7 +2139,7 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_punctuation_) || !defined(_di_f_utf_is_punctuation_) #if !defined(_di_f_utf_character_is_symbol_) || !defined(_di_f_utf_is_symbol_) - f_status_t private_f_utf_character_is_symbol(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_symbol(const f_utf_character_t character) { // reduce the number of checks by grouping checks by first byte. //const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); @@ -2151,7 +2151,7 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_symbol_) || !defined(_di_f_utf_is_symbol_) #if !defined(_di_f_utf_character_is_unassigned_) || !defined(_di_f_utf_is_unassigned_) - f_status_t private_f_utf_character_is_unassigned(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_unassigned(const f_utf_character_t character) { // reduce the number of checks by grouping checks by first byte. //const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); @@ -2170,12 +2170,15 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_unassigned_) || !defined(_di_f_utf_is_unassigned_) #if !defined(_di_f_utf_character_is_valid_) || !defined(_di_f_utf_is_valid_) - f_status_t private_f_utf_character_is_valid(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_valid(const f_utf_character_t character) { - // reduce the number of checks by grouping checks by byte. + // @todo Check to see if this logic handles U+FDD0 to U+FDEF and any character ending in FFFE or FFFF. + // Codes U+FDD0 to U+FDEF are: 0xefb79000 to 0xefb7af00. + + // Reduce the number of checks by grouping checks by byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); - if (width < 2) { + if (macro_f_utf_character_t_width_is(character) < 2) { if (byte_first >= 0x00 && byte_first <= 0x7f) { return F_true; } @@ -2185,7 +2188,7 @@ extern "C" { const uint8_t byte_second = macro_f_utf_character_t_to_char_2(character); - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { if (byte_first >= 0xc2 && byte_first <= 0xdf) { if (byte_second >= 0x80 && byte_second <= 0xbf) { return F_true; @@ -2197,7 +2200,7 @@ extern "C" { const uint8_t byte_third = macro_f_utf_character_t_to_char_3(character); - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { if (byte_first == 0xe0) { if (byte_second >= 0xa0 && byte_second <= 0xbf) { if (byte_third >= 0x80 && byte_third <= 0xbf) { @@ -2231,7 +2234,7 @@ extern "C" { const uint8_t byte_fourth = macro_f_utf_character_t_to_char_4(character); - if (width == 4) { + if (macro_f_utf_character_t_width_is(character) == 4) { if (byte_first == 0xf0) { if (byte_second >= 0x90 && byte_second <= 0xbf) { if (byte_third >= 0x80 && byte_third <= 0xbf) { @@ -2272,16 +2275,16 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_valid_) || !defined(_di_f_utf_is_valid_) #if !defined(_di_f_utf_character_is_whitespace_) || !defined(_di_f_utf_is_whitespace_) - f_status_t private_f_utf_character_is_whitespace(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_whitespace(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Latin-1 Supplement: U+00A0. if (character == 0xc2a00000) { return F_true; } } - else if (width == 3) { + else if (macro_f_utf_character_t_width_is(character) == 3) { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); @@ -2312,9 +2315,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_whitespace_) || !defined(_di_f_utf_is_whitespace_) #if !defined(_di_f_utf_character_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_modifier_) - f_status_t private_f_utf_character_is_whitespace_modifier(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_whitespace_modifier(const f_utf_character_t character) { - if (width == 2) { + if (macro_f_utf_character_t_width_is(character) == 2) { // Spacing Modifier Letters: U+02B0 to U+02FF. if (character >= 0xcab00000 && character <= 0xcbbf0000) { @@ -2327,7 +2330,7 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_modifier_) #if !defined(_di_f_utf_character_is_whitespace_other_) || !defined(_di_f_utf_is_whitespace_other_) - f_status_t private_f_utf_character_is_whitespace_other(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_whitespace_other(const f_utf_character_t character) { // Ogham: U+1680 (isn't whitespace but is technically considered one: ( )). if (character == 0xe19a8000) { @@ -2338,14 +2341,52 @@ extern "C" { } #endif // !defined(_di_f_utf_character_is_whitespace_other_) || !defined(_di_f_utf_is_whitespace_other_) +#if !defined(_di_f_utf_character_is_wide_) || !defined(_di_f_utf_is_wide_) + f_status_t private_f_utf_character_is_wide(const f_utf_character_t character) { + #ifndef _di_level_0_parameter_checking_ + if (!character) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } + + /*if (macro_f_utf_character_t_width_is(character) == 2) { + return F_false; + }*/ + + // @todo there are 95360 WIDE characters...starting at U+1100 ending at U+2FA1D! + + if (macro_f_utf_character_t_width_is(character) == 3) { + + // CJK Symbols: U+3000. + if (character == 0xe3808000) { + return F_true; + } + + // Half Width and Full Width Forms: U+FF01 to U+FF60. + if (character >= 0xefbc8100 && character <= 0xefbda000) { + return F_true; + } + + // Half Width and Full Width Forms: U+FFE0 to U+FFE6. + if (character >= 0xefbfa000 && character <= 0xefbfa600) { + return F_true; + } + } + + return F_false; + } +#endif // !defined(_di_f_utf_character_is_wide_) || !defined(_di_f_utf_is_wide_) + #if !defined(_di_f_utf_character_is_word_) || !defined(_di_f_utf_is_word_) - f_status_t private_f_utf_character_is_word(const f_utf_character_t character, const uint8_t width, const bool strict) { + f_status_t private_f_utf_character_is_word(const f_utf_character_t character, const bool strict) { - if (private_f_utf_character_is_alpha_digit(character, width)) { + if (private_f_utf_character_is_alpha_digit(character)) { return F_true; } - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); @@ -2383,13 +2424,13 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_word_) || !defined(_di_f_utf_is_word_) #if !defined(_di_f_utf_character_is_word_dash_) || !defined(_di_f_utf_is_word_dash_) - f_status_t private_f_utf_character_is_word_dash(const f_utf_character_t character, const uint8_t width, const bool strict) { + f_status_t private_f_utf_character_is_word_dash(const f_utf_character_t character, const bool strict) { - if (private_f_utf_character_is_word(character, width, strict)) { + if (private_f_utf_character_is_word(character, strict)) { return F_true; } - if (width == 3) { + if (macro_f_utf_character_t_width_is(character) == 3) { // General Punctuation: U+2010, U+2011. if (character == 0xe2809000 || character == 0xe2809100) { @@ -2402,9 +2443,9 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_word_dash_) || !defined(_di_f_utf_is_word_dash_) #if !defined(_di_f_utf_character_is_word_dash_plus_) || !defined(_di_f_utf_is_word_dash_plus_) - f_status_t private_f_utf_character_is_word_dash_plus(const f_utf_character_t character, const uint8_t width, const bool strict) { + f_status_t private_f_utf_character_is_word_dash_plus(const f_utf_character_t character, const bool strict) { - if (private_f_utf_character_is_word_dash(character, width, strict)) { + if (private_f_utf_character_is_word_dash(character, strict)) { return F_true; } @@ -2421,7 +2462,7 @@ extern "C" { #endif // !defined(_di_f_utf_character_is_word_dash_plus_) || !defined(_di_f_utf_is_word_dash_plus_) #if !defined(_di_f_utf_character_is_zero_width_) || !defined(_di_f_utf_is_zero_width_) - f_status_t private_f_utf_character_is_zero_width(const f_utf_character_t character, const uint8_t width) { + f_status_t private_f_utf_character_is_zero_width(const f_utf_character_t character) { // reduce the number of checks by grouping checks by first byte. const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); @@ -2452,491 +2493,6 @@ extern "C" { } #endif // !defined(_di_f_utf_character_is_zero_width_) || !defined(_di_f_utf_is_zero_width_) -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) - f_status_t private_f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - - if (destination->used + length > destination->size) { - const f_status_t status = private_f_utf_string_dynamic_increase_by(length, destination); - if (F_status_is_error(status)) return status; - } - - memcpy(destination->string + destination->used, source, length); - destination->used = destination->used + length; - - return F_none; - } -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) - -#if !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) - f_status_t private_f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - - if (destination->used + length > F_string_t_size_d) { - return F_status_set_error(F_string_too_large); - } - - f_status_t status = F_none; - - f_array_length_t i = 0; - f_array_length_t first = 0; - f_array_length_t size = 0; - - for (; i < length; ++i) { - - if (source[i]) continue; - - if (i && i > first) { - size = i - first; - - if (destination->used + size > destination->size) { - status = private_f_utf_string_dynamic_increase_by(size, destination); - if (F_status_is_error(status)) return status; - } - - memcpy(destination->string + destination->used, source + first, size); - destination->used = destination->used + size; - } - - while (i + 1 < length && !source[i + 1]) { - ++i; - } // while - - first = i + 1; - } // for - - if (i > first) { - size = i - first; - - if (destination->used + size > destination->size) { - status = private_f_utf_string_dynamic_increase_by(size, destination); - if (F_status_is_error(status)) return status; - } - - memcpy(destination->string + destination->used, source + first, size); - destination->used = destination->used + size; - } - - return F_none; - } -#endif // !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) - -#if !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - f_status_t private_f_utf_string_dynamic_adjust(const f_array_length_t length, f_utf_string_dynamic_t *dynamic) { - - f_status_t status = f_memory_adjust(dynamic->size, length, sizeof(f_utf_string_t), (void **) & dynamic->string); - - if (F_status_is_error_not(status)) { - dynamic->size = length; - - if (dynamic->used > dynamic->size) { - dynamic->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - f_status_t private_f_utf_string_dynamic_increase_by(const f_array_length_t amount, f_utf_string_dynamic_t *dynamic) { - - if (dynamic->used + amount > dynamic->size) { - if (dynamic->used + amount > F_string_t_size_d) { - return F_status_set_error(F_string_too_large); - } - - return private_f_utf_string_dynamic_resize(dynamic->used + amount, dynamic); - } - - return F_data_not; - } -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - f_status_t private_f_utf_string_dynamic_resize(const f_array_length_t length, f_utf_string_dynamic_t *dynamic) { - - const f_status_t status = f_memory_resize(dynamic->size, length, sizeof(f_utf_string_t), (void **) & dynamic->string); - - if (F_status_is_error_not(status)) { - dynamic->size = length; - - if (dynamic->used > dynamic->size) { - dynamic->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - -#if !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) - f_status_t private_f_utf_string_dynamics_adjust(const f_array_length_t length, f_utf_string_dynamics_t *dynamics) { - - if (dynamics->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < dynamics->size; ++i) { - - status = private_f_utf_string_dynamic_adjust(0, &dynamics->array[i]); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_adjust(dynamics->size, length, sizeof(f_utf_string_dynamic_t), (void **) & dynamics->array); - - if (F_status_is_error_not(status)) { - dynamics->size = length; - - if (dynamics->used > dynamics->size) { - dynamics->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) - -#if !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) - f_status_t private_f_utf_string_dynamics_append(const f_utf_string_dynamics_t source, f_utf_string_dynamics_t *destination) { - f_status_t status = F_none; - - if (destination->used + source.used > destination->size) { - status = private_f_utf_string_dynamics_adjust(destination->used + source.used, destination); - if (F_status_is_error(status)) return status; - } - - for (f_array_length_t i = 0; i < source.used; ++i, ++destination->used) { - - destination->array[destination->used].used = 0; - - if (source.array[i].used) { - status = private_f_utf_string_append(source.array[i].string, source.array[i].used, &destination->array[destination->used]); - if (F_status_is_error(status)) return status; - } - } // for - - return F_none; - } -#endif // !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) - -#if !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) - f_status_t private_f_utf_string_dynamics_resize(const f_array_length_t length, f_utf_string_dynamics_t *dynamics) { - - if (dynamics->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < dynamics->size; ++i) { - status = private_f_utf_string_dynamic_resize(0, &dynamics->array[i]); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_resize(dynamics->size, length, sizeof(f_utf_string_dynamic_t), (void **) & dynamics->array); - - if (F_status_is_error_not(status)) { - dynamics->size = length; - - if (dynamics->used > dynamics->size) { - dynamics->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) - -#if !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) - f_status_t private_f_utf_string_map_multis_adjust(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) { - - if (map_multis->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < map_multis->size; ++i) { - - status = private_f_utf_string_dynamic_adjust(0, &map_multis->array[i].name); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamics_adjust(0, &map_multis->array[i].value); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_adjust(map_multis->size, length, sizeof(f_utf_string_map_multi_t), (void **) & map_multis->array); - - if (F_status_is_error_not(status)) { - map_multis->size = length; - - if (map_multis->used > map_multis->size) { - map_multis->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) - -#if !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) - f_status_t private_f_utf_string_map_multis_resize(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) { - - if (map_multis->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < map_multis->size; ++i) { - - status = private_f_utf_string_dynamic_resize(0, &map_multis->array[i].name); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamics_resize(0, &map_multis->array[i].value); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_resize(map_multis->size, length, sizeof(f_utf_string_map_multi_t), (void **) & map_multis->array); - - if (F_status_is_error_not(status)) { - map_multis->size = length; - - if (map_multis->used > map_multis->size) { - map_multis->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) - -#if !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) - f_status_t private_f_utf_string_maps_adjust(const f_array_length_t length, f_utf_string_maps_t *maps) { - - if (maps->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < maps->size; ++i) { - - status = private_f_utf_string_dynamic_adjust(0, &maps->array[i].name); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_adjust(0, &maps->array[i].value); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_adjust(maps->size, length, sizeof(f_utf_string_map_t), (void **) & maps->array); - - if (F_status_is_error_not(status)) { - maps->size = length; - - if (maps->used > maps->size) { - maps->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) - -#if !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) - f_status_t private_f_utf_string_maps_resize(const f_array_length_t length, f_utf_string_maps_t *maps) { - - if (maps->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < maps->size; ++i) { - - status = private_f_utf_string_dynamic_resize(0, &maps->array[i].name); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_resize(0, &maps->array[i].value); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_resize(maps->size, length, sizeof(f_utf_string_map_t), (void **) & maps->array); - - if (F_status_is_error_not(status)) { - maps->size = length; - - if (maps->used > maps->size) { - maps->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) - -#if !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) - f_status_t private_f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - - if (destination->used + length > F_string_t_size_d) { - return F_status_set_error(F_string_too_large); - } - - if (destination->used + length > destination->size) { - const f_status_t status = private_f_utf_string_dynamic_increase_by(length, destination); - if (F_status_is_error(status)) return status; - } - - if (destination->used) { - memmove(destination->string + length, destination->string, destination->used); - memcpy(destination->string, source, length); - } - else { - memcpy(destination->string, source, length); - } - - destination->used = destination->used + length; - return F_none; - } -#endif // !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) - -#if !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) - f_status_t private_f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - - if (destination->used + length > F_string_t_size_d) { - return F_status_set_error(F_string_too_large); - } - - f_status_t status = F_none; - - f_array_length_t first = 0; - f_array_length_t offset = 0; - - f_array_length_t size = 0; - - for (f_array_length_t i = 0; i <= length; ++i) { - - if (i == length) { - if (i > first) { - size = i - first; - - if (destination->used + size > destination->size) { - status = private_f_utf_string_dynamic_increase_by(size, destination); - if (F_status_is_error(status)) return status; - } - - memmove(destination->string + offset + size, destination->string + offset, destination->used - offset); - memcpy(destination->string + offset, source + first, size); - - destination->used = destination->used + size; - offset += size; - } - - break; - } - - if (!source[i]) { - if (i > 0) { - if (i > first) { - size = i - first; - - if (destination->used + size > destination->size) { - status = private_f_utf_string_dynamic_increase_by(size, destination); - if (F_status_is_error(status)) return status; - } - - memmove(destination->string + offset + size, destination->string + offset, destination->used - offset); - memcpy(destination->string + offset, source + first, size); - - destination->used = destination->used + size; - offset += size; - } - } - - while (i + 1 < length && !source[i + 1]) { - ++i; - } // while - - first = i + 1; - continue; - } - } // for - - return F_none; - } -#endif // !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) - -#if !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - f_status_t private_f_utf_string_triples_adjust(const f_array_length_t length, f_utf_string_triples_t *triples) { - - if (triples->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < triples->size; ++i) { - - status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].one); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].two); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].three); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_adjust(triples->size, length, sizeof(f_utf_string_triple_t), (void **) & triples->array); - - if (F_status_is_error_not(status)) { - triples->size = length; - - if (triples->used > triples->size) { - triples->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - -#if !defined(_di_f_utf_string_triples_decrease_) || !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) - f_status_t private_f_utf_string_triples_resize(const f_array_length_t length, f_utf_string_triples_t *triples) { - - if (triples->used + length > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - f_status_t status = F_none; - - for (f_array_length_t i = length; i < triples->size; ++i) { - - status = private_f_utf_string_dynamic_resize(0, &triples->array[i].one); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_resize(0, &triples->array[i].two); - if (F_status_is_error(status)) return status; - - status = private_f_utf_string_dynamic_resize(0, &triples->array[i].three); - if (F_status_is_error(status)) return status; - } // for - - status = f_memory_resize(triples->size, length, sizeof(f_utf_string_triple_t), (void **) & triples->array); - - if (F_status_is_error_not(status)) { - triples->size = length; - - if (triples->used > triples->size) { - triples->used = length; - } - } - - return status; - } -#endif // !defined(_di_f_utf_string_triples_decrease_) || !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_utf/c/private-utf.h b/level_0/f_utf/c/private-utf.h index ff453a8..a074bc0 100644 --- a/level_0/f_utf/c/private-utf.h +++ b/level_0/f_utf/c/private-utf.h @@ -35,9 +35,10 @@ extern "C" { * @return * F_none if conversion was successful. * - * F_failure (with error bit) if width is not long enough to convert. + * F_failure (with error bit) if width_max is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_char_to_character() * @see f_utf_character_is_valid() @@ -61,15 +62,16 @@ extern "C" { * @see f_utf_is_whitespace() * @see f_utf_is_whitespace_modifier() * @see f_utf_is_whitespace_other() + * @see f_utf_is_wide() * @see f_utf_is_word() * @see f_utf_is_word_dash() * @see f_utf_is_word_dash_plus() * @see f_utf_is_zero_width() * @see f_utf_unicode_to() */ -#if !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) +#if !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_wide_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) extern f_status_t private_f_utf_char_to_character(const f_string_t character, const f_array_length_t width_max, f_utf_character_t *character_utf) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) +#endif // !defined(_di_f_utf_char_to_character_) || !defined(_di_f_utf_is_alpha_) || !defined(_di_f_utf_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_numeric_) || !defined(_di_f_utf_is_ascii_) || !defined(_di_f_utf_is_combining_) || !defined(_di_f_utf_is_control_) || !defined(_di_f_utf_is_control_picture_) || !defined(_di_f_utf_is_digit_) || !defined(_di_f_utf_is_emoji_) || !defined(_di_f_utf_is_graph_) || !defined(_di_f_utf_is_numeric_) || !defined(_di_f_utf_is_phonetic_) || !defined(_di_f_utf_is_private_) || !defined(_di_f_utf_is_punctuation_) || !defined(_di_f_utf_is_symbol_) || !defined(_di_f_utf_is_unassigned_) || !defined(_di_f_utf_is_valid_) || !defined(_di_f_utf_is_whitespace_) || !defined(_di_f_utf_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_other_) || !defined(_di_f_utf_is_wide_) || !defined(_di_f_utf_is_word_) || !defined(_di_f_utf_is_word_dash_) || !defined(_di_f_utf_is_word_dash_plus_) || !defined(_di_f_utf_is_zero_width_) || !defined(f_utf_unicode_to) /** * Private implementation of f_utf_character_is_alpha(). @@ -78,20 +80,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_alpha() * @see f_utf_is_alpha() */ #if !defined(_di_f_utf_character_is_alpha_) || !defined(_di_f_utf_is_alpha_) - extern f_status_t private_f_utf_character_is_alpha(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_alpha(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_alpha_) || !defined(_di_f_utf_is_alpha_) /** @@ -101,20 +102,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_alpha_digit() * @see f_utf_is_alpha_digit() */ #if !defined(_di_f_utf_character_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_digit_) - extern f_status_t private_f_utf_character_is_alpha_digit(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_alpha_digit(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_alpha_digit_) || !defined(_di_f_utf_is_alpha_digit_) /** @@ -124,20 +124,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_alpha_numeric() * @see f_utf_is_alpha_numeric() */ #if !defined(_di_f_utf_character_is_alpha_numeric_) || !defined(_di_f_utf_is_alpha_numeric_) - extern f_status_t private_f_utf_character_is_alpha_numeric(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_alpha_numeric(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_alpha_numeric_) || !defined(_di_f_utf_is_alpha_numeric_) /** @@ -147,21 +146,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. - * A width of 0 or 1 are treated as ASCII (width 1). * * @return * F_true if a UTF-8 control picture character. * F_false if not a UTF-8 control picture character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_ascii() * @see f_utf_is_ascii() */ #if !defined(_di_f_utf_character_is_ascii_) || !defined(_di_f_utf_is_ascii_) - extern f_status_t private_f_utf_character_is_ascii(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_ascii(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_ascii_) || !defined(_di_f_utf_is_ascii_) /** @@ -171,20 +168,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 combining character. * F_false if not a UTF-8 combining character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_combining() * @see f_utf_is_combining() */ #if !defined(_di_f_utf_character_is_combining_) || !defined(_di_f_utf_is_combining_) - extern f_status_t private_f_utf_character_is_combining(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_combining(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_combining_) || !defined(_di_f_utf_is_combining_) /** @@ -194,20 +190,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_control() * @see f_utf_is_control() */ #if !defined(_di_f_utf_character_is_control_) || !defined(_di_f_utf_is_control_) - extern f_status_t private_f_utf_character_is_control(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_control(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_control_) || !defined(_di_f_utf_is_control_) /** @@ -217,20 +212,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_control_code() * @see f_utf_is_control_code() */ #if !defined(_di_f_utf_character_is_control_code_) || !defined(_di_f_utf_is_control_code_) - extern f_status_t private_f_utf_character_is_control_code(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_control_code(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_control_code_) || !defined(_di_f_utf_is_control_code_) /** @@ -240,20 +234,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_control_format() * @see f_utf_is_control_format() */ #if !defined(_di_f_utf_character_is_control_format_) || !defined(_di_f_utf_is_control_format_) - extern f_status_t private_f_utf_character_is_control_format(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_control_format(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_control_format_) || !defined(_di_f_utf_is_control_format_) /** @@ -263,20 +256,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control picture character. * F_false if not a UTF-8 control picture character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_control_picture() * @see f_utf_is_control_picture() */ #if !defined(_di_f_utf_character_is_control_picture_) || !defined(_di_f_utf_is_control_picture_) - extern f_status_t private_f_utf_character_is_control_picture(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_control_picture(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_control_picture_) || !defined(_di_f_utf_is_control_picture_) /** @@ -286,20 +278,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_digit() * @see f_utf_is_digit() */ #if !defined(_di_f_utf_character_is_digit_) || !defined(_di_f_utf_is_digit_) - extern f_status_t private_f_utf_character_is_digit(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_digit(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_digit_) || !defined(_di_f_utf_is_digit_) /** @@ -309,20 +300,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_emoji() * @see f_utf_is_emoji() */ #if !defined(_di_f_utf_character_is_emoji_) || !defined(_di_f_utf_is_emoji_) - extern f_status_t private_f_utf_character_is_emoji(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_emoji(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_emoji_) || !defined(_di_f_utf_is_emoji_) /** @@ -332,20 +322,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_numeric() * @see f_utf_is_numeric() */ #if !defined(_di_f_utf_character_is_numeric_) || !defined(_di_f_utf_is_numeric_) - extern f_status_t private_f_utf_character_is_numeric(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_numeric(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_numeric_) || !defined(_di_f_utf_is_numeric_) /** @@ -355,20 +344,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_phonetic() * @see f_utf_is_phonetic() */ #if !defined(_di_f_utf_character_is_phonetic_) || !defined(_di_f_utf_is_phonetic_) - extern f_status_t private_f_utf_character_is_phonetic(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_phonetic(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_phonetic_) || !defined(_di_f_utf_is_phonetic_) /** @@ -378,20 +366,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_private() * @see f_utf_is_private() */ #if !defined(_di_f_utf_character_is_private_) || !defined(_di_f_utf_is_private_) - extern f_status_t private_f_utf_character_is_private(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_private(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_private_) || !defined(_di_f_utf_is_private_) /** @@ -401,20 +388,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_punctuation() * @see f_utf_is_punctuation() */ #if !defined(_di_f_utf_character_is_punctuation_) || !defined(_di_f_utf_is_punctuation_) - extern f_status_t private_f_utf_character_is_punctuation(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_punctuation(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_punctuation_) || !defined(_di_f_utf_is_punctuation_) /** @@ -424,20 +410,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_symbol() * @see f_utf_is_symbol() */ #if !defined(_di_f_utf_character_is_symbol_) || !defined(_di_f_utf_is_symbol_) - extern f_status_t private_f_utf_character_is_symbol(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_symbol(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_symbol_) || !defined(_di_f_utf_is_symbol_) /** @@ -447,20 +432,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_unassigned() * @see f_utf_is_unassigned() */ #if !defined(_di_f_utf_character_is_unassigned_) || !defined(_di_f_utf_is_unassigned_) - extern f_status_t private_f_utf_character_is_unassigned(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_unassigned(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_unassigned_) || !defined(_di_f_utf_is_unassigned_) /** @@ -470,21 +454,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. - * A width of 0 or 1 are treated as ASCII (width 1). * * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_valid() * @see f_utf_is_valid() */ #if !defined(_di_f_utf_character_is_valid_) || !defined(_di_f_utf_is_valid_) - extern f_status_t private_f_utf_character_is_valid(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_valid(const f_utf_character_t characterh) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_valid_) || !defined(_di_f_utf_is_valid_) /** @@ -494,20 +476,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_whitespace() * @see f_utf_is_whitespace() */ #if !defined(_di_f_utf_character_is_whitespace_) || !defined(_di_f_utf_is_whitespace_) - extern f_status_t private_f_utf_character_is_whitespace(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_whitespace(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_whitespace_) || !defined(_di_f_utf_is_whitespace_) /** @@ -517,20 +498,19 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 phonetic whitespace. * F_false if not a UTF-8 phonetic whitespace. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_whitespace_modifier() * @see f_utf_is_whitespace_modifier() */ #if !defined(_di_f_utf_character_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_modifier_) - extern f_status_t private_f_utf_character_is_whitespace_modifier(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_whitespace_modifier(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_whitespace_modifier_) || !defined(_di_f_utf_is_whitespace_modifier_) /** @@ -540,31 +520,48 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_whitespace_other() * @see f_utf_is_whitespace_other() */ #if !defined(_di_f_utf_character_is_whitespace_other_) || !defined(_di_f_utf_is_whitespace_other_) - extern f_status_t private_f_utf_character_is_whitespace_other(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_whitespace_other(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_whitespace_other_) || !defined(_di_f_utf_is_whitespace_other_) /** + * Private implementation of f_utf_character_is_wide(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param character + * The (UTF-8) character. + * + * @return + * F_none on success. + * + * F_failure (with error bit) if width is not long enough to convert. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + */ +#if !defined(_di_f_utf_character_is_wide_) || !defined(_di_f_utf_is_wide_) + extern f_status_t private_f_utf_character_is_wide(const f_utf_character_t character) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_character_is_wide_) || !defined(_di_f_utf_is_wide_) + +/** * Private implementation of f_utf_character_is_word(). * * Intended to be shared to each of the different implementation variations. * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * @param strict * When TRUE, include all appropriate characters by type as per Unicode. * When FALSE, non-inline punctuation connectors are not considered a character (such as U+FE33 '︳'). @@ -574,13 +571,14 @@ extern "C" { * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_word() * @see f_utf_is_word() */ #if !defined(_di_f_utf_character_is_word_) || !defined(_di_f_utf_is_word_) - extern f_status_t private_f_utf_character_is_word(const f_utf_character_t character, const uint8_t width, const bool strict) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_word(const f_utf_character_t character, const bool strict) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_word_) || !defined(_di_f_utf_is_word_) /** @@ -590,8 +588,6 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * @param strict * When TRUE, include all appropriate characters by type as per Unicode. * When FALSE, non-inline punctuation connectors are not considered a character (such as U+FE33 '︳'). @@ -601,13 +597,14 @@ extern "C" { * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_word_dash() * @see f_utf_is_word_dash() */ #if !defined(_di_f_utf_character_is_word_dash_) || !defined(_di_f_utf_is_word_dash_) - extern f_status_t private_f_utf_character_is_word_dash(const f_utf_character_t character, const uint8_t width, const bool strict) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_word_dash(const f_utf_character_t character, const bool strict) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_word_dash_) || !defined(_di_f_utf_is_word_dash_) /** @@ -617,8 +614,6 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * @param strict * When TRUE, include all appropriate characters by type as per Unicode. * When FALSE, non-inline punctuation connectors are not considered a character (such as U+FE33 '︳'). @@ -628,13 +623,14 @@ extern "C" { * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_word_dash_plus() * @see f_utf_is_word_dash_plus() */ #if !defined(_di_f_utf_character_is_word_dash_plus_) || !defined(_di_f_utf_is_word_dash_plus_) - extern f_status_t private_f_utf_character_is_word_dash_plus(const f_utf_character_t character, const uint8_t width, const bool strict) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_word_dash_plus(const f_utf_character_t character, const bool strict) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_word_dash_plus_) || !defined(_di_f_utf_is_word_dash_plus_) /** @@ -644,527 +640,21 @@ extern "C" { * * @param character * The character to validate. - * @param width - * The number of bytes repesenting the character width. * * @return * F_true if a UTF-8 non-printing or zero-width character. * F_false if not a UTF-8 non-printing or zero-width character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_zero_width() * @see f_utf_is_zero_width() */ #if !defined(_di_f_utf_character_is_zero_width_) || !defined(_di_f_utf_is_zero_width_) - extern f_status_t private_f_utf_character_is_zero_width(const f_utf_character_t character, const uint8_t width) F_attribute_visibility_internal_d; + extern f_status_t private_f_utf_character_is_zero_width(const f_utf_character_t character) F_attribute_visibility_internal_d; #endif // !defined(_di_f_utf_character_is_zero_width_) || !defined(_di_f_utf_is_zero_width_) -/** - * Private implementation of f_utf_string_append(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param source - * The source string to append. - * @param length - * Length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see memcpy() - * - * @see f_utf_string_append() - * @see f_utf_string_append_assure() - * @see f_utf_string_dynamic_append() - * @see f_utf_string_dynamic_append_assure() - * @see f_utf_string_dynamic_mash() - * @see f_utf_string_dynamic_partial_append) - * @see f_utf_string_dynamic_partial_append_assure() - * @see f_utf_string_dynamic_partial_mash() - * @see f_utf_string_dynamics_append() - * @see f_utf_string_map_multis_append() - * @see f_utf_string_mash() - * @see f_utf_string_maps_append() - * @see f_utf_string_triples_append() - */ -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) - extern f_status_t private_f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) - -/** - * Private implementation of f_utf_string_append_nulless(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param source - * The source string to append. - * @param length - * Length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * - * F_string_too_large (with error bit) if the combined string is too large. - * - * @see memcpy() - * - * @see f_utf_string_append_assure_nulless() - * @see f_utf_string_append_nulless() - * @see f_utf_string_dynamic_append_assure_nulless() - * @see f_utf_string_dynamic_append_nulless() - * @see f_utf_string_dynamic_mash_nulless() - * @see f_utf_string_dynamic_partial_append_assure_nulless() - * @see f_utf_string_dynamic_partial_append_nulless() - * @see f_utf_string_dynamic_partial_mash_nulless() - * @see f_utf_string_mash_nulless() - */ -#if !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) - extern f_status_t private_f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param string - * The string to adjust. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_memory_adjust() - * @see f_utf_string_dynamic_adjust() - * @see f_utf_string_dynamic_decimate_by() - * @see f_utf_string_dynamics_adjust() - * @see f_utf_string_dynamics_append() - * @see f_utf_string_dynamics_decimate_by() - * @see f_utf_string_map_multis_adjust() - * @see f_utf_string_map_multis_append() - * @see f_utf_string_triples_adjust() - * @see f_utf_string_triples_decimate_by() - */ -#if !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - extern f_status_t private_f_utf_string_dynamic_adjust(const f_array_length_t length, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - -/** - * Private implementation of f_utf_string_dynamic_increase_by(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param amount - * A positive number representing how much to increase the size by. - * @param string - * The string to resize. - * - * @return - * F_none on success. - * F_data_not on success, but there is no reason to increase size (used + amount <= size). - * - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see memcpy() - * - * @see f_utf_string_append() - * @see f_utf_string_append_assure() - * @see f_utf_string_append_mash() - * @see f_utf_string_append_nulless() - * @see f_utf_string_dynamic_append() - * @see f_utf_string_dynamic_append_assure() - * @see f_utf_string_dynamic_append_nulless() - * @see f_utf_string_dynamic_increase_by() - * @see f_utf_string_dynamic_mash() - * @see f_utf_string_dynamic_mash_nulless() - * @see f_utf_string_dynamic_partial_append) - * @see f_utf_string_dynamic_partial_append_assure() - * @see f_utf_string_dynamic_partial_mash() - * @see f_utf_string_dynamic_prepend() - * @see f_utf_string_dynamic_prepend_nulless() - * @see f_utf_string_dynamics_append() - * @see f_utf_string_map_multis_append() - * @see f_utf_string_mash() - * @see f_utf_string_mash_nulless() - * @see f_utf_string_maps_append() - * @see f_utf_string_prepend() - * @see f_utf_string_prepend_nulless() - * @see f_utf_string_triples_append() - */ -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - extern f_status_t private_f_utf_string_dynamic_increase_by(const f_array_length_t amount, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param string - * The string to resize. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_resize() - * @see f_utf_string_append() - * @see f_utf_string_append_assure() - * @see f_utf_string_append_mash() - * @see f_utf_string_append_nulless() - * @see f_utf_string_dynamic_append() - * @see f_utf_string_dynamic_append_assure() - * @see f_utf_string_dynamic_append_nulless() - * @see f_utf_string_dynamic_decrease_by() - * @see f_utf_string_dynamic_increase() - * @see f_utf_string_dynamic_increase_by() - * @see f_utf_string_dynamic_mash() - * @see f_utf_string_dynamic_mash_nulless() - * @see f_utf_string_dynamic_partial_append) - * @see f_utf_string_dynamic_partial_append_assure() - * @see f_utf_string_dynamic_partial_mash() - * @see f_utf_string_dynamic_prepend() - * @see f_utf_string_dynamic_prepend_nulless() - * @see f_utf_string_dynamic_terminate() - * @see f_utf_string_dynamic_terminate_after() - * @see f_utf_string_dynamics_append() - * @see f_utf_string_map_multis_append() - * @see f_utf_string_mash_nulless() - * @see f_utf_string_mash() - * @see f_utf_string_maps_append() - * @see f_utf_string_prepend() - * @see f_utf_string_prepend_nulless() - * @see f_utf_string_triples_append() - */ -#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - extern f_status_t private_f_utf_string_dynamic_resize(const f_array_length_t length, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param strings - * The strings to adjust. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_memory_adjust() - * @see f_utf_string_dynamics_adjust() - * @see f_utf_string_dynamics_append() - * @see f_utf_string_dynamics_decimate_by() - * @see f_utf_string_map_multis_adjust() - * @see f_utf_string_map_multis_append() - */ -#if !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) - extern f_status_t private_f_utf_string_dynamics_adjust(const f_array_length_t length, f_utf_string_dynamics_t *strings) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) - -/** - * Private implementation for appending. - * - * Intended to be shared to each of the different implementation variations. - * - * @param source - * The source strings to append. - * @param destination - * The destination strings the source is appended onto. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_utf_string_dynamics_append() - * @see f_utf_string_map_multis_append() - */ -#if !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) - extern f_status_t private_f_utf_string_dynamics_append(const f_utf_string_dynamics_t source, f_utf_string_dynamics_t *destination) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param strings - * The strings to resize. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_resize() - * @see f_utf_string_dynamics_decrease_by() - * @see f_utf_string_dynamics_increase() - * @see f_utf_string_dynamics_increase_by() - */ -#if !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) - extern f_status_t private_f_utf_string_dynamics_resize(const f_array_length_t length, f_utf_string_dynamics_t *strings) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param map_multis - * The map_multis to adjust. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_memory_adjust() - * @see f_utf_string_map_multis_adjust() - */ -#if !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) - extern f_status_t private_f_utf_string_map_multis_adjust(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param map_multis - * The map_multis to resize. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_adjust() - * @see f_utf_string_map_multis_decrease_by() - * @see f_utf_string_map_multis_increase() - * @see f_utf_string_map_multis_increase_by() - * @see f_utf_string_map_multis_terminate() - * @see f_utf_string_map_multis_terminate_after() - */ -#if !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) - extern f_status_t private_f_utf_string_map_multis_resize(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param maps - * The maps to adjust. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_memory_adjust() - * @see f_utf_string_maps_adjust() - */ -#if !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) - extern f_status_t private_f_utf_string_maps_adjust(const f_array_length_t length, f_utf_string_maps_t *maps) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param maps - * The maps to resize. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_adjust() - * @see f_utf_string_maps_decrease_by() - * @see f_utf_string_maps_increase() - * @see f_utf_string_maps_increase_by() - * @see f_utf_string_maps_terminate() - * @see f_utf_string_maps_terminate_after() - */ -#if !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) - extern f_status_t private_f_utf_string_maps_resize(const f_array_length_t length, f_utf_string_maps_t *maps) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) - -/** - * Private implementation of f_utf_string_prepend(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param source - * The source string to prepend. - * @param length - * Length of source to append. - * @param destination - * The destination string the source and glue are prepended onto. - * - * @return - * F_none on success. - * - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see memcopy() - * @see memmove() - * - * @see f_utf_string_dynamic_mish() - * @see f_utf_string_dynamic_partial_mish() - * @see f_utf_string_dynamic_partial_prepend_assure() - * @see f_utf_string_dynamic_partial_prepend() - * @see f_utf_string_dynamic_prepend_assure() - * @see f_utf_string_dynamic_prepend() - * @see f_utf_string_mish() - * @see f_utf_string_prepend_assure() - * @see f_utf_string_prepend() - */ -#if !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) - extern f_status_t private_f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) - -/** - * Private implementation of f_utf_string_prepend_nulless(). - * - * Intended to be shared to each of the different implementation variations. - * - * @param source - * The source string to prepend. - * @param length - * Length of source to append. - * @param destination - * The destination string the source and glue are prepended onto. - * - * @return - * F_none on success. - * - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see memcopy() - * @see memmove() - * - * @see f_utf_string_dynamic_mish_nulless() - * @see f_utf_string_dynamic_partial_mish_nulless() - * @see f_utf_string_dynamic_partial_prepend_assure_nulless() - * @see f_utf_string_dynamic_partial_prepend_nulless() - * @see f_utf_string_dynamic_prepend_assure_nulless() - * @see f_utf_string_dynamic_prepend_nulless() - * @see f_utf_string_mish_nulless() - * @see f_utf_string_prepend_assure_nulless() - * @see f_utf_string_prepend_nulless() - */ -#if !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) - extern f_status_t private_f_utf_string_prepend_nulless(const f_utf_string_t source, f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param triples - * The triples to adjust. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_adjust(). - * - * @see f_memory_adjust() - * @see f_utf_string_triples_adjust() - * @see f_utf_string_triples_decimate_by() - */ -#if !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - extern f_status_t private_f_utf_string_triples_adjust(const f_array_length_t length, f_utf_string_triples_t *triples) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) - -/** - * Private implementation for resizing. - * - * Intended to be shared to each of the different implementation variations. - * - * @param length - * The new size to use. - * @param triples - * The triples to resize. - * - * @return - * F_none on success. - * - * F_array_too_large (with error bit) if the combined array is too large. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_resize() - * @see f_utf_string_triples_decrease_by() - * @see f_utf_string_triples_increase() - * @see f_utf_string_triples_increase_by() - * @see f_utf_string_triples_terminate() - * @see f_utf_string_triples_terminate_after() - */ -#if !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) - extern f_status_t private_f_utf_string_triples_resize(const f_array_length_t length, f_utf_string_triples_t *triples) F_attribute_visibility_internal_d; -#endif // !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_utf/c/private-utf_string.c b/level_0/f_utf/c/private-utf_string.c new file mode 100644 index 0000000..e601116 --- /dev/null +++ b/level_0/f_utf/c/private-utf_string.c @@ -0,0 +1,496 @@ +#include "utf.h" +#include "private-utf_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) + f_status_t private_f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + + if (destination->used + length > destination->size) { + const f_status_t status = private_f_utf_string_dynamic_increase_by(length, destination); + if (F_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source, length); + destination->used = destination->used + length; + + return F_none; + } +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) + +#if !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) + f_status_t private_f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + + if (destination->used + length > F_string_t_size_d) { + return F_status_set_error(F_string_too_large); + } + + f_status_t status = F_none; + + f_array_length_t i = 0; + f_array_length_t first = 0; + f_array_length_t size = 0; + + for (; i < length; ++i) { + + if (source[i]) continue; + + if (i && i > first) { + size = i - first; + + if (destination->used + size > destination->size) { + status = private_f_utf_string_dynamic_increase_by(size, destination); + if (F_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, size); + destination->used = destination->used + size; + } + + while (i + 1 < length && !source[i + 1]) { + ++i; + } // while + + first = i + 1; + } // for + + if (i > first) { + size = i - first; + + if (destination->used + size > destination->size) { + status = private_f_utf_string_dynamic_increase_by(size, destination); + if (F_status_is_error(status)) return status; + } + + memcpy(destination->string + destination->used, source + first, size); + destination->used = destination->used + size; + } + + return F_none; + } +#endif // !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) + +#if !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + f_status_t private_f_utf_string_dynamic_adjust(const f_array_length_t length, f_utf_string_dynamic_t *dynamic) { + + f_status_t status = f_memory_adjust(dynamic->size, length, sizeof(f_utf_string_t), (void **) & dynamic->string); + + if (F_status_is_error_not(status)) { + dynamic->size = length; + + if (dynamic->used > dynamic->size) { + dynamic->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + f_status_t private_f_utf_string_dynamic_increase_by(const f_array_length_t amount, f_utf_string_dynamic_t *dynamic) { + + if (dynamic->used + amount > dynamic->size) { + if (dynamic->used + amount > F_string_t_size_d) { + return F_status_set_error(F_string_too_large); + } + + return private_f_utf_string_dynamic_resize(dynamic->used + amount, dynamic); + } + + return F_data_not; + } +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + f_status_t private_f_utf_string_dynamic_resize(const f_array_length_t length, f_utf_string_dynamic_t *dynamic) { + + const f_status_t status = f_memory_resize(dynamic->size, length, sizeof(f_utf_string_t), (void **) & dynamic->string); + + if (F_status_is_error_not(status)) { + dynamic->size = length; + + if (dynamic->used > dynamic->size) { + dynamic->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + +#if !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) + f_status_t private_f_utf_string_dynamics_adjust(const f_array_length_t length, f_utf_string_dynamics_t *dynamics) { + + if (dynamics->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < dynamics->size; ++i) { + + status = private_f_utf_string_dynamic_adjust(0, &dynamics->array[i]); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_adjust(dynamics->size, length, sizeof(f_utf_string_dynamic_t), (void **) & dynamics->array); + + if (F_status_is_error_not(status)) { + dynamics->size = length; + + if (dynamics->used > dynamics->size) { + dynamics->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) + +#if !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) + f_status_t private_f_utf_string_dynamics_append(const f_utf_string_dynamics_t source, f_utf_string_dynamics_t *destination) { + + f_status_t status = F_none; + + if (destination->used + source.used > destination->size) { + status = private_f_utf_string_dynamics_adjust(destination->used + source.used, destination); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < source.used; ++i, ++destination->used) { + + destination->array[destination->used].used = 0; + + if (source.array[i].used) { + status = private_f_utf_string_append(source.array[i].string, source.array[i].used, &destination->array[destination->used]); + if (F_status_is_error(status)) return status; + } + } // for + + return F_none; + } +#endif // !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) + +#if !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) + f_status_t private_f_utf_string_dynamics_resize(const f_array_length_t length, f_utf_string_dynamics_t *dynamics) { + + if (dynamics->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < dynamics->size; ++i) { + status = private_f_utf_string_dynamic_resize(0, &dynamics->array[i]); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_resize(dynamics->size, length, sizeof(f_utf_string_dynamic_t), (void **) & dynamics->array); + + if (F_status_is_error_not(status)) { + dynamics->size = length; + + if (dynamics->used > dynamics->size) { + dynamics->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) + +#if !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) + f_status_t private_f_utf_string_map_multis_adjust(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) { + + if (map_multis->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < map_multis->size; ++i) { + + status = private_f_utf_string_dynamic_adjust(0, &map_multis->array[i].name); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamics_adjust(0, &map_multis->array[i].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_adjust(map_multis->size, length, sizeof(f_utf_string_map_multi_t), (void **) & map_multis->array); + + if (F_status_is_error_not(status)) { + map_multis->size = length; + + if (map_multis->used > map_multis->size) { + map_multis->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) + +#if !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) + f_status_t private_f_utf_string_map_multis_resize(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) { + + if (map_multis->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < map_multis->size; ++i) { + + status = private_f_utf_string_dynamic_resize(0, &map_multis->array[i].name); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamics_resize(0, &map_multis->array[i].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_resize(map_multis->size, length, sizeof(f_utf_string_map_multi_t), (void **) & map_multis->array); + + if (F_status_is_error_not(status)) { + map_multis->size = length; + + if (map_multis->used > map_multis->size) { + map_multis->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) + +#if !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) + f_status_t private_f_utf_string_maps_adjust(const f_array_length_t length, f_utf_string_maps_t *maps) { + + if (maps->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < maps->size; ++i) { + + status = private_f_utf_string_dynamic_adjust(0, &maps->array[i].name); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_adjust(0, &maps->array[i].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_adjust(maps->size, length, sizeof(f_utf_string_map_t), (void **) & maps->array); + + if (F_status_is_error_not(status)) { + maps->size = length; + + if (maps->used > maps->size) { + maps->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) + +#if !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) + f_status_t private_f_utf_string_maps_resize(const f_array_length_t length, f_utf_string_maps_t *maps) { + + if (maps->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < maps->size; ++i) { + + status = private_f_utf_string_dynamic_resize(0, &maps->array[i].name); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_resize(0, &maps->array[i].value); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_resize(maps->size, length, sizeof(f_utf_string_map_t), (void **) & maps->array); + + if (F_status_is_error_not(status)) { + maps->size = length; + + if (maps->used > maps->size) { + maps->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) + +#if !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) + f_status_t private_f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + + if (destination->used + length > F_string_t_size_d) { + return F_status_set_error(F_string_too_large); + } + + if (destination->used + length > destination->size) { + const f_status_t status = private_f_utf_string_dynamic_increase_by(length, destination); + if (F_status_is_error(status)) return status; + } + + if (destination->used) { + memmove(destination->string + length, destination->string, destination->used); + memcpy(destination->string, source, length); + } + else { + memcpy(destination->string, source, length); + } + + destination->used = destination->used + length; + return F_none; + } +#endif // !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) + +#if !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) + f_status_t private_f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + + if (destination->used + length > F_string_t_size_d) { + return F_status_set_error(F_string_too_large); + } + + f_status_t status = F_none; + + f_array_length_t first = 0; + f_array_length_t offset = 0; + + f_array_length_t size = 0; + + for (f_array_length_t i = 0; i <= length; ++i) { + + if (i == length) { + if (i > first) { + size = i - first; + + if (destination->used + size > destination->size) { + status = private_f_utf_string_dynamic_increase_by(size, destination); + if (F_status_is_error(status)) return status; + } + + memmove(destination->string + offset + size, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, size); + + destination->used = destination->used + size; + offset += size; + } + + break; + } + + if (!source[i]) { + if (i > 0) { + if (i > first) { + size = i - first; + + if (destination->used + size > destination->size) { + status = private_f_utf_string_dynamic_increase_by(size, destination); + if (F_status_is_error(status)) return status; + } + + memmove(destination->string + offset + size, destination->string + offset, destination->used - offset); + memcpy(destination->string + offset, source + first, size); + + destination->used = destination->used + size; + offset += size; + } + } + + while (i + 1 < length && !source[i + 1]) { + ++i; + } // while + + first = i + 1; + continue; + } + } // for + + return F_none; + } +#endif // !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) + +#if !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + f_status_t private_f_utf_string_triples_adjust(const f_array_length_t length, f_utf_string_triples_t *triples) { + + if (triples->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < triples->size; ++i) { + + status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].one); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].two); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_adjust(0, &triples->array[i].three); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_adjust(triples->size, length, sizeof(f_utf_string_triple_t), (void **) & triples->array); + + if (F_status_is_error_not(status)) { + triples->size = length; + + if (triples->used > triples->size) { + triples->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + +#if !defined(_di_f_utf_string_triples_decrease_) || !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) + f_status_t private_f_utf_string_triples_resize(const f_array_length_t length, f_utf_string_triples_t *triples) { + + if (triples->used + length > F_array_length_t_size_d) { + return F_status_set_error(F_array_too_large); + } + + f_status_t status = F_none; + + for (f_array_length_t i = length; i < triples->size; ++i) { + + status = private_f_utf_string_dynamic_resize(0, &triples->array[i].one); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_resize(0, &triples->array[i].two); + if (F_status_is_error(status)) return status; + + status = private_f_utf_string_dynamic_resize(0, &triples->array[i].three); + if (F_status_is_error(status)) return status; + } // for + + status = f_memory_resize(triples->size, length, sizeof(f_utf_string_triple_t), (void **) & triples->array); + + if (F_status_is_error_not(status)) { + triples->size = length; + + if (triples->used > triples->size) { + triples->used = length; + } + } + + return status; + } +#endif // !defined(_di_f_utf_string_triples_decrease_) || !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_utf/c/private-utf_string.h b/level_0/f_utf/c/private-utf_string.h new file mode 100644 index 0000000..e7679f1 --- /dev/null +++ b/level_0/f_utf/c/private-utf_string.h @@ -0,0 +1,529 @@ +/** + * FLL - Level 0 + * + * Project: UTF + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Provides UTF-8 string capabilities. + * + * These are provided for internal reduction in redundant code. + * These should not be exposed/used outside of this project. + */ +#ifndef _PRIVATE_F_utf_string_h +#define _PRIVATE_F_utf_string_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Private implementation of f_utf_string_append(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to append. + * @param length + * Length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see memcpy() + * + * @see f_utf_string_append() + * @see f_utf_string_append_assure() + * @see f_utf_string_dynamic_append() + * @see f_utf_string_dynamic_append_assure() + * @see f_utf_string_dynamic_mash() + * @see f_utf_string_dynamic_partial_append) + * @see f_utf_string_dynamic_partial_append_assure() + * @see f_utf_string_dynamic_partial_mash() + * @see f_utf_string_dynamics_append() + * @see f_utf_string_map_multis_append() + * @see f_utf_string_mash() + * @see f_utf_string_maps_append() + * @see f_utf_string_triples_append() + */ +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) + extern f_status_t private_f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_triples_append_) + +/** + * Private implementation of f_utf_string_append_nulless(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to append. + * @param length + * Length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * + * F_string_too_large (with error bit) if the combined string is too large. + * + * @see memcpy() + * + * @see f_utf_string_append_assure_nulless() + * @see f_utf_string_append_nulless() + * @see f_utf_string_dynamic_append_assure_nulless() + * @see f_utf_string_dynamic_append_nulless() + * @see f_utf_string_dynamic_mash_nulless() + * @see f_utf_string_dynamic_partial_append_assure_nulless() + * @see f_utf_string_dynamic_partial_append_nulless() + * @see f_utf_string_dynamic_partial_mash_nulless() + * @see f_utf_string_mash_nulless() + */ +#if !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) + extern f_status_t private_f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_append_assure_nulless_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mash_nulless_) || !defined(_di_f_utf_string_mash_nulless_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param string + * The string to adjust. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_memory_adjust() + * @see f_utf_string_dynamic_adjust() + * @see f_utf_string_dynamic_decimate_by() + * @see f_utf_string_dynamics_adjust() + * @see f_utf_string_dynamics_append() + * @see f_utf_string_dynamics_decimate_by() + * @see f_utf_string_map_multis_adjust() + * @see f_utf_string_map_multis_append() + * @see f_utf_string_triples_adjust() + * @see f_utf_string_triples_decimate_by() + */ +#if !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + extern f_status_t private_f_utf_string_dynamic_adjust(const f_array_length_t length, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamic_adjust_) || !defined(_di_f_utf_string_dynamic_decimate_by_) || !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + +/** + * Private implementation of f_utf_string_dynamic_increase_by(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param amount + * A positive number representing how much to increase the size by. + * @param string + * The string to resize. + * + * @return + * F_none on success. + * F_data_not on success, but there is no reason to increase size (used + amount <= size). + * + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see memcpy() + * + * @see f_utf_string_append() + * @see f_utf_string_append_assure() + * @see f_utf_string_append_mash() + * @see f_utf_string_append_nulless() + * @see f_utf_string_dynamic_append() + * @see f_utf_string_dynamic_append_assure() + * @see f_utf_string_dynamic_append_nulless() + * @see f_utf_string_dynamic_increase_by() + * @see f_utf_string_dynamic_mash() + * @see f_utf_string_dynamic_mash_nulless() + * @see f_utf_string_dynamic_partial_append) + * @see f_utf_string_dynamic_partial_append_assure() + * @see f_utf_string_dynamic_partial_mash() + * @see f_utf_string_dynamic_prepend() + * @see f_utf_string_dynamic_prepend_nulless() + * @see f_utf_string_dynamics_append() + * @see f_utf_string_map_multis_append() + * @see f_utf_string_mash() + * @see f_utf_string_mash_nulless() + * @see f_utf_string_maps_append() + * @see f_utf_string_prepend() + * @see f_utf_string_prepend_nulless() + * @see f_utf_string_triples_append() + */ +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + extern f_status_t private_f_utf_string_dynamic_increase_by(const f_array_length_t amount, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(_di_f_utf_string_dynamic_partial_append_) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param string + * The string to resize. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_utf_string_append() + * @see f_utf_string_append_assure() + * @see f_utf_string_append_mash() + * @see f_utf_string_append_nulless() + * @see f_utf_string_dynamic_append() + * @see f_utf_string_dynamic_append_assure() + * @see f_utf_string_dynamic_append_nulless() + * @see f_utf_string_dynamic_decrease_by() + * @see f_utf_string_dynamic_increase() + * @see f_utf_string_dynamic_increase_by() + * @see f_utf_string_dynamic_mash() + * @see f_utf_string_dynamic_mash_nulless() + * @see f_utf_string_dynamic_partial_append) + * @see f_utf_string_dynamic_partial_append_assure() + * @see f_utf_string_dynamic_partial_mash() + * @see f_utf_string_dynamic_prepend() + * @see f_utf_string_dynamic_prepend_nulless() + * @see f_utf_string_dynamic_terminate() + * @see f_utf_string_dynamic_terminate_after() + * @see f_utf_string_dynamics_append() + * @see f_utf_string_map_multis_append() + * @see f_utf_string_mash_nulless() + * @see f_utf_string_mash() + * @see f_utf_string_maps_append() + * @see f_utf_string_prepend() + * @see f_utf_string_prepend_nulless() + * @see f_utf_string_triples_append() + */ +#if !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + extern f_status_t private_f_utf_string_dynamic_resize(const f_array_length_t length, f_utf_string_dynamic_t *string) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_append_) || !defined(_di_f_utf_string_append_assure_) || !defined(_di_f_utf_string_append_mash_) || !defined(_di_f_utf_string_append_nulless_) || !defined(_di_f_utf_string_dynamic_append_) || !defined(_di_f_utf_string_dynamic_append_assure_) || !defined(_di_f_utf_string_dynamic_append_nulless_) || !defined(_di_f_utf_string_dynamic_decrease_by_) || !defined(_di_f_utf_string_dynamic_increase_) || !defined(_di_f_utf_string_dynamic_increase_by_) || !defined(_di_f_utf_string_dynamic_mash_) || !defined(_di_f_utf_string_dynamic_mash_nulless_) || !defined(f_utf_string_dynamic_partial_append) || !defined(_di_f_utf_string_dynamic_partial_append_assure_) || !defined(_di_f_utf_string_dynamic_partial_mash_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_terminate_) || !defined(_di_f_utf_string_dynamic_terminate_after_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) || !defined(_di_f_utf_string_mash_nulless_) || !defined(_di_f_utf_string_mash_) || !defined(_di_f_utf_string_maps_append_) || !defined(_di_f_utf_string_prepend_) || !defined(_di_f_utf_string_prepend_nulless_) || !defined(_di_f_utf_string_triples_append_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param strings + * The strings to adjust. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_memory_adjust() + * @see f_utf_string_dynamics_adjust() + * @see f_utf_string_dynamics_append() + * @see f_utf_string_dynamics_decimate_by() + * @see f_utf_string_map_multis_adjust() + * @see f_utf_string_map_multis_append() + */ +#if !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) + extern f_status_t private_f_utf_string_dynamics_adjust(const f_array_length_t length, f_utf_string_dynamics_t *strings) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamics_adjust_) || !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_dynamics_decimate_by_) || !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_append_) + +/** + * Private implementation for appending. + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source strings to append. + * @param destination + * The destination strings the source is appended onto. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_utf_string_dynamics_append() + * @see f_utf_string_map_multis_append() + */ +#if !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) + extern f_status_t private_f_utf_string_dynamics_append(const f_utf_string_dynamics_t source, f_utf_string_dynamics_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamics_append_) || !defined(_di_f_utf_string_map_multis_append_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param strings + * The strings to resize. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_utf_string_dynamics_decrease_by() + * @see f_utf_string_dynamics_increase() + * @see f_utf_string_dynamics_increase_by() + */ +#if !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) + extern f_status_t private_f_utf_string_dynamics_resize(const f_array_length_t length, f_utf_string_dynamics_t *strings) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamics_decrease_by_) || !defined(_di_f_utf_string_dynamics_increase_) || !defined(_di_f_utf_string_dynamics_increase_by_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param map_multis + * The map_multis to adjust. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_memory_adjust() + * @see f_utf_string_map_multis_adjust() + */ +#if !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) + extern f_status_t private_f_utf_string_map_multis_adjust(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_map_multis_adjust_) || !defined(_di_f_utf_string_map_multis_decimate_by_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param map_multis + * The map_multis to resize. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_adjust() + * @see f_utf_string_map_multis_decrease_by() + * @see f_utf_string_map_multis_increase() + * @see f_utf_string_map_multis_increase_by() + * @see f_utf_string_map_multis_terminate() + * @see f_utf_string_map_multis_terminate_after() + */ +#if !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) + extern f_status_t private_f_utf_string_map_multis_resize(const f_array_length_t length, f_utf_string_map_multis_t *map_multis) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_map_multis_decrease_by_) || !defined(_di_f_utf_string_map_multis_increase_) || !defined(_di_f_utf_string_map_multis_increase_by_) || !defined(_di_f_utf_string_map_multis_terminate_) || !defined(_di_f_utf_string_map_multis_terminate_after_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param maps + * The maps to adjust. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_memory_adjust() + * @see f_utf_string_maps_adjust() + */ +#if !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) + extern f_status_t private_f_utf_string_maps_adjust(const f_array_length_t length, f_utf_string_maps_t *maps) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_maps_adjust_) || !defined(_di_f_utf_string_maps_decimate_by_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param maps + * The maps to resize. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_adjust() + * @see f_utf_string_maps_decrease_by() + * @see f_utf_string_maps_increase() + * @see f_utf_string_maps_increase_by() + * @see f_utf_string_maps_terminate() + * @see f_utf_string_maps_terminate_after() + */ +#if !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) + extern f_status_t private_f_utf_string_maps_resize(const f_array_length_t length, f_utf_string_maps_t *maps) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_maps_decrease_by_) || !defined(_di_f_utf_string_maps_increase_) || !defined(_di_f_utf_string_maps_increase_by_) || !defined(_di_f_utf_string_maps_terminate_) || !defined(_di_f_utf_string_maps_terminate_after_) + +/** + * Private implementation of f_utf_string_prepend(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to prepend. + * @param length + * Length of source to append. + * @param destination + * The destination string the source and glue are prepended onto. + * + * @return + * F_none on success. + * + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see memcopy() + * @see memmove() + * + * @see f_utf_string_dynamic_mish() + * @see f_utf_string_dynamic_partial_mish() + * @see f_utf_string_dynamic_partial_prepend_assure() + * @see f_utf_string_dynamic_partial_prepend() + * @see f_utf_string_dynamic_prepend_assure() + * @see f_utf_string_dynamic_prepend() + * @see f_utf_string_mish() + * @see f_utf_string_prepend_assure() + * @see f_utf_string_prepend() + */ +#if !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) + extern f_status_t private_f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamic_mish_) || !defined(_di_f_utf_string_dynamic_partial_mish_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_) || !defined(_di_f_utf_string_dynamic_partial_prepend_) || !defined(_di_f_utf_string_dynamic_prepend_assure_) || !defined(_di_f_utf_string_dynamic_prepend_) || !defined(_di_f_utf_string_mish_) || !defined(_di_f_utf_string_prepend_assure_) || !defined(_di_f_utf_string_prepend_) + +/** + * Private implementation of f_utf_string_prepend_nulless(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param source + * The source string to prepend. + * @param length + * Length of source to append. + * @param destination + * The destination string the source and glue are prepended onto. + * + * @return + * F_none on success. + * + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see memcopy() + * @see memmove() + * + * @see f_utf_string_dynamic_mish_nulless() + * @see f_utf_string_dynamic_partial_mish_nulless() + * @see f_utf_string_dynamic_partial_prepend_assure_nulless() + * @see f_utf_string_dynamic_partial_prepend_nulless() + * @see f_utf_string_dynamic_prepend_assure_nulless() + * @see f_utf_string_dynamic_prepend_nulless() + * @see f_utf_string_mish_nulless() + * @see f_utf_string_prepend_assure_nulless() + * @see f_utf_string_prepend_nulless() + */ +#if !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) + extern f_status_t private_f_utf_string_prepend_nulless(const f_utf_string_t source, f_array_length_t length, f_utf_string_dynamic_t *destination) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_dynamic_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_mish_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_partial_prepend_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_assure_nulless_) || !defined(_di_f_utf_string_dynamic_prepend_nulless_) || !defined(_di_f_utf_string_mish_nulless_) || !defined(_di_f_utf_string_prepend_assure_nulless_) || !defined(_di_f_utf_string_prepend_nulless_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param triples + * The triples to adjust. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_adjust(). + * + * @see f_memory_adjust() + * @see f_utf_string_triples_adjust() + * @see f_utf_string_triples_decimate_by() + */ +#if !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + extern f_status_t private_f_utf_string_triples_adjust(const f_array_length_t length, f_utf_string_triples_t *triples) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_triples_adjust_) || !defined(_di_f_utf_string_triples_decimate_by_) + +/** + * Private implementation for resizing. + * + * Intended to be shared to each of the different implementation variations. + * + * @param length + * The new size to use. + * @param triples + * The triples to resize. + * + * @return + * F_none on success. + * + * F_array_too_large (with error bit) if the combined array is too large. + * + * Errors (with error bit) from: f_memory_resize(). + * + * @see f_memory_resize() + * @see f_utf_string_triples_decrease_by() + * @see f_utf_string_triples_increase() + * @see f_utf_string_triples_increase_by() + * @see f_utf_string_triples_terminate() + * @see f_utf_string_triples_terminate_after() + */ +#if !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) + extern f_status_t private_f_utf_string_triples_resize(const f_array_length_t length, f_utf_string_triples_t *triples) F_attribute_visibility_internal_d; +#endif // !defined(_di_f_utf_string_triples_decrease_by_) || !defined(_di_f_utf_string_triples_increase_) || !defined(_di_f_utf_string_triples_increase_by_) || !defined(_di_f_utf_string_triples_terminate_) || !defined(_di_f_utf_string_triples_terminate_after_) + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_F_utf_string_h diff --git a/level_0/f_utf/c/utf-common.c b/level_0/f_utf/c/utf-common.c index ecfcf7f..8fb6b89 100644 --- a/level_0/f_utf/c/utf-common.c +++ b/level_0/f_utf/c/utf-common.c @@ -1,5 +1,6 @@ #include "utf.h" #include "private-utf.h" +#include "private-utf_string.h" #ifdef __cplusplus extern "C" { diff --git a/level_0/f_utf/c/utf-common.h b/level_0/f_utf/c/utf-common.h index 2d16acd..24a2050 100644 --- a/level_0/f_utf/c/utf-common.h +++ b/level_0/f_utf/c/utf-common.h @@ -225,6 +225,30 @@ extern "C" { #define macro_f_utf_string_t_destroy_simple(string, length) f_memory_adjust(length, 0, sizeof(f_utf_string_t), (void **) & string); #endif // _di_f_utf_string_t_ +/** + * Define unicode special character widths. + * + * F_utf_width_*: + * - none: Designate this is not a width value or has no width (aka: NULL). + * - ambiguous: Characters appear in East Asian DBCS and in SBCS. + * - full: Wide character that has a equivilent to a narrow character. + * - half: Narrow character that has a equivilent to a wide character. + * - narrow: Narrow character, without a wide equivalent. + * - nuetral: Characters that do not appear in East Asian DBCS codes. + * - wide: Wide character, without a narrow equivalent. + */ +#ifndef _di_f_utf_widths_t_ + enum { + F_utf_width_none_e, + F_utf_width_ambiguous_e, + F_utf_width_full_e, + F_utf_width_half_e, + F_utf_width_narrow_e, + F_utf_width_nuetral_e, + F_utf_width_wide_e, + }; +#endif // _di_f_utf_widths_t_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_utf/c/utf.c b/level_0/f_utf/c/utf.c index 9c32813..e3d3158 100644 --- a/level_0/f_utf/c/utf.c +++ b/level_0/f_utf/c/utf.c @@ -62,6 +62,7 @@ extern "C" { } range->start += width; + return F_none_stop; } else if (range->start + width >= buffer.used) { @@ -70,6 +71,7 @@ extern "C" { } range->start += width; + return F_none_eos; } @@ -89,6 +91,14 @@ extern "C" { if (!character_utf) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } + + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } + return private_f_utf_char_to_character(character, width_max, character_utf); } #endif // _di_f_utf_char_to_character_ @@ -96,605 +106,556 @@ extern "C" { #ifndef _di_f_utf_character_is_ f_status_t f_utf_character_is(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - return F_false; - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_utf_fragment; + } - if (width == 1) { - return F_status_is_error(F_utf); + return F_true; } - return F_true; + return F_false; } #endif // _di_f_utf_character_is_ #ifndef _di_f_utf_character_is_alpha_ f_status_t f_utf_character_is_alpha(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalpha(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_alpha(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalpha(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_alpha(character, width); + return F_false; } #endif // _di_f_utf_character_is_alpha_ #ifndef _di_f_utf_character_is_alpha_digit_ f_status_t f_utf_character_is_alpha_digit(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalnum(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_alpha_digit(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalnum(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_alpha_digit(character, width); + return F_false; } #endif // _di_f_utf_character_is_alpha_digit_ #ifndef _di_f_utf_character_is_alpha_numeric_ f_status_t f_utf_character_is_alpha_numeric(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalnum(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_alpha_numeric(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalnum(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_alpha_numeric(character, width); + return F_false; } #endif // _di_f_utf_character_is_alpha_numeric_ #ifndef _di_f_utf_character_is_ascii_ f_status_t f_utf_character_is_ascii(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (width == 1) { - return F_status_is_error(F_utf); + if (macro_f_utf_character_t_width_is(character)) { + return F_false; } - return private_f_utf_character_is_ascii(character, width); + return F_true; } #endif // _di_f_utf_character_is_ascii_ #ifndef _di_f_utf_character_is_combining_ f_status_t f_utf_character_is_combining(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - // There are no combining characters in ASCII. - return F_false; - } - - if (width == 1) { - return F_status_is_error(F_utf); - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width != 3) { - return F_false; + return private_f_utf_character_is_combining(character); } - return private_f_utf_character_is_combining(character, width); + // There are no combining characters in ASCII. + return F_false; } #endif // _di_f_utf_character_is_combining_ #ifndef _di_f_utf_character_is_control_ f_status_t f_utf_character_is_control(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (iscntrl(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_control(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (iscntrl(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_control(character, width); + return F_false; } #endif // _di_f_utf_character_is_control_ #ifndef _di_f_utf_character_is_control_code_ f_status_t f_utf_character_is_control_code(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (iscntrl(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_control_code(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (iscntrl(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_control_code(character, width); + return F_false; } #endif // _di_f_utf_character_is_control_code_ #ifndef _di_f_utf_character_is_control_picture_ f_status_t character_is_control_format(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // There are no control format characters in ASCII. - return F_false; - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_utf); + return private_f_utf_character_is_control_format(character); } - return private_f_utf_character_is_control_format(character, width); + // There are no control format characters in ASCII. + return F_false; } #endif // _di_f_utf_character_is_control_format_ #ifndef _di_f_utf_character_is_control_picture_ f_status_t f_utf_character_is_control_picture(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // There are no control picture characters in ASCII. - return F_false; - } - - if (width == 1) { - return F_status_is_error(F_utf); - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width != 3) { - return F_false; + return private_f_utf_character_is_control_picture(character); } - return private_f_utf_character_is_control_picture(character, width); + // There are no control picture characters in ASCII. + return F_false; } #endif // _di_f_utf_character_is_control_picture_ #ifndef _di_f_utf_character_is_digit_ f_status_t f_utf_character_is_digit(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isdigit(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_digit(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isdigit(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_digit(character, width); + return F_false; } #endif // _di_f_utf_character_is_digit_ #ifndef _di_f_utf_character_is_emoji_ f_status_t f_utf_character_is_emoji(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isdigit(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_emoji(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isdigit(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_emoji(character, width); + return F_false; } #endif // _di_f_utf_character_is_emoji_ #ifndef _di_f_utf_character_is_fragment_ f_status_t f_utf_character_is_fragment(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (width == 1) return F_true; - - return F_false; + return macro_f_utf_character_t_width_is(character) == 1; } #endif // _di_f_utf_character_is_fragment_ #ifndef _di_f_utf_character_is_graph_ f_status_t f_utf_character_is_graph(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isgraph(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + if (private_f_utf_character_is_control(character)) { + return F_false; + } - if (width == 1) { - return F_status_is_error(F_utf); - } + if (private_f_utf_character_is_whitespace(character)) { + return F_false; + } - if (private_f_utf_character_is_control(character, width)) { - return F_false; - } + if (private_f_utf_character_is_zero_width(character)) { + return F_false; + } - if (private_f_utf_character_is_whitespace(character, width)) { - return F_false; + return F_true; } - if (private_f_utf_character_is_zero_width(character, width)) { - return F_false; + if (isgraph(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return F_true; + return F_false; } #endif // _di_f_utf_character_is_graph_ #ifndef _di_f_utf_character_is_numeric_ f_status_t f_utf_character_is_numeric(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isdigit(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_numeric(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isdigit(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_numeric(character, width); + return F_false; } #endif // _di_f_utf_character_is_numeric_ #ifndef _di_f_utf_character_is_phonetic_ f_status_t f_utf_character_is_phonetic(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // There are no ASCII phonetic characters. - return F_false; - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_utf); + return private_f_utf_character_is_phonetic(character); } - return private_f_utf_character_is_phonetic(character, width); + // There are no ASCII phonetic characters. + return F_false; } #endif // _di_f_utf_character_is_phonetic_ #ifndef _di_f_utf_character_is_private_ f_status_t f_utf_character_is_private(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // There are no ASCII private characters. - return F_false; - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_utf); + return private_f_utf_character_is_private(character); } - return private_f_utf_character_is_private(character, width); + // There are no ASCII private characters. + return F_false; } #endif // _di_f_utf_character_is_phonetic_ #ifndef _di_f_utf_character_is_punctuation_ f_status_t f_utf_character_is_punctuation(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // ASCII: '!' to '#'. - if (character > 0x20000000 && character < 0x24000000) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - // ASCII: '%' to '*'. - if (character > 0x24000000 && character < 0x2b000000) { - return F_true; - } + return private_f_utf_character_is_punctuation(character); + } - // ASCII: ',' to '/'. - if (character > 0x2b000000 && character < 0x30000000) { - return F_true; - } + // ASCII: '!' to '#'. + if (character > 0x20000000 && character < 0x24000000) { + return F_true; + } - // ASCII: ':', ';', '?', or '@'. - if (character == 0x3a000000 || character == 0x3b000000 || character == 0x3f000000 || character == 0x40000000) { - return F_true; - } + // ASCII: '%' to '*'. + if (character > 0x24000000 && character < 0x2b000000) { + return F_true; + } - // ASCII: '[' to ']'. - if (character > 0x5a000000 && character < 0x5d000000) { - return F_true; - } + // ASCII: ',' to '/'. + if (character > 0x2b000000 && character < 0x30000000) { + return F_true; + } - // ASCII: '_', '{', or '}'. - if (character == 0x5f000000 || character == 0x7b000000 || character == 0x7d000000) { - return F_true; - } + // ASCII: ':', ';', '?', or '@'. + if (character == 0x3a000000 || character == 0x3b000000 || character == 0x3f000000 || character == 0x40000000) { + return F_true; + } - return F_false; + // ASCII: '[' to ']'. + if (character > 0x5a000000 && character < 0x5d000000) { + return F_true; } - if (width == 1) { - return F_status_is_error(F_utf); + // ASCII: '_', '{', or '}'. + if (character == 0x5f000000 || character == 0x7b000000 || character == 0x7d000000) { + return F_true; } - return private_f_utf_character_is_punctuation(character, width); + return F_false; } #endif // _di_f_utf_character_is_punctuation_ #ifndef _di_f_utf_character_is_symbol_ f_status_t f_utf_character_is_symbol(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - - // ASCII: '$' or '+'. - if (character == 0x24000000 || character == 0x2b000000) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - // ASCII: '<' to '>'. - if (character > 0x3c000000 && character < 0x3e000000) { - return F_true; - } + return private_f_utf_character_is_symbol(character); + } - // ASCII: '^', '`', '|', or '~'. - if (character == 0x5e000000 || character == 0x60000000 || character == 0x7c000000 || character == 0x7e000000) { - return F_true; - } + // ASCII: '$' or '+'. + if (character == 0x24000000 || character == 0x2b000000) { + return F_true; + } - return F_false; + // ASCII: '<' to '>'. + if (character > 0x3c000000 && character < 0x3e000000) { + return F_true; } - if (width == 1) { - return F_status_is_error(F_utf); + // ASCII: '^', '`', '|', or '~'. + if (character == 0x5e000000 || character == 0x60000000 || character == 0x7c000000 || character == 0x7e000000) { + return F_true; } - return private_f_utf_character_is_symbol(character, width); + return F_false; } #endif // _di_f_utf_character_is_symbol_ #ifndef _di_f_utf_character_is_unassigned_ f_status_t f_utf_character_is_unassigned(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (!width || width == 1) { - return F_false; + return private_f_utf_character_is_unassigned(character); } - return private_f_utf_character_is_unassigned(character, width); + return F_false; } #endif // _di_f_utf_character_is_unassigned_ #ifndef _di_f_utf_character_is_valid_ f_status_t f_utf_character_is_valid(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_false; + return private_f_utf_character_is_valid(character); } - return private_f_utf_character_is_valid(character, width); + return F_true; } #endif // _di_f_utf_character_is_valid_ #ifndef _di_f_utf_character_is_whitespace_ f_status_t f_utf_character_is_whitespace(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isspace(macro_f_utf_character_t_to_char_1(character))) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_whitespace(character); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isspace(macro_f_utf_character_t_to_char_1(character))) { + return F_true; } - return private_f_utf_character_is_whitespace(character, width); + return F_false; } #endif // _di_f_utf_character_is_whitespace_ #ifndef _di_f_utf_character_is_whitespace_modifier_ f_status_t f_utf_character_is_whitespace_modifier(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - // There are no ASCII whitespace modifiers. - return F_false; - } + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_utf); + return private_f_utf_character_is_whitespace_modifier(character); } - return private_f_utf_character_is_whitespace_modifier(character, width); + // There are no ASCII whitespace modifiers. + return F_false; } #endif // _di_f_utf_character_is_whitespace_modifier_ #ifndef _di_f_utf_character_is_whitespace_other_ f_status_t f_utf_character_is_whitespace_other(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - // There are no ASCII whitespace other. - return F_false; + return private_f_utf_character_is_whitespace_other(character); } - if (width == 1) { - return F_status_is_error(F_utf); + // There are no ASCII whitespace other. + return F_false; + } +#endif // _di_f_utf_character_is_whitespace_other_ + +#ifndef _di_f_utf_character_is_wide_ + f_status_t f_utf_character_is_wide(const f_utf_character_t character) { + + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } + + return private_f_utf_character_is_wide(character); } - return private_f_utf_character_is_whitespace_other(character, width); + // There are no wide ASCII characters. + return F_false; } -#endif // _di_f_utf_character_is_whitespace_other_ +#endif // _di_f_utf_character_is_wide_ #ifndef _di_f_utf_character_is_word_ f_status_t f_utf_character_is_word(const f_utf_character_t character, const bool strict) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == '_') { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_word(character, strict); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == f_string_ascii_underscore_s[0]) { + return F_true; } - return private_f_utf_character_is_word(character, width, strict); + return F_false; } #endif // _di_f_utf_character_is_word_ #ifndef _di_f_utf_character_is_word_dash_ f_status_t f_utf_character_is_word_dash(const f_utf_character_t character, const bool strict) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == '_' || character == '-') { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_word_dash(character, strict); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == f_string_ascii_underscore_s[0] || character == f_string_ascii_minus_s[0]) { + return F_true; } - return private_f_utf_character_is_word_dash(character, width, strict); + return F_false; } #endif // _di_f_utf_character_is_word_dash_ #ifndef _di_f_utf_character_is_word_dash_plus_ f_status_t f_utf_character_is_word_dash_plus(const f_utf_character_t character, const bool strict) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == '_' || character == '-' || character == '+') { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_word_dash_plus(character, strict); } - if (width == 1) { - return F_status_is_error(F_utf); + if (isalnum(macro_f_utf_character_t_to_char_1(character)) || character == f_string_ascii_underscore_s[0] || character == f_string_ascii_minus_s[0] || character == f_string_ascii_plus_s[0]) { + return F_true; } - return private_f_utf_character_is_word_dash_plus(character, width, strict); + return F_false; } #endif // _di_f_utf_character_is_word_dash_plus_ #ifndef _di_f_utf_character_is_zero_width_ f_status_t f_utf_character_is_zero_width(const f_utf_character_t character) { - const uint8_t width = macro_f_utf_character_t_width_is(character); - - if (!width) { - const uint8_t ascii = macro_f_utf_character_t_to_char_1(character); - - // These control characters are considered zero-width spaces. - if (ascii >= 0x00 && ascii <= 0x08) { - return F_true; - } - else if (ascii == 0x0a) { - return F_true; - } - else if (ascii >= 0x0c && ascii <= 0x1f) { - return F_true; - } - else if (ascii == 0x7f) { - return F_true; + if (macro_f_utf_character_t_width_is(character)) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; + return private_f_utf_character_is_zero_width(character); } - if (width == 1) { - return F_status_is_error(F_utf); + const uint8_t ascii = macro_f_utf_character_t_to_char_1(character); + + // These control characters are considered zero-width spaces. + if (ascii >= 0x00 && ascii <= 0x08) { + return F_true; + } + else if (ascii == 0x0a) { + return F_true; + } + else if (ascii >= 0x0c && ascii <= 0x1f) { + return F_true; + } + else if (ascii == 0x7f) { + return F_true; } - return private_f_utf_character_is_zero_width(character, width); + return F_false; } #endif // _di_f_utf_character_is_zero_width_ @@ -708,12 +669,11 @@ extern "C" { #endif // _di_level_0_parameter_checking_ if (macro_f_utf_character_t_width_is(utf_character)) { - - // @todo endianess is compile time so a function is not needed, replace with macros. - if (f_utf_is_big_endian()) { - memcpy(*character, &utf_character, macro_f_utf_character_t_width_is(utf_character)); + if (macro_f_utf_character_t_width_is(utf_character) == 1) { + return F_status_set_error(F_utf_fragment); } - else { + + #if __BYTE_ORDER == __LITTLE_ENDIAN uint32_t utf = 0; switch (macro_f_utf_character_t_width_is(utf_character)) { @@ -734,20 +694,20 @@ extern "C" { } memcpy(*character, &utf, macro_f_utf_character_t_width_is(utf_character)); - } + #else + memcpy(*character, &utf_character, macro_f_utf_character_t_width_is(utf_character)); + #endif // __BYTE_ORDER == __LITTLE_ENDIAN + + return F_none; } - else { - // @todo endianess is compile time so a function is not needed, replace with macros. - if (f_utf_is_big_endian()) { - memcpy(*character, &utf_character, 1); - } - else { - uint32_t utf = macro_f_utf_character_t_to_char_1(utf_character) << 24; + #if __BYTE_ORDER == __LITTLE_ENDIAN + uint32_t utf = macro_f_utf_character_t_to_char_1(utf_character) << 24; - memcpy(*character, &utf, 1); - } - } + memcpy(*character, &utf, 1); + #else + memcpy(*character, &utf_character, 1); + #endif // __BYTE_ORDER == __LITTLE_ENDIAN return F_none; } @@ -759,33 +719,34 @@ extern "C" { if (!unicode) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_character_t_width(character); - - if (private_f_utf_character_is_valid(character, width) == F_false) { - return F_status_set_error(F_utf); + // ASCII. + if (!macro_f_utf_character_t_width_is(character)) { + *unicode = macro_f_utf_character_t_to_char_1(character) & 0x7f; } - if (width < 2) { + if (macro_f_utf_character_t_width_is(character) == 1) { + return F_status_set_error(F_utf_fragment); + } - // U+0000 -> U+007F - *unicode = macro_f_utf_character_t_to_char_1(character) & 0x7f; + if (private_f_utf_character_is_valid(character) == F_false) { + return F_status_set_error(F_utf); } - else if (width == 2) { - // U+0080 -> U+07FF + // U+0080 -> U+07FF. + if (macro_f_utf_character_t_width_is(character) == 2) { *unicode = (macro_f_utf_character_t_to_char_1(character) & 0x1f) << 6; *unicode |= macro_f_utf_character_t_to_char_2(character) & 0x3f; } - else if (width == 3) { - // U+0800 -> U+FFFF + // U+0800 -> U+FFFF. + else if (macro_f_utf_character_t_width_is(character) == 3) { *unicode = (macro_f_utf_character_t_to_char_1(character) & 0xf) << 12; *unicode |= (macro_f_utf_character_t_to_char_2(character) & 0x3f) << 6; *unicode |= macro_f_utf_character_t_to_char_3(character) & 0x3f; } - else if (width == 4) { - // U+10000 -> U+10FFFF + // U+10000 -> U+10FFFF. + else if (macro_f_utf_character_t_width_is(character) == 4) { *unicode = (macro_f_utf_character_t_to_char_1(character) & 0x7) << 18; *unicode |= (macro_f_utf_character_t_to_char_2(character) & 0x3f) << 12; *unicode |= (macro_f_utf_character_t_to_char_2(character) & 0x3f) << 6; @@ -806,29 +767,28 @@ extern "C" { return F_status_set_error(F_utf); } + // U+0000 -> U+007F. if (unicode < 0x80) { - - // U+0000 -> U+007F *character = unicode; } - else if (unicode < 0x800) { - // U+0080 -> U+07FF + // U+0080 -> U+07FF. + else if (unicode < 0x800) { *character = (unicode & 0x7c0) << 2; *character |= unicode & 0x3f; *character |= 0xc080; } - else if (unicode < 0x10000) { - // U+0800 -> U+FFFF + // U+0800 -> U+FFFF. + else if (unicode < 0x10000) { *character = (unicode & 0xf000) << 4; *character |= (unicode & 0xfc0) << 2; *character |= unicode & 0x3f; *character |= 0xe08080; } - else { - // U+10000 -> U+ + // U+100000 -> U+10FFFF. + else { *character = (unicode & 0x1c0000) << 6; *character |= (unicode & 0x3f000) << 4; *character |= (unicode & 0xfc0) << 2; @@ -840,36 +800,10 @@ extern "C" { } #endif // _di_f_utf_character_unicode_from_ -#ifndef _di_f_utf_is_big_endian_ - f_status_t f_utf_is_big_endian() { - uint16_t test_int = (0x01 << 8) | 0x02; - uint8_t test_char[2] = {0x01, 0x02}; - - if (!memcmp(&test_int, test_char, 2)) { - return F_true; - } - - return F_false; - } -#endif // _di_f_utf_is_big_endian_ - #ifndef _di_f_utf_is_ - f_status_t f_utf_is(const f_string_t character, const f_array_length_t width_max) { - #ifndef _di_level_0_parameter_checking_ - if (width_max < 1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { - return F_false; - } + f_status_t f_utf_is(const f_string_t character) { - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } - - return F_true; + return macro_f_utf_byte_width_is(*character); } #endif // _di_f_utf_is_ @@ -879,28 +813,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isalpha(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_alpha(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isalpha(*character)) { + return F_true; } - return private_f_utf_character_is_alpha(character_utf, width); + return F_false; } #endif // _di_f_utf_is_alpha_ @@ -910,28 +846,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } + + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } + + f_utf_character_t character_utf = 0; - if (!width) { - if (isalnum(*character)) { - return F_true; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; } - return F_false; + return private_f_utf_character_is_alpha_digit(character_utf); } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); + if (isalnum(*character)) { + return F_true; } - f_utf_character_t character_utf = 0; - - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; - } - - return private_f_utf_character_is_alpha_digit(character_utf, width); + return F_false; } #endif // _di_f_utf_is_alpha_digit_ @@ -941,28 +879,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isalnum(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_alpha_numeric(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isalnum(*character)) { + return F_true; } - return private_f_utf_character_is_alpha_numeric(character_utf, width); + return F_false; } #endif // _di_f_utf_is_alpha_numeric_ @@ -972,20 +912,19 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - f_utf_character_t character_utf = 0; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return F_false; } - return private_f_utf_character_is_ascii(character_utf, width); + return F_true; } #endif // _di_f_utf_is_ascii_ @@ -995,25 +934,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII combining characters. - if (!width) { - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_combining(character_utf); } - return private_f_utf_character_is_combining(character_utf, width); + // There are no ASCII combining characters. + return F_false; } #endif // _di_f_utf_is_combining_ @@ -1023,28 +964,26 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { - if (iscntrl(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); } - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_control(character_utf); } - return private_f_utf_character_is_control(character_utf, width); + return iscntrl(*character); } #endif // _di_f_utf_is_control_ @@ -1054,26 +993,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (iscntrl(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_control_code(character_utf); + } - f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (iscntrl(*character)) { + return F_true; + } - return private_f_utf_character_is_control_code(character_utf, width); + return F_false; } #endif // _di_f_utf_is_control_code_ @@ -1083,25 +1026,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII control formats. - if (!width) { - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_control_format(character_utf); } - return private_f_utf_character_is_control_format(character_utf, width); + // There are no ASCII control formats. + return F_false; } #endif // _di_f_utf_is_control_format_ @@ -1111,29 +1056,31 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII control pictures. - if (!width) { - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + if (macro_f_utf_byte_width_is(*character) != 3) { + return F_false; + } - if (width != 3) { - return F_false; - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_control_picture(character_utf); } - return private_f_utf_character_is_control_picture(character_utf, width); + // There are no ASCII control pictures. + return F_false; } #endif // _di_f_utf_is_control_picture_ @@ -1143,28 +1090,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isdigit(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_digit(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isdigit(*character)) { + return F_true; } - return private_f_utf_character_is_digit(character_utf, width); + return F_false; } #endif // _di_f_utf_is_digit_ @@ -1174,40 +1123,37 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isdigit(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_emoji(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isdigit(*character)) { + return F_true; } - return private_f_utf_character_is_emoji(character_utf, width); + return F_false; } #endif // _di_f_utf_is_emoji_ #ifndef _di_f_utf_is_fragment_ - f_status_t f_utf_is_fragment(const f_string_t character, const f_array_length_t width_max) { - #ifndef _di_level_0_parameter_checking_ - if (width_max < 1) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - const uint8_t width = macro_f_utf_byte_width_is(*character); + f_status_t f_utf_is_fragment(const f_string_t character) { - if (width == 1) { + if (macro_f_utf_byte_width_is(*character) == 1) { return F_true; } @@ -1221,41 +1167,43 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isgraph(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + if (private_f_utf_character_is_control(character_utf)) { + return F_false; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; - } + if (private_f_utf_character_is_whitespace(character_utf)) { + return F_false; + } - if (private_f_utf_character_is_control(character_utf, width)) { - return F_false; - } + // Zero-width characters are be treated as a non-graph. + if (private_f_utf_character_is_zero_width(character_utf)) { + return F_false; + } - if (private_f_utf_character_is_whitespace(character_utf, width)) { - return F_false; + return F_true; } - // This test is in isolation so zero-width characters must be treated as a non-graph. - if (private_f_utf_character_is_zero_width(character_utf, width)) { - return F_false; + if (isgraph(*character)) { + return F_true; } - return F_true; + return F_false; } #endif // _di_f_utf_is_graph_ @@ -1265,28 +1213,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isdigit(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_numeric(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isdigit(*character)) { + return F_true; } - return private_f_utf_character_is_numeric(character_utf, width); + return F_false; } #endif // _di_f_utf_is_numeric_ @@ -1296,26 +1246,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII phonetic characters. - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_phonetic(character_utf); } - return private_f_utf_character_is_phonetic(character_utf, width); + // There are no ASCII phonetic characters. + return F_false; } #endif // _di_f_utf_is_phonetic_ @@ -1325,26 +1276,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII private characters. - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_private(character_utf); } - return private_f_utf_character_is_private(character_utf, width); + // There are no ASCII private characters. + return F_false; } #endif // _di_f_utf_is_private_ @@ -1354,55 +1306,56 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { - - // ASCII: '!' to '#'. - if (character[0] > 0x20 && character[0] < 0x24) { - return F_true; + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); } - // ASCII: '%' to '*'. - if (character[0] > 0x24 && character[0] < 0x2b) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - // ASCII: ',' to '/'. - if (character[0] > 0x2b && character[0] < 0x30) { - return F_true; - } + f_utf_character_t character_utf = 0; - // ASCII: ':', ';', '?', or '@'. - if (character[0] == 0x3a || character[0] == 0x3b || character[0] == 0x3f || character[0] == 0x40) { - return F_true; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; } - // ASCII: '[' to ']'. - if (character[0] > 0x5a && character[0] < 0x5d) { - return F_true; - } + return private_f_utf_character_is_punctuation(character_utf); + } - // ASCII: '_', '{', or '}'. - if (character[0] == 0x5f || character[0] == 0x7b || character[0] == 0x7d) { - return F_true; - } + // ASCII: '!' to '#'. + if (character[0] > 0x20 && character[0] < 0x24) { + return F_true; + } - return F_false; + // ASCII: '%' to '*'. + if (character[0] > 0x24 && character[0] < 0x2b) { + return F_true; } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); + // ASCII: ',' to '/'. + if (character[0] > 0x2b && character[0] < 0x30) { + return F_true; } - f_utf_character_t character_utf = 0; + // ASCII: ':', ';', '?', or '@'. + if (character[0] == 0x3a || character[0] == 0x3b || character[0] == 0x3f || character[0] == 0x40) { + return F_true; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + // ASCII: '[' to ']'. + if (character[0] > 0x5a && character[0] < 0x5d) { + return F_true; + } + + // ASCII: '_', '{', or '}'. + if (character[0] == 0x5f || character[0] == 0x7b || character[0] == 0x7d) { + return F_true; } - return private_f_utf_character_is_punctuation(character_utf, width); + return F_false; } #endif // _di_f_utf_is_punctuation_ @@ -1412,40 +1365,41 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { - - // ASCII: '$' or '+'. - if (character[0] == 0x24 || character[0] == 0x2b) { - return F_true; + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); } - // ASCII: '<' to '>'. - if (character[0] > 0x3c && character[0] < 0x3e) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - // ASCII: '^', '`', '|', or '~'. - if (character[0] == 0x5e || character[0] == 0x60 || character[0] == 0x7c || character[0] == 0x7e) { - return F_true; + f_utf_character_t character_utf = 0; + + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; } - return F_false; + return private_f_utf_character_is_symbol(character_utf); } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); + // ASCII: '$' or '+'. + if (character[0] == 0x24 || character[0] == 0x2b) { + return F_true; } - f_utf_character_t character_utf = 0; + // ASCII: '<' to '>'. + if (character[0] > 0x3c && character[0] < 0x3e) { + return F_true; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + // ASCII: '^', '`', '|', or '~'. + if (character[0] == 0x5e || character[0] == 0x60 || character[0] == 0x7c || character[0] == 0x7e) { + return F_true; } - return private_f_utf_character_is_symbol(character_utf, width); + return F_false; } #endif // _di_f_utf_is_symbol_ @@ -1455,20 +1409,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width || width == 1) { - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - f_utf_character_t character_utf = 0; + f_utf_character_t character_utf = 0; - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_character_is_unassigned(character_utf); } - return private_f_utf_character_is_unassigned(character_utf, width); + // ASCII are never unassigned. + return F_false; } #endif // _di_f_utf_is_unassigned_ @@ -1478,20 +1439,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } + + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_false; - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_valid(character_utf); } - return private_f_utf_character_is_valid(character_utf, width); + // ASCII are valid. + return F_true; } #endif // _di_f_utf_is_valid_ @@ -1501,28 +1469,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isspace(*character)) { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_whitespace(character_utf); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isspace(*character)) { + return F_true; } - return f_utf_character_is_whitespace(character_utf); + return F_false; } #endif // _di_f_utf_is_whitespace_ @@ -1532,26 +1502,27 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - // There are no ASCII whitespace modifiers. - return F_false; - } + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + f_utf_character_t character_utf = 0; - f_utf_character_t character_utf = 0; + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + return private_f_utf_character_is_whitespace_modifier(character_utf); } - return private_f_utf_character_is_whitespace_modifier(character_utf, width); + // There are no ASCII whitespace modifiers. + return F_false; } #endif // _di_f_utf_is_whitespace_modifier_ @@ -1561,28 +1532,56 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } - // There are no ASCII whitespace other. - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_character_is_whitespace_other(character_utf); } - f_utf_character_t character_utf = 0; + // There are no ASCII whitespace other. + return F_false; + } +#endif // _di_f_utf_is_whitespace_other_ + +#ifndef _di_f_utf_is_wide_ + f_status_t f_utf_is_wide(const f_string_t character, const f_array_length_t width_max) { - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } + + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } + + f_utf_character_t character_utf = 0; + + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_character_is_wide(character_utf); } - return private_f_utf_character_is_whitespace_other(character_utf, width); + // There are no wide ASCII characters. + return F_false; } -#endif // _di_f_utf_is_whitespace_other_ +#endif // _di_f_utf_is_wide_ #ifndef _di_f_utf_is_word_ f_status_t f_utf_is_word(const f_string_t character, const f_array_length_t width_max, const bool strict) { @@ -1590,28 +1589,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isalnum(*character) || *character == '_') { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_word(character_utf, strict); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isalnum(*character) || *character == f_string_ascii_underscore_s[0]) { + return F_true; } - return private_f_utf_character_is_word(character_utf, width, strict); + return F_false; } #endif // _di_f_utf_is_word_ @@ -1621,28 +1622,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isalnum(*character) || *character == '_' || *character == '-') { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_word_dash(character_utf, strict); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isalnum(*character) || *character == f_string_ascii_underscore_s[0] || *character == f_string_ascii_minus_s[0]) { + return F_true; } - return private_f_utf_character_is_word_dash(character_utf, width, strict); + return F_false; } #endif // _di_f_utf_is_word_dash_ @@ -1652,28 +1655,30 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); + } - if (!width) { - if (isalnum(*character) || *character == '_' || *character == '-' || *character == '+') { - return F_true; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - return F_false; - } + f_utf_character_t character_utf = 0; - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; + } - f_utf_character_t character_utf = 0; + return private_f_utf_character_is_word_dash_plus(character_utf, strict); + } - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; + if (isalnum(*character) || *character == f_string_ascii_underscore_s[0] || *character == f_string_ascii_minus_s[0] || *character == f_string_ascii_plus_s[0]) { + return F_true; } - return private_f_utf_character_is_word_dash_plus(character_utf, width, strict); + return F_false; } #endif // _di_f_utf_is_word_dash_plus_ @@ -1683,404 +1688,177 @@ extern "C" { if (width_max < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width_is(*character); - - if (!width) { - - // These control characters are considered zero-width spaces. - if (*character >= 0x00 && *character <= 0x08) { - return F_true; - } - else if (*character >= 0x0c && *character <= 0x1f) { - return F_true; - } - else if (*character == 0x7f) { - return F_true; + if (macro_f_utf_byte_width_is(*character)) { + if (macro_f_utf_byte_width_is(*character) > width_max) { + return F_status_set_error(F_failure); } - return F_false; - } - - if (width == 1) { - return F_status_is_error(F_complete_not_utf); - } - - f_utf_character_t character_utf = 0; - - { - const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); - if (F_status_is_error(status)) return status; - } - - return private_f_utf_character_is_zero_width(character_utf, width); - } -#endif // _di_f_utf_is_zero_width_ - -#ifndef _di_f_utf_string_append_ - f_status_t f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - - return private_f_utf_string_append(source, length, destination); - } -#endif // _di_f_utf_string_append_ - -#ifndef _di_f_utf_string_append_assure_ - f_status_t f_utf_string_append_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - if (destination->used < length) return private_f_utf_string_append(source, length, destination); - - f_array_length_t i = 1; - f_array_length_t j = 1; - - while (i <= length && j <= destination->used) { - - if (!source[length - i]) { - ++i; - - continue; + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); } - if (!destination->string[destination->used - j]) { - ++j; - - continue; - } + f_utf_character_t character_utf = 0; - if (source[length - i] != destination->string[destination->used - j]) { - return private_f_utf_string_append(source, length, destination); + { + const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); + if (F_status_is_error(status)) return status; } - ++i; - ++j; - } // while - - return F_none; - } -#endif // _di_f_utf_string_append_assure_ - -#ifndef _di_f_utf_string_append_assure_nulless_ - f_status_t f_utf_string_append_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) { - return F_data_not_eos; + return private_f_utf_character_is_zero_width(character_utf); } - if (destination->used < length) { - return private_f_utf_string_append_nulless(source, length, destination); - } - - f_array_length_t i = 1; - f_array_length_t j = 1; - - while (i <= length && j <= destination->used) { - - if (!source[length - i]) { - ++i; - - continue; - } - - if (!destination->string[destination->used - j]) { - ++j; - - continue; - } - - if (source[length - i] != destination->string[destination->used - j]) { - return private_f_utf_string_append_nulless(source, length, destination); - } - - ++i; - ++j; - } // while - - return F_none; - } -#endif // _di_f_utf_string_append_assure_nulless_ - -#ifndef _di_f_utf_string_append_nulless_ - f_status_t f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - - return private_f_utf_string_append_nulless(source, length, destination); - } -#endif // _di_f_utf_string_append_nulless_ - -#ifndef _di_f_utf_string_mash_ - f_status_t f_utf_string_mash(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - - if (glue_length && destination->used) { - f_status_t status = private_f_utf_string_append(glue, glue_length, destination); - if (F_status_is_error(status)) return status; + // These control characters are considered zero-width spaces. + if (*character >= 0x00 && *character <= 0x08) { + return F_true; } - - return private_f_utf_string_append(source, length, destination); - } -#endif // _di_f_utf_string_mash_ - -#ifndef _di_f_utf_string_mash_nulless_ - f_status_t f_utf_string_mash_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - - if (glue_length && destination->used) { - f_status_t status = private_f_utf_string_append_nulless(glue, glue_length, destination); - if (F_status_is_error(status)) return status; + else if (*character >= 0x0c && *character <= 0x1f) { + return F_true; } - - return private_f_utf_string_append_nulless(source, length, destination); - } -#endif // _di_f_utf_string_mash_nulless_ - -#ifndef _di_f_utf_string_mish_ - f_status_t f_utf_string_mish(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; - - if (glue_length && destination->used) { - f_status_t status = private_f_utf_string_prepend(glue, glue_length, destination); - if (F_status_is_error(status)) return status; + else if (*character == 0x7f) { + return F_true; } - return private_f_utf_string_prepend(source, length, destination); + return F_false; } -#endif // _di_f_utf_string_mish_ +#endif // _di_f_utf_is_zero_width_ -#ifndef _di_f_utf_string_mish_nulless_ - f_status_t f_utf_string_mish_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { +#ifndef _di_f_utf_unicode_from_ + f_status_t f_utf_unicode_from(const uint32_t unicode, const f_array_length_t width_max, f_string_t *character) { #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); + if (width_max < 1) return F_status_set_error(F_parameter); + if (!unicode) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!length) return F_data_not_eos; - - if (glue_length && destination->used) { - f_status_t status = private_f_utf_string_prepend_nulless(glue, glue_length, destination); - if (F_status_is_error(status)) return status; + // @fixme the code here needs to be reviewed for endianess accuracy for both big and little endian. + if (unicode > 0x10ffff) { + return F_status_set_error(F_utf); } - return private_f_utf_string_prepend_nulless(source, length, destination); - } -#endif // _di_f_utf_string_mish_nulless_ - -#ifndef _di_f_utf_string_prepend_ - f_status_t f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) return F_data_not_eos; + if (unicode < 0x80) { - return private_f_utf_string_prepend(source, length, destination); - } -#endif // _di_f_utf_string_prepend_ + // U+0000 -> U+007F + (*character)[0] = (uint8_t) unicode; -#ifndef _di_f_utf_string_prepend_assure_ - f_status_t f_utf_string_prepend_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + if (width_max > 1) { + (*character)[1] = 0; - if (!length) return F_data_not_eos; + if (width_max > 2) { + (*character)[2] = 0; - if (destination->used < length) { - return private_f_utf_string_prepend(source, length, destination); + if (width_max > 3) { + (*character)[3] = 0; + } + } + } } - - f_array_length_t i = 0; - f_array_length_t j = 0; - - while (i < length && j < destination->used) { - - if (!source[i]) { - ++i; - - continue; + else if (unicode < 0x800) { + if (width_max < 2) { + return F_status_set_error(F_utf); } - if (!destination->string[j]) { - ++j; + // U+0080 -> U+07FF + (*character)[0] = F_utf_byte_2_d | ((uint8_t) ((unicode & 0x7c0) >> 6)); + (*character)[1] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); - continue; - } + if (width_max > 2) { + (*character)[2] = 0; - if (source[i] != destination->string[i]) { - return private_f_utf_string_prepend(source, length, destination); + if (width_max > 2) { + (*character)[2] = 0; + } } - - ++i; - ++j; - } // while - - return F_none; - } -#endif // _di_f_utf_string_prepend_assure_ - -#ifndef _di_f_utf_string_prepend_assure_nulless_ - f_status_t f_utf_string_prepend_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { - #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (!length) { - return F_data_not_eos; } - - if (destination->used < length) { - return private_f_utf_string_prepend_nulless(source, length, destination); - } - - f_array_length_t i = 0; - f_array_length_t j = 0; - - while (i < length && j < destination->used) { - - if (!source[i]) { - ++i; - - continue; + else if (unicode < 0x10000) { + if (width_max < 3) { + return F_status_set_error(F_utf); } - if (!destination->string[j]) { - ++j; + // U+0800 -> U+FFFF + (*character)[0] = F_utf_byte_3_d | ((uint8_t) ((unicode & 0xf000) >> 12)); + (*character)[1] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0xfc0) >> 6)); + (*character)[2] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); - continue; + if (width_max > 3) { + character[3] = 0; } - - if (source[i] != destination->string[i]) { - return private_f_utf_string_prepend_nulless(source, length, destination); + } + else { + if (width_max < 4) { + return F_status_set_error(F_utf); } - ++i; - ++j; - } // while + // U+10000 -> U+10FFFF + (*character)[0] = F_utf_byte_4_d | ((uint8_t) ((unicode & 0x1c0000) >> 18)); + (*character)[1] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0x3f000) >> 12)); + (*character)[2] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0xfc0) >> 6)); + (*character)[3] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); + } return F_none; } -#endif // _di_f_utf_string_prepend_assure_nulless_ +#endif // _di_f_utf_unicode_from_ -#ifndef _di_f_utf_string_prepend_nulless_ - f_status_t f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { +#ifndef _di_f_utf_unicode_string_from_f_ + f_status_t f_utf_unicode_string_from(const f_string_t string, const f_array_length_t length, uint32_t *unicode) { #ifndef _di_level_0_parameter_checking_ - if (!destination) return F_status_set_error(F_parameter); + if (!unicode) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - if (!length) return F_data_not_eos; - - return private_f_utf_string_prepend_nulless(source, length, destination); - } -#endif // _di_f_utf_string_prepend_nulless_ - -#ifndef _di_f_utf_string_seek_line_ - f_status_t f_utf_string_seek_line(const f_utf_string_t string, f_string_range_t *range) { - #ifndef _di_level_0_parameter_checking_ - if (!range) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + f_array_length_t i = 0; - if (range->start > range->stop) { - return F_data_not_stop; - } + for (; i < length; ++i) { + if (!string[i]) continue; + } // for - while (string[range->start] != F_utf_character_t_eol_d) { + if (i < length) { + if (string[i] == f_string_ascii_U_s[0] || string[i] == f_string_ascii_U_s[0]) { + for (; i < length; ++i) { + if (!string[i]) continue; + } // for - if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { - return F_status_set_error(F_utf); + if (i < length && string[i] == f_string_ascii_plus_s[0]) { + ++i; + } + else { + i = length; + } } - - ++range->start; - - if (range->start > range->stop) { - return F_none_stop; + else { + i = length; } - } // while - - return F_none; - } -#endif // _di_f_utf_string_seek_line_ - -#ifndef _di_f_utf_string_seek_line_to_ - f_status_t f_utf_string_seek_line_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range) { - #ifndef _di_level_0_parameter_checking_ - if (!range) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + } - if (range->start > range->stop) { - return F_data_not_stop; + if (i == length) { + return F_status_set_error(F_valid_not); } - while (string[range->start] != seek_to) { + uint32_t value = 0; - if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { - return F_status_set_error(F_utf); - } + for (; i < length; ++i) { - if (string[range->start] == F_utf_character_t_eol_d) { - return F_none_eol; - } + if (!string[i]) continue; - ++range->start; + value *= 16; - if (range->start > range->stop) { - return F_none_stop; + if (string[i] > 0x2f && string[i] < 0x3a) { + value += string[i] - 0x30; } - } // while - - return F_none; - } -#endif // _di_f_utf_string_seek_line_to_ - -#ifndef _di_f_utf_string_seek_to_ - f_status_t f_utf_string_seek_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range) { - #ifndef _di_level_0_parameter_checking_ - if (!range) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - if (range->start > range->stop) { - return F_data_not_stop; - } - - while (string[range->start] != seek_to) { - - if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { - return F_status_set_error(F_utf); + else if (string[i] > 0x40 && string[i] < 0x47) { + value += (string[i] - 0x41) + 10; } - - ++range->start; - - if (range->start > range->stop) { - return F_none_stop; + else if (string[i] > 0x60 && string[i] < 0x67) { + value += (string[i] - 0x61) + 10; + } + else { + return F_status_set_error(F_valid_not); } - } // while + } // for + + *unicode = value; return F_none; } -#endif // _di_f_utf_string_seek_to_ +#endif // _di_f_utf_unicode_string_from_ #ifndef _di_f_utf_unicode_to_ f_status_t f_utf_unicode_to(const f_string_t character, const f_array_length_t width_max, uint32_t *unicode) { @@ -2089,7 +1867,9 @@ extern "C" { if (!unicode) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - const uint8_t width = macro_f_utf_byte_width(*character); + if (macro_f_utf_byte_width_is(*character) == 1) { + return F_status_set_error(F_utf_fragment); + } { f_utf_character_t character_utf = 0; @@ -2097,33 +1877,31 @@ extern "C" { const f_status_t status = private_f_utf_char_to_character(character, width_max, &character_utf); if (F_status_is_error(status)) return status; - if (private_f_utf_character_is_valid(character_utf, width) == F_false) { + if (private_f_utf_character_is_valid(character_utf) == F_false) { return F_status_set_error(F_utf); } } - // @fixme the code here needs to be reviewed for endianess accuracy for both big and little endian. - if (width == 1) { - - // U+0000 -> U+007F + // U+0000 -> U+007F. + if (macro_f_utf_byte_width(*character) == 1) { *unicode = ((uint8_t) character[0]) & 0x7f; } - else if (width == 2) { - // U+0080 -> U+07FF + // U+0080 -> U+07FF. + else if (macro_f_utf_byte_width(*character) == 2) { *unicode = (((uint8_t) character[0]) & 0x1f) << 6; *unicode |= ((uint8_t) character[1]) & 0x3f; } - else if (width == 3) { - // U+0800 -> U+FFFF + // U+0800 -> U+FFFF. + else if (macro_f_utf_byte_width(*character) == 3) { *unicode = (((uint8_t) character[0]) & 0xf) << 12; *unicode |= (((uint8_t) character[1]) & 0x3f) << 6; *unicode |= ((uint8_t) character[2]) & 0x3f; } - else if (width == 4) { - // U+10000 -> U+10FFFF + // U+10000 -> U+10FFFF. + else if (macro_f_utf_byte_width(*character) == 4) { *unicode = (((uint8_t) character[0]) & 0x7) << 18; *unicode |= (((uint8_t) character[1]) & 0x3f) << 12; *unicode |= (((uint8_t) character[2]) & 0x3f) << 6; @@ -2134,82 +1912,6 @@ extern "C" { } #endif // _di_f_utf_unicode_to_ -#ifndef _di_f_utf_unicode_from_ - f_status_t f_utf_unicode_from(const uint32_t unicode, const f_array_length_t width_max, f_string_t *character) { - #ifndef _di_level_0_parameter_checking_ - if (width_max < 1) return F_status_set_error(F_parameter); - if (!unicode) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - - // @fixme the code here needs to be reviewed for endianess accuracy for both big and little endian. - if (unicode > 0x10ffff) { - return F_status_set_error(F_utf); - } - - if (unicode < 0x80) { - - // U+0000 -> U+007F - (*character)[0] = (uint8_t) unicode; - - if (width_max > 1) { - (*character)[1] = 0; - - if (width_max > 2) { - (*character)[2] = 0; - - if (width_max > 3) { - (*character)[3] = 0; - } - } - } - } - else if (unicode < 0x800) { - if (width_max < 2) { - return F_status_set_error(F_utf); - } - - // U+0080 -> U+07FF - (*character)[0] = F_utf_byte_2_d | ((uint8_t) ((unicode & 0x7c0) >> 6)); - (*character)[1] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); - - if (width_max > 2) { - (*character)[2] = 0; - - if (width_max > 2) { - (*character)[2] = 0; - } - } - } - else if (unicode < 0x10000) { - if (width_max < 3) { - return F_status_set_error(F_utf); - } - - // U+0800 -> U+FFFF - (*character)[0] = F_utf_byte_3_d | ((uint8_t) ((unicode & 0xf000) >> 12)); - (*character)[1] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0xfc0) >> 6)); - (*character)[2] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); - - if (width_max > 3) { - character[3] = 0; - } - } - else { - if (width_max < 4) { - return F_status_set_error(F_utf); - } - - // U+10000 -> U+10FFFF - (*character)[0] = F_utf_byte_4_d | ((uint8_t) ((unicode & 0x1c0000) >> 18)); - (*character)[1] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0x3f000) >> 12)); - (*character)[2] = F_utf_byte_1_d | ((uint8_t) ((unicode & 0xfc0) >> 6)); - (*character)[3] = F_utf_byte_1_d | ((uint8_t) (unicode & 0x3f)); - } - - return F_none; - } -#endif // _di_f_utf_unicode_from_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_utf/c/utf.h b/level_0/f_utf/c/utf.h index 1a0b480..0493eeb 100644 --- a/level_0/f_utf/c/utf.h +++ b/level_0/f_utf/c/utf.h @@ -37,6 +37,7 @@ #define _F_utf_h // libc includes +#include #include #include @@ -50,6 +51,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -132,8 +134,7 @@ extern "C" { * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. - * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf_fragment if this is a UTF-8 character fragment. * * @see f_utf_character_is_valid() */ @@ -151,7 +152,8 @@ extern "C" { * F_true if a UTF-8 alphabet character. * F_false if not a UTF-8 alphabet character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalpha() */ @@ -173,7 +175,8 @@ extern "C" { * F_true if a UTF-8 alpha-digit character. * F_false if not a UTF-8 alpha-digit character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -193,7 +196,8 @@ extern "C" { * F_true if a UTF-8 alpha-numeric character. * F_false if not a UTF-8 alpha-numeric character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -204,14 +208,14 @@ extern "C" { /** * Check to see if the entire byte block of the character is an ASCII character. * + * This does not validate whether the UTF-8 character is valid or not. + * * @param character * The character to validate. * * @return * F_true if an ASCII character. * F_false if not an ASCII character. - * - * F_utf (with error bit) if character is an invalid UTF-8 character. */ #ifndef _di_f_utf_character_is_ascii_ extern f_status_t f_utf_character_is_ascii(const f_utf_character_t character); @@ -227,7 +231,8 @@ extern "C" { * F_true if a UTF-8 combining character. * F_false if not a UTF-8 combining character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_combining_ extern f_status_t f_utf_character_is_combining(const f_utf_character_t character); @@ -245,7 +250,8 @@ extern "C" { * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see iscntrl() */ @@ -265,7 +271,8 @@ extern "C" { * F_true if a UTF-8 control code character. * F_false if not a UTF-8 control code character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see iscntrl() */ @@ -286,7 +293,8 @@ extern "C" { * F_true if a UTF-8 control format character. * F_false if not a UTF-8 control format character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_control_format_ extern f_status_t f_utf_character_is_control_format(const f_utf_character_t character); @@ -304,7 +312,8 @@ extern "C" { * F_true if a UTF-8 control picture character. * F_false if not a UTF-8 control picture character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_control_picture_ extern f_status_t f_utf_character_is_control_picture(const f_utf_character_t character); @@ -324,7 +333,8 @@ extern "C" { * F_true if a UTF-8 digit character. * F_false if not a UTF-8 digit character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isdigit() */ @@ -344,7 +354,8 @@ extern "C" { * F_true if a UTF-8 emoji character. * F_false if not a UTF-8 emoji character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_emoji_ extern f_status_t f_utf_character_is_emoji(const f_utf_character_t character); @@ -376,7 +387,8 @@ extern "C" { * F_true if a UTF-8 character. * F_false if not a UTF-8 character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is() * @see f_utf_character_is_valid() @@ -395,7 +407,8 @@ extern "C" { * F_true if a UTF-8 graph. * F_false if not a UTF-8 graph. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isgraph() */ @@ -415,7 +428,8 @@ extern "C" { * F_true if a UTF-8 numeric character. * F_false if not a UTF-8 numeric character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isdigit() */ @@ -433,7 +447,8 @@ extern "C" { * F_true if a UTF-8 phonetic character. * F_false if not a UTF-8 phonetic character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_phonetic_ extern f_status_t f_utf_character_is_phonetic(const f_utf_character_t character); @@ -449,7 +464,8 @@ extern "C" { * F_true if a UTF-8 private character. * F_false if not a UTF-8 private character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_private_ extern f_status_t f_utf_character_is_private(const f_utf_character_t character); @@ -467,7 +483,8 @@ extern "C" { * F_true if a UTF-8 punctuation character. * F_false if not a UTF-8 punctuation character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_punctuation_ extern f_status_t f_utf_character_is_punctuation(const f_utf_character_t character); @@ -485,7 +502,8 @@ extern "C" { * F_true if a UTF-8 symbol character. * F_false if not a UTF-8 symbol character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_symbol_ extern f_status_t f_utf_character_is_symbol(const f_utf_character_t character); @@ -504,7 +522,8 @@ extern "C" { * F_true if a UTF-8 unassigned character. * F_false if not a UTF-8 unassigned character. * - * F_utf (with error bit) if character is an inunassigned UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is() * @see f_utf_character_is_fragment() @@ -519,7 +538,9 @@ extern "C" { * This does validate if the UTF-8 character is a valid UTF-8 character. * To not do this, use f_utf_character_is(). * - * Valid ASCII character codes are considered valid by this function. + * ASCII character codes are considered valid by this function. + * + * Codes U+FDD0 to U+FDEF and any character ending in FFFE or FFFF are non-characters, and are therefore invalid. * * @param character * The character to validate. @@ -528,7 +549,8 @@ extern "C" { * F_true if a UTF-8 character. * F_false if not a UTF-8 character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is() * @see f_utf_character_is_fragment() @@ -555,7 +577,8 @@ extern "C" { * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isspace() */ @@ -578,7 +601,8 @@ extern "C" { * F_true if a UTF-8 modifier character. * F_false if not a UTF-8 modifier character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_whitespace_modifier_ extern f_status_t f_utf_character_is_whitespace_modifier(const f_utf_character_t character); @@ -596,7 +620,8 @@ extern "C" { * F_true if a UTF-8 (other) whitespace. * F_false if not a UTF-8 (other) whitespace. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isspace() */ @@ -605,6 +630,29 @@ extern "C" { #endif // _di_f_utf_character_is_whitespace_other_ /** + * Get whether or not the UTF-8 character is a wide character on display. + * + * This is not the wide as in width in bytes that the codepoint takes up in UTF-8. + * Instead, this is the width in characters on the screen the character takes up. + * When "wide" characters that take up either 2 characters on render. + * When "narrow" characters that take up either 1 character on render. + * + * @param character + * The (UTF-8) character. + * + * @return + * F_none on success. + * + * F_failure (with error bit) if width is not long enough to convert. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + */ +#ifndef _di_f_utf_character_is_wide_ + extern f_status_t f_utf_character_is_wide(const f_utf_character_t character); +#endif // _di_f_utf_character_is_wide_ + +/** * Check to see if the entire byte block of the character is an ASCII or UTF-8 word character. * * A word character is alpha-numeric or an underscore '_'. @@ -620,7 +668,8 @@ extern "C" { * F_true if a UTF-8 word character. * F_false if not a UTF-8 word character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -649,7 +698,8 @@ extern "C" { * F_true if a UTF-8 word or dash character. * F_false if not a UTF-8 word or dash character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -680,7 +730,8 @@ extern "C" { * F_true if a UTF-8 word or dash character. * F_false if not a UTF-8 word or dash character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -700,7 +751,8 @@ extern "C" { * F_true if a UTF-8 non-printing or zero-width character. * F_false if not a UTF-8 non-printing or zero-width character. * - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_is_zero_width_ extern f_status_t f_utf_character_is_zero_width(const f_utf_character_t character); @@ -726,7 +778,8 @@ extern "C" { * * F_failure (with error bit) if width is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_to_char_ extern f_status_t f_utf_character_to_char(const f_utf_character_t utf_character, f_string_t *character, f_array_length_t *width_max); @@ -748,7 +801,8 @@ extern "C" { * F_none on success. * * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_valid() */ @@ -773,25 +827,13 @@ extern "C" { * * F_parameter (with error bit) if a parameter is invalid. * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_character_unicode_from_ extern f_status_t f_utf_character_unicode_from(const uint32_t unicode, f_utf_character_t *character); #endif // _di_f_utf_character_unicode_from_ /** - * Helper function for UTF-8 processing code to determine endianess of the system. - * - * @todo relocate this outside of f_utf into a more general path, perhaps f_memory (f_memory_is_big_endian). - * - * @return - * F_true if the system is big-endian. - * F_false if the system is little-endian. - */ -#ifndef _di_f_utf_is_big_endian_ - extern f_status_t f_utf_is_big_endian(); -#endif // _di_f_utf_is_big_endian_ - -/** * Check to see if the entire byte block of the character is a non-ASCII UTF-8 character. * * This does not check the validity of the character, for that instead use f_utf_is_valid(). @@ -799,19 +841,13 @@ extern "C" { * @param character * The character to validate. * There must be enough space allocated to compare against, as limited by width_max. - * @param width_max - * The maximum width available for checking. - * Can be anything greater than 0. * * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. - * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. - * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_utf_is_ - extern f_status_t f_utf_is(const f_string_t character, const f_array_length_t width_max); + extern f_status_t f_utf_is(const f_string_t character); #endif // _di_f_utf_is_ /** @@ -828,7 +864,8 @@ extern "C" { * F_true if a UTF-8 alphabet character. * F_false if not a UTF-8 alphabet character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalpha() */ @@ -854,7 +891,8 @@ extern "C" { * F_true if a UTF-8 alphabet character. * F_false if not a UTF-8 alpha-numeric character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -878,7 +916,8 @@ extern "C" { * F_true if a UTF-8 alphabet character. * F_false if not a UTF-8 alpha-numeric character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -900,7 +939,8 @@ extern "C" { * F_true if an ASCII character. * F_false if not an ASCII character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_ascii_ extern f_status_t f_utf_is_ascii(const f_string_t character, const f_array_length_t width_max); @@ -920,7 +960,8 @@ extern "C" { * F_true if a UTF-8 combining character. * F_false if not a UTF-8 combining character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_combining_ extern f_status_t f_utf_is_combining(const f_string_t character, const f_array_length_t width_max); @@ -942,7 +983,8 @@ extern "C" { * F_true if a UTF-8 control character. * F_false if not a UTF-8 control character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see iscntrl() */ @@ -966,7 +1008,8 @@ extern "C" { * F_true if a UTF-8 control code character. * F_false if not a UTF-8 control code character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_control_code_ extern f_status_t f_utf_is_control_code(const f_string_t character, const f_array_length_t width_max); @@ -989,7 +1032,8 @@ extern "C" { * F_true if a UTF-8 control format character. * F_false if not a UTF-8 control format character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_control_format_ extern f_status_t f_utf_is_control_format(const f_string_t character, const f_array_length_t width_max); @@ -1011,7 +1055,8 @@ extern "C" { * F_true if a UTF-8 control picture character. * F_false if not a UTF-8 control picture character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_control_picture_ extern f_status_t f_utf_is_control_picture(const f_string_t character, const f_array_length_t width_max); @@ -1031,7 +1076,8 @@ extern "C" { * F_true if a UTF-8 digit character. * F_false if not a UTF-8 digit character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isdigit() */ @@ -1054,7 +1100,9 @@ extern "C" { * @return * F_true if a UTF-8 emoji character. * F_false if not a UTF-8 emoji character. - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_emoji_ extern f_status_t f_utf_is_emoji(const f_string_t character, const f_array_length_t width_max); @@ -1082,16 +1130,13 @@ extern "C" { * @param character * The character to validate. * There must be enough space allocated to compare against, as limited by width_max. - * @param width_max - * The maximum width available for checking. - * Can be anything greater than 0. * * @return * F_true if a UTF-8 character. * F_false if not a UTF-8 character. */ #ifndef _di_f_utf_is_fragment_ - extern f_status_t f_utf_is_fragment(const f_string_t character, const f_array_length_t width_max); + extern f_status_t f_utf_is_fragment(const f_string_t character); #endif // _di_f_utf_is_fragment_ /** @@ -1108,9 +1153,10 @@ extern "C" { * F_true if a UTF-8 graph. * F_false if not a UTF-8 graph. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_maybe (with error bit) if this could be a graph but width is not long enough. * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isgraph() */ @@ -1134,7 +1180,8 @@ extern "C" { * F_true if a UTF-8 numeric character. * F_false if not a UTF-8 numeric character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isdigit() */ @@ -1156,7 +1203,8 @@ extern "C" { * F_true if a UTF-8 phonetic character. * F_false if not a UTF-8 phonetic character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_phonetic_ extern f_status_t f_utf_is_phonetic(const f_string_t character, const f_array_length_t width_max); @@ -1176,7 +1224,8 @@ extern "C" { * F_true if a UTF-8 punctuation character. * F_false if not a UTF-8 punctuation character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_private_ extern f_status_t f_utf_is_private(const f_string_t character, const f_array_length_t width_max); @@ -1198,7 +1247,8 @@ extern "C" { * F_true if a UTF-8 punctuation character. * F_false if not a UTF-8 punctuation character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_punctuation_ extern f_status_t f_utf_is_punctuation(const f_string_t character, const f_array_length_t width_max); @@ -1220,7 +1270,8 @@ extern "C" { * F_true if a UTF-8 symbol character. * F_false if not a UTF-8 symbol character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_symbol_ extern f_status_t f_utf_is_symbol(const f_string_t character, const f_array_length_t width_max); @@ -1242,8 +1293,9 @@ extern "C" { * F_true if an unassigned UTF-8 character. * F_false if not an unassigned UTF-8 character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_parameter (with error bit) if a parameter is inunassigned. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_unassigned_ extern f_status_t f_utf_is_unassigned(const f_string_t character, const f_array_length_t width_max); @@ -1257,6 +1309,8 @@ extern "C" { * * Valid ASCII character codes are considered valid by this function. * + * Codes U+FDD0 to U+FDEF and any character ending in FFFE or FFFF are non-characters, and are therefore invalid. + * * @param character * The character to validate. * There must be enough space allocated to compare against, as limited by width_max. @@ -1265,11 +1319,12 @@ extern "C" { * Can be anything greater than 0. * * @return - * F_true if a valid UTF-8 character. + * F_true if a valid UTF-8 character or is an ASCII character. * F_false if not a valid UTF-8 character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_failure (with error bit) if width_max is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_valid_ extern f_status_t f_utf_is_valid(const f_string_t character, const f_array_length_t width_max); @@ -1297,9 +1352,10 @@ extern "C" { * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_maybe (with error bit) if this could be a whitespace but width is not long enough. * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isspace() */ @@ -1326,9 +1382,10 @@ extern "C" { * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_maybe (with error bit) if this could be a whitespace but width is not long enough. * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_whitespace_modifier_ extern f_status_t f_utf_is_whitespace_modifier(const f_string_t character, const f_array_length_t width_max); @@ -1350,15 +1407,44 @@ extern "C" { * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_maybe (with error bit) if this could be a whitespace but width is not long enough. * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_whitespace_other_ extern f_status_t f_utf_is_whitespace_other(const f_string_t character, const f_array_length_t width_max); #endif // _di_f_utf_is_whitespace_other_ /** + * Get whether or not the UTF-8 character is a wide character on display. + * + * This is not the wide as in width in bytes that the codepoint takes up in UTF-8. + * Instead, this is the width in characters on the screen the character takes up. + * When "wide" characters that take up either 2 characters on render. + * When "narrow" characters that take up either 1 character on render. + * + * @param character + * The (UTF-8) character. + * @param width_max + * The max width available for representing the UTF-8 character. + * There must be enough space in the character buffer to handle the Unicode width. + * It is recommended to always have 4 characters (4 uint8_t) of space available in character. + * This is the width in bytes the codepoint takes up in UTF-8. + * + * @return + * F_none on success. + * + * F_failure (with error bit) if width_max is not long enough to convert. + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + */ +#ifndef _di_f_utf_is_wide_ + extern f_status_t f_utf_is_wide(const f_string_t character, const f_array_length_t width_max); +#endif // _di_f_utf_is_wide_ + +/** * Check to see if the entire byte block of the character is an ASCII or UTF-8 word character. * * A word character is alpha-digit or an underscore '_'. @@ -1378,7 +1464,8 @@ extern "C" { * F_true if a UTF-8 word character. * F_false if not a UTF-8 word character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -1411,7 +1498,8 @@ extern "C" { * F_true if a UTF-8 word or dash character. * F_false if not a UTF-8 word or dash character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -1446,7 +1534,8 @@ extern "C" { * F_true if a UTF-8 word or dash character. * F_false if not a UTF-8 word or dash character. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see isalnum() */ @@ -1470,9 +1559,10 @@ extern "C" { * F_true if a UTF-8 whitespace. * F_false if not a UTF-8 whitespace. * - * F_complete_not_utf (with error bit) if character is an incomplete UTF-8 fragment. * F_maybe (with error bit) if this could be a whitespace but width is not long enough. * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_is_zero_width_ extern f_status_t f_utf_is_zero_width(const f_string_t character, const f_array_length_t width_max); @@ -1496,431 +1586,87 @@ extern "C" { * * F_failure (with error bit) if width is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ #ifndef _di_f_utf_char_to_character_ extern f_status_t f_utf_char_to_character(const f_string_t character, const f_array_length_t width_max, f_utf_character_t *character_utf); #endif // _di_f_utf_char_to_character_ /** - * Append the source string onto the destination. - * - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_append_ - extern f_status_t f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_append_ - -/** - * Append the source string onto the destination, but only if the string is not already at the end. - * - * This ignores NULL characters when comparing both the source and the destination. - * - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_append_assure_ - extern f_status_t f_utf_string_append_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_append_assure_ - -/** - * Append the source string onto the destination, but only if the string is not already at the end. - * - * This ignores NULL characters when comparing both the source and the destination. - * Skips over NULL characters from source when appending. - * - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_append_assure_nulless_ - extern f_status_t f_utf_string_append_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_append_assure_nulless_ - -/** - * Append the source string onto the destination. - * - * Skips over NULL characters from source when appending. - * - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_append_nulless_ - extern f_status_t f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_append_nulless_ - -/** - * Append the source string onto the destination with the glue in between. - * - * If the destination string is empty, then no glue is appended. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_mash_ - extern f_status_t f_utf_string_mash(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_mash_ - -/** - * Append the source string onto the destination with the glue in between. - * - * If the destination string is empty, then no glue is appended. - * - * Skips over NULL characters from glue and source when appending. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_mash_nulless_ - extern f_status_t f_utf_string_mash_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_mash_nulless_ - -/** - * Prepend the source string onto the destination with the glue in between. - * - * If the destination string is empty, then no glue is appended. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_mish_ - extern f_status_t f_utf_string_mish(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_mish_ - -/** - * Prepend the source string onto the destination with the glue in between. - * - * If the destination string is empty, then no glue is appended. - * - * Skips over NULL characters from glue and source when appending. - * - * @param glue - * A string to append between the source and destination, such as a space: ' '. - * @param glue_length - * The number of bytes the glue takes up. - * @param source - * The source string to append. - * @param length - * The length of source to append. - * @param destination - * The destination string the source and glue are appended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_mish_nulless_ - extern f_status_t f_utf_string_mish_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_mish_nulless_ - -/** - * Prepend the source string onto the destination. - * - * Prepend operations require memory move operations and are therefore likely more expensive than append operations. - * - * @param source - * The source string to prepend. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is prepended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_prepend_ - extern f_status_t f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_prepend_ - -/** - * Prepend the source string onto the destination, but only if the string is not already at the beginning. - * - * Prepend operations require memory move operations and are therefore likely more expensive than append operations. - * - * This ignores NULL characters when comparing both the source and the destination. - * - * @param source - * The source string to prepend. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is prepended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_prepend_assure_ - extern f_status_t f_utf_string_prepend_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_prepend_assure_ - -/** - * Prepend the source string onto the destination, but only if the string is not already at the beginning. - * - * Prepend operations require memory move operations and are therefore likely more expensive than append operations. - * - * This ignores NULL characters when comparing both the source and the destination. - * Skips over NULL characters from source when prepending. - * - * @param source - * The source string to prepend. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is prepended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_prepend_assure_nulless_ - extern f_status_t f_utf_string_prepend_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_prepend_assure_nulless_ - -/** - * Prepend the source string onto the destination, but only if the string is not already at the beginning. - * - * Prepend operations require memory move operations and are therefore likely more expensive than append operations. - * - * This ignores NULL characters when comparing both the source and the destination. - * Skips over NULL characters from source when prepending. - * - * @param source - * The source string to prepend. - * @param length - * The length of source to append. - * @param destination - * The destination string the source is prepended onto. - * - * @return - * F_none on success. - * F_data_not_eos if source length is 0. - * - * F_parameter (with error bit) if a parameter is invalid. - * F_string_too_large (with error bit) if the combined string is too large. - * - * Errors (with error bit) from: f_memory_resize(). - */ -#ifndef _di_f_utf_string_prepend_nulless_ - extern f_status_t f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); -#endif // _di_f_utf_string_prepend_nulless_ - -/** - * Seek the string location forward until EOL is reached. + * Convert a given Unicode into a string block representing a single character. * - * @param string - * The string to traverse. - * @param range - * A range within the buffer representing the start and stop locations. - * The start location will be incremented by seek. + * @param character + * The (UTF-8) character. + * The f_utf_character_t is a 32-bit integer containing UTF-8 sequences, unchanged. + * @param width_max + * The max width available for representing the UTF-8 character. + * There must be enough space in the character buffer to handle the Unicode width. + * It is recommended to always have 4 characters (4 uint8_t) of space available in character. + * @param unicode + * A 32-bit integer representing the Unicode (such as U+0001). + * Does not need to be interpretted like UTF-8, this is a number from 0 onto max supported Unicode integer value (U+10FFFF). * * @return * F_none on success. - * F_none_stop on success, but stopped at end of range. - * F_data_not_stop on success, but the range.start > range.stop. * + * F_failure (with error bit) if width_max is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is invalid UTF-8. - * - * Errors (with error bit) from: f_memory_resize(). + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. */ -#ifndef _di_f_utf_string_seek_line_ - extern f_status_t f_utf_string_seek_line(const f_utf_string_t string, f_string_range_t *range); -#endif // _di_f_utf_string_seek_line_ +#ifndef _di_f_utf_unicode_from_ + extern f_status_t f_utf_unicode_from(const uint32_t unicode, const f_array_length_t width_max, f_string_t *character); +#endif // _di_f_utf_unicode_from_ /** - * Seek the string location forward until the character (1-byte wide) or EOL is reached. - * - * @param string - * The string to traverse. - * @param seek_to - * A single-width character representing a character to seek to. - * @param range - * A range within the buffer representing the start and stop locations. - * The start location will be incremented by seek. - * - * @return - * F_none on success. - * F_none_eol on success, but stopped at EOL. - * F_none_stop on success, but stopped stop location. - * F_data_not_stop if range.start > range.stop. + * Convert a string of the format "U+FFFF" into the codepoint value. * - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is invalid UTF-8. - */ -#ifndef _di_f_utf_string_seek_line_to_ - extern f_status_t f_utf_string_seek_line_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range); -#endif // _di_f_utf_string_seek_line_to_ - -/** - * Seek the string location forward until the character (1-byte wide) is reached. + * This ignores NULL characters. + * The string may only contain "U+" followed by a hexidecimal digit, upper or lower case. + * The "U+" prefix is optional. + * Only ASCII characters are allowed to represent the Unicode sequence string. * * @param string - * The string to traverse. - * @param seek_to - * A single-width character representing a character to seek to. - * @param range - * A range within the buffer representing the start and stop locations. - * The start location will be incremented by seek. + * The string representing a Unicode sequence. + * @param length + * The maximum number of characters. + * @param unicode + * A 32-bit integer representing the Unicode (such as U+0001). + * Does not need to be interpretted like UTF-8, this is a number from 0 onto max supported Unicode integer value (U+10FFFF). * * @return * F_none on success. - * F_none_stop on success, but stopped stop location. - * F_data_not_stop if range.start > range.stop. * + * F_failure (with error bit) if width_max is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is invalid UTF-8. + * F_valid_not (with error bit) if string is not a valid Unicode string. */ -#ifndef _di_f_utf_string_seek_to_ - extern f_status_t f_utf_string_seek_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range); -#endif // _di_f_utf_string_seek_to_ +#ifndef _di_f_utf_unicode_string_from_f_ + extern f_status_t f_utf_unicode_string_from(const f_string_t string, const f_array_length_t length, uint32_t *unicode); +#endif // _di_f_utf_unicode_string_from_ /** * Convert a given string block representing a single character into Unicode. * - * The f_utf_character_t is a 32-bit integer containing UTF-8 sequences, unchanged. - * The Unicode is a 32-bit integer representing the Unicode (such as U+0001). - * The Unciode does not need to be interpretted like UTF-8, it simple is a sequence of number from 0 onto max supported Unicode integer value (U+10FFFF). - * * @param character * The (UTF-8) character to convert to the Unicode representation. + * The f_utf_character_t is a 32-bit integer containing UTF-8 sequences, unchanged. * @param width_max * The max width available for representing the UTF-8 character. * There must be enough space in the character buffer to handle the Unicode width. * It is recommended to always have 4 characters (4 uint8_t) of space available in character. * @param unicode - * The Unicode number. + * A 32-bit integer representing the Unicode (such as U+0001). + * Does not need to be interpretted like UTF-8, this is a number from 0 onto max supported Unicode integer value (U+10FFFF). * * @return * F_none on success. * * F_failure (with error bit) if width is not long enough to convert. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if character is an invalid UTF-8 character. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. * * @see f_utf_character_is_valid() */ @@ -1928,33 +1674,6 @@ extern "C" { extern f_status_t f_utf_unicode_to(const f_string_t character, const f_array_length_t width_max, uint32_t *unicode); #endif // _di_f_utf_unicode_to_ -/** - * Convert a given Unicode into a string block representing a single character. - * - * The f_string is a 32-bit integer containing UTF-8 sequences, unchanged. - * The Unicode is a 32-bit integer representing the Unicode (such as U+0001). - * The Unciode does not need to be interpretted like UTF-8, it simple is a sequence of number from 0 onto max supported Unicode integer value (U+10FFFF). - * - * @param character - * The (UTF-8) character. - * @param width_max - * The max width available for representing the UTF-8 character. - * There must be enough space in the character buffer to handle the Unicode width. - * It is recommended to always have 4 characters (4 uint8_t) of space available in character. - * @param unicode - * The Unicode number. - * - * @return - * F_none on success. - * - * F_failure (with error bit) if width is not long enough to convert. - * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) if unicode is an invalid Unicode character. - */ -#ifndef _di_f_utf_unicode_from_ - extern f_status_t f_utf_unicode_from(const uint32_t unicode, const f_array_length_t width_max, f_string_t *character); -#endif // _di_f_utf_unicode_from_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_0/f_utf/c/utf_dynamic.c b/level_0/f_utf/c/utf_dynamic.c index c8f48ef..c38016a 100644 --- a/level_0/f_utf/c/utf_dynamic.c +++ b/level_0/f_utf/c/utf_dynamic.c @@ -1,5 +1,6 @@ #include "utf.h" #include "private-utf.h" +#include "private-utf_string.h" #ifdef __cplusplus extern "C" { diff --git a/level_0/f_utf/c/utf_dynamic.h b/level_0/f_utf/c/utf_dynamic.h index 6a4b1c4..4412c1f 100644 --- a/level_0/f_utf/c/utf_dynamic.h +++ b/level_0/f_utf/c/utf_dynamic.h @@ -5,9 +5,9 @@ * API Version: 0.5 * Licenses: lgplv2.1 * - * Defines dynamic (and static) string data. + * Defines dynamic (and static) UTF-8 string data. * - * This is auto-included by string.h and should not need to be explicitly included. + * This is auto-included by utf.h and should not need to be explicitly included. */ #ifndef _F_utf_string_dynamic_h #define _F_utf_string_dynamic_h @@ -46,6 +46,13 @@ extern "C" { #endif // _di_f_utf_string_static_t_ /** + * Define a a global empty UTF-8 string. + */ +#ifndef _di_f_utf_string_static_empty_s_ + const extern f_utf_string_static_t f_utf_string_static_empty_s; +#endif // _di_f_utf_string_static_empty_s_ + +/** * A string that supports contains a size attribute to handle dynamic allocations and deallocations. * * Save the string size along with the string, so that strlen(..) commands can be avoided as much as possible. @@ -125,10 +132,6 @@ extern "C" { #define macro_f_utf_string_dynamics_t_decimate_by(status, dynamics, amount) status = f_utf_string_dynamics_decimate_by(amount, &dynamics); #endif // _di_f_utf_string_dynamics_t_ -#ifndef _di_f_utf_string_static_empty_s_ - const extern f_utf_string_static_t f_utf_string_static_empty_s; -#endif // _di_f_utf_string_static_empty_s_ - /** * Resize the dynamic string. * diff --git a/level_0/f_utf/c/utf_map.c b/level_0/f_utf/c/utf_map.c index 58601a2..429a79c 100644 --- a/level_0/f_utf/c/utf_map.c +++ b/level_0/f_utf/c/utf_map.c @@ -1,5 +1,6 @@ #include "utf.h" #include "private-utf.h" +#include "private-utf_string.h" #ifdef __cplusplus extern "C" { diff --git a/level_0/f_utf/c/utf_map.h b/level_0/f_utf/c/utf_map.h index 2adf956..05adb06 100644 --- a/level_0/f_utf/c/utf_map.h +++ b/level_0/f_utf/c/utf_map.h @@ -5,9 +5,9 @@ * API Version: 0.5 * Licenses: lgplv2.1 * - * Defines map string data. + * Defines map UTF-8 string data. * - * This is auto-included by string.h and should not need to be explicitly included. + * This is auto-included by utf.h and should not need to be explicitly included. */ #ifndef _F_utf_string_map_h #define _F_utf_string_map_h diff --git a/level_0/f_utf/c/utf_string.c b/level_0/f_utf/c/utf_string.c new file mode 100644 index 0000000..7011fe2 --- /dev/null +++ b/level_0/f_utf/c/utf_string.c @@ -0,0 +1,377 @@ +#include "utf.h" +#include "utf_string.h" +#include "private-utf_string.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_f_utf_string_append_ + f_status_t f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + return private_f_utf_string_append(source, length, destination); + } +#endif // _di_f_utf_string_append_ + +#ifndef _di_f_utf_string_append_assure_ + f_status_t f_utf_string_append_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + if (destination->used < length) return private_f_utf_string_append(source, length, destination); + + f_array_length_t i = 1; + f_array_length_t j = 1; + + while (i <= length && j <= destination->used) { + + if (!source[length - i]) { + ++i; + + continue; + } + + if (!destination->string[destination->used - j]) { + ++j; + + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_f_utf_string_append(source, length, destination); + } + + ++i; + ++j; + } // while + + return F_none; + } +#endif // _di_f_utf_string_append_assure_ + +#ifndef _di_f_utf_string_append_assure_nulless_ + f_status_t f_utf_string_append_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) { + return F_data_not_eos; + } + + if (destination->used < length) { + return private_f_utf_string_append_nulless(source, length, destination); + } + + f_array_length_t i = 1; + f_array_length_t j = 1; + + while (i <= length && j <= destination->used) { + + if (!source[length - i]) { + ++i; + + continue; + } + + if (!destination->string[destination->used - j]) { + ++j; + + continue; + } + + if (source[length - i] != destination->string[destination->used - j]) { + return private_f_utf_string_append_nulless(source, length, destination); + } + + ++i; + ++j; + } // while + + return F_none; + } +#endif // _di_f_utf_string_append_assure_nulless_ + +#ifndef _di_f_utf_string_append_nulless_ + f_status_t f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + return private_f_utf_string_append_nulless(source, length, destination); + } +#endif // _di_f_utf_string_append_nulless_ + +#ifndef _di_f_utf_string_mash_ + f_status_t f_utf_string_mash(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + if (glue_length && destination->used) { + f_status_t status = private_f_utf_string_append(glue, glue_length, destination); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_string_append(source, length, destination); + } +#endif // _di_f_utf_string_mash_ + +#ifndef _di_f_utf_string_mash_nulless_ + f_status_t f_utf_string_mash_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + if (glue_length && destination->used) { + f_status_t status = private_f_utf_string_append_nulless(glue, glue_length, destination); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_string_append_nulless(source, length, destination); + } +#endif // _di_f_utf_string_mash_nulless_ + +#ifndef _di_f_utf_string_mish_ + f_status_t f_utf_string_mish(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + if (glue_length && destination->used) { + f_status_t status = private_f_utf_string_prepend(glue, glue_length, destination); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_string_prepend(source, length, destination); + } +#endif // _di_f_utf_string_mish_ + +#ifndef _di_f_utf_string_mish_nulless_ + f_status_t f_utf_string_mish_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + if (glue_length && destination->used) { + f_status_t status = private_f_utf_string_prepend_nulless(glue, glue_length, destination); + if (F_status_is_error(status)) return status; + } + + return private_f_utf_string_prepend_nulless(source, length, destination); + } +#endif // _di_f_utf_string_mish_nulless_ + +#ifndef _di_f_utf_string_prepend_ + f_status_t f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + return private_f_utf_string_prepend(source, length, destination); + } +#endif // _di_f_utf_string_prepend_ + +#ifndef _di_f_utf_string_prepend_assure_ + f_status_t f_utf_string_prepend_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + if (destination->used < length) { + return private_f_utf_string_prepend(source, length, destination); + } + + f_array_length_t i = 0; + f_array_length_t j = 0; + + while (i < length && j < destination->used) { + + if (!source[i]) { + ++i; + + continue; + } + + if (!destination->string[j]) { + ++j; + + continue; + } + + if (source[i] != destination->string[i]) { + return private_f_utf_string_prepend(source, length, destination); + } + + ++i; + ++j; + } // while + + return F_none; + } +#endif // _di_f_utf_string_prepend_assure_ + +#ifndef _di_f_utf_string_prepend_assure_nulless_ + f_status_t f_utf_string_prepend_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) { + return F_data_not_eos; + } + + if (destination->used < length) { + return private_f_utf_string_prepend_nulless(source, length, destination); + } + + f_array_length_t i = 0; + f_array_length_t j = 0; + + while (i < length && j < destination->used) { + + if (!source[i]) { + ++i; + + continue; + } + + if (!destination->string[j]) { + ++j; + + continue; + } + + if (source[i] != destination->string[i]) { + return private_f_utf_string_prepend_nulless(source, length, destination); + } + + ++i; + ++j; + } // while + + return F_none; + } +#endif // _di_f_utf_string_prepend_assure_nulless_ + +#ifndef _di_f_utf_string_prepend_nulless_ + f_status_t f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination) { + #ifndef _di_level_0_parameter_checking_ + if (!destination) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!length) return F_data_not_eos; + + return private_f_utf_string_prepend_nulless(source, length, destination); + } +#endif // _di_f_utf_string_prepend_nulless_ + +#ifndef _di_f_utf_string_seek_line_ + f_status_t f_utf_string_seek_line(const f_utf_string_t string, f_string_range_t *range) { + #ifndef _di_level_0_parameter_checking_ + if (!range) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (range->start > range->stop) { + return F_data_not_stop; + } + + while (string[range->start] != F_utf_character_t_eol_d) { + + if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { + return F_status_set_error(F_utf_fragment); + } + + ++range->start; + + if (range->start > range->stop) { + return F_none_stop; + } + } // while + + return F_none; + } +#endif // _di_f_utf_string_seek_line_ + +#ifndef _di_f_utf_string_seek_line_to_ + f_status_t f_utf_string_seek_line_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range) { + #ifndef _di_level_0_parameter_checking_ + if (!range) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (range->start > range->stop) { + return F_data_not_stop; + } + + while (string[range->start] != seek_to) { + + if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { + return F_status_set_error(F_utf_fragment); + } + + if (string[range->start] == F_utf_character_t_eol_d) { + return F_none_eol; + } + + ++range->start; + + if (range->start > range->stop) { + return F_none_stop; + } + } // while + + return F_none; + } +#endif // _di_f_utf_string_seek_line_to_ + +#ifndef _di_f_utf_string_seek_to_ + f_status_t f_utf_string_seek_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range) { + #ifndef _di_level_0_parameter_checking_ + if (!range) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (range->start > range->stop) { + return F_data_not_stop; + } + + while (string[range->start] != seek_to) { + + if (macro_f_utf_character_t_width_is(string[range->start]) == 1) { + return F_status_set_error(F_utf_fragment); + } + + ++range->start; + + if (range->start > range->stop) { + return F_none_stop; + } + } // while + + return F_none; + } +#endif // _di_f_utf_string_seek_to_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_0/f_utf/c/utf_string.h b/level_0/f_utf/c/utf_string.h new file mode 100644 index 0000000..b322ad6 --- /dev/null +++ b/level_0/f_utf/c/utf_string.h @@ -0,0 +1,423 @@ +/** + * FLL - Level 0 + * + * Project: UTF + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Defines UTF-8 string data. + * + * This is auto-included by utf.h and should not need to be explicitly included. + */ +#ifndef _F_utf_string_h +#define _F_utf_string_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Append the source string onto the destination. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_append_ + extern f_status_t f_utf_string_append(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_append_ + +/** + * Append the source string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_append_assure_ + extern f_status_t f_utf_string_append_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_append_assure_ + +/** + * Append the source string onto the destination, but only if the string is not already at the end. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_append_assure_nulless_ + extern f_status_t f_utf_string_append_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_append_assure_nulless_ + +/** + * Append the source string onto the destination. + * + * Skips over NULL characters from source when appending. + * + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_append_nulless_ + extern f_status_t f_utf_string_append_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_append_nulless_ + +/** + * Append the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_mash_ + extern f_status_t f_utf_string_mash(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_mash_ + +/** + * Append the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_mash_nulless_ + extern f_status_t f_utf_string_mash_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_mash_nulless_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_mish_ + extern f_status_t f_utf_string_mish(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_mish_ + +/** + * Prepend the source string onto the destination with the glue in between. + * + * If the destination string is empty, then no glue is appended. + * + * Skips over NULL characters from glue and source when appending. + * + * @param glue + * A string to append between the source and destination, such as a space: ' '. + * @param glue_length + * The number of bytes the glue takes up. + * @param source + * The source string to append. + * @param length + * The length of source to append. + * @param destination + * The destination string the source and glue are appended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_mish_nulless_ + extern f_status_t f_utf_string_mish_nulless(const f_utf_string_t glue, const f_array_length_t glue_length, const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_mish_nulless_ + +/** + * Prepend the source string onto the destination. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_prepend_ + extern f_status_t f_utf_string_prepend(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_prepend_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_prepend_assure_ + extern f_status_t f_utf_string_prepend_assure(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_prepend_assure_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_prepend_assure_nulless_ + extern f_status_t f_utf_string_prepend_assure_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_prepend_assure_nulless_ + +/** + * Prepend the source string onto the destination, but only if the string is not already at the beginning. + * + * Prepend operations require memory move operations and are therefore likely more expensive than append operations. + * + * This ignores NULL characters when comparing both the source and the destination. + * Skips over NULL characters from source when prepending. + * + * @param source + * The source string to prepend. + * @param length + * The length of source to append. + * @param destination + * The destination string the source is prepended onto. + * + * @return + * F_none on success. + * F_data_not_eos if source length is 0. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_string_too_large (with error bit) if the combined string is too large. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_prepend_nulless_ + extern f_status_t f_utf_string_prepend_nulless(const f_utf_string_t source, const f_array_length_t length, f_utf_string_dynamic_t *destination); +#endif // _di_f_utf_string_prepend_nulless_ + +/** + * Seek the string location forward until EOL is reached. + * + * @param string + * The string to traverse. + * @param range + * A range within the buffer representing the start and stop locations. + * The start location will be incremented by seek. + * + * @return + * F_none on success. + * F_none_stop on success, but stopped at end of range. + * F_data_not_stop on success, but the range.start > range.stop. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + * + * Errors (with error bit) from: f_memory_resize(). + */ +#ifndef _di_f_utf_string_seek_line_ + extern f_status_t f_utf_string_seek_line(const f_utf_string_t string, f_string_range_t *range); +#endif // _di_f_utf_string_seek_line_ + +/** + * Seek the string location forward until the character (1-byte wide) or EOL is reached. + * + * @param string + * The string to traverse. + * @param seek_to + * A single-width character representing a character to seek to. + * @param range + * A range within the buffer representing the start and stop locations. + * The start location will be incremented by seek. + * + * @return + * F_none on success. + * F_none_eol on success, but stopped at EOL. + * F_none_stop on success, but stopped stop location. + * F_data_not_stop if range.start > range.stop. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + */ +#ifndef _di_f_utf_string_seek_line_to_ + extern f_status_t f_utf_string_seek_line_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range); +#endif // _di_f_utf_string_seek_line_to_ + +/** + * Seek the string location forward until the character (1-byte wide) is reached. + * + * @param string + * The string to traverse. + * @param seek_to + * A single-width character representing a character to seek to. + * @param range + * A range within the buffer representing the start and stop locations. + * The start location will be incremented by seek. + * + * @return + * F_none on success. + * F_none_stop on success, but stopped stop location. + * F_data_not_stop if range.start > range.stop. + * + * F_parameter (with error bit) if a parameter is invalid. + * F_utf (with error bit) if unicode is an invalid Unicode character. + * F_utf_fragment (with error bit) if character is an incomplete UTF-8 fragment. + */ +#ifndef _di_f_utf_string_seek_to_ + extern f_status_t f_utf_string_seek_to(const f_utf_string_t string, const uint8_t seek_to, f_string_range_t *range); +#endif // _di_f_utf_string_seek_to_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_utf_string_h diff --git a/level_0/f_utf/c/utf_triple.c b/level_0/f_utf/c/utf_triple.c index 99bd571..8ae6ae0 100644 --- a/level_0/f_utf/c/utf_triple.c +++ b/level_0/f_utf/c/utf_triple.c @@ -1,5 +1,6 @@ #include "utf.h" #include "private-utf.h" +#include "private-utf_string.h" #ifdef __cplusplus extern "C" { diff --git a/level_0/f_utf/c/utf_triple.h b/level_0/f_utf/c/utf_triple.h index 2253c68..632b3bb 100644 --- a/level_0/f_utf/c/utf_triple.h +++ b/level_0/f_utf/c/utf_triple.h @@ -5,9 +5,9 @@ * API Version: 0.5 * Licenses: lgplv2.1 * - * Defines 3-tuple of string data called a triple (which is an ordered list of 3 strings). + * Defines 3-tuple of UTF-8 string data called a triple (which is an ordered list of 3 strings). * - * This is auto-included by string.h and should not need to be explicitly included. + * This is auto-included by utf.h and should not need to be explicitly included. */ #ifndef _F_utf_string_triple_h #define _F_utf_string_triple_h diff --git a/level_0/f_utf/data/build/settings b/level_0/f_utf/data/build/settings index 7952aea..3c6f536 100644 --- a/level_0/f_utf/data/build/settings +++ b/level_0/f_utf/data/build/settings @@ -24,13 +24,13 @@ build_libraries -lc build_libraries-individual -lf_memory -lf_string build_libraries_shared build_libraries_static -build_sources_library utf.c utf-common.c private-utf.c utf_dynamic.c utf_map.c utf_triple.c +build_sources_library utf.c utf-common.c utf_dynamic.c utf_map.c utf_string.c utf_triple.c private-utf.c private-utf_string.c build_sources_library_shared build_sources_library_static build_sources_program build_sources_program_shared build_sources_program_static -build_sources_headers utf.h utf-common.h utf_dynamic.h utf_map.h utf_triple.h +build_sources_headers utf.h utf-common.h utf_dynamic.h utf_map.h utf_string.h utf_triple.h build_sources_headers_shared build_sources_headers_static build_sources_script diff --git a/level_1/fl_conversion/c/conversion.c b/level_1/fl_conversion/c/conversion.c index 49b2ecc..88fd9d0 100644 --- a/level_1/fl_conversion/c/conversion.c +++ b/level_1/fl_conversion/c/conversion.c @@ -138,7 +138,7 @@ extern "C" { } uint8_t width = 0; - uint8_t width_max = 0; + f_array_length_t width_max = 0; uint8_t mode = 0; int8_t vector = 0; // 0 for assumed positive, 1 for explicit positive, -1 for negative. f_array_length_t j = 0; @@ -300,7 +300,7 @@ extern "C" { } uint8_t width = 0; - uint8_t width_max = 0; + f_array_length_t width_max = 0; uint8_t mode = 0; f_array_length_t j = 0; f_array_length_t offset = 0; diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index a44ca3f..5a4c8c9 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -399,6 +399,12 @@ extern "C" { case F_failure_not: *string = FL_status_string_failure_not; break; + case F_first: + *string = FL_status_string_first; + break; + case F_first_not: + *string = FL_status_string_first_not; + break; case F_fork: *string = FL_status_string_fork; break; @@ -456,6 +462,12 @@ extern "C" { case F_interrupt_not: *string = FL_status_string_interrupt_not; break; + case F_last: + *string = FL_status_string_last; + break; + case F_last_not: + *string = FL_status_string_last_not; + break; case F_limit: *string = FL_status_string_limit; break; @@ -522,6 +534,12 @@ extern "C" { case F_name_not: *string = FL_status_string_name_not; break; + case F_next: + *string = FL_status_string_next; + break; + case F_next_not: + *string = FL_status_string_next_not; + break; case F_nice: *string = FL_status_string_nice; break; @@ -552,6 +570,12 @@ extern "C" { case F_parent_not: *string = FL_status_string_parent_not; break; + case F_previous: + *string = FL_status_string_previous; + break; + case F_previous_not: + *string = FL_status_string_previous_not; + break; case F_pipe: *string = FL_status_string_pipe; break; @@ -720,6 +744,12 @@ extern "C" { case F_utf: *string = FL_status_string_utf; break; + case F_utf_fragment: + *string = FL_status_string_utf_fragment; + break; + case F_utf_fragment_not: + *string = FL_status_string_utf_fragment_not; + break; case F_utf_not: *string = FL_status_string_utf_not; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index 354f45c..b887309 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -225,6 +225,8 @@ extern "C" { #define FL_status_string_exist_not "F_exist_not" #define FL_status_string_failure "F_failure" #define FL_status_string_failure_not "F_failure_not" + #define FL_status_string_first "F_first" + #define FL_status_string_first_not "F_first_not" #define FL_status_string_fork "F_fork" #define FL_status_string_fork_not "F_fork_not" #define FL_status_string_format "F_format" @@ -246,6 +248,8 @@ extern "C" { #define FL_status_string_interrupt_not "F_interrupt_not" #define FL_status_string_known "F_known" #define FL_status_string_known_not "F_known_not" + #define FL_status_string_last "F_last" + #define FL_status_string_last_not "F_last_not" #define FL_status_string_limit "F_limit" #define FL_status_string_limit_not "F_limit_not" #define FL_status_string_link "F_link" @@ -268,6 +272,8 @@ extern "C" { #define FL_status_string_mount_not "F_mount_not" #define FL_status_string_name "F_name" #define FL_status_string_name_not "F_name_not" + #define FL_status_string_next "F_next" + #define FL_status_string_next_not "F_next_not" #define FL_status_string_nice "F_nice" #define FL_status_string_nice_not "F_nice_not" #define FL_status_string_optional "F_optional" @@ -278,6 +284,8 @@ extern "C" { #define FL_status_string_parameter_not "F_parameter_not" #define FL_status_string_parent "F_parent" #define FL_status_string_parent_not "F_parent_not" + #define FL_status_string_previous "F_previous" + #define FL_status_string_previous_not "F_previous_not" #define FL_status_string_pipe "F_pipe" #define FL_status_string_pipe_not "F_pipe_not" #define FL_status_string_port "F_port" @@ -332,6 +340,8 @@ extern "C" { #define FL_status_string_user "F_user" #define FL_status_string_user_not "F_user_not" #define FL_status_string_utf "F_utf" + #define FL_status_string_utf_fragment "F_utf_fragment" + #define FL_status_string_utf_fragment_not "F_utf_fragment_not" #define FL_status_string_utf_not "F_utf_not" #define FL_status_string_valid "F_valid" #define FL_status_string_valid_not "F_valid_not" @@ -408,6 +418,8 @@ extern "C" { #define FL_status_string_exist_not_length 11 #define FL_status_string_failure_length 9 #define FL_status_string_failure_not_length 13 + #define FL_status_string_first_length 7 + #define FL_status_string_first_not_length 11 #define FL_status_string_fork_length 6 #define FL_status_string_fork_not_length 10 #define FL_status_string_format_length 8 @@ -429,6 +441,8 @@ extern "C" { #define FL_status_string_interrupt_not_length 15 #define FL_status_string_known_length 7 #define FL_status_string_known_not_length 11 + #define FL_status_string_last_length 6 + #define FL_status_string_last_not_length 10 #define FL_status_string_limit_length 7 #define FL_status_string_limit_not_length 11 #define FL_status_string_link_length 6 @@ -451,6 +465,8 @@ extern "C" { #define FL_status_string_mount_not_length 11 #define FL_status_string_name_length 6 #define FL_status_string_name_not_length 10 + #define FL_status_string_next_length 6 + #define FL_status_string_next_not_length 10 #define FL_status_string_nice_length 6 #define FL_status_string_nice_not_length 10 #define FL_status_string_optional_length 10 @@ -465,6 +481,8 @@ extern "C" { #define FL_status_string_pipe_not_length 10 #define FL_status_string_port_length 6 #define FL_status_string_port_not_length 10 + #define FL_status_string_previous_length 10 + #define FL_status_string_previous_not_length 14 #define FL_status_string_processor_length 11 #define FL_status_string_processor_not_length 15 #define FL_status_string_prohibited_length 12 @@ -515,6 +533,8 @@ extern "C" { #define FL_status_string_user_length 6 #define FL_status_string_user_not_length 10 #define FL_status_string_utf_length 5 + #define FL_status_string_utf_fragment_length 14 + #define FL_status_string_utf_fragment_not_length 18 #define FL_status_string_utf_not_length 9 #define FL_status_string_valid_length 7 #define FL_status_string_valid_not_length 11 diff --git a/level_1/fl_string/c/private-string.c b/level_1/fl_string/c/private-string.c index 213b378..c2f4c47 100644 --- a/level_1/fl_string/c/private-string.c +++ b/level_1/fl_string/c/private-string.c @@ -117,7 +117,7 @@ extern "C" { f_array_length_t e2 = 0; uint8_t width = 0; - uint8_t width_max = 0; + f_array_length_t width_max = 0; f_status_t status = F_none; @@ -340,14 +340,22 @@ extern "C" { f_array_length_t i1 = offset1; f_array_length_t i2 = offset2; + f_string_static_t debug1; + debug1.string = string1 + offset1; + debug1.used = (stop1 - offset1) + 1; + + f_string_static_t debug2; + debug2.string = string2 + offset2; + debug2.used = (stop2 - offset2) + 1; + uint8_t width = 0; - uint8_t width_max = 0; + f_array_length_t width_max = 0; f_status_t status = F_none; - // skip past leading whitespace in string1. + // Skip past leading whitespace in string1. for (; i1 < stop1; i1 += width) { - // skip past NULL in string1. + // Skip past NULL in string1. while (i1 < stop1 && !string1[i1]) ++i1; if (i1 == stop1) break; @@ -367,10 +375,10 @@ extern "C" { width = macro_f_utf_byte_width(string1[i1]); } // for - // skip past leading whitespace in string2. + // Skip past leading whitespace in string2. for (; i2 < stop2; i2 += width) { - // skip past NULL in string2. + // Skip past NULL in string2. while (i2 < stop2 && !string2[i2]) ++i2; if (i2 == stop2) break; @@ -394,14 +402,14 @@ extern "C" { f_array_length_t last2 = i2; { - // size1 and size2 are to represent to total number of characters after trim. + // Size1 and size2 are to represent to total number of characters after trim. f_array_length_t size1 = 0; f_array_length_t size2 = 0; - // determine where the last non-whitespace is in string1. + // Determine where the last non-whitespace is in string1. for (f_array_length_t j = i1; j < stop1; j += width) { - // skip past NULL in string1. + // Skip past NULL in string1. while (j < stop1 && !string1[j]) ++j; if (j == stop1) break; @@ -424,10 +432,10 @@ extern "C" { } } // for - // determine where the last non-whitespace is in string2. + // Determine where the last non-whitespace is in string2. for (f_array_length_t j = i2; j < stop2; j += width) { - // skip past NULL in string2. + // Skip past NULL in string2. while (j < stop2 && !string2[j]) ++j; if (j == stop2) break; @@ -457,11 +465,11 @@ extern "C" { for (; i1 < last1 && i2 < last2; ++i1, ++i2) { - // skip past NULL in string1. + // Skip past NULL in string1. while (i1 < last1 && !string1[i1]) ++i1; if (i1 == last1) break; - // skip past NULL in string2. + // Skip past NULL in string2. while (i2 < last2 && !string2[i2]) ++i2; if (i2 == last2) break; @@ -470,18 +478,14 @@ extern "C" { } } // for - // only return F_equal_to if all remaining characters are NULL. - while (i1 < last1) { - + // Only return F_equal_to if all remaining characters are NULL. + for (; i1 < last1; ++i1) { if (string1[i1] != 0) return F_equal_to_not; - ++i1; - } // while - - while (i2 < last2) { + } // for + for (; i2 < last2; ++i2) { if (string2[i2] != 0) return F_equal_to_not; - ++i2; - } // while + } // for return F_equal_to; } diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index 4ded8b8..c634c52 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -793,6 +793,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_first, length, FL_status_string_first_length) == F_equal_to) { + *code = F_first; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_first_not, length, FL_status_string_first_not_length) == F_equal_to) { + *code = F_first_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_fork, length, FL_status_string_fork_length) == F_equal_to) { *code = F_fork; @@ -919,6 +931,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_last, length, FL_status_string_last_length) == F_equal_to) { + *code = F_last; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_last_not, length, FL_status_string_last_not_length) == F_equal_to) { + *code = F_last_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_limit, length, FL_status_string_limit_length) == F_equal_to) { *code = F_limit; @@ -1051,6 +1075,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_next, length, FL_status_string_next_length) == F_equal_to) { + *code = F_next; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_next_not, length, FL_status_string_next_not_length) == F_equal_to) { + *code = F_next_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_nice, length, FL_status_string_nice_length) == F_equal_to) { *code = F_nice; @@ -1135,6 +1171,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_previous, length, FL_status_string_previous_length) == F_equal_to) { + *code = F_previous; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_previous_not, length, FL_status_string_previous_not_length) == F_equal_to) { + *code = F_previous_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_processor, length, FL_status_string_processor_length) == F_equal_to) { *code = F_processor; @@ -1435,6 +1483,18 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_utf_fragment, length, FL_status_string_utf_fragment_length) == F_equal_to) { + *code = F_utf_fragment; + + return F_none; + } + + if (fl_string_compare(string, FL_status_string_utf_fragment_not, length, FL_status_string_utf_fragment_not_length) == F_equal_to) { + *code = F_utf_fragment_not; + + return F_none; + } + if (fl_string_compare(string, FL_status_string_utf_not, length, FL_status_string_utf_not_length) == F_equal_to) { *code = F_utf_not; diff --git a/level_3/byte_dump/c/byte_dump.c b/level_3/byte_dump/c/byte_dump.c index 95985e1..9825f8f 100644 --- a/level_3/byte_dump/c/byte_dump.c +++ b/level_3/byte_dump/c/byte_dump.c @@ -34,14 +34,16 @@ extern "C" { f_print_character(f_string_eol_s[0], file.stream); - fll_program_print_help_option(file, context, byte_dump_short_first_s, byte_dump_long_first_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Start reading at this byte offset."); - fll_program_print_help_option(file, context, byte_dump_short_last_s, byte_dump_long_last_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Stop reading at this (inclusive) byte offset."); - fll_program_print_help_option(file, context, byte_dump_short_width_s, byte_dump_long_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Set number of columns of Bytes to display."); + fll_program_print_help_option(file, context, byte_dump_short_first_s, byte_dump_long_first_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Start reading at this byte offset."); + fll_program_print_help_option(file, context, byte_dump_short_last_s, byte_dump_long_last_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Stop reading at this (inclusive) byte offset."); f_print_character(f_string_eol_s[0], file.stream); - fll_program_print_help_option(file, context, byte_dump_short_text_s, byte_dump_long_text_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include a column of text when displaying the bytes."); + fll_program_print_help_option(file, context, byte_dump_short_narrow_s, byte_dump_long_narrow_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use narrow display, resulting in 1*width reducing size of the text columns."); fll_program_print_help_option(file, context, byte_dump_short_placeholder_s, byte_dump_long_placeholder_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Use a placeholder character instead of a space for placeholders."); + fll_program_print_help_option(file, context, byte_dump_short_text_s, byte_dump_long_text_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Include a column of text when displaying the bytes."); + fll_program_print_help_option(file, context, byte_dump_short_wide_s, byte_dump_long_wide_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Use wide display, resulting in 2*width allowing for space for wide characters in the text columns."); + fll_program_print_help_option(file, context, byte_dump_short_width_s, byte_dump_long_width_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Set number of columns of Bytes to display."); f_print_character(f_string_eol_s[0], file.stream); f_print_character(f_string_eol_s[0], file.stream); @@ -235,7 +237,7 @@ extern "C" { fl_print_format("%[%SThe parameter '%]", main->error.to.stream, main->context.set.error, main->error.prefix, main->context.set.error); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_width_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); funlockfile(main->error.to.stream); @@ -275,7 +277,7 @@ extern "C" { fl_print_format("%[%SThe parameter '%]", main->error.to.stream, main->context.set.error, main->error.prefix, main->context.set.error); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_first_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); funlockfile(main->error.to.stream); @@ -317,7 +319,7 @@ extern "C" { fl_print_format("%[%SThe parameter '%]", main->error.to.stream, main->context.set.error, main->error.prefix, main->context.set.error); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, byte_dump_long_last_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); funlockfile(main->error.to.stream); diff --git a/level_3/byte_dump/c/byte_dump.h b/level_3/byte_dump/c/byte_dump.h index 3df9f94..c19feb2 100644 --- a/level_3/byte_dump/c/byte_dump.h +++ b/level_3/byte_dump/c/byte_dump.h @@ -143,9 +143,12 @@ extern "C" { #define byte_dump_short_first_s "f" #define byte_dump_short_last_s "l" + + #define byte_dump_short_narrow_s "N" + #define byte_dump_short_placeholder_s "p" #define byte_dump_short_text_s "t" + #define byte_dump_short_wide_s "W" #define byte_dump_short_width_s "w" - #define byte_dump_short_placeholder_s "p" #define byte_dump_long_binary_s "binary" #define byte_dump_long_decimal_s "decimal" @@ -154,16 +157,18 @@ extern "C" { #define byte_dump_long_octal_s "octal" #define byte_dump_long_unicode_s "unicode" - #define byte_dump_long_first_s "first" // first offset byte size. - #define byte_dump_long_last_s "last" // last offset byte size. - #define byte_dump_long_width_s "width" // number of characters to display per row. + #define byte_dump_long_first_s "first" // First offset byte size. + #define byte_dump_long_last_s "last" // Last offset byte size. - #define byte_dump_long_text_s "text" // display text - #define byte_dump_long_placeholder_s "placeholder" // display (colored) placeholders to signify codes that are UTF-8 fragments. + #define byte_dump_long_narrow_s "narrow" // Each character in the displyed text will take at least 1 columns. + #define byte_dump_long_placeholder_s "placeholder" // Display (colored) placeholders to signify codes that are UTF-8 fragments. + #define byte_dump_long_text_s "text" // Display text + #define byte_dump_long_wide_s "wide" // Each character in the displyed text will take at least 2 columns. + #define byte_dump_long_width_s "width" // Number of characters to display per row. - #define byte_dump_long_normal_s "normal" // use normal presentation, displaying UTF-8 sequence codes for ASCII special codes. - #define byte_dump_long_simple_s "simple" // use simple presentation, displaying spaces for ASCII special codes instead of UTF-8 sequence codes. - #define byte_dump_long_classic_s "classic" // use classic presentation, displaying periods for ASCII special codes instead of UTF-8 sequence codes. + #define byte_dump_long_normal_s "normal" // Use normal presentation, displaying UTF-8 sequence codes for ASCII special codes. + #define byte_dump_long_simple_s "simple" // Use simple presentation, displaying spaces for ASCII special codes instead of UTF-8 sequence codes. + #define byte_dump_long_classic_s "classic" // Use classic presentation, displaying periods for ASCII special codes instead of UTF-8 sequence codes. enum { byte_dump_parameter_help, @@ -185,10 +190,12 @@ extern "C" { byte_dump_parameter_first, byte_dump_parameter_last, - byte_dump_parameter_width, - byte_dump_parameter_text, + byte_dump_parameter_narrow, byte_dump_parameter_placeholder, + byte_dump_parameter_text, + byte_dump_parameter_wide, + byte_dump_parameter_width, byte_dump_parameter_normal, byte_dump_parameter_simple, @@ -214,15 +221,17 @@ extern "C" { f_console_parameter_t_initialize(byte_dump_short_unicode_s, byte_dump_long_unicode_s, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(byte_dump_short_first_s, byte_dump_long_first_s, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(byte_dump_short_last_s, byte_dump_long_last_s, 0, 1, f_console_type_normal), \ - f_console_parameter_t_initialize(byte_dump_short_width_s, byte_dump_long_width_s, 0, 1, f_console_type_normal), \ - f_console_parameter_t_initialize(byte_dump_short_text_s, byte_dump_long_text_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(byte_dump_short_narrow_s, byte_dump_long_narrow_s, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(byte_dump_short_placeholder_s, byte_dump_long_placeholder_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(byte_dump_short_text_s, byte_dump_long_text_s, 0, 0, f_console_type_normal), \ + f_console_parameter_t_initialize(byte_dump_short_wide_s, byte_dump_long_wide_s, 0, 1, f_console_type_normal), \ + f_console_parameter_t_initialize(byte_dump_short_width_s, byte_dump_long_width_s, 0, 1, f_console_type_normal), \ f_console_parameter_t_initialize(0, byte_dump_long_normal_s, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(0, byte_dump_long_simple_s, 0, 0, f_console_type_normal), \ f_console_parameter_t_initialize(0, byte_dump_long_classic_s, 0, 0, f_console_type_normal), \ } - #define byte_dump_total_parameters_d 23 + #define byte_dump_total_parameters_d 25 #endif // _di_byte_dump_defines_ #ifndef _di_byte_dump_main_t_ diff --git a/level_3/byte_dump/data/build/settings b/level_3/byte_dump/data/build/settings index cca9d35..4008172 100644 --- a/level_3/byte_dump/data/build/settings +++ b/level_3/byte_dump/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/control/data/build/settings b/level_3/control/data/build/settings index 526a7ac..c8e6bd3 100644 --- a/level_3/control/data/build/settings +++ b/level_3/control/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/controller/c/controller.c b/level_3/controller/c/controller.c index e4f46bb..e6a389c 100644 --- a/level_3/controller/c/controller.c +++ b/level_3/controller/c/controller.c @@ -196,7 +196,7 @@ extern "C" { fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_settings_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); controller_unlock_print_flush(main->error.to, 0); } @@ -235,7 +235,7 @@ extern "C" { fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_pid_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); controller_unlock_print_flush(main->error.to, 0); } @@ -287,7 +287,7 @@ extern "C" { fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_control_s, main->context.set.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); controller_unlock_print_flush(main->error.to, 0); } diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index ab11d7d..ad38903 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -5774,6 +5774,7 @@ extern "C" { } } else { + // @fixme change this to handle UTF-8 characters (cannot use f_print_character_safely() as it is not UTF-8 safe as-is). f_print_character_safely(parameter->string[k], main->output.to.stream); } } // for diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 18e9b1a..d1b22e0 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -2580,7 +2580,7 @@ extern "C" { } else { - // replace any potential existing value. + // Replace any potential existing value. settings_single_destination[i]->used = 0; *status = f_string_dynamic_append_nulless(settings_single_source[i]->array[0], settings_single_destination[i]); diff --git a/level_3/fake/c/private-print.c b/level_3/fake/c/private-print.c index fdfea52..c1e1942 100644 --- a/level_3/fake/c/private-print.c +++ b/level_3/fake/c/private-print.c @@ -335,7 +335,7 @@ extern "C" { fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings index 78bb39a..abd671d 100644 --- a/level_3/fss_basic_list_read/data/build/settings +++ b/level_3/fss_basic_list_read/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.c b/level_3/fss_basic_list_write/c/fss_basic_list_write.c index 6e97da5..41f1a24 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.c @@ -308,7 +308,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_basic_list_write_long_prepend_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c index ce64de5..213ce23 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c @@ -55,7 +55,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_basic_list_write/data/build/settings b/level_3/fss_basic_list_write/data/build/settings index fa4e211..679ec49 100644 --- a/level_3/fss_basic_list_write/data/build/settings +++ b/level_3/fss_basic_list_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings index 553772e..8afe05f 100644 --- a/level_3/fss_basic_read/data/build/settings +++ b/level_3/fss_basic_read/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_basic_write/c/fss_basic_write.c b/level_3/fss_basic_write/c/fss_basic_write.c index 0bad5fc..da080b8 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.c +++ b/level_3/fss_basic_write/c/fss_basic_write.c @@ -306,7 +306,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_basic_write_long_prepend_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.c b/level_3/fss_basic_write/c/private-fss_basic_write.c index 0980837..98a0afe 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.c +++ b/level_3/fss_basic_write/c/private-fss_basic_write.c @@ -38,7 +38,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_basic_write/data/build/settings b/level_3/fss_basic_write/data/build/settings index 7f86d60..8ed0368 100644 --- a/level_3/fss_basic_write/data/build/settings +++ b/level_3/fss_basic_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_embedded_list_read/data/build/settings b/level_3/fss_embedded_list_read/data/build/settings index 54772e1..99b237d 100644 --- a/level_3/fss_embedded_list_read/data/build/settings +++ b/level_3/fss_embedded_list_read/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c index 1541118..f0cfcf8 100644 --- a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c +++ b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c @@ -308,7 +308,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_embedded_list_write_long_prepend_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c b/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c index 0e391a3..a01f265 100644 --- a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c +++ b/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c @@ -55,7 +55,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_embedded_list_write/data/build/settings b/level_3/fss_embedded_list_write/data/build/settings index 9bc0c71..36bf537 100644 --- a/level_3/fss_embedded_list_write/data/build/settings +++ b/level_3/fss_embedded_list_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_extended_list_read/data/build/settings b/level_3/fss_extended_list_read/data/build/settings index b0658dd..8c8c80c 100644 --- a/level_3/fss_extended_list_read/data/build/settings +++ b/level_3/fss_extended_list_read/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.c b/level_3/fss_extended_list_write/c/fss_extended_list_write.c index 33e019a..ee13042 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.c @@ -309,7 +309,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_extended_list_write_long_prepend_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c index dc91946..a00b35e 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c @@ -55,7 +55,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_extended_list_write/data/build/settings b/level_3/fss_extended_list_write/data/build/settings index 3a5d711..db5d018 100644 --- a/level_3/fss_extended_list_write/data/build/settings +++ b/level_3/fss_extended_list_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings index b24d6de..9fbb2d9 100644 --- a/level_3/fss_extended_read/data/build/settings +++ b/level_3/fss_extended_read/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_extended_write/c/fss_extended_write.c b/level_3/fss_extended_write/c/fss_extended_write.c index 9f20684..12f69d5 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -320,7 +320,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, fss_extended_write_long_prepend_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.c b/level_3/fss_extended_write/c/private-fss_extended_write.c index e5ec11e..85dc7f1 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.c +++ b/level_3/fss_extended_write/c/private-fss_extended_write.c @@ -38,7 +38,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%S%S%]", main->error.to.stream, main->error.notable, symbol, parameter, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/fss_extended_write/data/build/settings b/level_3/fss_extended_write/data/build/settings index 77a8097..4661eb3 100644 --- a/level_3/fss_extended_write/data/build/settings +++ b/level_3/fss_extended_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_identify/data/build/settings b/level_3/fss_identify/data/build/settings index dcbe3fd..72902d2 100644 --- a/level_3/fss_identify/data/build/settings +++ b/level_3/fss_identify/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_fss -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/fss_status_code/data/build/settings b/level_3/fss_status_code/data/build/settings index 076ce52..b063e9e 100644 --- a/level_3/fss_status_code/data/build/settings +++ b/level_3/fss_status_code/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfll_status -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_file -lfll_fss -lfll_print -lfll_program -lfll_status -lfl_console -lfl_conversion -lfl_directory -lfl_fss -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_directory -lf_environment -lf_file -lf_fss -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/iki_write/c/iki_write.c b/level_3/iki_write/c/iki_write.c index 3a69c7e..fe3df0b 100644 --- a/level_3/iki_write/c/iki_write.c +++ b/level_3/iki_write/c/iki_write.c @@ -188,7 +188,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_write_long_file_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } @@ -203,7 +203,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_write_long_object_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } @@ -217,7 +217,7 @@ extern "C" { fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_write_long_content_s, main->error.notable); - fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); funlockfile(main->error.to.stream); } diff --git a/level_3/iki_write/data/build/settings b/level_3/iki_write/data/build/settings index ebf2494..31c4d8d 100644 --- a/level_3/iki_write/data/build/settings +++ b/level_3/iki_write/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_iki -lfll_print -lfll_program -lfl_console -lfl_iki -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_iki -lfll_print -lfll_program -lfl_console -lfl_iki -lfl_print -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/status_code/data/build/settings b/level_3/status_code/data/build/settings index 0c0ab9f..88416f4 100644 --- a/level_3/status_code/data/build/settings +++ b/level_3/status_code/data/build/settings @@ -21,7 +21,7 @@ build_indexer ar build_indexer_arguments rcs build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_print -lfll_program -lfll_status -lfl_console -lfl_conversion -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfll_status -lfl_console -lfl_conversion -lfl_print -lfl_status -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared diff --git a/level_3/utf8/c/private-common.c b/level_3/utf8/c/private-common.c index b625b78..8152b4a 100644 --- a/level_3/utf8/c/private-common.c +++ b/level_3/utf8/c/private-common.c @@ -1,152 +1,15 @@ #include "utf8.h" #include "private-common.h" +#include "private-print.h" #ifdef __cplusplus extern "C" { #endif -#ifndef _di_utf8_print_error_no_from_ - void utf8_print_error_no_from(utf8_main_t * const main) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - fll_print_format("%c%[%sNo from sources are specified, please pipe data, designate a file, or add parameters.%]%c", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context, f_string_eol_s[0]); - } -#endif // _di_utf8_print_error_no_from_ - -#ifndef _di_utf8_print_error_no_value_ - void utf8_print_error_no_value(utf8_main_t * const main, const f_string_t parameter) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, main->context.set.error); - fl_print_format("%[%s%S%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, parameter, main->context.set.notable); - fl_print_format("%[' is specified, but no value was given.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } -#endif // _di_utf8_print_error_no_value_ - -#ifndef _di_utf8_print_error_parameter_conflict_ - void utf8_print_error_parameter_conflict(utf8_main_t * const main, const f_string_t first, const f_string_t second) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - flockfile(main->output.to.stream); - - fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); - fl_print_format("%[%s%S%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, first, main->error.notable); - fl_print_format("%[' cannot be used with the parameter '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%S%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, second, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } -#endif // _di_utf8_print_error_parameter_conflict_ - -#ifndef _di_utf8_print_error_parameter_file_name_empty_ - void utf8_print_error_parameter_file_name_empty(utf8_main_t * const main, const f_array_length_t index) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SNo file specified at parameter index %]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, main->context.set.error); - fl_print_format("%[%ul%]", main->error.to.stream, main->context.set.notable, index, main->context.set.notable); - fl_print_format("%[.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } -#endif // _di_utf8_print_error_parameter_file_name_empty_ - -#ifndef _di_utf8_print_error_parameter_file_not_found_ - void utf8_print_error_parameter_file_not_found(utf8_main_t * const main, const bool from, const f_string_t name) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - flockfile(main->error.to.stream); - - fl_print_format("%c%[%SFailed to find the %s file '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, from ? utf8_string_from_s : utf8_string_to_s, main->context.set.error); - fl_print_format("%[%S%]", main->error.to.stream, main->context.set.notable, name, main->context.set.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); - - funlockfile(main->error.to.stream); - } -#endif // _di_utf8_print_error_parameter_file_not_found_ - -#ifndef _di_utf8_print_error_parameter_file_to_too_many_ - void utf8_print_error_parameter_file_to_too_many(utf8_main_t * const main) { - - if (main->error.verbosity == f_console_verbosity_quiet) return; - - fll_print_format("%c%[%SToo many %s files specified, there may only be one to file.%]%c", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->error.prefix, utf8_string_to_s, main->context.set.error, f_string_eol_s[0]); - } -#endif // _di_utf8_print_error_parameter_file_to_too_many_ - -#ifndef _di_utf8_print_section_header_file_ - void utf8_print_section_header_file(utf8_main_t * const main, const f_string_t name) { - - if (main->output.verbosity == f_console_verbosity_quiet) return; - if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; - - flockfile(main->output.to.stream); - - fl_print_format("%c%[File%] ", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title); - fl_print_format("%[%S%]:%c", main->output.to.stream, main->output.set->notable, name, main->output.set->notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } -#endif // _di_utf8_print_section_header_file_ - -#ifndef _di_utf8_print_section_header_parameter_ - void utf8_print_section_header_parameter(utf8_main_t * const main, const f_array_length_t index) { - - if (main->output.verbosity == f_console_verbosity_quiet) return; - if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; - - flockfile(main->output.to.stream); - - fl_print_format("%c%[Parameter%] ", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title); - fl_print_format("%[%ul%]:%c", main->output.to.stream, main->output.set->notable, index, main->output.set->notable, f_string_eol_s[0]); - - funlockfile(main->output.to.stream); - } -#endif // _di_utf8_print_section_header_parameter_ - -#ifndef _di_utf8_print_section_header_pipe_ - void utf8_print_section_header_pipe(utf8_main_t * const main) { - - if (main->output.verbosity == f_console_verbosity_quiet) return; - if (main->parameters[utf8_parameter_headers].result == f_console_result_none) return; - - fll_print_format("%c%[Pipe%]:%c", main->output.to.stream, f_string_eol_s[0], main->output.set->title, main->output.set->title, f_string_eol_s[0]); - } -#endif // _di_utf8_print_section_header_pipe_ - -#ifndef _di_utf8_print_signal_received_ - void utf8_print_signal_received(utf8_main_t * const main, const f_status_t signal) { - - if (main->warning.verbosity != f_console_verbosity_verbose) return; - - // Must flush and reset color because the interrupt may have interrupted the middle of a print function. - fflush(main->warning.to.stream); - - flockfile(main->warning.to.stream); - - fl_print_format("%]%c%c%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s[0], f_string_eol_s[0], main->context.set.warning, main->context.set.warning); - fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable); - fl_print_format("%[.%]%c", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } -#endif // _di_utf8_print_signal_received_ - #ifndef _di_utf8_signal_received_ - f_status_t utf8_signal_received(utf8_main_t * const main) { + f_status_t utf8_signal_received(utf8_data_t * const data) { - if (!main->signal.id) { + if (!data->main->signal.id) { return F_false; } @@ -154,7 +17,7 @@ extern "C" { memset(&information, 0, sizeof(struct signalfd_siginfo)); - if (f_signal_read(main->signal, 0, &information) == F_signal) { + if (f_signal_read(data->main->signal, 0, &information) == F_signal) { switch (information.ssi_signo) { case F_signal_abort: case F_signal_broken_pipe: @@ -162,7 +25,7 @@ extern "C" { case F_signal_interrupt: case F_signal_quit: case F_signal_termination: - utf8_print_signal_received(main, information.ssi_signo); + utf8_print_signal_received(data, information.ssi_signo); return information.ssi_signo; } diff --git a/level_3/utf8/c/private-common.h b/level_3/utf8/c/private-common.h index b7f40ca..caed850 100644 --- a/level_3/utf8/c/private-common.h +++ b/level_3/utf8/c/private-common.h @@ -13,123 +13,91 @@ extern "C" { #endif /** - * Print error message for when no sources are provided. - * - * @param main - * The main program data. + * private_utf8_codepoint_mode_*: + * - ready: The codepoint has yet to be processed, skip leading spaces until first 'U' is matched. + * - begin: The first 'U' is matched, look for the '+'. + * - number: The '+' is matched, process numbers. + * - end: The last number is reached (at either whitespace or EOS/EOF). + * - bad: This is not a valid codepoint. + * - bad_begin: This is the beginning of an invalid codepoint. + * - bad_end: The end of bad is detected, which happens on whitespace or end of buffer. */ -#ifndef _di_utf8_print_error_no_from_ - extern void utf8_print_error_no_from(utf8_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_no_from_ +#ifndef _di_utf8_codepoint_modes_ + enum { + utf8_codepoint_mode_ready = 1, + utf8_codepoint_mode_begin, + utf8_codepoint_mode_number, + utf8_codepoint_mode_end, + utf8_codepoint_mode_bad, + utf8_codepoint_mode_bad_begin, + utf8_codepoint_mode_bad_end, + }; +#endif // _di__utf8_codepoint_modes_ /** - * Print error message for when no sources are provided. + * The program data. * - * @param main - * The main program data. - * @param parameter_1 - * The long parameter name. + * main: The main program data. + * file: The output file for writing the processed data to (may potentially default to "output"). + * mode: The input/output mode (see utf8_modes). + * valid: Designate the output context set for valid characters. + * valid_not: Designate the output context set for invalid characters. + * append: A string to append. A value of NULL results in not appending. + * prepend: A string to prepend. A value of NULL results in not prepending. + * file_name: The name of the file being output to for processed data (is empty if defaulting to "output"). + * buffer: A buffer to use for printing output (generally for storing a block of input from an input file). + * text: A buffer for storing a series of characters for processing (generally for codepoint processing). */ -#ifndef _di_utf8_print_error_no_value_ - extern void utf8_print_error_no_value(utf8_main_t * const main, const f_string_t parameter) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_no_value_ +#ifndef _di_utf8_data_t_ + typedef struct { + utf8_main_t *main; -/** - * Print error message for two parameters not being allowed to be used together. - * - * @param main - * The main program data. - * @param first - * The long parameter name for the first parameter. - * @param second - * The long parameter name for the second parameter. - */ -#ifndef _di_utf8_print_error_parameter_conflict_ - extern void utf8_print_error_parameter_conflict(utf8_main_t * const main, const f_string_t first, const f_string_t second) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_parameter_conflict_ + f_file_t file; + uint8_t mode; -/** - * Print error message for when the file parameter is an empty string. - * - * @param main - * The main program data. - * @param index - * The index within the argv[] array where the empty string is found. - */ -#ifndef _di_utf8_print_error_parameter_file_name_empty_ - extern void utf8_print_error_parameter_file_name_empty(utf8_main_t * const main, const f_array_length_t index) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_parameter_file_name_empty_ + f_color_set_t valid; + f_color_set_t valid_not; -/** - * Print error message for when no sources are provided in the main program parameters. - * - * @param main - * The main program data. - * @param from - * If TRUE, then this is a from file (source file). - * If FALSE, then this is a to file (destination file). - * @param name - * The file path name. - */ -#ifndef _di_utf8_print_error_parameter_file_not_found_ - extern void utf8_print_error_parameter_file_not_found(utf8_main_t * const main, const bool from, const f_string_t name) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_parameter_file_not_found_ + f_string_t append; + f_string_t prepend; -/** - * Print error message for when too many 'to' destinations are specified. - * - * @param main - * The main program data. - */ -#ifndef _di_utf8_print_error_parameter_file_to_too_many_ - extern void utf8_print_error_parameter_file_to_too_many(utf8_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_error_parameter_file_to_too_many_ + f_string_static_t file_name; + f_string_dynamic_t buffer; + f_string_dynamic_t text; + } utf8_data_t; -/** - * Print the input file section header. - * - * @param main - * The main program data. - * @param name - * The name of the file. - */ -#ifndef _di_utf8_print_section_header_file_ - extern void utf8_print_section_header_file(utf8_main_t * const main, const f_string_t name) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_section_header_file_ + #define utf8_data_t_initialize \ + { \ + 0, \ + f_file_t_initialize, \ + utf8_mode_from_binary_d | utf8_mode_to_codepoint_d, \ + f_color_set_t_initialize, \ + f_color_set_t_initialize, \ + f_string_t_initialize, \ + f_string_t_initialize, \ + f_string_static_t_initialize, \ + f_string_dynamic_t_initialize, \ + f_string_dynamic_t_initialize, \ + } +#endif // _di_utf8_data_t_ /** - * Print the input parameter section header. + * Check to see if a process signal is received. * - * @param main - * The main program data. - * @param index - * The index position of the parameter. - */ -#ifndef _di_utf8_print_section_header_parameter_ - extern void utf8_print_section_header_parameter(utf8_main_t * const main, const f_array_length_t index) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_section_header_parameter_ - -/** - * Print the input pipe section header. + * Only signals that are blocked via main.signal will be received. * - * @param main - * The main program data. - */ -#ifndef _di_utf8_print_section_header_pipe_ - extern void utf8_print_section_header_pipe(utf8_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_section_header_pipe_ - -/** - * Print a message about a process signal being recieved, such as an interrupt signal. + * @param data + * The program data. + * + * @return + * A positive number representing a valid signal on signal received. + * F_false on no signal received. * - * @param main - * The main program data. - * @param signal - * The signal code received. + * @see f_signal_read() */ -#ifndef _di_utf8_print_signal_received_ - extern void utf8_print_signal_received(utf8_main_t * const main, const f_status_t signal) F_attribute_visibility_internal_d; -#endif // _di_utf8_print_signal_received_ +#ifndef _di_utf8_signal_received_ + extern f_status_t utf8_signal_received(utf8_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_utf8_signal_received_ #ifdef __cplusplus } // extern "C" diff --git a/level_3/utf8/c/private-print.c b/level_3/utf8/c/private-print.c new file mode 100644 index 0000000..68cc1aa --- /dev/null +++ b/level_3/utf8/c/private-print.c @@ -0,0 +1,192 @@ +#include "utf8.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_print_character_ + void utf8_print_character(utf8_data_t * const data, const f_string_static_t character, const f_color_set_t set) { + + if (data->main->parameters[utf8_parameter_strip_invalid].result == f_console_result_found || !character.used) { + return; + } + + if (data->mode & utf8_mode_to_binary_d) { + fl_print_format("%s%[", data->file.stream, data->prepend, set); + f_print_dynamic_raw(character, data->file.stream); + fl_print_format("%s%]", data->file.stream, data->append, set); + } + else { + fl_print_format("%s%[0x", data->file.stream, data->prepend, set); + + for (uint8_t i = 0; i < character.used; ++i) { + fl_print_format("%04_uii", data->file.stream, (uint8_t) character.string[i]); + } // for + + fl_print_format("%s%]", data->file.stream, data->append, set); + } + } +#endif // _di_utf8_print_character_ + +#ifndef _di_utf8_print_error_decode_ + void utf8_print_error_decode(utf8_data_t * const data, const f_status_t status, const f_string_static_t character) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + fl_print_format("%c%[%SFailed to decode character '%]", data->main->error.to.stream, f_string_eol_s[0], data->main->context.set.error, data->main->context.set.error); + fl_print_format("%[%r%]", data->main->error.to.stream, data->main->context.set.notable, character, data->main->context.set.notable); + fl_print_format("%[', error status code%] ", data->main->error.to.stream, data->main->context.set.error, data->main->context.set.error, f_string_eol_s[0]); + fl_print_format("%[%S%]", data->main->error.to.stream, data->main->context.set.notable, F_status_set_fine(status), data->main->context.set.notable); + fl_print_format("%[.%]%c", data->main->error.to.stream, data->main->context.set.error, data->main->context.set.error, f_string_eol_s[0]); + } +#endif // _di_utf8_print_error_decode_ + +#ifndef _di_utf8_print_error_no_from_ + void utf8_print_error_no_from(utf8_data_t * const data) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + fll_print_format("%c%[%sNo from sources are specified, please pipe data, designate a file, or add parameters.%]%c", data->main->error.to.stream, f_string_eol_s[0], data->main->error.context, data->main->error.prefix, data->main->error.context, f_string_eol_s[0]); + } +#endif // _di_utf8_print_error_no_from_ + +#ifndef _di_utf8_print_error_no_value_ + void utf8_print_error_no_value(utf8_data_t * const data, const f_string_t parameter) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(data->main->error.to.stream); + + fl_print_format("%c%[%SThe parameter '%]", data->main->error.to.stream, f_string_eol_s[0], data->main->context.set.error, data->main->error.prefix, data->main->context.set.error); + fl_print_format("%[%s%S%]", data->main->error.to.stream, data->main->context.set.notable, f_console_symbol_long_enable_s, parameter, data->main->context.set.notable); + fl_print_format("%[' is specified, but no value was given.%]%c", data->main->error.to.stream, data->main->context.set.error, data->main->context.set.error, f_string_eol_s[0]); + + funlockfile(data->main->error.to.stream); + } +#endif // _di_utf8_print_error_no_value_ + +#ifndef _di_utf8_print_error_parameter_conflict_ + void utf8_print_error_parameter_conflict(utf8_data_t * const data, const f_string_t first, const f_string_t second) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(data->main->output.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", data->main->error.to.stream, f_string_eol_s[0], data->main->error.context, data->main->error.prefix, data->main->error.context); + fl_print_format("%[%s%S%]", data->main->error.to.stream, data->main->error.notable, f_console_symbol_long_enable_s, first, data->main->error.notable); + fl_print_format("%[' cannot be used with the parameter '%]", data->main->error.to.stream, data->main->error.context, data->main->error.context); + fl_print_format("%[%s%S%]", data->main->error.to.stream, data->main->error.notable, f_console_symbol_long_enable_s, second, data->main->error.notable); + fl_print_format("%['.%]%c", data->main->error.to.stream, data->main->error.context, data->main->error.context, f_string_eol_s[0]); + + funlockfile(data->main->output.to.stream); + } +#endif // _di_utf8_print_error_parameter_conflict_ + +#ifndef _di_utf8_print_error_parameter_file_name_empty_ + void utf8_print_error_parameter_file_name_empty(utf8_data_t * const data, const f_array_length_t index) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(data->main->error.to.stream); + + fl_print_format("%c%[%SNo file specified at parameter index %]", data->main->error.to.stream, f_string_eol_s[0], data->main->context.set.error, data->main->error.prefix, data->main->context.set.error); + fl_print_format("%[%ul%]", data->main->error.to.stream, data->main->context.set.notable, index, data->main->context.set.notable); + fl_print_format("%[.%]%c", data->main->error.to.stream, data->main->context.set.error, data->main->context.set.error, f_string_eol_s[0]); + + funlockfile(data->main->error.to.stream); + } +#endif // _di_utf8_print_error_parameter_file_name_empty_ + +#ifndef _di_utf8_print_error_parameter_file_not_found_ + void utf8_print_error_parameter_file_not_found(utf8_data_t * const data, const bool from, const f_string_t name) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + flockfile(data->main->error.to.stream); + + fl_print_format("%c%[%SFailed to find the %s file '%]", data->main->error.to.stream, f_string_eol_s[0], data->main->context.set.error, data->main->error.prefix, from ? utf8_string_from_s : utf8_string_to_s, data->main->context.set.error); + fl_print_format("%[%S%]", data->main->error.to.stream, data->main->context.set.notable, name, data->main->context.set.notable); + fl_print_format("%['.%]%c", data->main->error.to.stream, data->main->context.set.error, data->main->context.set.error, f_string_eol_s[0]); + + funlockfile(data->main->error.to.stream); + } +#endif // _di_utf8_print_error_parameter_file_not_found_ + +#ifndef _di_utf8_print_error_parameter_file_to_too_many_ + void utf8_print_error_parameter_file_to_too_many(utf8_data_t * const data) { + + if (data->main->error.verbosity == f_console_verbosity_quiet) return; + + fll_print_format("%c%[%SToo many %s files specified, there may only be one to file.%]%c", data->main->error.to.stream, f_string_eol_s[0], data->main->context.set.error, data->main->error.prefix, utf8_string_to_s, data->main->context.set.error, f_string_eol_s[0]); + } +#endif // _di_utf8_print_error_parameter_file_to_too_many_ + +#ifndef _di_utf8_print_section_header_file_ + void utf8_print_section_header_file(utf8_data_t * const data, const f_string_t name) { + + if (data->main->output.verbosity == f_console_verbosity_quiet) return; + if (data->main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + flockfile(data->main->output.to.stream); + + fl_print_format("%c%[File%] ", data->main->output.to.stream, f_string_eol_s[0], data->main->output.set->title, data->main->output.set->title); + + if (data->file.stream == data->main->output.to.stream) { + fl_print_format("%[%S%]:%c", data->main->output.to.stream, data->main->output.set->notable, name, data->main->output.set->notable, f_string_eol_s[0]); + } + else { + fl_print_format("%[%S%]: %S.%c", data->main->output.to.stream, data->main->output.set->notable, name, data->main->output.set->notable, data->file_name, f_string_eol_s[0]); + } + + funlockfile(data->main->output.to.stream); + } +#endif // _di_utf8_print_section_header_file_ + +#ifndef _di_utf8_print_section_header_parameter_ + void utf8_print_section_header_parameter(utf8_data_t * const data, const f_array_length_t index) { + + if (data->main->output.verbosity == f_console_verbosity_quiet) return; + if (data->main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + flockfile(data->main->output.to.stream); + + fl_print_format("%c%[Parameter%] ", data->main->output.to.stream, f_string_eol_s[0], data->main->output.set->title, data->main->output.set->title); + fl_print_format("%[%ul%]:%c", data->main->output.to.stream, data->main->output.set->notable, index, data->main->output.set->notable, f_string_eol_s[0]); + + funlockfile(data->main->output.to.stream); + } +#endif // _di_utf8_print_section_header_parameter_ + +#ifndef _di_utf8_print_section_header_pipe_ + void utf8_print_section_header_pipe(utf8_data_t * const data) { + + if (data->main->output.verbosity == f_console_verbosity_quiet) return; + if (data->main->parameters[utf8_parameter_headers].result == f_console_result_none) return; + + fll_print_format("%c%[Pipe%]:%c", data->main->output.to.stream, f_string_eol_s[0], data->main->output.set->title, data->main->output.set->title, f_string_eol_s[0]); + } +#endif // _di_utf8_print_section_header_pipe_ + +#ifndef _di_utf8_print_signal_received_ + void utf8_print_signal_received(utf8_data_t * const data, const f_status_t signal) { + + if (data->main->warning.verbosity != f_console_verbosity_verbose) return; + + // Must flush and reset color because the interrupt may have interrupted the middle of a print function. + fflush(data->main->warning.to.stream); + + flockfile(data->main->warning.to.stream); + + fl_print_format("%]%c%c%[Received signal code %]", data->main->warning.to.stream, data->main->context.set.reset, f_string_eol_s[0], f_string_eol_s[0], data->main->context.set.warning, data->main->context.set.warning); + fl_print_format("%[%i%]", data->main->warning.to.stream, data->main->context.set.notable, signal, data->main->context.set.notable); + fl_print_format("%[.%]%c", data->main->warning.to.stream, data->main->context.set.warning, data->main->context.set.warning, f_string_eol_s[0]); + + funlockfile(data->main->warning.to.stream); + } +#endif // _di_utf8_print_signal_received_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/private-print.h b/level_3/utf8/c/private-print.h new file mode 100644 index 0000000..802d9dd --- /dev/null +++ b/level_3/utf8/c/private-print.h @@ -0,0 +1,164 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + */ +#ifndef _PRIVATE_utf8_print_h +#define _PRIVATE_utf8_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the character either as a Unicode codeblock or as a binary. + * + * @param data + * The program data. + * @param character + * The character block to print. + * @param set + * The output context set. + */ +#ifndef _di_utf8_print_character_ + extern void utf8_print_character(utf8_data_t * const data, const f_string_static_t character, const f_color_set_t set) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_character_ + +/** + * Print error message when attempt to decode the character failed. + * + * @param data + * The program data. + * @param character + * The character block to print. + */ +#ifndef _di_utf8_print_error_decode_ + extern void utf8_print_error_decode(utf8_data_t * const data, const f_status_t status, const f_string_static_t character) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_decode_ + +/** + * Print error message for when no sources are provided. + * + * @param data + * The program data. + */ +#ifndef _di_utf8_print_error_no_from_ + extern void utf8_print_error_no_from(utf8_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_no_from_ + +/** + * Print error message for when no sources are provided. + * + * @param data + * The program data. + * @param parameter_1 + * The long parameter name. + */ +#ifndef _di_utf8_print_error_no_value_ + extern void utf8_print_error_no_value(utf8_data_t * const data, const f_string_t parameter) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_no_value_ + +/** + * Print error message for two parameters not being allowed to be used together. + * + * @param data + * The program data. + * @param first + * The long parameter name for the first parameter. + * @param second + * The long parameter name for the second parameter. + */ +#ifndef _di_utf8_print_error_parameter_conflict_ + extern void utf8_print_error_parameter_conflict(utf8_data_t * const data, const f_string_t first, const f_string_t second) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_conflict_ + +/** + * Print error message for when the file parameter is an empty string. + * + * @param data + * The program data. + * @param index + * The index within the argv[] array where the empty string is found. + */ +#ifndef _di_utf8_print_error_parameter_file_name_empty_ + extern void utf8_print_error_parameter_file_name_empty(utf8_data_t * const data, const f_array_length_t index) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_name_empty_ + +/** + * Print error message for when no sources are provided in the main program parameters. + * + * @param data + * The program data. + * @param from + * If TRUE, then this is a from file (source file). + * If FALSE, then this is a to file (destination file). + * @param name + * The file path name. + */ +#ifndef _di_utf8_print_error_parameter_file_not_found_ + extern void utf8_print_error_parameter_file_not_found(utf8_data_t * const data, const bool from, const f_string_t name) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_not_found_ + +/** + * Print error message for when too many 'to' destinations are specified. + * + * @param data + * The program data. + */ +#ifndef _di_utf8_print_error_parameter_file_to_too_many_ + extern void utf8_print_error_parameter_file_to_too_many(utf8_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_error_parameter_file_to_too_many_ + +/** + * Print the input file section header. + * + * @param data + * The program data. + * @param name + * The name of the file. + */ +#ifndef _di_utf8_print_section_header_file_ + extern void utf8_print_section_header_file(utf8_data_t * const data, const f_string_t name) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_file_ + +/** + * Print the input parameter section header. + * + * @param data + * The program data. + * @param index + * The index position of the parameter. + */ +#ifndef _di_utf8_print_section_header_parameter_ + extern void utf8_print_section_header_parameter(utf8_data_t * const data, const f_array_length_t index) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_parameter_ + +/** + * Print the input pipe section header. + * + * @param data + * The program data. + */ +#ifndef _di_utf8_print_section_header_pipe_ + extern void utf8_print_section_header_pipe(utf8_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_section_header_pipe_ + +/** + * Print a message about a process signal being recieved, such as an interrupt signal. + * + * @param data + * The program data. + * @param signal + * The signal code received. + */ +#ifndef _di_utf8_print_signal_received_ + extern void utf8_print_signal_received(utf8_data_t * const data, const f_status_t signal) F_attribute_visibility_internal_d; +#endif // _di_utf8_print_signal_received_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_utf8_print_h diff --git a/level_3/utf8/c/private-utf8.c b/level_3/utf8/c/private-utf8.c index 7689cde..d8f22c5 100644 --- a/level_3/utf8/c/private-utf8.c +++ b/level_3/utf8/c/private-utf8.c @@ -1,306 +1,28 @@ #include "utf8.h" #include "private-common.h" +#include "private-print.h" #include "private-utf8.h" +#include "private-utf8_binary.h" +#include "private-utf8_codepoint.h" #ifdef __cplusplus extern "C" { #endif -#ifndef _di_utf8_convert_binary_ - f_status_t utf8_convert_binary(utf8_main_t * const main, const f_string_static_t character) { +#ifndef _di_utf8_data_delete_ + void utf8_data_delete(utf8_data_t *data) { - f_status_t status = F_none; - - f_string_t prepend = ""; - f_string_t append = ""; - f_color_set_t error = f_color_set_t_initialize; - - if (main->mode & utf8_mode_to_codepoint_d) { - if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { - if (main->parameters[utf8_parameter_headers].result == f_console_result_found) { - prepend = " "; - } - else { - prepend = " "; - } - - append = f_string_eol_s; - } - else { - error = main->output.set->error; - prepend = " "; - } - } - - uint32_t codepoint = 0; - - if (character.used) { - status = f_utf_unicode_to(character.string, character.used, &codepoint); - } - else { - status = F_status_set_error(F_utf); - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_utf) { - if (main->parameters[utf8_parameter_strip_invalid].result == f_console_result_none) { - if (main->mode & utf8_mode_to_binary_d) { - fl_print_format("%s%[", main->output.to.stream, prepend, error); - - for (f_array_length_t i = 0; i < character.used; ++i) { - f_print_character(character.string[i], main->output.to.stream); - } // for - - fl_print_format("%s%[", main->output.to.stream, error, append); - } - else { - fl_print_format("%s%[0x", main->output.to.stream, prepend, error); - - for (uint8_t i = 0; i < character.used; ++i) { - fl_print_format("%02_uii", main->output.to.stream, (uint8_t) character.string[i]); - } // for - - fl_print_format("%]%s", main->output.to.stream, error, append); - } - } - } - else { - if (main->error.verbosity != f_console_verbosity_quiet) { - fl_print_format("%c%[%SFailed to decode character '%]", main->error.to.stream, f_string_eol_s[0], main->context.set.error, main->context.set.error); - fl_print_format("%[%r%]", main->error.to.stream, main->context.set.notable, character, main->context.set.notable); - fl_print_format("%[', error status code%] ", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); - fl_print_format("%[%S%]", main->error.to.stream, main->context.set.notable, F_status_set_fine(status), main->context.set.notable); - fl_print_format("%[.%]%c", main->error.to.stream, main->context.set.error, main->context.set.error, f_string_eol_s[0]); - } - - return status; - } - } - else if (main->parameters[utf8_parameter_verify].result == f_console_result_none) { - if (main->mode & utf8_mode_to_binary_d) { - f_print_terminated(prepend, main->output.to.stream); - - for (f_array_length_t i = 0; i < character.used; ++i) { - f_print_character(character.string[i], main->output.to.stream); - } // for - - f_print_terminated(append, main->output.to.stream); - } - else { - if (character.used < 4) { - fl_print_format("%sU+%04_U%s", main->output.to.stream, prepend, codepoint, append); - } - else { - fl_print_format("%sU+%06_U%s", main->output.to.stream, prepend, codepoint, append); - } - } - } - - if (F_status_is_error(status)) { - return F_utf; - } - - return F_none; - } -#endif // _di_utf8_convert_binary_ - -#ifndef _di_utf8_convert_codepoint_ - f_status_t utf8_convert_codepoint(utf8_main_t * const main, const f_string_static_t character, uint8_t *mode) { - - f_status_t status = F_none; - - // @todo - - - return F_none; - } -#endif // _di_utf8_convert_codepoint_ - -#ifndef _di_utf8_process_file_binary_ - f_status_t utf8_process_file_binary(utf8_main_t * const main, const f_file_t file) { - - f_status_t status = F_none; - bool valid = F_true; - bool next = F_true; - uint8_t mode = 0; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - char block_character[4] = { 0, 0, 0, 0 }; - f_string_static_t character = macro_f_string_static_t_initialize(block_character, 4); - - do { - status = f_file_read_block(file, &main->buffer); - - if (status == F_none_eof && !main->buffer.used) break; - - for (i = 0; F_status_is_fine(status) && i < main->buffer.used; ) { - - status = utf8_signal_received(main); - - if (status) { - utf8_print_signal_received(main, status); - - status = F_status_set_error(F_signal); - break; - } - else { - status = F_none; - } - - // Get the current width only when processing a new block. - if (next) { - character.used = macro_f_utf_byte_width(main->buffer.string[i]); - next = F_false; - } - - for (; j < character.used && i < main->buffer.used; ++j, ++i) { - character.string[j] = main->buffer.string[i]; - } // for - - if (j == character.used) { - if (main->mode & utf8_mode_from_binary_d) { - status = utf8_convert_binary(main, character); - } - else { - // @todo: check character and determine status. - /*private_utf8_codepoint_modes_ready = 1, - private_utf8_codepoint_modes_begin, - private_utf8_codepoint_modes_number, - private_utf8_codepoint_modes_end, - private_utf8_codepoint_modes_bad,*/ - status = utf8_convert_codepoint(main, character, &mode); - } - - if (status == F_utf) { - valid = F_false; - } - - j = 0; - next = F_true; - } - } // for - - i = 0; - main->buffer.used = 0; - - } while (F_status_is_fine(status) && status != F_signal); - - // Handle last (incomplete) character when the buffer ended before the character is supposed to end. - if (status != F_signal && next == F_false) { - character.used = j; - - if (main->mode & utf8_mode_from_binary_d) { - status = utf8_convert_binary(main, character); - } - else { - // @todo: check character and determine status. - /*private_utf8_codepoint_modes_ready = 1, - private_utf8_codepoint_modes_begin, - private_utf8_codepoint_modes_number, - private_utf8_codepoint_modes_end, - private_utf8_codepoint_modes_bad,*/ - status = utf8_convert_codepoint(main, character, &mode); - } - - if (status == F_utf) { - valid = F_false; - } + if (data->file.stream != data->main->output.to.stream) { + f_file_stream_close(F_true, &data->file); } - main->buffer.used = 0; - - if (F_status_is_error(status)) { - return status; - } - - return valid; + macro_f_string_dynamic_t_delete_simple(data->buffer); + macro_f_string_dynamic_t_delete_simple(data->text); } -#endif // _di_utf8_process_file_binary_ - -#ifndef _di_utf8_process_file_codepoint_ - f_status_t utf8_process_file_codepoint(utf8_main_t * const main, const f_file_t file) { - - f_status_t status = F_none; - bool valid = F_true; - bool next = F_true; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - char block[4] = { 0, 0, 0, 0 }; - f_string_static_t character = macro_f_string_static_t_initialize(block, 4); - - do { - status = f_file_read_block(file, &main->buffer); - - if (status == F_none_eof && !main->buffer.used) break; - - for (i = 0; F_status_is_fine(status) && i < main->buffer.used; ) { - - status = utf8_signal_received(main); - - if (status) { - utf8_print_signal_received(main, status); - - status = F_status_set_error(F_signal); - break; - } - else { - status = F_none; - } - - // Get the current width only when processing a new block. - if (next) { - character.used = macro_f_utf_byte_width(main->buffer.string[i]); - next = F_false; - } - - for (; j < character.used && i < main->buffer.used; ++j, ++i) { - character.string[j] = main->buffer.string[i]; - } // for - - if (j == character.used) { - status = utf8_convert_binary(main, character); - - if (status == F_utf) { - valid = F_false; - } - - j = 0; - next = F_true; - } - } // for - - i = 0; - main->buffer.used = 0; - - } while (F_status_is_fine(status) && status != F_signal); - - // Handle last (incomplete) character when the buffer ended before the character is supposed to end. - if (status != F_signal && next == F_false) { - character.used = j; - - status = utf8_convert_binary(main, character); - - if (status == F_utf) { - valid = F_false; - } - } - - main->buffer.used = 0; - - if (F_status_is_error(status)) { - return status; - } - - return valid; - } -#endif // _di_utf8_process_file_codepoint_ +#endif // _di_utf8_data_delete_ #ifndef _di_utf8_process_text_ - f_status_t utf8_process_text(utf8_main_t * const main, const f_string_t text) { + f_status_t utf8_process_text(utf8_data_t * const data, const f_string_t text) { if (!text) { return F_true; @@ -308,18 +30,18 @@ extern "C" { f_status_t status = F_none; bool valid = F_true; - uint8_t mode = 0; + uint8_t mode_codepoint = utf8_codepoint_mode_ready; f_string_static_t character = macro_f_string_static_t_initialize(text, 4); - flockfile(main->output.to.stream); + flockfile(data->file.stream); while (*character.string && F_status_is_error_not(status)) { - status = utf8_signal_received(main); + status = utf8_signal_received(data); if (status) { - utf8_print_signal_received(main, status); + utf8_print_signal_received(data, status); status = F_status_set_error(F_signal); break; @@ -359,17 +81,15 @@ extern "C" { character.used = 0; } - if (main->mode & utf8_mode_from_binary_d) { - status = utf8_convert_binary(main, character); + if (data->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(data, character); } else { - // @todo: check character and determine status. - /*private_utf8_codepoint_modes_ready = 1, - private_utf8_codepoint_modes_begin, - private_utf8_codepoint_modes_number, - private_utf8_codepoint_modes_end, - private_utf8_codepoint_modes_bad,*/ - status = utf8_convert_codepoint(main, character, &mode); + status = utf8_detect_codepoint(data, character, &mode_codepoint); + + if (F_status_is_fine(status) && status != F_next) { + status = utf8_convert_codepoint(data, character, &mode_codepoint); + } } character.string += character.used; @@ -379,17 +99,32 @@ extern "C" { } } // while + if (F_status_is_error_not(status) && !(data->mode & utf8_mode_from_binary_d)) { + if (mode_codepoint != utf8_codepoint_mode_ready && mode_codepoint != utf8_codepoint_mode_end && mode_codepoint != utf8_codepoint_mode_bad_end) { + if (mode_codepoint == utf8_codepoint_mode_number) { + mode_codepoint = utf8_codepoint_mode_end; + } + else { + mode_codepoint = utf8_codepoint_mode_bad_end; + } + + character.used = 0; + + status = utf8_convert_codepoint(data, character, &mode_codepoint); + } + } + if (F_status_is_error(status)) { - funlockfile(main->output.to.stream); + funlockfile(data->file.stream); return status; } - if (main->parameters[utf8_parameter_verify].result == f_console_result_none) { - f_print_character(f_string_eol_s[0], main->output.to.stream); + if (data->main->parameters[utf8_parameter_verify].result == f_console_result_none) { + f_print_terminated(f_string_eol_s, data->file.stream); } - funlockfile(main->output.to.stream); + funlockfile(data->file.stream); return valid; } diff --git a/level_3/utf8/c/private-utf8.h b/level_3/utf8/c/private-utf8.h index 7c48eeb..052e70c 100644 --- a/level_3/utf8/c/private-utf8.h +++ b/level_3/utf8/c/private-utf8.h @@ -13,127 +13,23 @@ extern "C" { #endif /** - * @todo make this a define rather than an enum so that "bad/invalid" can be passed along with different state values. - * Or do some sort of trick ("XXX >> 1, to get enum value such that the first bit represents valid/invalid). - * private_utf8_codepoint_modes_*: - * - ready: The codepoint has yet to be processed, skip leading spaces until first 'U' is matched. - * - begin: The first 'U' is matched, look for the '+'. - * - number: The '+' is matched, process numbers. - * - end: The last number is reached (at either whitespace or EOS/EOF). - * - bad: This is not a valid codepoint. - */ -#ifndef _di_private_utf8_codepoint_modes_ - enum { - private_utf8_codepoint_modes_ready = 1, - private_utf8_codepoint_modes_begin, - private_utf8_codepoint_modes_number, - private_utf8_codepoint_modes_end, - private_utf8_codepoint_modes_bad, - }; -#endif // _di_private_utf8_codepoint_modes_ - -/** - * Convert a binary character to another format. - * - * This automatically determines the output format and is also handles the verify process. - * - * @param main - * The main program data. - * @param character - * The a single character to convert. - * This does not stop on NULL and will process all text until text.used. - * - * @return - * F_none on success. - * F_utf on invalid UTF-8 (which is still "success" when verifying). - * - * F_utf (with error bit) if not verifying and - * - * Errors (with error bit) from: f_utf_unicode_to() - */ -#ifndef _di_utf8_convert_binary_ - extern f_status_t utf8_convert_binary(utf8_main_t * const main, const f_string_static_t character) F_attribute_visibility_internal_d; -#endif // _di_utf8_convert_binary_ - -/** - * Convert a codepoint character representation to another format. - * - * This automatically determines the output format and is also handles the verify process. + * Deallocate program data. * - * @param main - * The main program data. - * @param character - * The a single character to convert. - * This does not stop on NULL and will process all text until text.used. - * @param mode - * Designate the mode in which the curent state is being processed. + * @param data + * The program data. * * @return * F_none on success. - * F_utf on invalid UTF-8 (which is still "success" when verifying). - * - * F_utf (with error bit) if not verifying and - * - * Errors (with error bit) from: f_utf_unicode_to() */ -#ifndef _di_utf8_convert_codepoint_ - extern f_status_t utf8_convert_codepoint(utf8_main_t * const main, const f_string_static_t text, uint8_t *mode) F_attribute_visibility_internal_d; -#endif // _di_utf8_convert_codepoint_ - -/** - * Process file as a binary input, handling conversion or verification as appropriate. - * - * @param main - * The main program data. - * @param file - * The file stream to process. - * This file may contain NULLs. - * - * @return - * F_true on success and is valid. - * F_false on success and contains invalid sequences. - * F_signal on (exit) signal received. - * - * Errors (with error bit) from: utf8_convert_binary() - * Errors (with error bit) from: utf8_convert_codepoint() - * - * @see utf8_convert_binary() - * @see utf8_signal_received() - */ -#ifndef _di_utf8_process_file_binary_ - extern f_status_t utf8_process_file_binary(utf8_main_t * const main, const f_file_t file) F_attribute_visibility_internal_d; -#endif // _di_utf8_process_file_binary_ - -/** - * Process file as a codepoint input, handling conversion or verification as appropriate. - * - * @param main - * The main program data. - * @param file - * The file stream to process. - * This file may contain NULLs. - * - * @return - * F_true on success and is valid. - * F_false on success and contains invalid sequences. - * F_signal on (exit) signal received. - * - * Errors (with error bit) from: utf8_convert_binary() - * Errors (with error bit) from: utf8_convert_codepoint() - * - * @see utf8_convert_binary() - * @see utf8_convert_codepoint() - * @see utf8_signal_received() - */ -#ifndef _di_utf8_process_file_codepoint_ - extern f_status_t utf8_process_file_codepoint(utf8_main_t * const main, const f_file_t file) F_attribute_visibility_internal_d; -#endif // _di_utf8_process_file_codepoint_ +#ifndef _di_utf8_data_delete_ + extern void utf8_data_delete(utf8_data_t *data); +#endif // _di_utf8_data_delete_ /** * Convert the text from one format to other another format or verify text. * - * @param main - * The main program data. + * @param data + * The program data. * @param text * This represent a single text data. * This text is NULL terminated and can therefore not contain any NULLs. @@ -145,33 +41,17 @@ extern "C" { * * Errors (with error bit) from: utf8_convert_binary() * Errors (with error bit) from: utf8_convert_codepoint() + * Errors (with error bit) from: utf8_detect_codepoint() * * @see utf8_convert_binary() * @see utf8_convert_codepoint() + * @see utf8_detect_codepoint() * @see utf8_signal_received() */ #ifndef _di_utf8_process_text_ - extern f_status_t utf8_process_text(utf8_main_t * const main, const f_string_t text) F_attribute_visibility_internal_d; + extern f_status_t utf8_process_text(utf8_data_t * const data, const f_string_t text) F_attribute_visibility_internal_d; #endif // _di_utf8_process_text_ -/** - * Check to see if a process signal is received. - * - * Only signals that are blocked via main.signal will be received. - * - * @param main - * The main program data. - * - * @return - * A positive number representing a valid signal on signal received. - * F_false on no signal received. - * - * @see f_signal_read() - */ -#ifndef _di_utf8_signal_received_ - extern f_status_t utf8_signal_received(utf8_main_t * const main); -#endif // _di_utf8_signal_received_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/utf8/c/private-utf8_binary.c b/level_3/utf8/c/private-utf8_binary.c new file mode 100644 index 0000000..accba66 --- /dev/null +++ b/level_3/utf8/c/private-utf8_binary.c @@ -0,0 +1,158 @@ +#include "utf8.h" +#include "private-common.h" +#include "private-print.h" +#include "private-utf8.h" +#include "private-utf8_binary.h" +#include "private-utf8_codepoint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_convert_binary_ + f_status_t utf8_convert_binary(utf8_data_t * const data, const f_string_static_t character) { + + f_status_t status = F_none; + + uint32_t codepoint = 0; + + if (character.used) { + status = f_utf_unicode_to(character.string, character.used, &codepoint); + } + else { + status = F_status_set_error(F_utf); + } + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_utf) { + utf8_print_character(data, character, data->valid_not); + } + else { + utf8_print_error_decode(data, status, character); + + return status; + } + } + else if (data->main->parameters[utf8_parameter_verify].result == f_console_result_none) { + if (data->mode & utf8_mode_to_binary_d) { + f_print_terminated(data->prepend, data->file.stream); + f_print_dynamic_raw(character, data->file.stream); + f_print_terminated(data->append, data->file.stream); + } + else { + fl_print_format(codepoint < 0xffff ? "%sU+%04_U%s" : "%sU+%6_U%s", data->file.stream, data->prepend, codepoint, data->append); + } + } + + if (F_status_is_error(status)) { + return F_utf; + } + + return F_none; + } +#endif // _di_utf8_convert_binary_ + +#ifndef _di_utf8_process_file_binary_ + f_status_t utf8_process_file_binary(utf8_data_t * const data, const f_file_t file) { + + f_status_t status = F_none; + + bool valid = F_true; + bool next = F_true; + uint8_t mode_codepoint = utf8_codepoint_mode_ready; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + char block_character[4] = { 0, 0, 0, 0 }; + f_string_static_t character = macro_f_string_static_t_initialize(block_character, 4); + + do { + status = f_file_read_block(file, &data->buffer); + + if (status == F_none_eof && !data->buffer.used) break; + + for (i = 0; F_status_is_fine(status) && i < data->buffer.used; ) { + + status = utf8_signal_received(data); + + if (status) { + utf8_print_signal_received(data, status); + + status = F_status_set_error(F_signal); + break; + } + else { + status = F_none; + } + + // Get the current width only when processing a new block. + if (next) { + character.used = macro_f_utf_byte_width(data->buffer.string[i]); + next = F_false; + } + + for (; j < character.used && i < data->buffer.used; ++j, ++i) { + character.string[j] = data->buffer.string[i]; + } // for + + if (j == character.used) { + if (data->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(data, character); + } + else { + status = utf8_detect_codepoint(data, character, &mode_codepoint); + + if (F_status_is_fine(status) && status != F_next) { + status = utf8_convert_codepoint(data, character, &mode_codepoint); + } + } + + if (status == F_utf) { + valid = F_false; + } + + j = 0; + next = F_true; + } + } // for + + i = 0; + data->buffer.used = 0; + + } while (F_status_is_fine(status) && status != F_signal); + + // Handle last (incomplete) character when the buffer ended before the character is supposed to end. + if (status != F_signal && next == F_false) { + + character.used = j; + + if (data->mode & utf8_mode_from_binary_d) { + status = utf8_convert_binary(data, character); + } + else { + status = utf8_detect_codepoint(data, character, &mode_codepoint); + + if (F_status_is_fine(status) && status != F_next) { + status = utf8_convert_codepoint(data, character, &mode_codepoint); + } + } + + if (status == F_utf) { + valid = F_false; + } + } + + data->buffer.used = 0; + + if (F_status_is_error(status)) { + return status; + } + + return valid; + } +#endif // _di_utf8_process_file_binary_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/private-utf8_binary.h b/level_3/utf8/c/private-utf8_binary.h new file mode 100644 index 0000000..89355ae --- /dev/null +++ b/level_3/utf8/c/private-utf8_binary.h @@ -0,0 +1,67 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + */ +#ifndef _PRIVATE_utf8_binary_h +#define _PRIVATE_utf8_binary_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Convert a binary character to another format. + * + * This automatically determines the output format and is also handles the verify process. + * + * @param data + * The program data. + * @param character + * The a single character to convert. + * This does not stop on NULL and will process all text until character.used. + * + * @return + * F_none on success. + * F_utf on invalid UTF-8 (which is still "success" when verifying). + * + * F_utf (with error bit) if not verifying and + * + * Errors (with error bit) from: f_utf_unicode_to() + */ +#ifndef _di_utf8_convert_binary_ + extern f_status_t utf8_convert_binary(utf8_data_t * const data, const f_string_static_t character) F_attribute_visibility_internal_d; +#endif // _di_utf8_convert_binary_ + +/** + * Process file as a binary input, handling conversion or verification as appropriate. + * + * @param data + * The program data. + * @param file + * The file stream to process. + * This file may contain NULLs. + * + * @return + * F_true on success and is valid. + * F_false on success and contains invalid sequences. + * F_signal on (exit) signal received. + * + * Errors (with error bit) from: utf8_convert_binary() + * Errors (with error bit) from: utf8_detect_codepoint() + * + * @see utf8_convert_binary() + * @see utf8_detect_codepoint() + * @see utf8_signal_received() + */ +#ifndef _di_utf8_process_file_binary_ + extern f_status_t utf8_process_file_binary(utf8_data_t * const data, const f_file_t file) F_attribute_visibility_internal_d; +#endif // _di_utf8_process_file_binary_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_utf8_binary_h diff --git a/level_3/utf8/c/private-utf8_codepoint.c b/level_3/utf8/c/private-utf8_codepoint.c new file mode 100644 index 0000000..b373dec --- /dev/null +++ b/level_3/utf8/c/private-utf8_codepoint.c @@ -0,0 +1,260 @@ +#include "utf8.h" +#include "private-common.h" +#include "private-print.h" +#include "private-utf8.h" +#include "private-utf8_binary.h" +#include "private-utf8_codepoint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_utf8_convert_codepoint_ + f_status_t utf8_convert_codepoint(utf8_data_t * const data, const f_string_static_t character, uint8_t *mode) { + + f_status_t status = F_none; + + if (*mode != utf8_codepoint_mode_end) { + if (data->text.used + character.used >= data->text.size) { + status = f_string_dynamic_increase_by(utf8_default_allocation_step_d, &data->text); + if (F_status_is_error(status)) return status; + } + + for (f_array_length_t i = 0; i < character.used; ++i) { + data->text.string[data->text.used++] = character.string[i]; + } // for + } + + if (!(*mode == utf8_codepoint_mode_end || *mode == utf8_codepoint_mode_bad_end)) { + return F_none; + } + + if (*mode == utf8_codepoint_mode_end) { + uint32_t codepoint = 0; + + status = f_utf_unicode_string_from(data->text.string, data->text.used, &codepoint); + + if (F_status_is_error(status)) { + if (F_status_set_fine(status) == F_failure || F_status_set_fine(status) == F_utf) { + utf8_print_character(data, data->text, data->valid_not); + } + else { + utf8_print_error_decode(data, status, character); + } + } + else { + if (data->mode & utf8_mode_to_binary_d) { + char byte[5] = { 0, 0, 0, 0, 0 }; + f_string_static_t text = f_string_static_t_initialize; + text.string = byte; + text.used = macro_f_utf_byte_width(codepoint); + text.size = 5; + + byte[0] = macro_f_utf_character_t_to_char_1(codepoint); + + if (text.used > 1) { + byte[1] = macro_f_utf_character_t_to_char_2(codepoint); + + if (text.used > 2) { + byte[2] = macro_f_utf_character_t_to_char_3(codepoint); + + if (text.used > 3) { + byte[3] = macro_f_utf_character_t_to_char_4(codepoint); + } + } + } + + f_print_terminated(data->prepend, data->file.stream); + f_print_dynamic_raw(text, data->file.stream); + f_print_terminated(data->append, data->file.stream); + } + else { + fl_print_format(codepoint < 0xffff ? "%sU+%04_U%s" : "%sU+%6_U%s", data->file.stream, data->prepend, codepoint, data->append); + } + } + } + else { + status = F_none; + + utf8_print_character(data, data->text, data->valid_not); + } + + *mode = utf8_codepoint_mode_ready; + data->text.used = 0; + + return status; + } +#endif // _di_utf8_convert_codepoint_ + +#ifndef _di_utf8_detect_codepoint_ + f_status_t utf8_detect_codepoint(utf8_data_t * const data, const f_string_static_t character, uint8_t *mode) { + + // Skip past NULL. + if (!character.string[0]) { + return F_next; + } + + f_status_t status = F_none; + + if (character.string[0] == f_string_ascii_u_s[0] || character.string[0] == f_string_ascii_U_s[0] || character.string[0] == f_string_ascii_plus_s[0]) { + // Do nothing. + } + else if (character.string[0] == f_string_ascii_space_s[0]) { + status = F_space; + } + else if (macro_f_utf_byte_width_is(*character.string)) { + status = f_utf_is_whitespace(character.string, 4); + if (F_status_is_error(status)) return status; + + if (status == F_true) { + status = F_space; + } + else { + status = F_valid_not; + } + } + else { + if (character.string[0] < 0x30 || character.string[0] > 0x39 && character.string[0] < 0x41 || character.string[0] > 0x46 && character.string[0] < 0x61 || character.string[0] > 0x66) { + + status = f_utf_is_whitespace(character.string, 4); + if (F_status_is_error(status)) return status; + + if (status == F_true) { + status = F_space; + } + else { + status = F_valid_not; + } + } + } + + if (status == F_valid_not) { + if (*mode != utf8_codepoint_mode_bad) { + if (*mode == utf8_codepoint_mode_bad_begin) { + *mode = utf8_codepoint_mode_bad; + } + else { + *mode = utf8_codepoint_mode_bad_begin; + } + } + } + else { + if (*mode == utf8_codepoint_mode_bad) { + if (status == F_space) { + *mode = utf8_codepoint_mode_bad_end; + } + } + else if (*mode == utf8_codepoint_mode_ready) { + if (status == F_space) { + status = F_next; + } + else if (character.string[0] == f_string_ascii_u_s[0] || character.string[0] == f_string_ascii_U_s[0]) { + *mode = utf8_codepoint_mode_begin; + data->text.used = 0; + } + else { + *mode = utf8_codepoint_mode_bad; + } + } + else if (*mode == utf8_codepoint_mode_begin) { + if (character.string[0] == f_string_ascii_plus_s[0]) { + *mode = utf8_codepoint_mode_number; + } + else { + *mode = utf8_codepoint_mode_bad; + } + } + else if (*mode == utf8_codepoint_mode_number) { + if (status == F_space) { + *mode = utf8_codepoint_mode_end; + } + } + } + + return F_none; + } +#endif // _di_utf8_detect_codepoint_ + +#ifndef _di_utf8_process_file_codepoint_ + f_status_t utf8_process_file_codepoint(utf8_data_t * const data, const f_file_t file) { + + f_status_t status = F_none; + bool valid = F_true; + bool next = F_true; + + f_array_length_t i = 0; + f_array_length_t j = 0; + + char block[4] = { 0, 0, 0, 0 }; + f_string_static_t character = macro_f_string_static_t_initialize(block, 4); + + do { + status = f_file_read_block(file, &data->buffer); + + if (status == F_none_eof && !data->buffer.used) break; + + for (i = 0; F_status_is_fine(status) && i < data->buffer.used; ) { + + status = utf8_signal_received(data); + + if (status) { + utf8_print_signal_received(data, status); + + status = F_status_set_error(F_signal); + break; + } + else { + status = F_none; + } + + // Get the current width only when processing a new block. + if (next) { + character.used = macro_f_utf_byte_width(data->buffer.string[i]); + next = F_false; + } + + for (; j < character.used && i < data->buffer.used; ++j, ++i) { + character.string[j] = data->buffer.string[i]; + } // for + + if (j == character.used) { + status = utf8_convert_binary(data, character); + + if (status == F_utf) { + valid = F_false; + } + + j = 0; + next = F_true; + } + } // for + + i = 0; + data->buffer.used = 0; + + } while (F_status_is_fine(status) && status != F_signal); + + // Handle last (incomplete) character when the buffer ended before the character is supposed to end. + if (status != F_signal && next == F_false) { + character.used = j; + + status = utf8_convert_binary(data, character); + + if (status == F_utf) { + valid = F_false; + } + } + + data->buffer.used = 0; + + if (F_status_is_error(status)) { + return status; + } + + return valid; + } +#endif // _di_utf8_process_file_codepoint_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/utf8/c/private-utf8_codepoint.h b/level_3/utf8/c/private-utf8_codepoint.h new file mode 100644 index 0000000..c5bd2aa --- /dev/null +++ b/level_3/utf8/c/private-utf8_codepoint.h @@ -0,0 +1,88 @@ +/** + * FLL - Level 3 + * + * Project: UTF-8 + * API Version: 0.5 + * Licenses: lgplv2.1 + */ +#ifndef _PRIVATE_utf8_codepoint_h +#define _PRIVATE_utf8_codepoint_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Convert a codepoint character representation to another format. + * + * This automatically determines the output format and is also handles the verify process. + * + * @param data + * The program data. + * @param character + * The a single character currently being processed. + * @param mode + * The codepoint mode the text is currently in. + * + * @return + * F_none on success. + * F_utf on invalid UTF-8 (which is still "success" when verifying). + * + * F_utf (with error bit) if not verifying and + * + * Errors (with error bit) from: f_utf_unicode_to() + */ +#ifndef _di_utf8_convert_codepoint_ + extern f_status_t utf8_convert_codepoint(utf8_data_t * const data, const f_string_static_t character, uint8_t *mode) F_attribute_visibility_internal_d; +#endif // _di_utf8_convert_codepoint_ + +/** + * Detect a codepoint character. + * + * @param data + * The program data. + * @param character + * The a single character to analyze. + * @param mode + * Designate the mode in which the curent state is being processed. + * + * @return + * F_none on success. + * F_next on success, but should not be processed (it is whitespace or NULL). + * + * Errors (with error bit) from: f_utf_is_whitespace() + */ +#ifndef _di_utf8_detect_codepoint_ + extern f_status_t utf8_detect_codepoint(utf8_data_t * const data, const f_string_static_t character, uint8_t *mode) F_attribute_visibility_internal_d; +#endif // _di_utf8_detect_codepoint_ + +/** + * Process file as a codepoint input, handling conversion or verification as appropriate. + * + * @param data + * The program data. + * @param file + * The file stream to process. + * This file may contain NULLs. + * + * @return + * F_true on success and is valid. + * F_false on success and contains invalid sequences. + * F_signal on (exit) signal received. + * + * Errors (with error bit) from: utf8_convert_binary() + * Errors (with error bit) from: utf8_detect_codepoint() + * + * @see utf8_convert_binary() + * @see utf8_detect_codepoint() + * @see utf8_signal_received() + */ +#ifndef _di_utf8_process_file_codepoint_ + extern f_status_t utf8_process_file_codepoint(utf8_data_t * const data, const f_file_t file) F_attribute_visibility_internal_d; +#endif // _di_utf8_process_file_codepoint_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_utf8_codepoint_h diff --git a/level_3/utf8/c/utf8.c b/level_3/utf8/c/utf8.c index 7839c0f..a94eef7 100644 --- a/level_3/utf8/c/utf8.c +++ b/level_3/utf8/c/utf8.c @@ -1,6 +1,9 @@ #include "utf8.h" #include "private-common.h" +#include "private-print.h" #include "private-utf8.h" +#include "private-utf8_binary.h" +#include "private-utf8_codepoint.h" #ifdef __cplusplus extern "C" { @@ -63,6 +66,9 @@ extern "C" { f_status_t status = F_none; + utf8_data_t data = utf8_data_t_initialize; + data.main = main; + { const f_console_parameters_t parameters = macro_f_console_parameters_t_initialize(main->parameters, utf8_total_parameters_d); @@ -96,6 +102,7 @@ extern "C" { if (F_status_is_error(status)) { fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process", F_true); + utf8_data_delete(&data); utf8_main_delete(main); return F_status_set_error(status); @@ -114,6 +121,7 @@ extern "C" { fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); utf8_main_delete(main); + utf8_data_delete(&data); return status; } @@ -151,24 +159,25 @@ extern "C" { if (F_status_is_error(status)) { fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); + utf8_data_delete(&data); utf8_main_delete(main); return status; } if (choice == utf8_parameter_from_binary) { - if (main->mode & utf8_mode_from_codepoint_d) { - main->mode -= utf8_mode_from_codepoint_d; + if (data.mode & utf8_mode_from_codepoint_d) { + data.mode -= utf8_mode_from_codepoint_d; } - main->mode |= utf8_mode_from_binary_d; + data.mode |= utf8_mode_from_binary_d; } else if (choice == utf8_parameter_from_codepoint) { - if (main->mode & utf8_mode_from_binary_d) { - main->mode -= utf8_mode_from_binary_d; + if (data.mode & utf8_mode_from_binary_d) { + data.mode -= utf8_mode_from_binary_d; } - main->mode |= utf8_mode_from_codepoint_d; + data.mode |= utf8_mode_from_codepoint_d; } } @@ -183,24 +192,25 @@ extern "C" { if (F_status_is_error(status)) { fll_error_print(main->error, F_status_set_fine(status), "f_console_parameter_prioritize_right", F_true); + utf8_data_delete(&data); utf8_main_delete(main); return status; } if (choice == utf8_parameter_to_binary) { - if (main->mode & utf8_mode_to_codepoint_d) { - main->mode -= utf8_mode_to_codepoint_d; + if (data.mode & utf8_mode_to_codepoint_d) { + data.mode -= utf8_mode_to_codepoint_d; } - main->mode |= utf8_mode_to_binary_d; + data.mode |= utf8_mode_to_binary_d; } else if (choice == utf8_parameter_to_codepoint) { - if (main->mode & utf8_mode_to_binary_d) { - main->mode -= utf8_mode_to_binary_d; + if (data.mode & utf8_mode_to_binary_d) { + data.mode -= utf8_mode_to_binary_d; } - main->mode |= utf8_mode_to_codepoint_d; + data.mode |= utf8_mode_to_codepoint_d; } } @@ -210,20 +220,24 @@ extern "C" { if (main->parameters[utf8_parameter_help].result == f_console_result_found) { utf8_print_help(main->output.to, main->context); + utf8_data_delete(&data); utf8_main_delete(main); + return F_none; } if (main->parameters[utf8_parameter_version].result == f_console_result_found) { fll_program_print_version(main->output.to, utf8_version_s); + utf8_data_delete(&data); utf8_main_delete(main); + return F_none; } if (main->parameters[utf8_parameter_from_binary].result == f_console_result_found) { if (main->parameters[utf8_parameter_from_codepoint].result == f_console_result_found) { - utf8_print_error_parameter_conflict(main, utf8_long_from_binary_s, utf8_long_from_codepoint_s); + utf8_print_error_parameter_conflict(&data, utf8_long_from_binary_s, utf8_long_from_codepoint_s); status = F_status_set_error(F_parameter); } @@ -231,7 +245,7 @@ extern "C" { if (F_status_is_error_not(status) && main->parameters[utf8_parameter_to_binary].result == f_console_result_found) { if (main->parameters[utf8_parameter_to_codepoint].result == f_console_result_found) { - utf8_print_error_parameter_conflict(main, utf8_long_to_binary_s, utf8_long_to_codepoint_s); + utf8_print_error_parameter_conflict(&data, utf8_long_to_binary_s, utf8_long_to_codepoint_s); status = F_status_set_error(F_parameter); } @@ -239,7 +253,7 @@ extern "C" { if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { if (main->parameters[utf8_parameter_strip_invalid].result == f_console_result_found) { - utf8_print_error_parameter_conflict(main, utf8_long_verify_s, utf8_long_strip_invalid_s); + utf8_print_error_parameter_conflict(&data, utf8_long_verify_s, utf8_long_strip_invalid_s); status = F_status_set_error(F_parameter); } @@ -256,7 +270,7 @@ extern "C" { if (arguments->argv[index][0]) { if (!f_file_exists(arguments->argv[index])) { - utf8_print_error_parameter_file_not_found(main, F_true, arguments->argv[index]); + utf8_print_error_parameter_file_not_found(&data, F_true, arguments->argv[index]); if (F_status_is_error_not(status)) { status = F_status_set_error(F_file_found_not); @@ -264,7 +278,7 @@ extern "C" { } } else { - utf8_print_error_parameter_file_name_empty(main, index); + utf8_print_error_parameter_file_name_empty(&data, index); if (F_status_is_error_not(status)) { status = F_status_set_error(F_parameter); @@ -273,7 +287,7 @@ extern "C" { } // for } else if (main->parameters[utf8_parameter_from_file].result == f_console_result_found) { - utf8_print_error_no_value(main, utf8_long_from_file_s); + utf8_print_error_no_value(&data, utf8_long_from_file_s); status = F_status_set_error(F_parameter); } @@ -284,65 +298,84 @@ extern "C" { if (F_status_is_error_not(status)) { if (main->parameters[utf8_parameter_to_file].result == f_console_result_additional) { if (main->parameters[utf8_parameter_to_file].values.used > 1) { - utf8_print_error_parameter_file_to_too_many(main); + utf8_print_error_parameter_file_to_too_many(&data); status = F_status_set_error(F_parameter); } else { - const f_array_length_t index = main->parameters[utf8_parameter_to_file].values.array[0]; + data.file_name.string = arguments->argv[main->parameters[utf8_parameter_to_file].values.array[0]]; + data.file_name.used = strnlen(data.file_name.string, PATH_MAX); - if (arguments->argv[index][0]) { - if (!f_file_exists(arguments->argv[index])) { - utf8_print_error_parameter_file_not_found(main, F_false, arguments->argv[index]); + if (data.file_name.used) { + status = f_file_stream_open(data.file_name.string, "a", &data.file); - status = F_status_set_error(F_file_found_not); + if (F_status_is_error(status)) { + fll_error_file_print(main->error, F_status_set_fine(status), "f_file_stream_open", F_true, data.file_name.string, "open", fll_error_file_type_file); } } else { - utf8_print_error_parameter_file_name_empty(main, index); + utf8_print_error_parameter_file_name_empty(&data, main->parameters[utf8_parameter_to_file].values.array[0]); status = F_status_set_error(F_parameter); } } } else if (main->parameters[utf8_parameter_to_file].result == f_console_result_found) { - utf8_print_error_no_value(main, utf8_long_to_file_s); + utf8_print_error_no_value(&data, utf8_long_to_file_s); status = F_status_set_error(F_parameter); } else { - main->destination = main->output.to; + data.file = main->output.to; } } if (F_status_is_error_not(status)) { if (main->parameters[utf8_parameter_from_file].result == f_console_result_none && !(main->process_pipe || main->remaining.used)) { - utf8_print_error_no_from(main); + utf8_print_error_no_from(&data); status = F_status_set_error(F_parameter); } + + if (data.mode & utf8_mode_to_codepoint_d) { + if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { + if (main->parameters[utf8_parameter_headers].result == f_console_result_found) { + data.prepend = " "; + } + else { + data.prepend = f_string_space_s; + } + + data.append = f_string_eol_s; + } + else { + data.prepend = f_string_space_s; + } + } + + data.valid_not = main->output.set->error; } if (F_status_is_error_not(status)) { status = F_none; if (main->process_pipe) { - f_file_t file = f_file_t_initialize; + f_file_t file = macro_f_file_t_initialize(0, -1, F_file_flag_read_only_d, 32768, F_file_default_write_size_d); file.id = F_type_descriptor_input_d; file.stream = F_type_input_d; - utf8_print_section_header_pipe(main); + utf8_print_section_header_pipe(&data); - if (main->mode & utf8_mode_from_binary_d) { - status = utf8_process_file_binary(main, file); + if (data.mode & utf8_mode_from_binary_d) { + status = utf8_process_file_binary(&data, file); } else { - status = utf8_process_file_codepoint(main, file); + status = utf8_process_file_codepoint(&data, file); } if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), main->mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, 0, utf8_string_process_s, fll_error_file_type_pipe); + fll_error_file_print(main->error, F_status_set_fine(status), data.mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, 0, utf8_string_process_s, fll_error_file_type_pipe); } } @@ -350,19 +383,18 @@ extern "C" { f_array_length_t i = 0; f_array_length_t index = 0; - f_file_t file = f_file_t_initialize; - file.size_read = 32768; + f_file_t file = macro_f_file_t_initialize(0, -1, F_file_flag_read_only_d, 32768, F_file_default_write_size_d); for (; i < main->parameters[utf8_parameter_from_file].values.used && status != F_signal; ++i) { - if (utf8_signal_received(main)) { + if (utf8_signal_received(&data)) { status = F_status_set_error(F_signal); break; } index = main->parameters[utf8_parameter_from_file].values.array[i]; - utf8_print_section_header_file(main, arguments->argv[index]); + utf8_print_section_header_file(&data, arguments->argv[index]); status = f_file_stream_open(arguments->argv[index], 0, &file); @@ -372,11 +404,11 @@ extern "C" { break; } - if (main->mode & utf8_mode_from_binary_d) { - status = utf8_process_file_binary(main, file); + if (data.mode & utf8_mode_from_binary_d) { + status = utf8_process_file_binary(&data, file); } else { - status = utf8_process_file_codepoint(main, file); + status = utf8_process_file_codepoint(&data, file); } f_file_stream_close(F_true, &file); @@ -388,7 +420,7 @@ extern "C" { } if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), main->mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, arguments->argv[index], utf8_string_process_s, fll_error_file_type_file); + fll_error_file_print(main->error, F_status_set_fine(status), data.mode & utf8_mode_from_binary_d ? "utf8_process_file_binary" : "utf8_process_file_codepoint", F_true, arguments->argv[index], utf8_string_process_s, fll_error_file_type_file); break; } @@ -401,16 +433,16 @@ extern "C" { for (; F_status_is_error_not(status) && i < main->remaining.used; ++i) { - if (utf8_signal_received(main)) { + if (utf8_signal_received(&data)) { status = F_status_set_error(F_signal); break; } index = main->remaining.array[i]; - utf8_print_section_header_parameter(main, index); + utf8_print_section_header_parameter(&data, index); - status = utf8_process_text(main, arguments->argv[index]); + status = utf8_process_text(&data, arguments->argv[index]); if (main->parameters[utf8_parameter_verify].result == f_console_result_found) { if (status == F_false) { @@ -423,12 +455,17 @@ extern "C" { if (main->output.verbosity != f_console_verbosity_quiet) { if (F_status_set_fine(status) == F_interrupt) { - fflush(main->output.to.stream); + fflush(data.file.stream); + + if (data.file.stream != main->output.to.stream) { + fflush(main->output.to.stream); + } } fll_print_terminated(f_string_eol_s, main->output.to.stream); } + utf8_data_delete(&data); utf8_main_delete(main); if (F_status_is_error(status)) { @@ -449,14 +486,6 @@ extern "C" { macro_f_array_lengths_t_delete_simple(main->parameters[i].values); } // for - macro_f_string_dynamic_t_delete_simple(main->buffer); - macro_f_string_dynamic_t_delete_simple(main->file_input); - macro_f_string_dynamic_t_delete_simple(main->file_output); - macro_f_string_dynamic_t_delete_simple(main->text); - - macro_f_string_dynamic_t_delete_simple(main->separate_character); - macro_f_string_dynamic_t_delete_simple(main->separate_source); - macro_f_array_lengths_t_delete_simple(main->remaining); macro_f_color_context_t_delete_simple(main->context); diff --git a/level_3/utf8/c/utf8.h b/level_3/utf8/c/utf8.h index 585d05e..0bb3080 100644 --- a/level_3/utf8/c/utf8.h +++ b/level_3/utf8/c/utf8.h @@ -16,11 +16,17 @@ #ifndef _utf8_h // libc includes +#include #include #include #include #include +// If limits.h does not provide PATH_MAX, define it instead of relying on . +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif /* PATH_MAX */ + // fll-0 includes #include #include @@ -31,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -76,7 +83,7 @@ extern "C" { * Set to at least 4 to provide a UTF-8 friendly allocation step. */ #ifndef _di_utf8_default_allocation_step_ - #define utf8_default_allocation_step_d 4 + #define utf8_default_allocation_step_d 16 #endif // _di_utf8_default_allocation_step_ #ifndef _di_utf8_defines_ @@ -175,6 +182,8 @@ extern "C" { #endif // _di_utf8_defines_ /** + * Modes used to designate how to the input and output are to be processed. + * * utf8_mode_from_*: * - binary: The input source is binary. * - codepoint: The input source is codepoint (U+XXXX or U+XXXXXX). @@ -190,6 +199,18 @@ extern "C" { #define utf8_mode_to_codepoint_d 0x8 #endif // _di_utf8_modes_ +/** + * The main program data. + * + * parameters: The state of pre-defined parameters passed to the program. + * remaining: The remaining, non-pre-defined parameters, passed to the program. + * process_pipe: Designate whether or not to process the input pipe. + * output: The output file for general printing. + * error: The output file for error printing. + * warning: The output file for warning printing. + * signal: The process signal management structure. + * context: The color context. + */ #ifndef _di_utf8_main_t_ typedef struct { f_console_parameter_t parameters[utf8_total_parameters_d]; @@ -203,17 +224,6 @@ extern "C" { f_signal_t signal; - f_file_t destination; - uint8_t mode; - - f_string_dynamic_t buffer; - f_string_dynamic_t file_input; - f_string_dynamic_t file_output; - f_string_dynamic_t text; - - f_string_dynamic_t separate_character; - f_string_dynamic_t separate_source; - f_color_context_t context; } utf8_main_t; @@ -226,14 +236,6 @@ extern "C" { macro_fl_print_t_initialize_error(), \ macro_fl_print_t_initialize_warning(), \ f_signal_t_initialize, \ - f_file_t_initialize, \ - utf8_mode_from_binary_d | utf8_mode_to_codepoint_d, \ - f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ - f_string_dynamic_t_initialize, \ f_color_context_t_initialize, \ } #endif // _di_utf8_main_t_ diff --git a/level_3/utf8/data/build/settings b/level_3/utf8/data/build/settings index 2de6a54..b15bde2 100644 --- a/level_3/utf8/data/build/settings +++ b/level_3/utf8/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library utf8.c private-common.c private-utf8.c +build_sources_library utf8.c private-common.c private-print.c private-utf8.c private-utf8_binary.c private-utf8_codepoint.c build_sources_library_shared build_sources_library_static build_sources_program main.c -- 1.8.3.1