From: Kevin Day Date: Fri, 3 Jul 2026 03:59:56 +0000 (-0500) Subject: Progress: Latest changes. X-Git-Url: https://www.git.kevux.org/?a=commitdiff_plain;h=refs%2Fheads%2F0.8-combining;p=fll Progress: Latest changes. The code has been sitting recently, so commit the changes as is. I need to come back and resume the work and then complete everything still. --- diff --git a/build/stand_alone/byte_dump.config.h b/build/stand_alone/byte_dump.config.h index 3cb3dc3b6..476ebb639 100644 --- a/build/stand_alone/byte_dump.config.h +++ b/build/stand_alone/byte_dump.config.h @@ -1331,7 +1331,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ //#define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner //#define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/example.config.h b/build/stand_alone/example.config.h index 85d7859cb..cd01de073 100644 --- a/build/stand_alone/example.config.h +++ b/build/stand_alone/example.config.h @@ -1296,7 +1296,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fake.config.h b/build/stand_alone/fake.config.h index 45cc3e753..07c5bf881 100644 --- a/build/stand_alone/fake.config.h +++ b/build/stand_alone/fake.config.h @@ -1774,7 +1774,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_identify.config.h b/build/stand_alone/fss_identify.config.h index 6f2f88849..11c204fc7 100644 --- a/build/stand_alone/fss_identify.config.h +++ b/build/stand_alone/fss_identify.config.h @@ -1477,7 +1477,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_basic.h b/build/stand_alone/fss_read.config.fss_basic.h index 2526178cf..982b5152d 100644 --- a/build/stand_alone/fss_read.config.fss_basic.h +++ b/build/stand_alone/fss_read.config.fss_basic.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_basic_list.h b/build/stand_alone/fss_read.config.fss_basic_list.h index 4f9e105d2..61ccb4491 100644 --- a/build/stand_alone/fss_read.config.fss_basic_list.h +++ b/build/stand_alone/fss_read.config.fss_basic_list.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_embedded_list.h b/build/stand_alone/fss_read.config.fss_embedded_list.h index 65624b403..ab49238c9 100644 --- a/build/stand_alone/fss_read.config.fss_embedded_list.h +++ b/build/stand_alone/fss_read.config.fss_embedded_list.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_extended.h b/build/stand_alone/fss_read.config.fss_extended.h index ced1f3d32..775aea20e 100644 --- a/build/stand_alone/fss_read.config.fss_extended.h +++ b/build/stand_alone/fss_read.config.fss_extended.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_extended_list.h b/build/stand_alone/fss_read.config.fss_extended_list.h index 8b045020d..06bda9390 100644 --- a/build/stand_alone/fss_read.config.fss_extended_list.h +++ b/build/stand_alone/fss_read.config.fss_extended_list.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.fss_payload.h b/build/stand_alone/fss_read.config.fss_payload.h index 18bfdec07..74bfd57a7 100644 --- a/build/stand_alone/fss_read.config.fss_payload.h +++ b/build/stand_alone/fss_read.config.fss_payload.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_read.config.h b/build/stand_alone/fss_read.config.h index 991feb200..2716bb300 100644 --- a/build/stand_alone/fss_read.config.h +++ b/build/stand_alone/fss_read.config.h @@ -1548,7 +1548,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_basic.h b/build/stand_alone/fss_write.config.fss_basic.h index 34e03ce2b..d45a69d20 100644 --- a/build/stand_alone/fss_write.config.fss_basic.h +++ b/build/stand_alone/fss_write.config.fss_basic.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_basic_list.h b/build/stand_alone/fss_write.config.fss_basic_list.h index 3132f4b83..f33fd2773 100644 --- a/build/stand_alone/fss_write.config.fss_basic_list.h +++ b/build/stand_alone/fss_write.config.fss_basic_list.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_embedded_list.h b/build/stand_alone/fss_write.config.fss_embedded_list.h index 04d8e9956..bfcdffcaf 100644 --- a/build/stand_alone/fss_write.config.fss_embedded_list.h +++ b/build/stand_alone/fss_write.config.fss_embedded_list.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_extended.h b/build/stand_alone/fss_write.config.fss_extended.h index 215ce9705..c5a29b777 100644 --- a/build/stand_alone/fss_write.config.fss_extended.h +++ b/build/stand_alone/fss_write.config.fss_extended.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_extended_list.h b/build/stand_alone/fss_write.config.fss_extended_list.h index 57536a753..2b46edf13 100644 --- a/build/stand_alone/fss_write.config.fss_extended_list.h +++ b/build/stand_alone/fss_write.config.fss_extended_list.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.fss_payload.h b/build/stand_alone/fss_write.config.fss_payload.h index ce360aafe..4ab9d178c 100644 --- a/build/stand_alone/fss_write.config.fss_payload.h +++ b/build/stand_alone/fss_write.config.fss_payload.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/fss_write.config.h b/build/stand_alone/fss_write.config.h index 406054a13..b44dcde98 100644 --- a/build/stand_alone/fss_write.config.h +++ b/build/stand_alone/fss_write.config.h @@ -1491,7 +1491,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/iki_read.config.eki.h b/build/stand_alone/iki_read.config.eki.h index 9d18e3936..3e207ebb0 100644 --- a/build/stand_alone/iki_read.config.eki.h +++ b/build/stand_alone/iki_read.config.eki.h @@ -1392,7 +1392,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/iki_read.config.h b/build/stand_alone/iki_read.config.h index b6756f88e..afc332121 100644 --- a/build/stand_alone/iki_read.config.h +++ b/build/stand_alone/iki_read.config.h @@ -1392,7 +1392,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/iki_write.config.eki.h b/build/stand_alone/iki_write.config.eki.h index 02e837647..3d03e3957 100644 --- a/build/stand_alone/iki_write.config.eki.h +++ b/build/stand_alone/iki_write.config.eki.h @@ -1343,7 +1343,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/iki_write.config.h b/build/stand_alone/iki_write.config.h index 01ea4f280..3832f9a3b 100644 --- a/build/stand_alone/iki_write.config.h +++ b/build/stand_alone/iki_write.config.h @@ -1343,7 +1343,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/status_code.config.fss.h b/build/stand_alone/status_code.config.fss.h index a07a44486..e20ceaf5c 100644 --- a/build/stand_alone/status_code.config.fss.h +++ b/build/stand_alone/status_code.config.fss.h @@ -1461,7 +1461,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/status_code.config.h b/build/stand_alone/status_code.config.h index ea8486fb4..a08336293 100644 --- a/build/stand_alone/status_code.config.h +++ b/build/stand_alone/status_code.config.h @@ -1391,7 +1391,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ #define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner #define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/build/stand_alone/utf8.config.h b/build/stand_alone/utf8.config.h index 65a188020..ec0642738 100644 --- a/build/stand_alone/utf8.config.h +++ b/build/stand_alone/utf8.config.h @@ -1349,7 +1349,7 @@ #define _di_f_utf_character_is_alphabetic_numeric_ #define _di_f_utf_character_is_ascii_ //#define _di_f_utf_character_is_combining_ -#define _di_f_utf_character_is_combining_joinger_ +#define _di_f_utf_character_is_combining_joiner //#define _di_f_utf_character_is_control_ #define _di_f_utf_character_is_control_code_ #define _di_f_utf_character_is_control_format_ diff --git a/level_0/f_fss/c/fss.c b/level_0/f_fss/c/fss.c index 335dde1e1..3c59400ad 100644 --- a/level_0/f_fss/c/fss.c +++ b/level_0/f_fss/c/fss.c @@ -24,6 +24,11 @@ extern "C" { for (f_number_unsigned_t i = 0; i < delimits.used; ++i) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (delimits.array[i] < buffer->used) { buffer->string[delimits.array[i]] = f_fss_placeholder_s.string[0]; } @@ -53,6 +58,11 @@ extern "C" { for (f_number_unsigned_t i = 0; i < delimits.used; ++i) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (delimits.array[i] < buffer->used && delimits.array[i] >= range.start && delimits.array[i] <= range.stop) { buffer->string[delimits.array[i]] = f_fss_placeholder_s.string[0]; } @@ -82,6 +92,11 @@ extern "C" { for (f_number_unsigned_t i = 0; i < before && i < buffer.used; i += macro_f_utf_byte_width(buffer.string[i])) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (buffer.string[i] == f_fss_eol_s.string[0]) { ++(*line); } @@ -111,6 +126,11 @@ extern "C" { for (f_number_unsigned_t i = range.start; i <= range.stop && i < buffer.used; i += macro_f_utf_byte_width(buffer.string[i])) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (buffer.string[i] == f_fss_eol_s.string[0]) { ++(*line); } @@ -171,7 +191,11 @@ extern "C" { : (range.stop - range.start) + 1 ); - if (state->status == F_true) return F_true; + if (state->status == F_true) { + state->status = F_combarudoo; + + return F_true; + } f_fss_fail_utf_to_false(state); @@ -179,6 +203,52 @@ extern "C" { } #endif // _di_f_fss_is_combining_ +#ifndef _di_f_fss_is_combining_joiner_ + f_status_t f_fss_is_combining_joiner(const f_string_static_t buffer, const f_range_t range, f_state_t * const state) { + #ifndef _di_level_0_parameter_checking_ + if (!state) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + state->status = F_data_not; + + return F_false; + } + + state->status = f_utf_is_combining( + buffer.string + range.start, + (range.stop - range.start) + 1 > buffer.used - range.start + ? buffer.used - range.start + : (range.stop - range.start) + 1 + ); + + if (state->status == F_true) { + state->status = F_combarudoo; + + return F_true; + } + + if (F_status_is_error_not(state->status)) { + state->status = f_utf_is_joiner( + buffer.string + range.start, + (range.stop - range.start) + 1 > buffer.used - range.start + ? buffer.used - range.start + : (range.stop - range.start) + 1 + ); + + if (state->status == F_true) { + state->status = F_bound; + + return F_true; + } + } + + f_fss_fail_utf_to_false(state); + + return F_false; + } +#endif // _di_f_fss_is_combining_joiner_ + #ifndef _di_f_fss_is_graph_ f_status_t f_fss_is_graph(const f_string_static_t buffer, const f_range_t range, f_state_t * const state) { #ifndef _di_level_0_parameter_checking_ @@ -206,6 +276,37 @@ extern "C" { } #endif // _di_f_fss_is_graph_ +#ifndef _di_f_fss_is_joiner_ + f_status_t f_fss_is_joiner(const f_string_static_t buffer, const f_range_t range, f_state_t * const state) { + #ifndef _di_level_0_parameter_checking_ + if (!state) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + if (!buffer.used || range.start > range.stop || range.start >= buffer.used) { + state->status = F_data_not; + + return F_false; + } + + state->status = f_utf_is_joiner( + buffer.string + range.start, + (range.stop - range.start) + 1 > buffer.used - range.start + ? buffer.used - range.start + : (range.stop - range.start) + 1 + ); + + if (state->status == F_true) { + state->status = F_bound; + + return F_true; + } + + f_fss_fail_utf_to_false(state); + + return F_false; + } +#endif // _di_f_fss_is_joiner_ + #ifndef _di_f_fss_is_space_ f_status_t f_fss_is_space(const f_string_static_t buffer, const f_range_t range, f_state_t * const state) { #ifndef _di_level_0_parameter_checking_ @@ -319,6 +420,11 @@ extern "C" { for (;; ++range->start) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; @@ -338,8 +444,8 @@ extern "C" { } #endif // _di_f_fss_seek_to_eol_ -#ifndef _di_f_fss_skip_past_combining_ - void f_fss_skip_past_combining(const f_string_static_t buffer, f_range_t * const range, f_state_t * const state) { +#ifndef _di_f_fss_skip_past_combining_joiner_ + void f_fss_skip_past_combining_joiner(const f_string_static_t buffer, f_range_t * const range, f_state_t * const state) { #ifndef _di_level_0_parameter_checking_ if (!state) return; @@ -359,6 +465,11 @@ extern "C" { // Skip past initial place holders. for (;; ++range->start) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; @@ -392,8 +503,16 @@ extern "C" { } } + // 0x1 = last is combining, 0x2 = last is joiner. + uint8_t flag = 0x0; + for (;;) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; @@ -449,11 +568,22 @@ extern "C" { } range->start += macro_f_utf_byte_width(buffer.string[range->start]); + + if (state->status == F_bound) { + flag = 0x1; + } + else if (state->status == F_combarudoo) { + flag = 0x2; + } } // for - state->status = F_okay; + status->status = flag & 0x1 + ? F_bound + : flag & 0x2 + ? F_combarudoo + : F_okay; } -#endif // _di_f_fss_skip_past_combining_ +#endif // _di_f_fss_skip_past_combining_joiner_ #ifndef _di_f_fss_skip_past_delimit_ void f_fss_skip_past_delimit(const f_string_static_t buffer, f_range_t * const range, f_state_t * const state) { @@ -475,6 +605,11 @@ extern "C" { for (;; ++range->start) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; @@ -515,6 +650,11 @@ extern "C" { // Skip past initial place holders. for (;; ++range->start) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; @@ -550,7 +690,7 @@ extern "C" { } } - // Check that the first character is not a combining character or a joiner. + // Check that the first character is not a combining character or a joiner character. state->status = f_utf_is_combining_joiner( buffer.string + previous, (range->stop - previous) + 1 > buffer.used - previous @@ -570,6 +710,11 @@ extern "C" { for (;;) { + if (state->interrupt) { + state->interrupt((void *) state, 0); + if (F_status_set_fine(state->status) == F_interrupt) return; + } + if (range->start >= buffer.used) { state->status = F_okay_eos; diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index 2bd98e299..1355646ec 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -52,6 +52,7 @@ extern "C" { * F_okay on success. * F_data_not on success but buffer.used is 0. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_apply_delimit_ @@ -76,6 +77,7 @@ extern "C" { * F_okay on success. * F_data_not on success but buffer.used is 0. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_apply_delimit_range_ @@ -104,7 +106,8 @@ extern "C" { * F_okay on success. * F_data_not on success but buffer.used is 0 (line is set to 0). * - * F_parameter (with error bit) if a parameter is invalid. + * F_interrupt (with error bit) if stopping due to an interrupt. + * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_count_lines_ extern void f_fss_count_lines(const f_string_static_t buffer, const f_number_unsigned_t before, f_number_unsigned_t * const line, f_state_t * const state); @@ -132,6 +135,7 @@ extern "C" { * F_okay on success. * F_data_not on success but the range.start is greater than buffer.used or buffer.used is 0 (line is set to 0). * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_count_lines_range_ @@ -200,10 +204,11 @@ extern "C" { * A state for providing flags and handling interrupts during long running operations. * * This alters state.status: + * F_combarudoo character in the buffer is a combining character (future versions will provide a more accurate status, like F_combine). * F_data_not on success but nothing is processed. * F_false if the character in the buffer is not a combining character. - * F_true if the character in the buffer is a combining character. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_combining(). @@ -219,6 +224,49 @@ extern "C" { extern f_status_t f_fss_is_combining(const f_string_static_t buffer, const f_range_t range, f_state_t * const state); #endif // _di_f_fss_is_combining_ +/** + * Identify whether or not a character in the buffer is a combining (ASCII or UTF-8) character or a joiner (ASCII or UTF-8) character. + * + * This only checks if the given character is a combining character and does not check what this combines into. + * + * The combining characters combine from right to left. + * It is recommended to use this after testing for other characters, such as f_fss_is_space() or f_fss_is_graph(). + * A combining character can follow any character, even if it is something like a control character. + * This is unclear behavior so a simple strategy is to assume that a combining character results in a graph for anything except a non-combining zero-width character. + * U+0020 followed by U+0301 would result in the combination of the two being considered a graph rather than a space. + * Given that NULL characters are ignored by the general FSS standard, combining characters are not considered to combine into NULL. + * + * @param buffer + * The string to process. + * @param range + * The character at the start position will be checked against the graph. + * @param state + * A state for providing flags and handling interrupts during long running operations. + * + * This alters state.status: + * F_bound character in the buffer is a joiner character (future versions will provide a more accurate status, like F_join). + * F_combarudoo character in the buffer is a combining character (future versions will provide a more accurate status, like F_combine). + * F_data_not on success but nothing is processed. + * F_false if the character in the buffer is not a combining character. + * + * F_interrupt (with error bit) if stopping due to an interrupt. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_is_combining(). + * Errors (with error bit) from: f_utf_is_joiner(). + * + * @return + * F_false if the character in the buffer is not a combining character. + * F_false is returned on any error. + * F_true if the character in the buffer is a combining character. + * + * @see f_utf_is_combining() + * @see f_utf_is_joiner() + */ +#ifndef _di_f_fss_is_combining_joiner_ + extern f_status_t f_fss_is_combining_joiner(const f_string_static_t buffer, const f_range_t range, f_state_t * const state); +#endif // _di_f_fss_is_combining_joiner_ + /** * Identify whether or not a character in the buffer is a graph (ASCII or UTF-8) character. * @@ -236,6 +284,7 @@ extern "C" { * F_false if the character in the buffer is not a graph character. * F_true on success and is a graph character. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_graph(). @@ -251,6 +300,46 @@ extern "C" { extern f_status_t f_fss_is_graph(const f_string_static_t buffer, const f_range_t range, f_state_t * const state); #endif // _di_f_fss_is_graph_ +/** + * Identify whether or not a character in the buffer is a joiner (ASCII or UTF-8) character. + * + * This only checks if the given character is a combining character and does not check what this combines into. + * + * The combining characters combine from right to left. + * It is recommended to use this after testing for other characters, such as f_fss_is_space() or f_fss_is_graph(). + * A combining character can follow any character, even if it is something like a control character. + * This is unclear behavior so a simple strategy is to assume that a combining character results in a graph for anything except a non-combining zero-width character. + * U+0020 followed by U+0301 would result in the combination of the two being considered a graph rather than a space. + * Given that NULL characters are ignored by the general FSS standard, combining characters are not considered to combine into NULL. + * + * @param buffer + * The string to process. + * @param range + * The character at the start position will be checked against the graph. + * @param state + * A state for providing flags and handling interrupts during long running operations. + * + * This alters state.status: + * F_bound character in the buffer is a joiner character (future versions will provide a more accurate status, like F_join). + * F_data_not on success but nothing is processed. + * F_false if the character in the buffer is not a combining character. + * + * F_interrupt (with error bit) if stopping due to an interrupt. + * F_parameter (with error bit) if a parameter is invalid. + * + * Errors (with error bit) from: f_utf_is_joiner(). + * + * @return + * F_false if the character in the buffer is not a combining character. + * F_false is returned on any error. + * F_true if the character in the buffer is a combining character. + * + * @see f_utf_is_joiner() + */ +#ifndef _di_f_fss_is_joiner_ + extern f_status_t f_fss_is_joiner(const f_string_static_t buffer, const f_range_t range, f_state_t * const state); +#endif // _di_f_fss_is_joiner_ + /** * Identify whether or not a character in the buffer is a non-zero-width white space or non-zero-width control (ASCII or UTF-8) character. * @@ -270,6 +359,7 @@ extern "C" { * F_control if the character is a control character (F_false is returned by this function when zero-width or F_true when is both a space and a control character). * F_true on success and is a space character. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_control(). @@ -310,6 +400,7 @@ extern "C" { * F_false if the character in the buffer is not a zero-width character. * F_true if the character in the buffer is a zero-width character. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_zero_width(). @@ -347,6 +438,7 @@ extern "C" { * F_okay_eos on success and EOS was reached. * F_okay_stop on success and stop point was reached. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_seek_to_eol_ @@ -359,7 +451,7 @@ extern "C" { * This will do nothing if the first character is not a combining character and is not a joiner character. * * This skips past place holders. - * + * This does not stop on a place holder (unless it is the end of string or the stop point). * This stops on end of line. * * @param buffer @@ -371,7 +463,9 @@ extern "C" { * A state for providing flags and handling interrupts during long running operations. * * This alters state.status: - * F_okay on success. + * F_okay on success and last skipped (if any) character is neither a combining character nor a joiner character. + * F_bound on success and last skipped character is a joiner character (future versions will provide a more accurate status, like F_join). + * F_combarudoo on success and last skipped character is a combining character (future versions will provide a more accurate status, like F_combine). * F_data_not on success but buffer.used is 0, initial range.start is greater than range.stop, or initial range.start is greater than or equal to buffer.used. * F_okay_eol on success and EOL was reached. * F_okay_eos on success and EOS was reached. @@ -380,15 +474,16 @@ extern "C" { * F_complete_not_utf_eos (with error bit) if unable to get entire UTF-8 sequence due to EOS. * F_complete_not_utf_start (with error bit) if the first character is a combining character. * F_complete_not_utf_stop (with error bit) if unable to get entire UTF-8 sequence due to stop point reached. + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_combining_joiner(). * * @see f_utf_is_combining_joiner() */ -#ifndef _di_f_fss_skip_past_combining_ - extern void f_fss_skip_past_combining(const f_string_static_t buffer, f_range_t * const range, f_state_t * const state); -#endif // _di_f_fss_skip_past_combining_ +#ifndef _di_f_fss_skip_past_combining_joiner_ + extern void f_fss_skip_past_combining_joiner(const f_string_static_t buffer, f_range_t * const range, f_state_t * const state); +#endif // _di_f_fss_skip_past_combining_joiner_ /** * Skip past all delimit placeholders until a non-delimit placeholder is reached. @@ -407,6 +502,7 @@ extern "C" { * F_okay_eos on success and EOS was reached. * F_okay_stop on success and stop point was reached. * + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. */ #ifndef _di_f_fss_skip_past_delimit_ @@ -445,6 +541,7 @@ extern "C" { * F_complete_not_utf_eos (with error bit) if unable to get entire UTF-8 sequence due to EOS. * F_complete_not_utf_start (with error bit) if the first character is a combining or a joiner character. * F_complete_not_utf_stop (with error bit) if unable to get entire UTF-8 sequence due to stop point reached. + * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * * Errors (with error bit) from: f_utf_is_combining_joiner(). diff --git a/level_1/fl_fss/c/fss/basic_list.c b/level_1/fl_fss/c/fss/basic_list.c index a04b3a942..b240f01ca 100644 --- a/level_1/fl_fss/c/fss/basic_list.c +++ b/level_1/fl_fss/c/fss/basic_list.c @@ -329,14 +329,23 @@ extern "C" { state->status = f_memory_array_increase_by(3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) return; + #define ___fl_flag_do_prepend___ 0x1 + #define ___fl_flag_has_graph___ 0x2 + #define ___fl_flag_is_comment___ 0x4 + #define ___fl_flag_is_combining___ 0x8 + #define ___fl_flag_is_combining_graph___ 0xa + #define ___fl_flag_is_joined___ 0x10 + #define ___fl_flag_is_joiner___ 0x20 + #define ___fl_flag_is_joiner_graph___ 0x22 + #define ___fl_flag_is_joinerd___ 0x30 + const f_number_unsigned_t destination_used = destination->used; - uint8_t is_comment = F_false; - uint8_t has_graph = F_false; - uint8_t do_prepend = prepend ? F_true : F_false; + uint8_t flag = prepend ? ___fl_flag_do_prepend___ : 0x0; uint8_t width = 0; f_number_unsigned_t i = 0; + f_number_unsigned_t previous = 0; f_number_unsigned_t slash_count = 0; f_number_unsigned_t start = 0; @@ -347,18 +356,50 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; } - if (content.string[range->start] == f_fss_slash_s.string[0] && !is_comment) { + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(content, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(content, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + + if (content.string[range->start] == f_fss_slash_s.string[0] && !(flag & ___fl_flag_is_comment___)) { slash_count = 1; - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } destination->string[destination->used++] = content.string[range->start]; - has_graph = F_true; + flag |= ___fl_flag_has_graph___; for (++range->start; range->start <= range->stop && range->start < content.used; ++range->start) { @@ -418,17 +459,17 @@ extern "C" { continue; } } - else if (content.string[range->start] == f_fss_basic_list_open_s.string[0] && !is_comment) { + else if (content.string[range->start] == f_fss_basic_list_open_s.string[0] && !(flag & ___fl_flag_is_comment___)) { start = range->start++; - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } - has_graph = F_true; + flag |= ___fl_flag_has_graph___; f_fss_skip_past_space(content, range, state); if (F_status_is_error(state->status)) break; @@ -458,32 +499,48 @@ extern "C" { continue; } - else if (content.string[range->start] == f_fss_comment_s.string[0] && !has_graph) { - is_comment = F_true; + else if (content.string[range->start] == f_fss_comment_s.string[0] && !(flag & ___fl_flag_has_graph___)) { + flag |= ___fl_flag_is_comment___; } else if (content.string[range->start] == f_fss_eol_s.string[0]) { - has_graph = F_false; - is_comment = F_false; + flag = 0x0; } - else { - if (f_fss_is_graph(content, *range, state) == F_false) { - if (F_status_is_error(state->status)) break; - } - else { - has_graph = F_true; + else if (f_fss_is_graph(content, *range, state) == F_false) { + if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(content, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(content, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } } + + if (F_status_is_error(state->status)) break; + + range->start = previous; + } + else { + flag |= ___fl_flag_has_graph___; } if (content.string[range->start] != f_fss_placeholder_s.string[0]) { - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } if (content.string[range->start] == f_fss_eol_s.string[0] && prepend) { - do_prepend = F_true; + flag |= ___fl_flag_do_prepend___; } width = macro_f_utf_byte_width(content.string[range->start]); @@ -536,6 +593,16 @@ extern "C" { else { state->status = F_okay; } + + #undef ___fl_flag_do_prepend___ + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_basic_list_content_write_ @@ -595,9 +662,21 @@ extern "C" { return; } + #define ___fl_flag_has_graph___ 0x1 + #define ___fl_flag_is_comment___ 0x2 + #define ___fl_flag_is_combining___ 0x4 + #define ___fl_flag_is_combining_graph___ 0x5 + #define ___fl_flag_is_joined___ 0x8 + #define ___fl_flag_is_joiner___ 0x10 + #define ___fl_flag_is_joiner_graph___ 0x11 + #define ___fl_flag_is_joinerd___ 0x18 + const f_number_unsigned_t destination_used = destination->used; + + f_number_unsigned_t previous = 0; f_number_unsigned_t slash_count = 0; + uint8_t flag = 0; uint8_t width = 0; // Find the first graph character. @@ -619,8 +698,59 @@ extern "C" { break; } + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(object, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(object, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + if (f_fss_is_graph(object, *range, state) == F_false) { if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(object, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(object, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } + } + + if (F_status_is_error(state->status)) break; + + range->start = previous; } else { break; @@ -770,6 +900,15 @@ extern "C" { else { state->status = F_okay; } + + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_basic_list_object_write_ diff --git a/level_1/fl_fss/c/fss/basic_list.h b/level_1/fl_fss/c/fss/basic_list.h index 5f74cd146..4e704a7e9 100644 --- a/level_1/fl_fss/c/fss/basic_list.h +++ b/level_1/fl_fss/c/fss/basic_list.h @@ -158,7 +158,10 @@ extern "C" { * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). * Errors (with error bit) from: f_memory_array_increase(). @@ -166,7 +169,10 @@ extern "C" { * Errors (with error bit) from: f_string_dynamic_append(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_skip_past_delimit() * @see f_fss_skip_past_space() * @see f_memory_array_increase() @@ -301,14 +307,20 @@ extern "C" { * F_okay_eol (with error bit) after reaching an EOL, which is not supported by the standard. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_is_space(). * Errors (with error bit) from: f_memory_array_increase(). * Errors (with error bit) from: f_memory_array_increase_by(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_is_space() * @see f_memory_array_increase() * @see f_memory_array_increase_by() diff --git a/level_1/fl_fss/c/fss/embedded_list.c b/level_1/fl_fss/c/fss/embedded_list.c index 63d18ccb9..b7f3acadc 100644 --- a/level_1/fl_fss/c/fss/embedded_list.c +++ b/level_1/fl_fss/c/fss/embedded_list.c @@ -595,15 +595,26 @@ extern "C" { return; } + #define ___fl_flag_do_prepend___ 0x1 + #define ___fl_flag_has_eol___ 0x2 + #define ___fl_flag_has_eol_do_prepend___ 0x3 + #define ___fl_flag_has_graph___ 0x4 + #define ___fl_flag_is_comment___ 0x8 + #define ___fl_flag_is_comment_graph___ 0xc + #define ___fl_flag_is_combining___ 0x10 + #define ___fl_flag_is_combining_graph___ 0x14 + #define ___fl_flag_is_joined___ 0x20 + #define ___fl_flag_is_joiner___ 0x40 + #define ___fl_flag_is_joiner_graph___ 0x44 + #define ___fl_flag_is_joinerd___ 0x60 + const f_number_unsigned_t destination_used = destination->used; - uint8_t is_comment = F_false; - uint8_t ends_on_eol = F_false; - uint8_t has_graph = F_false; - uint8_t do_prepend = prepend ? F_true : F_false; + uint8_t flag = prepend ? ___fl_flag_do_prepend___ : 0x0; uint8_t width = 0; f_number_unsigned_t i = 0; + f_number_unsigned_t previous = 0; f_number_unsigned_t r = 0; f_number_unsigned_t slash_count = 0; f_number_unsigned_t start = 0; @@ -615,14 +626,46 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; } - if (content.string[range->start] == f_fss_slash_s.string[0] && !is_comment) { + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(content, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(content, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + + if (content.string[range->start] == f_fss_slash_s.string[0] && !(flag & ___fl_flag_is_comment___)) { slash_count = 1; - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } state->status = f_memory_array_increase(state->step_large, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); @@ -683,7 +726,7 @@ extern "C" { if (F_status_is_error(state->status)) break; if (content.string[range->start] != f_fss_eol_s.string[0]) { - has_graph = F_true; + flag |= ___fl_flag_has_graph___; } continue; @@ -697,10 +740,10 @@ extern "C" { if (content.string[range->start] == f_fss_eol_s.string[0]) { destination->string[destination->used++] = f_fss_eol_s.string[0]; - ends_on_eol = F_true; + flag |= ___fl_flag_has_eol___; } else { - ends_on_eol = F_false; + flag &= ~___fl_flag_has_eol___; } range->start = start + 1; @@ -708,17 +751,17 @@ extern "C" { continue; } } - else if ((content.string[range->start] == f_fss_embedded_list_open_s.string[0] || (!has_graph && content.string[range->start] == f_fss_embedded_list_close_s.string[0])) && !is_comment) { + else if ((content.string[range->start] == f_fss_embedded_list_open_s.string[0] || (!(flag & ___fl_flag_has_graph___) && content.string[range->start] == f_fss_embedded_list_close_s.string[0])) && !(flag & ___fl_flag_is_comment___)) { start = range->start++; - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } - has_graph = F_true; + flag |= ___fl_flag_has_graph___; f_fss_skip_past_space(content, range, state); if (F_status_is_error(state->status)) break; @@ -726,11 +769,10 @@ extern "C" { if (range->start >= content.used || range->start > range->stop || content.string[range->start] == f_fss_eol_s.string[0]) { if (content.string[range->start] == f_fss_eol_s.string[0] && prepend) { - do_prepend = F_true; - ends_on_eol = F_true; + flag |= ___fl_flag_has_eol_do_prepend___; } else { - ends_on_eol = F_false; + flag &= ~___fl_flag_has_eol___; } if (ignore && ignore->used) { @@ -773,34 +815,51 @@ extern "C" { continue; } - else if (content.string[range->start] == f_fss_comment_s.string[0] && !has_graph) { - is_comment = F_true; + else if (content.string[range->start] == f_fss_comment_s.string[0] && !(flag & ___fl_flag_has_graph___)) { + flag |= ___fl_flag_is_comment___; } else if (content.string[range->start] == f_fss_eol_s.string[0]) { - has_graph = F_false; - is_comment = F_false; + flag &= ~___fl_flag_is_comment_graph___; } else if (f_fss_is_graph(content, *range, state) == F_false) { if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(content, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(content, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } + } + + if (F_status_is_error(state->status)) break; + + range->start = previous; } else { - has_graph = F_true; + flag |= ___fl_flag_has_graph___; } if (content.string[range->start] != f_fss_placeholder_s.string[0]) { - if (do_prepend) { + if (flag & ___fl_flag_do_prepend___) { state->status = f_string_dynamic_append(*prepend, destination); if (F_status_is_error(state->status)) break; - do_prepend = F_false; + flag &= ~___fl_flag_do_prepend___; } if (content.string[range->start] == f_fss_eol_s.string[0] && prepend) { - do_prepend = F_true; - ends_on_eol = F_true; + flag |= ___fl_flag_has_eol_do_prepend___; } else { - ends_on_eol = F_false; + flag &= ~___fl_flag_has_eol___; } width = macro_f_utf_byte_width(content.string[range->start]); @@ -827,7 +886,7 @@ extern "C" { state->status = f_memory_array_increase_by(3, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) return; - if (!ends_on_eol) { + if (!(flag & ___fl_flag_has_eol___)) { destination->string[destination->used++] = f_fss_eol_s.string[0]; } @@ -844,6 +903,19 @@ extern "C" { else { state->status = F_okay; } + + #undef ___fl_flag_do_prepend___ + #undef ___fl_flag_has_eol___ + #undef ___fl_flag_has_eol_do_prepend___ + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_comment_graph___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_embedded_list_content_write_ @@ -876,8 +948,7 @@ extern "C" { #endif // _di_level_1_parameter_checking_ f_fss_skip_past_delimit(object, range, state); - if (F_status_is_error(state->status)) return; - if (state->status == F_data_not) return; + if (F_status_is_error(state->status) || state->status == F_data_not) return; if (state->status == F_okay_eos) { state->status = F_data_not_eos; @@ -912,11 +983,22 @@ extern "C" { state->status = f_memory_array_increase_by(4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) return; + #define ___fl_flag_has_graph___ 0x2 + #define ___fl_flag_is_comment___ 0x4 + #define ___fl_flag_is_combining___ 0x8 + #define ___fl_flag_is_combining_graph___ 0xa + #define ___fl_flag_is_joined___ 0x10 + #define ___fl_flag_is_joiner___ 0x20 + #define ___fl_flag_is_joiner_graph___ 0x22 + #define ___fl_flag_is_joinerd___ 0x30 + const f_number_unsigned_t destination_used = destination->used; + + f_number_unsigned_t previous = 0; f_number_unsigned_t slash_count = 0; + uint8_t flag = 0; uint8_t ends_on_space = F_false; - uint8_t width = 0; // Find the first graph character. @@ -927,6 +1009,38 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; } + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(object, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(object, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + if (object.string[range->start] == f_fss_comment_s.string[0]) { // When a comment is found, escape it. @@ -940,6 +1054,25 @@ extern "C" { if (f_fss_is_graph(object, *range, state) == F_false) { if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(object, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(object, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } + } + + if (F_status_is_error(state->status)) break; + + range->start = previous; } else { break; @@ -1116,6 +1249,15 @@ extern "C" { else { state->status = F_okay; } + + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_embedded_list_object_write_ diff --git a/level_1/fl_fss/c/fss/embedded_list.h b/level_1/fl_fss/c/fss/embedded_list.h index 46b291c3b..19210fc2a 100644 --- a/level_1/fl_fss/c/fss/embedded_list.h +++ b/level_1/fl_fss/c/fss/embedded_list.h @@ -209,7 +209,10 @@ extern "C" { * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). * Errors (with error bit) from: f_memory_array_increase(). @@ -217,7 +220,10 @@ extern "C" { * Errors (with error bit) from: f_memory_array_increase_by(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_skip_past_delimit() * @see f_fss_skip_past_space() * @see f_memory_array_increase() @@ -352,14 +358,20 @@ extern "C" { * F_okay_eol (with error bit) after reaching an EOL, which is not supported by the standard. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_is_space(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_memory_array_increase(). * Errors (with error bit) from: f_memory_array_increase_by(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_is_space() * @see f_fss_skip_past_delimit() * @see f_memoy_array_increase() diff --git a/level_1/fl_fss/c/fss/extended_list.c b/level_1/fl_fss/c/fss/extended_list.c index 5da2e51d0..957a31cf9 100644 --- a/level_1/fl_fss/c/fss/extended_list.c +++ b/level_1/fl_fss/c/fss/extended_list.c @@ -274,20 +274,24 @@ extern "C" { state->status = f_memory_array_increase_by(4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) return; - const f_number_unsigned_t destination_used = destination->used; + #define ___fl_flag_do_prepend___ 0x1 + #define ___fl_flag_has_eol___ 0x2 + #define ___fl_flag_has_eol_do_prepend___ 0x3 + #define ___fl_flag_has_graph___ 0x4 + #define ___fl_flag_is_comment___ 0x8 + #define ___fl_flag_is_comment_graph___ 0xc + #define ___fl_flag_is_combining___ 0x10 + #define ___fl_flag_is_combining_graph___ 0x14 + #define ___fl_flag_is_joined___ 0x20 + #define ___fl_flag_is_joiner___ 0x40 + #define ___fl_flag_is_joiner_graph___ 0x44 + #define ___fl_flag_is_joinerd___ 0x60 - #define ___fl_flag_is_comment___ 0x1 - #define ___fl_flag_has_graph___ 0x2 - #define ___fl_flag_is_comment_graph___ 0x3 - #define ___fl_flag_ends_on_eol___ 0x4 - #define ___fl_flag_do_prepend___ 0x8 - #define ___fl_flag_do_prepend_ends_on_eol___ 0xc - #define ___fl_flag_graph_combine___ 0x10 // Is a graph only due to combining character. - #define ___fl_flag_graph_joiner___ 0x20 // Is a graph only due to a joining character. - #define ___fl_flag_graph_joiner_combine___ 0x30 + const f_number_unsigned_t destination_used = destination->used; uint8_t flag = prepend ? ___fl_flag_do_prepend___ : 0x0; + f_number_unsigned_t previous = 0; f_number_unsigned_t r = 0; f_number_unsigned_t start = 0; @@ -300,6 +304,38 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; } + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(content, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(content, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(content, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + if (content.string[range->start] == f_fss_slash_s.string[0] && !(flag & ___fl_flag_is_comment___)) { if (flag & ___fl_flag_do_prepend___) { @@ -379,10 +415,10 @@ extern "C" { if (content.string[range->start] == f_fss_eol_s.string[0]) { destination->string[destination->used++] = f_fss_eol_s.string[0]; - flag |= ___fl_flag_ends_on_eol___; + flag |= ___fl_flag_has_eol___; } else { - flag &= ~___fl_flag_ends_on_eol___; + flag &= ~___fl_flag_has_eol___; } range->start = start + 1; @@ -408,10 +444,10 @@ extern "C" { if (content.string[range->start] == f_fss_eol_s.string[0] || range->start >= content.used || range->start > range->stop) { if (content.string[range->start] == f_fss_eol_s.string[0] && prepend) { - flag |= ___fl_flag_do_prepend_ends_on_eol___; + flag |= ___fl_flag_has_eol_do_prepend___; } else { - flag &= ~___fl_flag_ends_on_eol___; + flag &= ~___fl_flag_has_eol___; } if (ignore && ignore->used) { @@ -463,11 +499,30 @@ extern "C" { else if (f_fss_is_graph(content, *range, state) == F_true) { flag |= ___fl_flag_has_graph___; } - else { + else if (f_fss_is_graph(content, *range, state) == F_false) { + if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(content, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(content, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } + } + if (F_status_is_error(state->status)) break; - // TODO: flag |= ___fl_flag_graph_combine___; - // TODO: flag |= ___fl_flag_graph_joiner___; + range->start = previous; + } + else { + flag |= ___fl_flag_has_graph___; } if (content.string[range->start] != f_fss_placeholder_s.string[0]) { @@ -479,34 +534,20 @@ extern "C" { } if (content.string[range->start] == f_fss_eol_s.string[0] && prepend) { - flag |= ___fl_flag_do_prepend_ends_on_eol___; + flag |= ___fl_flag_has_eol_do_prepend___; } else { - flag &= ~___fl_flag_ends_on_eol___; + flag &= ~___fl_flag_has_eol___; } width = macro_f_utf_byte_width(content.string[range->start]); - // ___fl_flag_graph_combine___ and ___fl_flag_graph_joiner___ are only set if the characters can be found, so it is therefore safe to trust that range->start + width can be used. - if (flag & ___fl_flag_graph_combine___) { - width += macro_f_utf_byte_width(content.string[range->start + width]); - } - state->status = f_memory_array_increase_by(width, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) break; memcpy(destination->string + destination->used, content.string + range->start, width); destination->used += width; - - if (flag & ___fl_flag_graph_combine___) { - state->status = f_utf_buffer_increment(content, range, 2); - if (F_status_is_error(state->status)) break; - - flag &= ~___fl_flag_graph_combine___; - - continue; - } } state->status = f_utf_buffer_increment(content, range, 1); @@ -529,7 +570,7 @@ extern "C" { return; } - if (!(flag & ___fl_flag_ends_on_eol___)) { + if (!(flag & ___fl_flag_has_eol___)) { destination->string[destination->used++] = f_fss_eol_s.string[0]; } @@ -547,15 +588,17 @@ extern "C" { state->status = F_okay; } - #undef ___fl_flag_is_comment___ - #undef ___fl_flag_has_graph___ - #undef ___fl_flag_is_comment_graph___ - #undef ___fl_flag_ends_on_eol___ #undef ___fl_flag_do_prepend___ - #undef ___fl_flag_do_prepend_ends_on_eol___ - #undef ___fl_flag_graph_combine___ - #undef ___fl_flag_graph_joiner___ - #undef ___fl_flag_graph_joiner_combine___ + #undef ___fl_flag_has_eol___ + #undef ___fl_flag_has_eol_do_prepend___ + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_extended_list_content_write_ @@ -624,12 +667,25 @@ extern "C" { state->status = f_memory_array_increase_by(4, sizeof(f_char_t), (void **) &destination->string, &destination->used, &destination->size); if (F_status_is_error(state->status)) return; + #define ___fl_flag_has_eol___ 0x2 + #define ___fl_flag_has_eol_do_prepend___ 0x3 + #define ___fl_flag_has_graph___ 0x4 + #define ___fl_flag_is_comment___ 0x8 + #define ___fl_flag_is_comment_graph___ 0xc + #define ___fl_flag_is_combining___ 0x10 + #define ___fl_flag_is_combining_graph___ 0x14 + #define ___fl_flag_is_joined___ 0x20 + #define ___fl_flag_is_joiner___ 0x40 + #define ___fl_flag_is_joiner_graph___ 0x44 + #define ___fl_flag_is_joinerd___ 0x60 + const f_number_unsigned_t destination_used = destination->used; + f_number_unsigned_t previous = 0; f_number_unsigned_t slash_count = 0; + uint8_t flag = 0; uint8_t ends_on_space = F_false; - uint8_t width = 0; // Find the first graph character. @@ -640,6 +696,38 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) break; } + if (flag & ___fl_flag_is_combining___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_combining(object, *range, state) != F_true) { + if (F_status_is_error(state->status)) break; + + flag &= ~___fl_flag_is_combining___; + } + } + + if (flag & ___fl_flag_is_joinerd___) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + + if (f_fss_is_joiner(object, *range, state) == F_true) { + flag |= ___fl_flag_is_joiner___; + flag &= ~___fl_flag_is_joined___; + } + else { + if (F_status_is_error(state->status)) break; + + if (flag & ___fl_flag_is_joiner___) { + flag |= ___fl_flag_is_joined___; + flag &= ~___fl_flag_is_joiner___; + } + else { + flag &= ~___fl_flag_is_joined___; + } + } + } + if (object.string[range->start] == f_fss_comment_s.string[0]) { // When a comment is found, escape it. @@ -653,6 +741,25 @@ extern "C" { if (f_fss_is_graph(object, *range, state) == F_false) { if (F_status_is_error(state->status)) break; + + previous = range->start; + + f_fss_skip_past_delimit(object, range, state); + + if (state->status == F_okay) { + if (f_fss_is_combining_joiner(object, *range, state)) { + if (state->status == F_combarudoo) { + flag |= ___fl_flag_is_combining_graph___; + } + else if (state->status == F_bound) { + flag |= ___fl_flag_is_joiner_graph___; + } + } + } + + if (F_status_is_error(state->status)) break; + + range->start = previous; } else { break; @@ -829,6 +936,17 @@ extern "C" { else { state->status = F_okay; } + + #undef ___fl_flag_has_eol___ + #undef ___fl_flag_has_eol_do_prepend___ + #undef ___fl_flag_has_graph___ + #undef ___fl_flag_is_comment___ + #undef ___fl_flag_is_combining___ + #undef ___fl_flag_is_combining_graph___ + #undef ___fl_flag_is_joined___ + #undef ___fl_flag_is_joiner___ + #undef ___fl_flag_is_joiner_graph___ + #undef ___fl_flag_is_joinerd___ } #endif // _di_fl_fss_extended_list_object_write_ diff --git a/level_1/fl_fss/c/fss/extended_list.h b/level_1/fl_fss/c/fss/extended_list.h index 54cca342a..8c51acd00 100644 --- a/level_1/fl_fss/c/fss/extended_list.h +++ b/level_1/fl_fss/c/fss/extended_list.h @@ -169,7 +169,10 @@ extern "C" { * F_interrupt (with error bit) if stopping due to an interrupt. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). * Errors (with error bit) from: f_memory_array_increase(). @@ -177,7 +180,10 @@ extern "C" { * Errors (with error bit) from: f_memory_array_increase_by(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_skip_past_delimit() * @see f_fss_skip_past_space() * @see f_memory_array_increase() @@ -312,14 +318,20 @@ extern "C" { * F_okay_eol (with error bit) after reaching an EOL, which is not supported by the standard. * F_parameter (with error bit) if a parameter is invalid. * + * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). + * Errors (with error bit) from: f_fss_is_joiner(). * Errors (with error bit) from: f_fss_is_space(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_memory_array_increase(). * Errors (with error bit) from: f_memory_array_increase_by(). * Errors (with error bit) from: f_utf_buffer_increment(). * + * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() + * @see f_fss_is_joiner() * @see f_fss_is_space() * @see f_fss_skip_past_delimit() * @see f_memory_array_increase() diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 20741781f..61c362f41 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -12,6 +12,7 @@ extern "C" { if (F_status_is_error(state->status) || state->status == F_data_not) return; if (state->status == F_okay_eol) { + // Move the start position to after the EOL. ++range->start; state->status = F_fss_found_object_not; @@ -25,16 +26,21 @@ extern "C" { return; } - // Save the delimits used position in case of unterminated quote. const f_number_unsigned_t delimits_used = delimits->used; - - // Begin the search. const f_number_unsigned_t begin = range->start; - found->start = range->start; + + f_number_unsigned_t previous = 0; + + found->start = begin; // Ignore all comment lines. - if ((flag & 0x1) && buffer.string[range->start] == f_fss_comment_s.string[0]) { - f_fss_seek_to_eol(buffer, range, state); + if ((flag & 0x1) && buffer.string[begin] == f_fss_comment_s.string[0]) { + state->status = f_utf_buffer_increment(buffer, range, 1); + + if (state->status == F_okay) { + f_fss_skip_past_delimit(buffer, range, state); + } + if (F_status_is_error(state->status)) return; if (range->start >= buffer.used || range->start > range->stop) { @@ -43,23 +49,36 @@ extern "C" { return; } - // Move the start position to after the EOL. - ++range->start; - state->status = F_fss_found_object_not; + if (f_fss_is_combining_joiner(buffer, *range, state) == F_false) { + if (F_status_is_error_not(state->status)) { + f_fss_seek_to_eol(buffer, range, state); + } - return; + if (F_status_is_error(state->status)) return; + + if (range->start >= buffer.used || range->start > range->stop) { + state->status = range->start >= buffer.used ? F_data_not_eos : F_data_not_stop; + + return; + } + + // Move the start position to after the EOL. + ++range->start; + state->status = F_fss_found_object_not; + + return; + } + + range->start = begin; } - // Handle quote support. - f_char_t quote_found = 0; // TODO: check if quote has combining characters? + f_char_t quote_found = 0; if (quote) *quote = f_fss_quote_type_none_e; // Identify where the object begins. if (buffer.string[range->start] == f_fss_slash_s.string[0]) { - f_number_unsigned_t first_slash = range->start; - - found->start = range->start; + f_number_unsigned_t first_slash = found->start = range->start; state->status = f_utf_buffer_increment(buffer, range, 1); @@ -71,41 +90,46 @@ extern "C" { if (F_status_is_error(state->status)) return; } - if (f_fss_is_zero_width(buffer, *range, state) == F_false) { - if (F_status_is_error(state->status)) return; - } - else { + if (buffer.string[range->start] == f_fss_placeholder_s.string[0]) { state->status = f_utf_buffer_increment(buffer, range, 1); if (F_status_is_error(state->status)) return; continue; } - if (buffer.string[range->start] != f_fss_slash_s.string[0]) { - if (f_fss_is_space(buffer, *range, state) == F_false) { + if (f_fss_is_combining_joiner(buffer, *range, state) == F_false) { + if (F_status_is_error(state->status)) return; + + if (f_fss_is_zero_width(buffer, *range, state) == F_false) { if (F_status_is_error(state->status)) return; - } - // Found the end of the object while processing the slash for potential delimits. - if (state->status == F_true) { - if (range->start > begin) { - found->stop = range->start - 1; - } - else { - found->start = 1; - found->stop = 0; - } + if (buffer.string[range->start] != f_fss_slash_s.string[0]) { + if (f_fss_is_space(buffer, *range, state) == F_false) { + if (F_status_is_error(state->status)) return; + } - state->status = f_utf_buffer_increment(buffer, range, 1); + // Found the end of the object while processing the slash for potential delimits. + if (state->status == F_true) { + if (range->start > begin) { + found->stop = range->start - 1; + } + else { + found->start = 1; + found->stop = 0; + } - if (F_status_is_error_not(state->status)) { - state->status = buffer.string[range->start] == f_fss_eol_s.string[0] ? F_fss_found_object_content_not : F_fss_found_object; - } + state->status = f_utf_buffer_increment(buffer, range, 1); - return; - } + if (F_status_is_error_not(state->status)) { + state->status = buffer.string[range->start] == f_fss_eol_s.string[0] ? F_fss_found_object_content_not : F_fss_found_object; + } - break; + return; + } + + break; + } + } } state->status = f_utf_buffer_increment(buffer, range, 1); @@ -139,7 +163,7 @@ extern "C" { } } else if (!(flag & 0x2) && (buffer.string[range->start] == f_fss_quote_single_s.string[0] || buffer.string[range->start] == f_fss_quote_double_s.string[0] || buffer.string[range->start] == f_fss_quote_grave_s.string[0])) { - quote_found = buffer.string[range->start]; + quote_found = buffer.string[range->start]; // TODO: check for combining and joiner. found->start = ++range->start; } @@ -148,7 +172,6 @@ extern "C" { f_number_unsigned_t first_slash = 0; f_number_unsigned_t slash_count = 0; f_number_unsigned_t location = 0; - f_number_unsigned_t previous = 0; while (range->start <= range->stop && range->start < buffer.used) { @@ -157,6 +180,8 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) return; } + // TODO: check for combinign and joiner flags. + if (buffer.string[range->start] == f_fss_slash_s.string[0]) { first_slash = range->start; slash_count = 1; @@ -201,10 +226,11 @@ extern "C" { return; } - if (buffer.string[range->start] == quote_found) { + if (buffer.string[range->start] == quote_found) { // TODO: check for combining and joiner. location = range->start; // Check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote and delimits do not apply. + // TODO: This should check for combining and joining and set flags. if (range->start + 1 <= range->stop && range->start + 1 < buffer.used) { ++range->start; @@ -271,48 +297,42 @@ extern "C" { range->start = location + 1; - while (buffer.string[range->start] == f_fss_placeholder_s.string[0]) { - - if (state->interrupt) { - state->interrupt((void *) state, 0); - if (F_status_set_fine(state->status) == F_interrupt) return; - } - - if (++range->start >= buffer.used) { - state->status = F_okay_eos; - - return; - } - - if (range->start > range->stop) { - state->status = F_okay_stop; - - return; - } - } // while + state->status = f_fss_skip_past_delimit(buffer, range, 1); + if (F_status_is_error(state->status)) return; if (f_fss_is_graph(buffer, *range, state) != F_true) { if (F_status_is_error(state->status)) return; // Anything other than a new line must be checked if a combining or joiner is in the next character. - if (buffer.string[range->start] != f_fss_eol_s.string[0] && range->start <= range->stop && range->start < buffer.used) { + // TODO: review this logic. + if (buffer.string[range->start] != f_fss_eol_s.string[0]) { previous = range->start; state->status = f_utf_buffer_increment(buffer, range, 1); if (F_status_is_error(state->status)) return; - state->status = f_utf_is_combining_joiner( - buffer.string + range->start, - (range->stop - range->start) + 1 > buffer.used - range->start - ? buffer.used - range->start - : (range->stop - range->start) + 1 - ); - - // When status is F_true, then this is a combining or joiner that causes the previous character to be treated as a graph. - if (state->status == F_false) { - range->start = previous; - } else if (F_status_is_error(state->status)) { - return; + if (state->status == F_okay) { + f_fss_skip_past_delimit(buffer, range, state); + if (F_status_is_error(state->status)) return; + + if (state->status == F_okay) { + f_fss_is_combining_joiner(buffer, *range, state); + if (F_status_is_error(state->status)) return; + } + + // TODO: the status is F_combarudoo for combining and F_bound for joiner. + + // Swap the status to represent F_true for is graph and otherwise for not is graph. + if (state->status == F_true) { + range->start = previous; + state->status = F_false; + } + else { + state->status = F_true; + } + } + else { + state->status = F_true; } } } @@ -573,6 +593,9 @@ extern "C" { return; } + else { + // TODO: check for combining and joiner and set flag. + } state->status = f_utf_buffer_increment(buffer, range, 1); if (F_status_is_error(state->status)) return; @@ -602,10 +625,31 @@ extern "C" { if (F_status_set_fine(state->status) == F_interrupt) return; } - if (f_fss_is_space(buffer, *range, state) == F_false) { + f_fss_skip_past_delimit(object, range, state); + if (F_status_is_error(state->status)) break; + if (range->start > range->stop || range->start >= buffer.used) break; + + if (f_fss_is_combining_joiner(buffer, *range, state) == F_true) { + f_fss_skip_past_combining_joiner(buffer, range, state); + if (F_status_is_error(state->status)) return; + + if (state->status == F_combarudoo) { + state->status = f_utf_buffer_increment(buffer, range, 2); + if (F_status_is_error(state->status)) return; + + continue; + } + } + else if (F_status_is_error(state->status)) { + return; + } + else if (f_fss_is_space(buffer, *range, state) == F_false) { if (F_status_is_error(state->status)) return; } else { + // TODO: Set internal flag here for designating that a space is found. + // The combining/joiner check above should check for this flag so that. + // If the flag is already set, then decrement/reset back to space position (maybe create a peek or similar function to check?). break; } diff --git a/level_1/fl_fss/c/private-fss.h b/level_1/fl_fss/c/private-fss.h index 6a5ce2009..05b3b01fd 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -70,11 +70,10 @@ extern "C" { * * Errors (with error bit) from: f_memory_array_increase(). * Errors (with error bit) from: f_memory_array_increase_by(). - * Errors (with error bit) from: f_fss_is_combining(). + * Errors (with error bit) from: f_fss_is_combining_joiner(). * Errors (with error bit) from: f_fss_is_graph(). * Errors (with error bit) from: f_fss_is_space(). * Errors (with error bit) from: f_fss_is_zero_width(). - * Errors (with error bit) from: f_fss_skip_past_combining(). * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). * Errors (with error bit) from: f_utf_buffer_increment(). @@ -82,11 +81,10 @@ extern "C" { * * @see f_memory_array_increase() * @see f_memory_array_increase_by() - * @see f_fss_is_combining() + * @see f_fss_is_combining_joiner() * @see f_fss_is_graph() * @see f_fss_is_space() * @see f_fss_is_zero_width() - * @see f_fss_skip_past_combining() * @see f_fss_skip_past_delimit() * @see f_fss_skip_past_space() * @see f_utf_buffer_increment() @@ -157,7 +155,7 @@ extern "C" { * Set to NULL to not use. * * @see f_fss_is_space() - * @see f_fss_skip_past_combining() + * @see f_fss_skip_past_combining_joiner() * @see f_fss_skip_past_delimit() * @see f_fss_skip_past_space() * @see f_memory_array_increase() diff --git a/specifications/fss.txt b/specifications/fss.txt index 53a570338..b714e36a0 100644 --- a/specifications/fss.txt +++ b/specifications/fss.txt @@ -1,7 +1,7 @@ # fss-0002 iki-0000 # # license open-standard-license-1.0-or-later -# version 2026/06/20 +# version 2026/06/27 # # This file (assumed to be named fss.txt) can be more easily read using the following iki_read commands: # iki_read fss.txt +Q -w -rrrrrrrr anti-KISS anti-KISS ASCII ASCII BOM BOM FSS FSS KISS KISS UTF-8 UTF-8 URL URL XML XML -WWW character "'" "'" code '"' '"' italic '"' '"' @@ -134,6 +134,7 @@ Featureless Settings Specifications: This delimit only applies to the start of a comment (the pound character:"#" character) as there is no terminating character for a comment (other than a new line character:"\n"). A line containing a valid comment is in its entirety ignored. This means that if there is white space before the designation symbol (the pound character:"#" character) then that white space is ignored. + Comments follow the standard combining and joiner rules. Unless otherwise specified, all designation characters italic:"must" represent ASCII:"American Standard Code for Information Interchange" codes. With designation characters being any character code used to designate how to identify an Object or Content (such as a colon character:":" at the end of a basic list).