From e6cf07bb1c9b55fb8181661d081e42f413294188 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Mon, 19 Oct 2020 23:55:53 -0500 Subject: [PATCH] Update: FSS should allow caller to determine when to apply delimits. Instead of automatically applying the delimits, pass the delimits to the caller. Let the caller decide when or when not to apply the delimits. Provide functions to help in this regard. The FSS read programs will need a new parameter to allow for designating to or not to apply delimits. This is particularly complex when it comes to FSS-0003 (Extended List) due to the nesting. This change gave me the opportunity to review the FSS read functions, to a certain extent. Code cleanup changes are included in this commit. Also add status codes: F_rrange, F_range_not, and F_utf_not. --- build/level_0/settings | 2 +- build/monolithic/settings | 2 +- level_0/f_fss/c/fss-common.h | 24 +- level_0/f_fss/c/fss.c | 262 +++++++++---- level_0/f_fss/c/fss.h | 91 ++++- level_0/f_fss/c/fss_delimit.h | 82 ++++ level_0/f_fss/c/fss_nest.h | 32 +- level_0/f_fss/data/build/settings | 2 +- level_0/f_status/c/status.h | 3 + level_1/fl_fss/c/fss_basic.c | 88 ++--- level_1/fl_fss/c/fss_basic.h | 32 +- level_1/fl_fss/c/fss_basic_list.c | 257 +++++++------ level_1/fl_fss/c/fss_basic_list.h | 16 +- level_1/fl_fss/c/fss_extended.c | 60 ++- level_1/fl_fss/c/fss_extended.h | 31 +- level_1/fl_fss/c/fss_extended_list.c | 411 +++++++++++---------- level_1/fl_fss/c/fss_extended_list.h | 15 +- level_1/fl_fss/c/fss_macro.h | 189 +--------- level_1/fl_fss/c/private-fss.c | 343 +++++++++-------- level_1/fl_fss/c/private-fss.h | 125 +++++-- level_1/fl_status/c/status.c | 9 + level_1/fl_status/c/status.h | 6 + level_2/fll_fss/c/fss_basic.c | 7 +- level_2/fll_fss/c/fss_basic.h | 5 +- level_2/fll_fss/c/fss_basic_list.c | 8 +- level_2/fll_fss/c/fss_basic_list.h | 5 +- level_2/fll_fss/c/fss_extended.c | 7 +- level_2/fll_fss/c/fss_extended.h | 5 +- level_2/fll_fss/c/fss_extended_list.c | 8 +- level_2/fll_fss/c/fss_extended_list.h | 5 +- level_2/fll_status/c/status.c | 15 + .../fss_basic_list_read/c/fss_basic_list_read.c | 8 +- .../c/private-fss_basic_list_read.c | 30 +- .../c/private-fss_basic_list_read.h | 4 +- level_3/fss_basic_read/c/fss_basic_read.c | 8 +- level_3/fss_basic_read/c/private-fss_basic_read.c | 30 +- level_3/fss_basic_read/c/private-fss_basic_read.h | 4 +- .../c/fss_extended_list_read.c | 7 +- .../c/private-fss_extended_list_read.c | 37 +- .../c/private-fss_extended_list_read.h | 16 +- level_3/fss_extended_read/c/fss_extended_read.c | 14 +- .../c/private-fss_extended_read.c | 30 +- .../c/private-fss_extended_read.h | 4 +- 43 files changed, 1370 insertions(+), 969 deletions(-) create mode 100644 level_0/f_fss/c/fss_delimit.h diff --git a/build/level_0/settings b/build/level_0/settings index 4725621..770c3fc 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -22,7 +22,7 @@ build_libraries -lc build_libraries-level build_sources_library account.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c private-print.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c build_sources_program -build_sources_headers account.h account-common.h color.h console.h console-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h file.h file-common.h fss.h fss-common.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h type.h type_array.h utf.h utf-common.h +build_sources_headers account.h account-common.h color.h console.h console-common.h conversion.h conversion-common.h directory.h directory_type.h directory-common.h environment.h environment-common.h file.h file-common.h fss.h fss-common.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h iki.h iki-common.h memory.h memory_structure.h path.h path-common.h pipe.h print.h serialize.h serialize-common.h signal.h signal-common.h socket.h socket-common.h status.h status_array.h string.h string-common.h string_dynamic.h string_map.h string_quantity.h string_range.h type.h type_array.h utf.h utf-common.h build_sources_script build_sources_setting build_script yes diff --git a/build/monolithic/settings b/build/monolithic/settings index 4e87cda..30ee620 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -22,7 +22,7 @@ build_libraries -lc build_libraries-monolithic build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/private-print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/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_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.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/error.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_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/program.c level_2/status.c build_sources_program -build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-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/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.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/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.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/status_array.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/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.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_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h +build_sources_headers level_0/account.h level_0/account-common.h level_0/color.h level_0/console.h level_0/console-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/file.h level_0/file-common.h level_0/fss.h level_0/fss-common.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/memory.h level_0/memory_structure.h level_0/path.h level_0/path-common.h level_0/pipe.h level_0/print.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/status_array.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/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.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_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h build_sources_script build_sources_setting build_script yes diff --git a/level_0/f_fss/c/fss-common.h b/level_0/f_fss/c/fss-common.h index 989224b..b8129ad 100644 --- a/level_0/f_fss/c/fss-common.h +++ b/level_0/f_fss/c/fss-common.h @@ -122,34 +122,14 @@ extern "C" { /** * Default allocation steps. + * + * Recommended to be set to at least 4 to be UTF-8 friendlier. */ #ifndef _di_f_fss_default_allocation_step_ - // recommended to be set to at least 4 to be UTF-8 friendlier. #define f_fss_default_allocation_step f_memory_default_allocation_step #endif // _di_f_fss_default_allocation_step_ /** - * An array of string locations representing where a delimit was applied or is to be applied with respect to some string. - */ -#ifndef _di_f_fss_delimits_t_ - typedef f_string_ranges_t f_fss_delimits_t; - - #define f_fss_delimits_initialize f_string_ranges_t_initialize - - #define f_macro_fss_delimits_clear(delimits) f_macro_memory_structure_t_clear(delimits) - - #define f_macro_fss_delimits_new(status, delimits) f_macro_string_ranges_t_new(status, delimits) - #define f_macro_fss_delimits_delete(status, delimits) f_macro_string_ranges_t_delete(status, delimits) - #define f_macro_fss_delimits_destroy(status, delimits) f_macro_string_ranges_t_destroy(status, delimits) - - #define f_macro_fss_delimits_delete_simple(delimits) f_macro_string_ranges_t_delete_simple(delimits) - #define f_macro_fss_delimits_destroy_simple(delimits) f_macro_string_ranges_t_destroy_simple(delimits) - - #define f_macro_fss_delimits_resize(status, delimits, new_length) f_macro_string_ranges_t_resize(status, delimits, new_length) - #define f_macro_fss_delimits_adjust(status, delimits, new_length) f_macro_string_ranges_t_adjust(status, delimits, new_length) -#endif // _di_f_fss_delimits_t_ - -/** * Stores information about a particular fss file, otherwise known as its header. * * @todo change this to use a range instead if a length to support multiple sub-headers. diff --git a/level_0/f_fss/c/fss.c b/level_0/f_fss/c/fss.c index 9ddc992..1b422a6 100644 --- a/level_0/f_fss/c/fss.c +++ b/level_0/f_fss/c/fss.c @@ -4,23 +4,55 @@ extern "C" { #endif +#ifndef _di_fl_fss_apply_delimit_ + f_return_status fl_fss_apply_delimit(const f_fss_delimits_t delimits, f_string_static_t *buffer) { + #ifndef _di_level_0_parameter_checking_ + if (!buffer) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + for (f_array_length_t i = 0; i < delimits.used; i++) { + if (delimits.array[i] < buffer->used) { + buffer->string[delimits.array[i]] = f_fss_delimit_placeholder; + } + } // for + + return F_none; + } +#endif // _di_fl_fss_apply_delimit_ + +#ifndef _di_fl_fss_apply_delimit_between_ + f_return_status fl_fss_apply_delimit_between(const f_fss_delimits_t delimits, const f_string_range_t range, f_string_static_t *buffer) { + #ifndef _di_level_0_parameter_checking_ + if (!buffer) return F_status_set_error(F_parameter); + #endif // _di_level_0_parameter_checking_ + + for (f_array_length_t i = 0; i < delimits.used; i++) { + if (delimits.array[i] < buffer->used && delimits.array[i] >= range.start && delimits.array[i] <= range.stop) { + buffer->string[delimits.array[i]] = f_fss_delimit_placeholder; + } + } // for + + return F_none; + } +#endif // _di_fl_fss_apply_delimit_between_ + #ifndef _di_f_fss_count_lines_ f_return_status f_fss_count_lines(const f_string_static_t buffer, const f_string_length_t before, f_string_length_t *line) { #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); - if (before >= buffer.used) return F_status_set_error(F_parameter); if (!line) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - f_string_length_t i = before; + if (before >= buffer.used) { + return F_none; + } - for (; i > 0; i--) { - if (buffer.string[i] == f_string_eol[0]) { + for (f_string_length_t i = before; i > 0; i--) { + if (buffer.string[i] == f_fss_eol) { (*line)++; } } // for - if (buffer.string[0] == f_string_eol[0]) { + if (buffer.string[0] == f_fss_eol) { (*line)++; } @@ -31,23 +63,20 @@ extern "C" { #ifndef _di_f_fss_count_lines_range_ f_return_status f_fss_count_lines_range(const f_string_static_t buffer, const f_string_range_t range, const f_string_length_t before, f_string_length_t *line) { #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); - if (range.start > range.stop) return F_status_set_error(F_parameter); - if (range.start >= buffer.used) return F_status_set_error(F_parameter); - if (before >= buffer.used) return F_status_set_error(F_parameter); - if (before > range.stop) return F_status_set_error(F_parameter); if (!line) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ - f_string_length_t i = before; + if (range.stop < range.start || range.start >= buffer.used || !buffer.used || before >= buffer.used || before > range.stop) { + return F_none; + } - for (; i > range.start; i--) { - if (buffer.string[i] == f_string_eol[0]) { + for (f_string_length_t i = before; i > range.start; i--) { + if (buffer.string[i] == f_fss_eol) { (*line)++; } } // for - if (buffer.string[range.start] == f_string_eol[0]) { + if (buffer.string[range.start] == f_fss_eol) { (*line)++; } @@ -57,12 +86,10 @@ extern "C" { #ifndef _di_f_fss_is_graph_ f_return_status f_fss_is_graph(const f_string_static_t buffer, const f_string_range_t range) { - #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); - if (range.start < 0) return F_status_set_error(F_parameter); - if (range.stop < range.start) return F_status_set_error(F_parameter); - if (range.start >= buffer.used) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + + if (range.stop < range.start || range.start >= buffer.used || !buffer.used) { + return F_false; + } f_string_length_t width_max = (range.stop - range.start) + 1; @@ -76,14 +103,10 @@ extern "C" { #ifndef _di_f_fss_is_space_ f_return_status f_fss_is_space(const f_string_static_t buffer, const f_string_range_t range) { - #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); - if (range.start < 0) return F_status_set_error(F_parameter); - if (range.stop < range.start) return F_status_set_error(F_parameter); - if (range.start >= buffer.used) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ - f_status_t status = F_none; + if (range.stop < range.start || range.start >= buffer.used || !buffer.used) { + return F_false; + } f_string_length_t width_max = (range.stop - range.start) + 1; @@ -91,7 +114,7 @@ extern "C" { width_max = buffer.used - range.start; } - status = f_utf_is_zero_width(buffer.string + range.start, width_max); + f_status_t status = f_utf_is_zero_width(buffer.string + range.start, width_max); if (status != F_false) { if (status == F_true) { @@ -113,12 +136,10 @@ extern "C" { #ifndef _di_f_fss_is_zero_width_ f_return_status f_fss_is_zero_width(const f_string_static_t buffer, const f_string_range_t range) { - #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); - if (range.start < 0) return F_status_set_error(F_parameter); - if (range.stop < range.start) return F_status_set_error(F_parameter); - if (range.start >= buffer.used) return F_status_set_error(F_parameter); - #endif // _di_level_0_parameter_checking_ + + if (range.stop < range.start || range.start >= buffer.used || !buffer.used) { + return F_false; + } f_string_length_t width_max = (range.stop - range.start) + 1; @@ -130,19 +151,37 @@ extern "C" { } #endif // _di_f_fss_is_zero_width_ -#ifndef _di_f_fss_shift_delimiters_ - f_return_status f_fss_shift_delimiters(f_string_dynamic_t *buffer, const f_string_range_t range) { +#ifndef _di_f_fss_seek_to_eol_ + f_return_status f_fss_seek_to_eol(const f_string_dynamic_t buffer, 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_ + + for (;; range->start++) { + if (range->start >= buffer.used) return F_none_eos; + if (range->start > range->stop) return F_none_stop; + if (buffer.string[range->start] == f_fss_eol) break; + } // for + + return F_none; + } +#endif // _di_f_fss_seek_to_eol_ + +#ifndef _di_f_fss_shift_delimit_ + f_return_status f_fss_shift_delimit(const f_string_range_t range, f_string_dynamic_t *buffer) { #ifndef _di_level_0_parameter_checking_ - if (!buffer->used) return F_status_set_error(F_parameter); - if (range.start < 0) return F_status_set_error(F_parameter); - if (range.stop < range.start) return F_status_set_error(F_parameter); - if (range.start >= buffer->used) return F_status_set_error(F_parameter); + if (!buffer) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (range.stop < range.start || range.start >= buffer->used || !buffer->used) { + return F_none; + } + f_string_length_t position = 0; f_string_length_t distance = 0; - unsigned short utf_width = 0; - unsigned short i = 0; + + uint8_t utf_width = 0; + uint8_t i = 0; position = range.start; @@ -152,7 +191,7 @@ extern "C" { distance++; } - // do not waste time trying to process what is only going to be replaced with a delimit placeholder + // do not waste time trying to process what is only going to be replaced with a delimit placeholder. if (position + distance >= buffer->used || position + distance > range.stop) { break; } @@ -167,16 +206,17 @@ extern "C" { } if (distance > 0) { - while (utf_width > 0) { + while (utf_width) { + buffer->string[position] = buffer->string[position + distance]; utf_width--; position++; - } + } // while } } else { - // shift everything down one for each placeholder found + // shift everything down one for each delimit placeholder found. if (distance > 0) { buffer->string[position] = buffer->string[position + distance]; } @@ -187,6 +227,7 @@ extern "C" { if (distance > 0) { while (position < buffer->used + distance && position <= range.stop) { + buffer->string[position] = f_fss_delimit_placeholder; position++; } @@ -194,17 +235,38 @@ extern "C" { return F_none; } -#endif // _di_f_fss_shift_delimiters_ +#endif // _di_f_fss_shift_delimit_ + +#ifndef _di_f_fss_skip_past_delimit_ + f_return_status f_fss_skip_past_delimit(const f_string_static_t buffer, 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_ + + for (;; range->start++) { + if (range->start >= buffer.used) return F_none_eos; + if (range->start > range->stop) return F_none_stop; + if (buffer.string[range->start] != f_fss_delimit_placeholder) break; + } // for + + return F_none; + } +#endif // _di_f_fss_skip_past_delimit_ #ifndef _di_f_fss_skip_past_space_ f_return_status f_fss_skip_past_space(const f_string_static_t buffer, f_string_range_t *range) { #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (range->start > range->stop) { + return F_none_stop; + } + + if (range->start >= buffer.used || !buffer.used) { + return F_none_eos; + } + f_status_t status = F_none; uint8_t width = 0; @@ -215,15 +277,21 @@ extern "C" { } for (;;) { - if (buffer.string[range->start] == f_string_eol[0]) { + + if (buffer.string[range->start] == f_fss_eol) { return F_none_eol; } if (buffer.string[range->start] == f_fss_delimit_placeholder) { range->start++; - if (range->start >= buffer.used) return F_none_eos; - if (range->start > range->stop) return F_none_stop; + if (range->start >= buffer.used) { + return F_none_eos; + } + + if (range->start > range->stop) { + return F_none_stop; + } continue; } @@ -245,19 +313,30 @@ extern "C" { if (!width) { width = 1; } - // Do not operate on UTF-8 fragments that are not the first byte of the character. else if (width == 1) { + + // Do not operate on UTF-8 fragments that are not the first byte of the character. return F_status_set_error(F_incomplete_utf); } else { - if (range->start + width >= buffer.used) return F_status_set_error(F_incomplete_utf_eos); - if (range->start + width > range->stop) return F_status_set_error(F_incomplete_utf_stop); + if (range->start + width >= buffer.used) { + return F_status_set_error(F_incomplete_utf_eos); + } + + if (range->start + width > range->stop) { + return F_status_set_error(F_incomplete_utf_stop); + } } range->start += width; - if (range->start >= buffer.used) return F_none_eos; - if (range->start > range->stop) return F_none_stop; + if (range->start >= buffer.used) { + return F_none_eos; + } + + if (range->start > range->stop) { + return F_none_stop; + } width_max = (range->stop - range->start) + 1; @@ -273,16 +352,23 @@ extern "C" { #ifndef _di_f_fss_skip_past_non_graph_ f_return_status f_fss_skip_past_non_graph(const f_string_static_t buffer, f_string_range_t *range) { #ifndef _di_level_0_parameter_checking_ - if (!buffer.used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (range->start > range->stop) { + return F_none_stop; + } + + if (range->start >= buffer.used || !buffer.used) { + return F_none_eos; + } + f_status_t status = F_none; - unsigned short width = 0; + uint8_t width = 0; f_string_length_t width_max = (range->stop - range->start) + 1; + f_string_length_t next = 0; + f_string_length_t next_width_max = 0; if (width_max > buffer.used - range->start) { width_max = buffer.used - range->start; @@ -294,6 +380,7 @@ extern "C" { status = f_utf_is_graph(buffer.string + range->start, width_max); if (status == F_true) { + // stop at a graph. break; } @@ -301,13 +388,16 @@ extern "C" { status = f_utf_is_zero_width(buffer.string + range->start, width_max); if (status == F_true) { - f_string_length_t next_width_max = 0; + next_width_max = 0; + next = range->start + 1; - for (f_string_length_t next = range->start + 1; next < buffer.used && next <= range->stop; next += f_macro_utf_byte_width_is(buffer.string[next])) { + for (; next < buffer.used && next <= range->stop; next += f_macro_utf_byte_width_is(buffer.string[next])) { next_width_max = (range->stop - next) + 1; status = f_utf_is_graph(buffer.string + next, width_max); + if (status == F_true) { + // treat zero-width as a graph when preceding a graph. return F_none; } @@ -315,47 +405,67 @@ extern "C" { status = f_utf_is_zero_width(buffer.string + next, width_max); if (status == F_true) { + // seek until a non-zero-width is reached. continue; } else if (status == F_false) { + // treat zero-width as a non-graph when preceding a non-graph (that is not a zero-width). break; } - else if (F_status_is_error(status)) return status; + else if (F_status_is_error(status)) { + return status; + } + } + else if (F_status_is_error(status)) { + return status; } - else if (F_status_is_error(status)) return status; } // for } else if (status == F_false) { + // continue on when non-graph and non-zero-width. break; } - else if (F_status_is_error(status)) return status; + else if (F_status_is_error(status)) { + return status; + } + } + else if (F_status_is_error(status)) { + return status; } - else if (F_status_is_error(status)) return status; } - if (F_status_is_error(status)) return status; - width = f_macro_utf_byte_width_is(buffer.string[range->start]); if (!width) { width = 1; } - // Do not operate on UTF-8 fragments that are not the first byte of the character. else if (width == 1) { + + // Do not operate on UTF-8 fragments that are not the first byte of the character. return F_status_set_error(F_incomplete_utf); } else { - if (range->start + width >= buffer.used) return F_status_set_error(F_incomplete_utf_eos); - if (range->start + width > range->stop) return F_status_set_error(F_incomplete_utf_stop); + if (range->start + width >= buffer.used) { + return F_status_set_error(F_incomplete_utf_eos); + } + + if (range->start + width > range->stop) { + return F_status_set_error(F_incomplete_utf_stop); + } } range->start += width; - if (range->start >= buffer.used) return F_none_eos; - if (range->start > range->stop) return F_none_stop; + if (range->start >= buffer.used) { + return F_none_eos; + } + + if (range->start > range->stop) { + return F_none_stop; + } width_max = (range->stop - range->start) + 1; diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index 2a3e45e..44e44c5 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -25,6 +25,7 @@ // fll-0 fss includes #include +#include #include #include #include @@ -35,6 +36,44 @@ extern "C" { #endif /** + * Replace all 1-byte character locations specified by the delimits within the given buffer by a delimit placeholder. + * + * Any delimits out of range (beyond the buffer.used) are ignored. + * + * @param delimits + * An array of locations containing the delimits to apply within the buffer. + * @param buffer + * The string to process. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_apply_delimit_ + extern f_return_status fl_fss_apply_delimit(const f_fss_delimits_t delimits, f_string_static_t *buffer); +#endif // _di_fl_fss_apply_delimit_ + +/** + * Replace all 1-byte character locations specified by the delimits within the given buffer by a delimit placeholder if within the given range. + * + * If the delimits are found to be (inclusively) within the range specified by range, then those delimits are applied. + * + * @param delimits + * An array of locations containing the delimits to apply within the buffer. + * @param range + * The range in which to restrict which delimits to apply. + * @param buffer + * The string to process. + * + * @return + * F_none on success. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_apply_delimit_between_ + extern f_return_status fl_fss_apply_delimit_between(const f_fss_delimits_t delimits, const f_string_range_t range, f_string_static_t *buffer); +#endif // _di_fl_fss_apply_delimit_between_ + +/** * Count the number of new lines from the buffer before the given location. * * Use this to calculate where a given range exists in relation to a line. @@ -153,25 +192,65 @@ extern "C" { #endif // _di_f_fss_is_zero_width_ /** - * Shift all of the delimiters to the end of the used buffer. + * Seek until an EOL character is reached. + * + * @param buffer + * The string to process. + * @param range + * The start and stop positions in the buffer being processed. + * This increments range->start. + * + * @return + * F_none on success. + * F_none_eos on success and EOS was reached. + * F_none_stop on success and stop point was reached. + * F_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_fss_seek_to_eol_ + extern f_return_status f_fss_seek_to_eol(const f_string_dynamic_t buffer, f_string_range_t *range); +#endif // _di_f_fss_seek_to_eol_ + +/** + * Shift all of the delimit placeholders to the end of the used buffer. * * This allows one to do a printf on the dynamic string without the delimiters arbitrarily stopping the output. * No reallocations are performed, this will only shift characters. * + * @param range + * A restriction on where within the buffer the shifting happens. * @param buffer * The string to process. * This gets updated. - * @param range - * A restriction on where within the buffer the shifting happens. * * @return * F_none on success. + * F_none_eos on success and EOS was reached. + * F_none_stop on success and stop point was reached. + * F_parameter (with error bit) if a parameter is invalid. * F_utf (with error bit) if UTF-8 cannot be fully processed (buffer or range range not long enough). + */ +#ifndef _di_f_fss_shift_delimit_ + extern f_return_status f_fss_shift_delimit(const f_string_range_t range, f_string_dynamic_t *buffer); +#endif // _di_f_fss_shift_delimit_ + +/** + * Skip past all delimit placeholders until a non-delimit placeholder is reached. + * + * @param buffer + * The string to process. + * @param range + * The start and stop positions in the buffer being processed. + * This increments range->start. + * + * @return + * F_none on success. + * F_none_eos on success and EOS was reached. + * F_none_stop on success and stop point was reached. * F_parameter (with error bit) if a parameter is invalid. */ -#ifndef _di_f_fss_shift_delimiters_ - extern f_return_status f_fss_shift_delimiters(f_string_dynamic_t *buffer, const f_string_range_t range); -#endif // _di_f_fss_shift_delimiters_ +#ifndef _di_f_fss_skip_past_delimit_ + extern f_return_status f_fss_skip_past_delimit(const f_string_static_t buffer, f_string_range_t *range); +#endif // _di_f_fss_skip_past_delimit_ /** * Skip past all whitespace and control characters, except newline. diff --git a/level_0/f_fss/c/fss_delimit.h b/level_0/f_fss/c/fss_delimit.h new file mode 100644 index 0000000..2eda779 --- /dev/null +++ b/level_0/f_fss/c/fss_delimit.h @@ -0,0 +1,82 @@ +/** + * FLL - Level 0 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgplv2.1 + * + * Defines set data to be used for/by project fss. + * + * This is auto-included by fss.h and should not need to be explicitly included. + */ +#ifndef _F_fss_delimit_h +#define _F_fss_delimit_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Designate an fss delimit location. + */ +#ifndef _di_f_fss_delimit_t_ + typedef f_string_length_t f_fss_delimit_t; +#endif // _di_f_fss_delimit_t_ + +/** + * An array of f_fss_delimit_t. + * + * array: the array of fss quote. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_fss_delimits_t_ + typedef f_string_lengths_t f_fss_delimits_t; + + #define f_fss_delimits_t_initialize f_string_lengths_t_initialize + + #define f_macro_fss_delimits_t_clear(delimits) f_macro_string_lengths_t_clear(delimits) + + #define f_macro_fss_delimits_t_new(status, delimits, length) f_macro_string_lengths_t_new(status, delimits, length) + + #define f_macro_fss_delimits_t_delete(status, delimits) f_macro_string_lengths_t_delete(status, delimits) + #define f_macro_fss_delimits_t_destroy(status, delimits) f_macro_string_lengths_t_destroy(status, delimits) + + #define f_macro_fss_delimits_t_delete_simple(delimits) f_macro_string_lengths_t_delete_simple(delimits) + #define f_macro_fss_delimits_t_destroy_simple(delimits) f_macro_string_lengths_t_destroy_simple(delimits) + + #define f_macro_fss_delimits_t_resize(status, delimits, new_length) f_macro_string_lengths_t_resize(status, delimits, new_length) + #define f_macro_fss_delimits_t_adjust(status, delimits, new_length) f_macro_string_lengths_t_adjust(status, delimits, new_length) +#endif // _di_f_fss_delimits_t_ + +/** + * An array of f_fss_delimits_t. + * + * array: the array of fss quotes. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_fss_delimitss_t_ + typedef f_string_lengthss_t f_fss_delimitss_t; + + #define f_fss_delimitss_t_initialize f_f_string_lengthss_t_initialize + + #define f_macro_fss_delimitss_t_clear(quotess) f_macro_string_lengthss_t_clear(quotess) + + #define f_macro_fss_delimitss_t_new(status, quotess, length) f_macro_string_lengthss_t_new(status, quotess, length) + + #define f_macro_fss_delimitss_t_delete(status, quotess) f_macro_string_lengthss_t_delete(status, quotess) + #define f_macro_fss_delimitss_t_destroy(status, quotess) f_macro_string_lengthss_t_destroy(status, quotess) + + #define f_macro_fss_delimitss_t_delete_simple(quotess) f_macro_string_lengthss_t_delete_simple(quotess) + #define f_macro_fss_delimitss_t_destroy_simple(quotess) f_macro_string_lengthss_t_destroy_simple(quotess) + + #define f_macro_fss_delimitss_t_resize(status, quotess, new_length) f_macro_string_lengthss_t_resize(status, quotess, new_length) + #define f_macro_fss_delimitss_t_adjust(status, quotess, new_length) f_macro_string_lengthss_t_adjust(status, quotess, new_length) +#endif // _di_f_fss_delimitss_t_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_fss_delimit_h diff --git a/level_0/f_fss/c/fss_nest.h b/level_0/f_fss/c/fss_nest.h index 2dc4f02..3b8af49 100644 --- a/level_0/f_fss/c/fss_nest.h +++ b/level_0/f_fss/c/fss_nest.h @@ -24,14 +24,18 @@ extern "C" { * To designate that either object or content is non-existent, set start position greater than stop position. * In particular, set start to 1 and stop to 0. * + * This does not have resize/adjust macros due to multiple things to potentially resize. + * Any resizing must be manually performed on each applicable property. + * * object: The object. * content: The content associated with the object. * parent: A location referencing a parrent object or content that this object content is nested under. */ #ifndef _di_fss_item_t_ typedef struct { - f_fss_object_t object; - f_fss_content_t content; + f_fss_object_t object; + f_fss_content_t content; + f_array_length_t parent; } f_fss_item_t; @@ -54,6 +58,7 @@ extern "C" { * Create a new fss item structure. * * This does not deallocate memory, be certain that memory is not allocated before calling this to avoid potential memory leaks. + * This does not allocate to item.delimits, allocation must be performed separately. * * status: the status to return. * structure: the structure to operate on. @@ -115,25 +120,6 @@ extern "C" { item.object.start = 1; \ item.object.stop = 0; \ item.parent = 0; - - /** - * Resize a fss item. - * - * status: the status to return. - * item: the f_fss_item_t structure to operate on. - * new_length: the new size of the array. - */ - #define f_macro_fss_item_t_resize(status, item, new_length) f_macro_fss_content_t_resize(status, item.content, new_length); - - /** - * Adjust a fss item. - * - * status: the status to return. - * item: the f_fss_item_t structure to operate on. - * new_length: the new size of the array. - */ - #define f_macro_fss_item_t_adjust(status, item, new_length) f_macro_fss_content_t_adjust(status, item.content, new_length); - #endif // _di_fss_item_t_ /** @@ -161,8 +147,8 @@ extern "C" { * } * * array: The array of object, their associated content, and their associated parent. - * size: Total amount of allocated space. - * used: Total number of allocated spaces used. + * size: Total amount of allocated space. + * used: Total number of allocated spaces used. */ #ifndef _di_fss_items_t_ typedef struct { diff --git a/level_0/f_fss/data/build/settings b/level_0/f_fss/data/build/settings index 17e0545..e06e7cd 100644 --- a/level_0/f_fss/data/build/settings +++ b/level_0/f_fss/data/build/settings @@ -22,7 +22,7 @@ build_libraries -lc build_libraries-individual -lf_memory -lf_utf build_sources_library fss.c build_sources_program -build_sources_headers fss.h fss-common.h fss_named.h fss_nest.h fss_quote.h fss_set.h +build_sources_headers fss.h fss-common.h fss_delimit.h fss_named.h fss_nest.h fss_quote.h fss_set.h build_sources_script build_sources_setting build_script yes diff --git a/level_0/f_status/c/status.h b/level_0/f_status/c/status.h index 28990f6..e4e30b9 100644 --- a/level_0/f_status/c/status.h +++ b/level_0/f_status/c/status.h @@ -184,6 +184,8 @@ extern "C" { F_process, F_process_too_many, F_prohibited, + F_range, + F_range_not, F_read_only, F_recurse, F_relative, @@ -196,6 +198,7 @@ extern "C" { F_unknown, F_unsupported, F_utf, + F_utf_not, F_value, F_value_not, F_warn, diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index 3cdcbb1..f8bd34c 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -6,83 +6,68 @@ extern "C" { #endif #ifndef _di_fl_fss_basic_object_read_ - f_return_status fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote) { + f_return_status fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used ) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - f_string_lengths_t delimits = f_string_lengths_t_initialize; + const f_array_length_t delimits_used = delimits->used; - status = private_fl_fss_basic_read(F_true, buffer, range, found, quote, &delimits); + f_status_t status = private_fl_fss_basic_read(F_true, buffer, range, found, quote, delimits); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - return status; - } - - if (status == FL_fss_found_object_not || status == F_data_not || status == F_data_not_eos || status == F_data_not_stop) { - f_macro_string_lengths_t_delete_simple(delimits); + delimits->used = delimits_used; return status; } - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - return status; } #endif // _di_fl_fss_basic_object_read_ #ifndef _di_fl_fss_basic_content_read_ - f_return_status fl_fss_basic_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found) { + f_return_status fl_fss_basic_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used ) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - - // delimits must only be applied once a valid object is found. - f_string_lengths_t delimits = f_string_lengths_t_initialize; - - status = f_fss_skip_past_space(*buffer, range); + f_status_t status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; - // return found nothing if this line only contains whitespace and delimit placeholders. if (status == F_none_eol) { range->start++; return FL_fss_found_content_not; } - else if (status == F_none_eos) { + + if (status == F_none_eos) { return F_data_not_eos; } - else if (status == F_none_stop) { + + if (status == F_none_stop) { return F_data_not_stop; } - fl_macro_fss_allocate_content_if_necessary((*found), delimits); + status = private_fl_fss_ranges_increase(found); + if (F_status_is_error(status)) return status; + found->array[found->used].start = range->start; - // search for valid content. for (;; range->start++) { - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + status = f_fss_skip_past_delimit(*buffer, range); + if (F_status_is_error(status)) return status; + + if (status == F_none_eos || status == F_none_stop) { + return status; + } if (buffer->string[range->start] == f_fss_basic_close) break; } // for - // Save the stop length/ - found->array[found->used].stop = range->start - 1; - found->used++; + found->array[found->used++].stop = range->start - 1; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -98,7 +83,7 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - const f_string_length_t used_start = destination->used; + const f_string_length_t destination_used = destination->used; f_status_t status = private_fl_fss_basic_write(F_true, object, quote ? quote : f_fss_delimit_quote_double, range, destination); @@ -106,7 +91,11 @@ extern "C" { // Objects cannot be empty, so write a quoted empty string. const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination); - if (F_status_is_error(status_allocation)) return status_allocation; + + if (F_status_is_error(status_allocation)) { + destination->used = destination_used; + return status_allocation; + } destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; destination->string[destination->used++] = quote ? quote : f_fss_delimit_quote_double; @@ -117,17 +106,29 @@ extern "C" { f_status_t status2 = F_none; if (complete == f_fss_complete_full_trim) { - status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double, used_start, destination); - if (F_status_is_error(status2)) return status2; + status2 = private_fl_fss_basic_write_object_trim(quote ? quote : f_fss_delimit_quote_double, destination_used, destination); + + if (F_status_is_error(status2)) { + destination->used = destination_used; + return status2; + } } status2 = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status2)) return status2; + + if (F_status_is_error(status2)) { + destination->used = destination_used; + return status2; + } destination->string[destination->used++] = f_fss_basic_open; } } + if (F_status_is_error(status)) { + destination->used = destination_used; + } + return status; } #endif // _di_fl_fss_basic_object_write_string_ @@ -141,7 +142,8 @@ extern "C" { f_status_t status = F_none; - fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); + status = f_fss_skip_past_delimit(content, range); + if (F_status_is_error(status)) return status; if (range->start > range->stop || range->start >= content.used) { @@ -164,12 +166,12 @@ extern "C" { status = private_fl_fss_destination_increase_by(destination->used + (range->stop - range->start) + 1, destination); if (F_status_is_error(status)) return status; - const f_string_length_t used_start = destination->used; + const f_string_length_t destination_used = destination->used; for (; range->start <= range->stop && range->start < content.used; range->start++) { if (content.string[range->start] == f_fss_eol) { - destination->used = used_start; + destination->used = destination_used; return F_status_set_error(F_none_eol); } diff --git a/level_1/fl_fss/c/fss_basic.h b/level_1/fl_fss/c/fss_basic.h index 469b921..ef7146d 100644 --- a/level_1/fl_fss/c/fss_basic.h +++ b/level_1/fl_fss/c/fss_basic.h @@ -34,8 +34,7 @@ extern "C" { /** * Read an fss-0000 object. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -50,6 +49,8 @@ extern "C" { * @param quote * This will store whether or not this object is quote and what quote is in use. * Set pointer address to 0 to not use. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -60,28 +61,24 @@ extern "C" { * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). * F_unterminated_group_eos if EOS was reached before the a group termination was reached. * F_unterminated_group_stop if stop point was reached before the a group termination was reached. - * F_buffer_too_large (with error bit) if a buffer is too large. - * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. - * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. - * F_incomplete_utf_stop (with error bit) if the stop location is reached before the complete UTF-8 character can be processed. - * F_memory_reallocation (with error bit) on reallocation error. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) is returned on failure to read/process a UTF-8 character. * * Errors (with error bit) from: f_utf_buffer_increment(). * 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_seek_to_eol(). + * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_basic_object_read_ - extern f_return_status fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote); + extern f_return_status fl_fss_basic_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_fss_delimits_t *delimits); #endif // _di_fl_fss_basic_object_read_ /** * Read an fss-0000 content. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -93,6 +90,8 @@ extern "C" { * A start location past the stop location or buffer used means that the entire range was processed. * @param found * A set of all locations where a valid content was found. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_content on success and content was found (start location is at end of content). @@ -103,21 +102,14 @@ extern "C" { * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). * F_unterminated_group_eos if EOS was reached before the a group termination was reached. * F_unterminated_group_stop if stop point was reached before the a group termination was reached. - * F_buffer_too_large (with error bit) if a buffer is too large. - * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. - * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. - * F_incomplete_utf_stop (with error bit) if the stop location is reached before the complete UTF-8 character can be processed. - * F_memory_reallocation (with error bit) on reallocation error. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) is returned on failure to read/process a UTF-8 character. * * Errors (with error bit) from: f_utf_buffer_increment(). - * 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_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_basic_content_read_ - extern f_return_status fl_fss_basic_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found); + extern f_return_status fl_fss_basic_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_delimits_t *delimits); #endif // _di_fl_fss_basic_content_read_ /** diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index a328590..c331cbe 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -6,33 +6,31 @@ extern "C" { #endif #ifndef _di_fl_fss_basic_list_object_read_ - f_return_status fl_fss_basic_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found) { + f_return_status fl_fss_basic_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; + const f_array_length_t delimits_used = delimits->used; - // delimits must only be applied once a valid object is found. - f_string_lengths_t delimits = f_string_lengths_t_initialize; - - status = f_fss_skip_past_space(*buffer, range); + f_status_t status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; - // return found nothing if this line only contains whitespace and delimit placeholders. if (status == F_none_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_not; } - else if (status == F_none_eos) { + + if (status == F_none_eos) { return F_data_not_eos; } - else if (status == F_none_stop) { + + if (status == F_none_stop) { return F_data_not_stop; } @@ -41,11 +39,21 @@ extern "C" { // ignore all comment lines. if (buffer->string[range->start] == f_fss_comment) { - fl_macro_fss_object_seek_till_newline((*buffer), (*range), delimits, F_data_not_eos, F_data_not_stop); - status = f_utf_buffer_increment(*buffer, range, 1); + status = f_fss_seek_to_eol(*buffer, range); if (F_status_is_error(status)) return status; + if (status == F_none_eos) { + return F_data_not_eos; + } + + if (status == F_none_stop) { + return F_data_not_stop; + } + + // move the start position to after the EOL. + range->start++; + return FL_fss_found_object_not; } @@ -55,7 +63,7 @@ extern "C" { f_string_length_t stop = 0; // identify where the object ends. - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { + while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_fss_eol) { if (buffer->string[range->start] == f_fss_delimit_slash) { first_slash = range->start; @@ -72,7 +80,7 @@ extern "C" { slash_count++; } // for - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); if (buffer->string[range->start] == f_fss_basic_list_open) { stop = range->start - 1; @@ -82,33 +90,39 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } if (status == F_false) break; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { start = range->start; range->start = first_slash; - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_t_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + status = private_fl_fss_delimits_increase_by((slash_count / 2) + 1, delimits); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; } if (slash_count % 2 == 0) { @@ -116,18 +130,20 @@ extern "C" { if (buffer->string[range->start] == f_fss_delimit_slash) { if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; + delimits->array[delimits->used] = range->start; + delimits->used++; } slash_count--; } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } + } // while found->stop = stop; range->start = start + 1; @@ -146,32 +162,46 @@ extern "C" { stop = range->start - 1; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } if (status == F_false) break; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } + } // while - if (buffer->string[range->start] == f_string_eol[0]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_object_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); + if (buffer->string[range->start] == f_fss_eol) { found->stop = stop; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } return FL_fss_found_object; } @@ -180,44 +210,54 @@ extern "C" { } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } } // while // seek to the end of the line when no valid object is found. - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while + status = f_fss_seek_to_eol(*buffer, range); - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + if (status == F_none_eos) { + return F_data_not_eos; + } + + if (status == F_none_stop) { + return F_data_not_stop; + } + + // move the start position to after the EOL. + range->start++; return FL_fss_found_object_not; } #endif // _di_fl_fss_basic_list_object_read_ #ifndef _di_fl_fss_basic_list_content_read_ - f_return_status fl_fss_basic_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found) { + f_return_status fl_fss_basic_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; + const f_array_length_t delimits_used = delimits->used; + + f_status_t status = f_fss_skip_past_delimit(*buffer, range); + if (F_status_is_error(status)) return status; - // delimits must only be applied once a valid object is found. - f_string_lengths_t delimits = f_string_lengths_t_initialize; + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_none_eos, F_none_stop); - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + status = private_fl_fss_ranges_increase(found); + if (F_status_is_error(status)) return status; - fl_macro_fss_allocate_content_if_necessary((*found), delimits); found->array[found->used].start = range->start; f_string_length_t last_newline = range->start; @@ -230,14 +270,14 @@ extern "C" { // identify where the content ends. while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { found_newline = F_true; last_newline = range->start; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + fl_macro_fss_content_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); continue; } @@ -258,10 +298,10 @@ extern "C" { } // for if (found_newline) { - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + fl_macro_fss_content_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); } else { - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); } if (buffer->string[range->start] == f_fss_basic_list_open) { @@ -270,7 +310,7 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } @@ -284,21 +324,19 @@ extern "C" { } // while if (found_newline) { - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + fl_macro_fss_content_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); } else { - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); } - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { start = range->start; range->start = first_slash; if (slash_count % 2 == 0) { if (found_newline) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->array[found->used].stop = last_newline; range->start = last_newline + 1; found->used++; @@ -309,21 +347,19 @@ extern "C" { return FL_fss_found_content_not; } - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_t_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + status = private_fl_fss_delimits_increase_by(slash_count / 2, delimits); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; } while (slash_count > 0) { if (buffer->string[range->start] == f_fss_delimit_slash) { if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; + delimits->array[delimits->used] = range->start; + delimits->used++; } slash_count--; @@ -346,7 +382,7 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } @@ -360,16 +396,14 @@ extern "C" { } // while if (found_newline) { - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + fl_macro_fss_content_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); } else { - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); } - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { if (found_newline) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->array[found->used++].stop = last_newline; range->start = last_newline + 1; @@ -391,17 +425,15 @@ extern "C" { } // while if (found_newline) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->array[found->used++].stop = last_newline; range->start = last_newline + 1; - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + fl_macro_fss_content_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); return FL_fss_found_content; } - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); return FL_fss_found_content_not; } @@ -413,18 +445,10 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); - - if (range->start > range->stop) { - status = F_data_not_stop; - } - else if (range->start >= object.used) { - status = F_data_not_eos; - } + f_status_t status = f_fss_skip_past_delimit(object, range); + if (F_status_is_error(status)) return status; - if (status == F_data_not_stop || status == F_data_not_eos) { + if (status == F_none_stop || status == F_none_eos) { if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination); if (F_status_is_error(status_allocation)) return status_allocation; @@ -436,7 +460,11 @@ extern "C" { } } - return status; + if (status == F_none_stop) { + return F_data_not_stop; + } + + return F_data_not_eos; } // ensure that there is room for a slash delimit, the object open character, and the end of line character. @@ -606,19 +634,18 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - - fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); + f_status_t status = f_fss_skip_past_delimit(content, range); + if (F_status_is_error(status)) return status; - if (range->start > range->stop || range->start >= content.used) { + if (status == F_none_stop || status == F_none_eos) { if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { - status = private_fl_fss_destination_increase(destination); - if (F_status_is_error(status)) return status; + const f_status_t status_allocation = private_fl_fss_destination_increase(destination); + if (F_status_is_error(status_allocation)) return status_allocation; destination->string[destination->used++] = f_fss_basic_list_close; } - if (range->start > range->stop) { + if (status == F_none_stop) { return F_data_not_stop; } @@ -669,7 +696,7 @@ extern "C" { if (content.string[range->start] == f_fss_basic_list_open) { start = range->start++; - status = private_fl_fss_basic_list_write_skip_whitespace(content, range); + status = f_fss_skip_past_space(content, range); if (F_status_is_error(status)) break; if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) { @@ -713,7 +740,7 @@ extern "C" { has_graph = F_true; - status = private_fl_fss_basic_list_write_skip_whitespace(content, range); + status = f_fss_skip_past_space(content, range); if (F_status_is_error(status)) break; if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) { @@ -747,11 +774,15 @@ extern "C" { has_graph = F_false; is_comment = F_false; } - else if ((status = f_fss_is_graph(content, *range)) == F_true) { - has_graph = F_true; - } - else if (F_status_is_error(status)) { - break; + else { + status = f_fss_is_graph(content, *range); + + if (status == F_true) { + has_graph = F_true; + } + else if (F_status_is_error(status)) { + break; + } } if (content.string[range->start] != f_fss_delimit_placeholder) { diff --git a/level_1/fl_fss/c/fss_basic_list.h b/level_1/fl_fss/c/fss_basic_list.h index 559de67..fc6689f 100644 --- a/level_1/fl_fss/c/fss_basic_list.h +++ b/level_1/fl_fss/c/fss_basic_list.h @@ -35,8 +35,7 @@ extern "C" { /** * Read an fss-0002 object. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -48,6 +47,8 @@ extern "C" { * A start location past the stop location or buffer used means that the entire range was processed. * @param found * A set of all locations where a valid object was found. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -69,17 +70,17 @@ extern "C" { * Errors (with error bit) from: f_utf_buffer_increment(). * 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_seek_to_eol(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_basic_list_object_read_ - extern f_return_status fl_fss_basic_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found); + extern f_return_status fl_fss_basic_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_delimits_t *delimits); #endif // _di_fl_fss_basic_list_object_read_ /** * Read an fss-0002 content from a given string. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -91,6 +92,8 @@ extern "C" { * A start location past the stop location or buffer used means that the entire range was processed. * @param found * A set of all locations where a valid content was found. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_content on success and content was found (start location is at end of content). @@ -112,10 +115,11 @@ extern "C" { * Errors (with error bit) from: f_utf_buffer_increment(). * 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_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_basic_list_content_read_ - extern f_return_status fl_fss_basic_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found); + extern f_return_status fl_fss_basic_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_delimits_t *delimits); #endif // _di_fl_fss_basic_list_content_read_ /** diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index 4425ea6..01b2bce 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -6,46 +6,37 @@ extern "C" { #endif #ifndef _di_fl_fss_extended_object_read_ - f_return_status fl_fss_extended_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted) { + f_return_status fl_fss_extended_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - f_string_lengths_t delimits = f_string_lengths_t_initialize; + const f_array_length_t delimits_used = delimits->used; - status = private_fl_fss_basic_read(F_true, buffer, range, found, quoted, &delimits); + f_status_t status = private_fl_fss_basic_read(F_true, buffer, range, found, quoted, delimits); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); + delimits->used = delimits_used; return status; } if (status == FL_fss_found_object_not || status == F_data_not || status == F_data_not_eos || status == F_data_not_stop) { - f_macro_string_lengths_t_delete_simple(delimits); + delimits->used = delimits_used; return status; } - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - return status; } #endif // _di_fl_fss_extended_object_read_ #ifndef _di_fl_fss_extended_content_read_ - f_return_status fl_fss_extended_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_quotes_t *quotes) { + f_return_status fl_fss_extended_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_quotes_t *quotes, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status_t status = F_none; @@ -54,19 +45,20 @@ extern "C" { status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; - // return found nothing if this line only contains whitespace and delimit placeholders. if (status == F_none_eol) { range->start++; return FL_fss_found_content_not; } - else if (status == F_none_eos) { + + if (status == F_none_eos) { return F_data_not_eos; } - else if (status == F_none_stop) { + + if (status == F_none_stop) { return F_data_not_stop; } - f_string_lengths_t delimits = f_string_lengths_t_initialize; + const f_array_length_t delimits_used = delimits->used; uint8_t content_found = 0; @@ -74,28 +66,20 @@ extern "C" { f_string_range_t content_partial = f_string_range_t_initialize; f_fss_quote_t quoted = 0; - status = private_fl_fss_basic_read(F_false, buffer, range, &content_partial, "ed, &delimits); + status = private_fl_fss_basic_read(F_false, buffer, range, &content_partial, "ed, delimits); if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { - if (found->used == found->size) { - if (found->used + f_fss_default_allocation_step > found->size) { - if (found->used == f_array_length_t_size) { - f_macro_string_lengths_t_delete_simple(delimits); - return F_status_set_error(F_buffer_too_large); - } - else { - f_macro_fss_content_t_resize(status_allocate, (*found), found->size + f_fss_default_allocation_step); - } - } - else { - f_macro_fss_content_t_resize(status_allocate, (*found), found->size + f_fss_default_allocation_step); - } - if (F_status_is_error(status_allocate)) return status_allocate; + if (found->used + 1 > found->size) { + status_allocate = private_fl_fss_ranges_increase(found); - if (quotes) { + if (F_status_is_fine(status_allocate) && quotes) { f_macro_fss_quotes_t_resize(status_allocate, (*quotes), found->size); - if (F_status_is_error(status_allocate)) return status_allocate; + } + + if (F_status_is_error(status_allocate)) { + delimits->used = delimits_used; + return status_allocate; } } @@ -137,14 +121,12 @@ extern "C" { break; } else if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); + delimits->used = delimits_used; return status; } } // while if (content_found) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - if (content_found == 2) { return status; } diff --git a/level_1/fl_fss/c/fss_extended.h b/level_1/fl_fss/c/fss_extended.h index cdb45d4..7285c2f 100644 --- a/level_1/fl_fss/c/fss_extended.h +++ b/level_1/fl_fss/c/fss_extended.h @@ -34,8 +34,7 @@ extern "C" { /** * Read an fss-0001 object. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -50,6 +49,8 @@ extern "C" { * @param quoted * This will store whether or not this object is quoted and what quote is in use. * Set pointer address to 0 to not use. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -60,28 +61,24 @@ extern "C" { * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). * F_unterminated_group_eos if EOS was reached before the a group termination was reached. * F_unterminated_group_stop if stop point was reached before the a group termination was reached. - * F_buffer_too_large (with error bit) if a buffer is too large. - * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. - * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. - * F_incomplete_utf_stop (with error bit) if the stop location is reached before the complete UTF-8 character can be processed. - * F_memory_reallocation (with error bit) on reallocation error. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) is returned on failure to read/process a UTF-8 character. * * Errors (with error bit) from: f_utf_buffer_increment(). * 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_seek_to_eol(). + * Errors (with error bit) from: f_fss_skip_past_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_object_read_ - extern f_return_status fl_fss_extended_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted); + extern f_return_status fl_fss_extended_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_fss_delimits_t *delimits); #endif // _di_fl_fss_extended_object_read_ /** * Read an fss-0001 content. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -96,6 +93,8 @@ extern "C" { * @param quotes * An array of quotes designating whether or not content is quoted and what quote is in use. * Set pointer address to 0 to not use. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_content on success and content was found (start location is at end of content). @@ -106,21 +105,17 @@ extern "C" { * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). * F_unterminated_group_eos if EOS was reached before the a group termination was reached. * F_unterminated_group_stop if stop point was reached before the a group termination was reached. - * F_buffer_too_large (with error bit) if a buffer is too large. - * F_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. - * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. - * F_incomplete_utf_stop (with error bit) if the stop location is reached before the complete UTF-8 character can be processed. - * F_memory_reallocation (with error bit) on reallocation error. * F_parameter (with error bit) if a parameter is invalid. - * F_utf (with error bit) is returned on failure to read/process a UTF-8 character. * * Errors (with error bit) from: f_utf_buffer_increment(). * 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_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_content_read_ - extern f_return_status fl_fss_extended_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_quotes_t *quotes); + extern f_return_status fl_fss_extended_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_content_t *found, f_fss_quotes_t *quotes, f_fss_delimits_t *delimits); #endif // _di_fl_fss_extended_content_read_ /** diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index 6cafe55..997693b 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -6,40 +6,39 @@ extern "C" { #endif #ifndef _di_fl_fss_extended_list_object_read_ - f_return_status fl_fss_extended_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found) { + f_return_status fl_fss_extended_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; + const f_array_length_t delimits_used = delimits->used; - // delimits must only be applied once a valid object is found. - f_string_lengths_t delimits = f_string_lengths_t_initialize; - - status = f_fss_skip_past_space(*buffer, range); + f_status_t status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; - // return found nothing if this line only contains whitespace and delimit placeholders. if (status == F_none_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_not; } - else if (status == F_none_eos) { + + if (status == F_none_eos) { return F_data_not_eos; } - else if (status == F_none_stop) { + + if (status == F_none_stop) { return F_data_not_stop; } // return found nothing if this line only contains whitespace and delimit placeholders. - if (buffer->string[range->start] == f_string_eol[0]) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + if (buffer->string[range->start] == f_fss_eol) { + + // move the start position to after the EOL. + range->start++; return FL_fss_found_object_not; } @@ -49,16 +48,29 @@ extern "C" { // ignore all comment lines. if (buffer->string[range->start] == f_fss_comment) { - fl_macro_fss_object_seek_till_newline((*buffer), (*range), delimits, F_data_not_eos, F_data_not_stop) + status = f_fss_seek_to_eol(*buffer, range); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; + } + + if (status == F_none_eos) { + return F_data_not_eos; + } + + if (status == F_none_stop) { + return F_data_not_stop; + } + + // move the start position to after the EOL. + range->start++; return FL_fss_found_object_not; } // identify where the object ends. - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { + while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_fss_eol) { if (buffer->string[range->start] == f_fss_delimit_slash) { f_string_length_t first_slash = range->start; @@ -76,7 +88,7 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); if (buffer->string[range->start] == f_fss_extended_list_open) { f_string_length_t stop_point = range->start - 1; @@ -86,7 +98,7 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0] || (status = f_fss_is_graph(*buffer, *range)) == F_true) { + if (buffer->string[range->start] == f_fss_eol || (status = f_fss_is_graph(*buffer, *range)) == F_true) { break; } @@ -96,20 +108,18 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { f_string_length_t start = range->start; range->start = first_slash; - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_t_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + status = private_fl_fss_delimits_increase_by((slash_count / 2) + 1, delimits); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) { + delimits->used = delimits_used; + return status; } if (slash_count % 2 == 0) { @@ -117,8 +127,8 @@ extern "C" { if (buffer->string[range->start] == f_fss_delimit_slash) { if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; + delimits->array[delimits->used] = range->start; + delimits->used++; } slash_count--; @@ -128,8 +138,6 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->stop = stop_point; range->start = start + 1; @@ -150,7 +158,7 @@ extern "C" { if (F_status_is_error(status)) return status; while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) break; + if (buffer->string[range->start] == f_fss_eol) break; status = f_fss_is_space(*buffer, *range); @@ -161,15 +169,13 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); - - if (buffer->string[range->start] == f_string_eol[0]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_object_return_on_overflow_delimited((*buffer), (*range), (*found), F_none_eos, F_none_stop); + if (buffer->string[range->start] == f_fss_eol) { found->stop = stop_point; - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + // move the start position to after the EOL. + range->start++; return FL_fss_found_object; } @@ -182,13 +188,13 @@ extern "C" { } // while // seek to the end of the line when no valid object is found. - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { + while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_fss_eol) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, F_data_not_eos, F_data_not_stop); status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -198,57 +204,57 @@ extern "C" { #endif // _di_fl_fss_extended_list_object_read_ #ifndef _di_fl_fss_extended_list_content_read_ - f_return_status fl_fss_extended_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *found) { + f_return_status fl_fss_extended_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *found, f_fss_delimits_t *delimits) { #ifndef _di_level_1_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); - if (!buffer->used) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!found) return F_status_set_error(F_parameter); - if (range->start > range->stop) return F_status_set_error(F_parameter); - if (range->start >= buffer->used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; + const f_array_length_t found_used = found->used; - // delimits must only be applied once a valid object is found. - f_string_lengths_t delimits = f_string_lengths_t_initialize; - f_string_lengths_t positions_start = f_string_lengths_t_initialize; - f_fss_objects_t objects = f_fss_objects_t_initialize; - - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), positions_start, delimits, objects, F_none_eos, F_none_stop) - - if (found->used + 1 >= found->size) { - f_macro_fss_nest_t_resize(status, (*found), found->size + f_fss_default_allocation_step + 1); + f_status_t status = f_fss_skip_past_delimit(*buffer, range); + if (F_status_is_error(status)) return status; - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - return status; - } + if (status == F_none_eos || status == F_none_stop) { + return status; } - f_array_length_t depth = 0; - f_string_length_t position_previous = range->start; - f_string_length_t line_start = range->start; - f_string_length_t last_newline = range->start; + status = private_fl_fss_nest_increase(found); + if (F_status_is_error(status)) return status; - f_macro_string_lengths_t_new(status, positions_start, f_fss_default_allocation_step); + f_string_lengths_t positions_start = f_string_lengths_t_initialize; - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); + f_macro_string_lengths_t_new(status, positions_start, f_fss_default_allocation_step); + if (F_status_is_error(status)) return status; - return status; - } + f_fss_objects_t objects = f_fss_objects_t_initialize; f_macro_fss_objects_t_new(status, objects, f_fss_default_allocation_step); if (F_status_is_error(status)) { f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_string_lengths_t_delete_simple(delimits); return status; } + const f_array_length_t delimits_used = delimits->used; + + f_array_length_t depth = 0; + f_array_length_t position = 0; + + f_string_length_t position_previous = range->start; + f_string_length_t line_start = range->start; + f_string_length_t last_newline = range->start; + + f_string_length_t slash_first = 0; + f_string_length_t slash_last = 0; + f_string_length_t slash_count = 0; + + f_string_length_t before_list_open = position_previous; + + bool is_open = F_false; + // initialize depth 1 start position. // positions_start.used is used as a max depth (such that positions_start.used == max depth + 1). positions_start.array[0] = range->start; @@ -256,16 +262,16 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; position_previous = range->start; range->start++; if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_none_eos, F_none_stop) + fl_macro_fss_nest_return_on_overflow_delimited((*buffer), (*range), (*found), positions_start, objects, F_none_eos, F_none_stop); } line_start = range->start; @@ -273,18 +279,18 @@ extern "C" { } if (buffer->string[range->start] == f_fss_delimit_slash) { - f_string_length_t slash_first = range->start; - f_string_length_t slash_last = range->start; - f_string_length_t slash_count = 1; + slash_first = range->start; + slash_last = range->start; + slash_count = 1; position_previous = range->start; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } @@ -299,19 +305,19 @@ extern "C" { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop); } // All slashes for an open are delimited (because it could represent a slash in the object name). @@ -319,15 +325,15 @@ extern "C" { // Only the first slash before a close is delimited, all others are maintained. // for example '}' = valid close, '\}' represents '}', '\\}' represents '\}', '\\\}' represents '\\}', '\\\\}' represents '\\\}', and so on.. // When slash is odd and a (delimited) valid open/close is found, then save delimited positions and continue. - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; position_previous = range->start; range->start++; line_start = range->start; } else if (buffer->string[range->start] == f_fss_extended_list_open || buffer->string[range->start] == f_fss_extended_list_close) { - f_string_length_t before_list_open = position_previous; - bool is_open = F_false; + before_list_open = position_previous; + is_open = F_false; if (buffer->string[range->start] == f_fss_extended_list_open) { is_open = F_true; @@ -338,7 +344,7 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; line_start = range->start + 1; break; @@ -349,10 +355,10 @@ extern "C" { } if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } @@ -360,23 +366,23 @@ extern "C" { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop); } // this is a valid object open/close that has been delimited, save the slash delimit positions. - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; line_start = range->start + 1; @@ -389,18 +395,15 @@ extern "C" { range->start = slash_first; - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_t_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - range->start = last_newline; + status = private_fl_fss_delimits_increase_by((slash_count / 2) + 1, delimits); - f_macro_string_lengths_t_delete_simple(delimits); - f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_fss_objects_t_delete_simple(objects); + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); - return status; - } + range->start = last_newline; + delimits->used = delimits_used; + return status; } // apply slash delimits, only slashes and placeholders should be present. @@ -408,8 +411,8 @@ extern "C" { if (buffer->string[range->start] == f_fss_delimit_slash) { if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; + delimits->array[delimits->used] = range->start; + delimits->used++; } slash_count--; @@ -428,12 +431,11 @@ extern "C" { f_macro_string_lengths_t_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step); if (F_status_is_error(status)) { - range->start = last_newline; - - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + range->start = last_newline; + delimits->used = delimits_used; return status; } } @@ -449,22 +451,19 @@ extern "C" { } } else { - if (delimits.used + 1 >= delimits.size) { - f_macro_string_lengths_t_resize(status, delimits, delimits.size + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - range->start = last_newline; + status = private_fl_fss_delimits_increase(delimits); - f_macro_string_lengths_t_delete_simple(delimits); - f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_fss_objects_t_delete_simple(objects); + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); - return status; - } + range->start = last_newline; + delimits->used = delimits_used; + return status; } - delimits.array[delimits.used] = slash_last; - delimits.used++; + delimits->array[delimits->used] = slash_last; + delimits->used++; } range->start = last_newline; @@ -472,77 +471,81 @@ extern "C" { } } else if (buffer->string[range->start] == f_fss_extended_list_open) { - f_string_length_t before_list_open = position_previous; + before_list_open = position_previous; position_previous = range->start; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } - if (buffer->string[range->start] != f_fss_delimit_placeholder && (status = f_fss_is_space(*buffer, *range)) == F_false) { - break; - } + if (buffer->string[range->start] != f_fss_delimit_placeholder) { + status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_fss_objects_t_delete_simple(objects); + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); - return status; + delimits->used = delimits_used; + return status; + } + + if (status == F_false) { + break; + } } position_previous = range->start; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop); } - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { depth++; if (depth >= positions_start.size) { f_macro_string_lengths_t_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } f_macro_fss_objects_t_resize(status, objects, objects.size + f_fss_default_allocation_step); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } @@ -559,33 +562,48 @@ extern "C" { last_newline = range->start; line_start = range->start + 1; } - // No valid object open found, seek until EOL. else { + + // No valid object close found, seek until EOL. + status = f_fss_seek_to_eol(*buffer, range); + + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); + + delimits->used = delimits_used; + return status; + } + + last_newline = range->start; + line_start = range->start + 1; + while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; line_start = range->start + 1; break; } position_previous = range->start; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop); } } } @@ -593,75 +611,78 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { position_previous = range->start; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { break; } - if (buffer->string[range->start] != f_fss_delimit_placeholder && (status = f_fss_is_space(*buffer, *range)) == F_false) { - break; - } + if (buffer->string[range->start] != f_fss_delimit_placeholder) { + status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_fss_objects_t_delete_simple(objects); + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); - return status; + delimits->used = delimits_used; + return status; + } + + if (status == F_false) { + break; + } } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop); } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop); } - if (buffer->string[range->start] == f_string_eol[0]) { - if (depth + 1 >= found->size) { - f_macro_fss_nest_t_resize(status, (*found), found->size + f_fss_default_allocation_step); + if (buffer->string[range->start] == f_fss_eol) { + status = private_fl_fss_nest_increase(found); - if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); - f_macro_string_lengths_t_delete_simple(positions_start); - f_macro_fss_objects_t_delete_simple(objects); + if (F_status_is_error(status)) { + f_macro_string_lengths_t_delete_simple(positions_start); + f_macro_fss_objects_t_delete_simple(objects); - return status; - } + delimits->used = delimits_used; + return status; } if (found->depth[depth].used == found->depth[depth].size) { f_macro_fss_items_t_resize(status, found->depth[depth], found->depth[depth].size + f_fss_default_allocation_step); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } - f_array_length_t position = found->depth[depth].used; + position = found->depth[depth].used; if (found->depth[depth].array[position].content.size != 1) { f_macro_fss_content_t_resize(status, found->depth[depth].array[position].content, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } @@ -691,17 +712,15 @@ extern "C" { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_none_eos, F_none_stop) + fl_macro_fss_nest_return_on_overflow_delimited((*buffer), (*range), (*found), positions_start, objects, F_none_eos, F_none_stop) - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); @@ -710,45 +729,48 @@ extern "C" { depth--; } - // No valid object close found, seek until EOL. else { + + // No valid object close found, seek until EOL. while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { last_newline = range->start; line_start = range->start + 1; break; } position_previous = range->start; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_unterminated_nest_eos, F_unterminated_nest_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), delimits, positions_start, objects, F_data_not_eos, F_data_not_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*range), (*found), (*delimits), delimits_used, positions_start, objects, F_data_not_eos, F_data_not_stop) } } } - else if (buffer->string[range->start] != f_string_eol[0]) { + else if (buffer->string[range->start] != f_fss_eol) { position_previous = range->start; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } @@ -760,18 +782,18 @@ extern "C" { } position_previous = range->start; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); + delimits->used = delimits_used; return status; } } // while - f_macro_string_lengths_t_delete_simple(delimits); f_macro_string_lengths_t_delete_simple(positions_start); f_macro_fss_objects_t_delete_simple(objects); @@ -797,16 +819,15 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); + f_status_t status = f_fss_skip_past_delimit(object, range); + if (F_status_is_error(status)) return status; - if (range->start > range->stop) { - status = F_data_not_stop; - } - else if (range->start >= object.used) { + if (status == F_none_eos) { status = F_data_not_eos; } + else if (status == F_none_stop) { + status = F_data_not_stop; + } if (status == F_data_not_stop || status == F_data_not_eos) { if (complete == f_fss_complete_partial || complete == f_fss_complete_partial_trim || complete == f_fss_complete_full || complete == f_fss_complete_full_trim) { @@ -1005,24 +1026,26 @@ extern "C" { if (!destination) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status_t status = F_none; + f_status_t status = f_fss_skip_past_delimit(content, range); + if (F_status_is_error(status)) return status; - fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); + if (status == F_none_eos) { + status = F_data_not_eos; + } + else if (status == F_none_stop) { + status = F_data_not_stop; + } if (range->start > range->stop || range->start >= content.used) { if (complete == f_fss_complete_full || complete == f_fss_complete_full_trim || complete == f_fss_complete_end) { - status = private_fl_fss_destination_increase_by(2, destination); - if (F_status_is_error(status)) return status; + const f_status_t status_allocation = private_fl_fss_destination_increase_by(2, destination); + if (F_status_is_error(status_allocation)) return status_allocation; destination->string[destination->used++] = f_fss_extended_list_close; destination->string[destination->used++] = f_fss_extended_list_close_end; } - if (range->start > range->stop) { - return F_data_not_stop; - } - - return F_data_not_eos; + return status; } // ensure that there is room for a slash delimit and possibly the end of content characters. @@ -1071,7 +1094,7 @@ extern "C" { if (content.string[range->start] == f_fss_extended_list_open || content.string[range->start] == f_fss_extended_list_close) { start = range->start++; - status = private_fl_fss_basic_list_write_skip_whitespace(content, range); + status = f_fss_skip_past_space(content, range); if (F_status_is_error(status)) break; if (has_graph && content.string[range->start] == f_fss_extended_list_close) { @@ -1139,7 +1162,7 @@ extern "C" { has_graph = F_true; - status = private_fl_fss_basic_list_write_skip_whitespace(content, range); + status = f_fss_skip_past_space(content, range); if (F_status_is_error(status)) break; if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) { diff --git a/level_1/fl_fss/c/fss_extended_list.h b/level_1/fl_fss/c/fss_extended_list.h index 4df2116..084a3b0 100644 --- a/level_1/fl_fss/c/fss_extended_list.h +++ b/level_1/fl_fss/c/fss_extended_list.h @@ -35,8 +35,7 @@ extern "C" { /** * Read an fss-0003 object. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * @param buffer * The buffer to read from. @@ -48,6 +47,8 @@ extern "C" { * A start location past the stop location or buffer used means that the entire range was processed. * @param found * A set of all locations where a valid object was found. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -69,17 +70,17 @@ extern "C" { * Errors (with error bit) from: f_utf_buffer_increment(). * 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_seek_to_eol(). * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_list_object_read_ - extern f_return_status fl_fss_extended_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found); + extern f_return_status fl_fss_extended_list_object_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_delimits_t *delimits); #endif // _di_fl_fss_extended_list_object_read_ /** * Read an fss-0003 content. * - * This will update the buffer at the given range with any placeholders to unescape any escaped data. - * Calling this more than once on the same buffer range could result in multiple unescaping. + * This will record where delimit placeholders exist but will not apply the delimits. * * This operates on the assumption that found.array[0].array[found.array[0].used].content is the current content being processed. * Therefore the object for this content will also need to be found.array[0].array[found.array[0].used].object. @@ -95,6 +96,8 @@ extern "C" { * A start location past the stop location or buffer used means that the entire range was processed. * @param found * A set of all locations where a valid content was found. + * @param delimits + * A delimits array representing where delimits exist within the buffer. * * @return * FL_fss_found_content on success and content was found (start location is at end of content). @@ -119,7 +122,7 @@ extern "C" { * Errors (with error bit) from: f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_list_content_read_ - extern f_return_status fl_fss_extended_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *found); + extern f_return_status fl_fss_extended_list_content_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *found, f_fss_delimits_t *delimits); #endif // _di_fl_fss_extended_list_content_read_ /** diff --git a/level_1/fl_fss/c/fss_macro.h b/level_1/fl_fss/c/fss_macro.h index 8364c63..be6b094 100644 --- a/level_1/fl_fss/c/fss_macro.h +++ b/level_1/fl_fss/c/fss_macro.h @@ -14,130 +14,69 @@ extern "C" { #endif -// TODO: check if character to be replaced is UTF and apply placeholder to entire width. -#ifndef _di_fl_macro_fss_apply_delimit_placeholders_ - #define fl_macro_fss_apply_delimit_placeholders(buffer, delimits) \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - \ - f_macro_string_lengths_t_delete_simple(delimits); -#endif // _di_fl_macro_fss_apply_delimit_placeholders_ - -#ifndef _di_fl_macro_fss_skip_past_delimit_placeholders_ - #define fl_macro_fss_skip_past_delimit_placeholders(buffer, range) \ - if (buffer.used) { \ - while (buffer.string[range.start] == f_fss_delimit_placeholder) { \ - range.start++;\ - \ - if (range.start >= buffer.used) break; \ - if (range.start > range.stop) break; \ - } \ - } -#endif // _di_fl_macro_fss_skip_past_delimit_placeholders_ - #ifndef _di_fl_macro_fss_object_return_on_overflow_ - #define fl_macro_fss_object_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + #define fl_macro_fss_object_return_on_overflow(buffer, range, found, delimits, delimits_used, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ + delimits.used = delimits_used; \ found.stop = buffer.used - 1; \ return eos_status; \ } \ else if (range.start > range.stop) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ + delimits.used = delimits_used; \ found.stop = range.stop; \ return stop_status; \ } #endif // _di_fl_macro_fss_object_return_on_overflow_ -#ifndef _di_fl_macro_fss_object_delimited_return_on_overflow_ - #define fl_macro_fss_object_delimited_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ +#ifndef _di_fl_macro_fss_object_return_on_overflow_delimited_ + #define fl_macro_fss_object_return_on_overflow_delimited(buffer, range, found, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ found.stop = buffer.used - 1; \ return eos_status; \ } \ else if (range.start > range.stop) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - _macro__i++; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ found.stop = range.stop; \ return stop_status; \ } -#endif // _di_fl_macro_fss_object_delimited_return_on_overflow_ +#endif // _di_fl_macro_fss_object_return_on_overflow_delimited_ #ifndef _di_fl_macro_fss_content_return_on_overflow_ - #define fl_macro_fss_content_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + #define fl_macro_fss_content_return_on_overflow(buffer, range, found, delimits, delimits_used, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ + delimits.used = delimits_used; \ found.array[found.used].stop = buffer.used - 1; \ return eos_status; \ } \ else if (range.start > range.stop) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ + delimits.used = delimits_used; \ found.array[found.used].stop = range.stop; \ return stop_status; \ } #endif // _di_fl_macro_fss_content_return_on_overflow_ -#ifndef _di_fl_macro_fss_content_delimited_return_on_overflow_ - #define fl_macro_fss_content_delimited_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ +#ifndef _di_fl_macro_fss_content_return_on_overflow_delimited_ + #define fl_macro_fss_content_return_on_overflow_delimited(buffer, range, found, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ found.array[found.used].stop = buffer.used - 1; \ return eos_status; \ } \ else if (range.start > range.stop) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ found.array[found.used].stop = range.stop; \ return stop_status; \ } -#endif // _di_fl_macro_fss_content_delimited_return_on_overflow_ - -#ifndef _di_fl_macro_fss_allocate_content_if_necessary_ - #define fl_macro_fss_allocate_content_if_necessary(content, delimits) \ - if (content.used == content.size) { \ - f_status_t status = F_none; \ - \ - f_macro_fss_content_t_resize(status, content, content.size + f_fss_default_allocation_step); \ - if (F_status_is_error(status)) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - return status; \ - } \ - } -#endif // _di_fl_macro_fss_allocate_content_if_necessary_ +#endif // _di_fl_macro_fss_content_return_on_overflow_delimited_ #ifndef _di_fl_macro_fss_nest_return_on_overflow_ - #define fl_macro_fss_nest_return_on_overflow(buffer, range, found, delimits, positions, objects, eos_status, stop_status) \ + #define fl_macro_fss_nest_return_on_overflow(buffer, range, found, delimits, delimits_used, positions, objects, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ + delimits.used = delimits_used; \ f_macro_string_lengths_t_delete_simple(positions); \ f_macro_fss_objects_t_delete_simple(objects); \ \ return eos_status; \ } \ else if (range.start > range.stop) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ + delimits.used = delimits_used; \ f_macro_string_lengths_t_delete_simple(positions); \ f_macro_fss_objects_t_delete_simple(objects); \ \ @@ -145,113 +84,21 @@ extern "C" { } #endif // _di_fl_macro_fss_nest_return_on_overflow_ -#ifndef _di_fl_macro_fss_nest_delimited_return_on_overflow_ - #define fl_macro_fss_nest_delimited_return_on_overflow(buffer, range, found, delimits, positions, objects, eos_status, stop_status) \ +#ifndef _di_fl_macro_fss_nest_return_on_overflow_delimited_ + #define fl_macro_fss_nest_return_on_overflow_delimited(buffer, range, found, positions, objects, eos_status, stop_status) \ if (range.start >= buffer.used) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ f_macro_string_lengths_t_delete_simple(positions); \ f_macro_fss_objects_t_delete_simple(objects); \ \ return eos_status; \ } \ else if (range.start > range.stop) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ f_macro_string_lengths_t_delete_simple(positions); \ f_macro_fss_objects_t_delete_simple(objects); \ \ return stop_status; \ } -#endif // _di_fl_macro_fss_nest_delimited_return_on_overflow_ - -#ifndef _di_fl_macro_fss_object_seek_till_newline_ - #define fl_macro_fss_object_seek_till_newline(buffer, range, delimits, eos_status, stop_status) \ - while (buffer.string[range.start] != f_string_eol[0]) { \ - range.start++; \ - if (range.start >= buffer.used) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - return eos_status; \ - } \ - if (range.start > range.stop) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - return stop_status; \ - } \ - } // while -#endif // _di_fl_macro_fss_object_seek_till_newline_ - -#ifndef _di_fl_macro_fss_object_delimited_seek_till_newline_ - #define fl_macro_fss_object_delimited_seek_till_newline(buffer, range, delimits, eos_status, stop_status) \ - while (buffer.string[range.start] != f_string_eol[0]) { \ - range.start++; \ - if (range.start >= buffer.used) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - return eos_status; \ - } \ - if (range.start > range.stop) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - return stop_status; \ - } \ - } // while -#endif // _di_fl_macro_fss_object_delimited_seek_till_newline_ - -#ifndef _di_fl_macro_fss_content_seek_till_newline_ - #define fl_macro_fss_content_seek_till_newline(buffer, range, found, delimits, eos_status, stop_status) \ - while (buffer.string[range.start] != f_string_eol[0]) { \ - range.start++; \ - if (range.start >= buffer.used) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - found.array[found.used].stop = range.stop; \ - return eos_status; \ - } \ - if (range.start > range.stop) { \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - found.array[found.used].stop = range.stop; \ - return stop_status; \ - } \ - } // while -#endif // _di_fl_macro_fss_content_seek_till_newline_ - -#ifndef _di_fl_macro_fss_content_delimited_seek_till_newline_ - #define fl_macro_fss_content_delimited_seek_till_newline(buffer, range, found, delimits, eos_status, stop_status) \ - while (buffer.string[range.start] != f_string_eol[0]) { \ - range.start++; \ - if (range.start >= buffer.used) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - found.array[found.used].stop = range.stop; \ - return eos_status; \ - } \ - if (range.start > range.stop) { \ - for (f_array_length_t _macro__i = 0; _macro__i < delimits.used; _macro__i++) { \ - buffer.string[delimits.array[_macro__i]] = f_fss_delimit_placeholder; \ - } \ - f_macro_string_lengths_t_delete_simple(delimits); \ - \ - found.array[found.used].stop = range.stop; \ - return stop_status; \ - } \ - } // while -#endif // _di_fl_macro_fss_content_delimited_seek_till_newline_ +#endif // _di_fl_macro_fss_nest_return_on_overflow_delimited_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 6d9a651..4a2e02a 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -190,48 +190,25 @@ extern "C" { } #endif // !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) -#if !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - f_return_status private_fl_fss_basic_list_write_skip_whitespace(const f_string_static_t buffer, f_string_range_t *range) { - f_status_t status = F_none; - - while (range->start <= range->stop && range->start < buffer.used) { - - if (buffer.string[range->start] == f_fss_delimit_placeholder) { - range->start++; - continue; - } - - if (buffer.string[range->start] == f_fss_eol) break; - - status = f_fss_is_space(buffer, *range); - if (F_status_is_error(status)) break; - - if (status == F_false) break; - - status = f_utf_buffer_increment(buffer, range, 1); - if (F_status_is_error(status)) break; - } // while - - return status; - } -#endif // !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) - f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_string_lengths_t *delimits) { - f_status_t status = F_none; + f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quote, f_fss_delimits_t *delimits) { - status = f_fss_skip_past_space(*buffer, range); + f_status_t status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; - // return found nothing if this line only contains whitespace and delimit placeholders. if (status == F_none_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_not; } - else if (status == F_none_eos) { + + if (status == F_none_eos) { return F_data_not_eos; } - else if (status == F_none_stop) { + + if (status == F_none_stop) { return F_data_not_stop; } @@ -240,22 +217,20 @@ extern "C" { // ignore all comment lines. if (object_as && buffer->string[range->start] == f_fss_comment) { - while (buffer->string[range->start] != f_string_eol[0]) { + + while (buffer->string[range->start] != f_fss_eol) { range->start++; if (range->start >= buffer->used) return F_data_not_eos; if (range->start > range->stop) return F_data_not_stop; } // while - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + // move the start position to after the EOL. + range->start++; return FL_fss_found_object_not; } - // delimits must only be applied once a valid object is found-> - const f_string_length_t delimit_initial = delimits->used; - // handle quoted support. int8_t quote_found = 0; @@ -286,6 +261,7 @@ extern "C" { if (buffer->string[range->start] != f_fss_delimit_slash) { status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) return status; // found the end of the object while processing the slash for potential delimits. if (status == F_true) { @@ -294,31 +270,26 @@ extern "C" { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { return FL_fss_found_object_content_not; } return FL_fss_found_object; } - else if (F_status_is_error(status)) { - return status; - } break; } status = f_utf_buffer_increment(*buffer, range, 1); - - if (F_status_is_error(status)) { - return status; - } + if (F_status_is_error(status)) return status; } // while if (range->start >= buffer->used) { found->stop = buffer->used - 1; return F_none_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; return F_none_stop; } @@ -327,20 +298,8 @@ extern "C" { // only the first slash before a quoted needs to be escaped (or not) as once there is a slash before a quoted, this cannot ever be a quote object. // this simplifies the number of slashes needed. - if (delimits->used == delimits->size) { - if (delimits->size + f_fss_default_allocation_step > f_array_length_t_size) { - if (delimits->size + 1 > f_array_length_t_size) { - return F_status_set_error(F_buffer_too_large); - } - - f_macro_string_lengths_t_resize(status, (*delimits), delimits->size + 1); - if (F_status_is_error(status)) return status; - } - else { - f_macro_string_lengths_t_resize(status, (*delimits), delimits->size + f_fss_default_allocation_step); - if (F_status_is_error(status)) return status; - } - } + status = private_fl_fss_delimits_increase(delimits); + if (F_status_is_error(status)) return status; delimits->array[delimits->used] = first_slash; delimits->used++; @@ -375,8 +334,11 @@ extern "C" { found->stop = range->start - 1; - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_content_not; } @@ -419,12 +381,11 @@ extern "C" { if (range->start >= buffer->used) { found->stop = buffer->used - 1; - delimits->used = delimit_initial; return F_unterminated_group_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; - delimits->used = delimit_initial; return F_unterminated_group_stop; } @@ -435,17 +396,18 @@ extern "C" { if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { range->start++; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + status = f_fss_skip_past_delimit(*buffer, range); + if (F_status_is_error(status)) return status; - if (range->start <= range->stop && range->start < buffer->used) { - status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) return status; - } - else { + if (range->start > range->stop || range->start >= buffer->used) { // EOS or EOL was reached, so it is a valid closing quoted. // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). status = F_true; } + else { + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) return status; + } } else { // EOS or EOL was reached, so it is a valid closing quoted. @@ -466,14 +428,8 @@ extern "C" { range->start = first_slash; if (slash_count % 2 == 0) { - if (delimits->used + (slash_count / 2) >= delimits->size) { - if (delimits->used + (slash_count / 2) >= f_array_length_t_size) { - return F_status_set_error(F_buffer_too_large); - } - - f_macro_string_lengths_t_resize(status, (*delimits), delimits->size + (slash_count / 2)); - if (F_status_is_error(status)) return status; - } + status = private_fl_fss_delimits_increase_by(slash_count / 2, delimits); + if (F_status_is_error(status)) return status; while (slash_count > 0) { @@ -499,9 +455,12 @@ extern "C" { if (range->start > range->stop) return F_none_stop; } // while - if ((status = f_fss_is_graph(*buffer, *range)) == F_true) { + status = f_fss_is_graph(*buffer, *range); + if (F_status_is_error(status)) return status; + + if (status == F_true) { - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { + while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_fss_eol) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -511,7 +470,8 @@ extern "C" { found->stop = buffer->used - 1; return F_data_not_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; return F_data_not_stop; } @@ -521,12 +481,13 @@ extern "C" { return FL_fss_found_object_not; } - else if (F_status_is_error(status)) { - return status; - } - else if (buffer->string[range->start] == f_string_eol[0]) { + + if (buffer->string[range->start] == f_fss_eol) { found->stop = location - 1; + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_content_not; } @@ -538,14 +499,8 @@ extern "C" { return FL_fss_found_object; } else { - if (delimits->used + (slash_count / 2) >= delimits->size) { - if (delimits->used + (slash_count / 2) >= f_array_length_t_size) { - return F_status_set_error(F_buffer_too_large); - } - - f_macro_string_lengths_t_resize(status, (*delimits), delimits->size + (slash_count / 2) + 1); - if (F_status_is_error(status)) return status; - } + status = private_fl_fss_delimits_increase_by((slash_count / 2) + 1, delimits); + if (F_status_is_error(status)) return status; while (slash_count > 0) { @@ -571,33 +526,33 @@ extern "C" { } } else if (buffer->string[range->start] == quote_found) { + // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted. - { - location = range->start; + location = range->start; - if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { - range->start++; + if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { + range->start++; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + status = f_fss_skip_past_delimit(*buffer, range); + if (F_status_is_error(status)) return status; - if (range->start <= range->stop && range->start < buffer->used) { - status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) return status; - } - else { - // EOS or EOL was reached, so it is a valid closing quoted. - // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). - status = F_true; - } - } - else { + if (range->start > range->stop || range->start >= buffer->used) { // EOS or EOL was reached, so it is a valid closing quoted. // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). status = F_true; } - - range->start = location; + else { + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) return status; + } } + else { + // EOS or EOL was reached, so it is a valid closing quoted. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } + + range->start = location; if (status == F_true) { if (quote) { @@ -616,22 +571,27 @@ extern "C" { while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { + if (buffer->string[range->start] == f_fss_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_content_not; } - else if ((status = f_fss_is_space(*buffer, *range)) == F_true) { + + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) return status; + + if (status == F_true) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; return FL_fss_found_object; } - else if (F_status_is_error(status)) { - return status; - } - else if (buffer->string[range->start] != f_fss_delimit_placeholder) { - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { + if (buffer->string[range->start] != f_fss_delimit_placeholder) { + + while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_fss_eol) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -641,7 +601,8 @@ extern "C" { found->stop = buffer->used - 1; return F_data_not_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; return F_data_not_stop; } @@ -660,14 +621,18 @@ extern "C" { found->stop = buffer->used - 1; return F_none_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; return F_none_stop; } } } - else if (buffer->string[range->start] == f_string_eol[0]) { + else if (buffer->string[range->start] == f_fss_eol) { + + // move the start position to after the EOL. range->start++; + return FL_fss_found_object_not; } @@ -677,51 +642,38 @@ extern "C" { if (range->start >= buffer->used) { found->stop = buffer->used - 1; - delimits->used = delimit_initial; return F_unterminated_group_eos; } - else if (range->start > range->stop) { + + if (range->start > range->stop) { found->stop = range->stop; - delimits->used = delimit_initial; return F_unterminated_group_stop; } } - // seek to the end of the line when no valid object is found. - while (range->start <= range->stop && range->start < buffer->used && buffer->string[range->start] != f_string_eol[0]) { - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (range->start >= buffer->used) { - found->stop = buffer->used - 1; - return F_data_not_eos; - } - else if (range->start > range->stop) { - found->stop = range->stop; - return F_data_not_stop; - } - - status = f_utf_buffer_increment(*buffer, range, 1); + // seek to the EOL when no valid object is found. + status = f_fss_seek_to_eol(*buffer, range); if (F_status_is_error(status)) return status; + // move the start position to after the EOL. + range->start++; + return FL_fss_found_object_not; } #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) #if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quote, f_string_range_t *range, f_string_dynamic_t *destination) { - f_status_t status = F_none; - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); + f_status_t status = f_fss_skip_past_space(object, range); + if (F_status_is_error(status)) return status; - if (range->start > range->stop) { - return F_data_not_stop; + if (status == F_none_eos) { + return F_data_not_eos; } - if (range->start >= object.used) { - return F_data_not_eos; + if (status == F_none_stop) { + return F_data_not_stop; } // ensure that there is room for the potential start and stop quotes, a potential delimit at start, and the potential object open character. @@ -800,7 +752,8 @@ extern "C" { break; } - else if (object.string[range->start] == f_fss_eol) { + + if (object.string[range->start] == f_fss_eol) { status = F_status_set_error(F_none_eol); break; } @@ -808,9 +761,11 @@ extern "C" { if (object.string[range->start] == quote) { item_first = range->start++; - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); + status = f_fss_skip_past_delimit(object, range); + if (F_status_is_error(status)) return status; if (range->start > range->stop || range->start >= object.used) { + status = private_fl_fss_destination_increase_by(item_total + 1, destination); if (F_status_is_error(status)) break; @@ -922,9 +877,11 @@ extern "C" { destination->string[used_start + 1] = f_fss_delimit_slash; } - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); + status = f_fss_skip_past_delimit(object, range); + if (F_status_is_error(status)) return status; if (range->start > range->stop || range->start >= object.used) { + status = private_fl_fss_destination_increase(destination); if (F_status_is_error(status)) break; @@ -1014,6 +971,7 @@ extern "C" { // The start quote may or may not need to be delimited in this case. if (destination->string[input_start] == quote) { + for (i = input_start + 1; i <= range->stop && i < object.used; i++) { if (object.string[i] != f_fss_delimit_placeholder) break; } // for @@ -1050,6 +1008,43 @@ extern "C" { #endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) #if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + f_return_status private_fl_fss_delimits_increase(f_fss_delimits_t *delimits) { + f_status_t status = F_none; + + if (delimits->used + 1 > delimits->size) { + if (delimits->size + f_fss_default_allocation_step > f_string_length_t_size) { + if (delimits->size + 1 > f_string_length_t_size) { + return F_status_set_error(F_string_too_large); + } + + f_macro_fss_delimits_t_resize(status, (*delimits), (delimits->size + 1)); + } + else { + f_macro_fss_delimits_t_resize(status, (*delimits), (delimits->size + f_fss_default_allocation_step)); + } + } + + return status; + } +#endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + +#if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + f_return_status private_fl_fss_delimits_increase_by(const f_string_length_t amount, f_fss_delimits_t *delimits) { + f_status_t status = F_none; + + if (delimits->used + amount > delimits->size) { + if (delimits->size + amount > f_string_length_t_size) { + return F_status_set_error(F_string_too_large); + } + + f_macro_fss_delimits_t_resize(status, (*delimits), (delimits->size + amount)); + } + + return status; + } +#endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + +#if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) f_return_status private_fl_fss_destination_increase(f_string_dynamic_t *destination) { f_status_t status = F_none; @@ -1059,10 +1054,10 @@ extern "C" { return F_status_set_error(F_string_too_large); } - f_macro_string_dynamic_t_resize(status, (*destination), destination->size + 1); + f_macro_string_dynamic_t_resize(status, (*destination), (destination->size + 1)); } else { - f_macro_string_dynamic_t_resize(status, (*destination), destination->size + f_fss_default_allocation_step); + f_macro_string_dynamic_t_resize(status, (*destination), (destination->size + f_fss_default_allocation_step)); } } @@ -1104,6 +1099,48 @@ extern "C" { } #endif // !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) +#if !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + f_return_status private_fl_fss_nest_increase(f_fss_nest_t *nest) { + f_status_t status = F_none; + + if (nest->used + 1 > nest->size) { + if (nest->size + f_fss_default_allocation_step > f_array_length_t_size) { + if (nest->size + 1 > f_array_length_t_size) { + return F_status_set_error(F_buffer_too_large); + } + + f_macro_fss_nest_t_resize(status, (*nest), (nest->size + 1)); + } + else { + f_macro_fss_nest_t_resize(status, (*nest), (nest->size + f_fss_default_allocation_step)); + } + } + + return status; + } +#endif // !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + +#if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_basic_content_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) || !defined(_di_fl_fss_basic_list_object_read_) || !defined(_di_fl_fss_basic_list_content_read_) || !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + f_return_status private_fl_fss_ranges_increase(f_string_ranges_t *ranges) { + f_status_t status = F_none; + + if (ranges->used + 1 > ranges->size) { + if (ranges->size + f_fss_default_allocation_step > f_array_length_t_size) { + if (ranges->size + 1 > f_array_length_t_size) { + return F_status_set_error(F_buffer_too_large); + } + + f_macro_string_ranges_t_resize(status, (*ranges), (ranges->size + 1)); + } + else { + f_macro_string_ranges_t_resize(status, (*ranges), (ranges->size + f_fss_default_allocation_step)); + } + } + + return status; + } +#endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_basic_content_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) || !defined(_di_fl_fss_basic_list_object_read_) || !defined(_di_fl_fss_basic_list_content_read_) || !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_1/fl_fss/c/private-fss.h b/level_1/fl_fss/c/private-fss.h index 644efe7..0a9baed 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -82,27 +82,6 @@ extern "C" { #endif // !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) /** - * Skip past whitespace, seeking until stop point, buffer end, or EOL. - * - * @param buffer - * The buffer to seek through. - * @param range - * The start/stop location within the buffer string to process. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_fss_is_space(). - * Errors (with error bit) from: f_utf_buffer_increment(). - * - * @see fl_fss_basic_list_content_write_string() - * @see fl_fss_extended_list_content_write_string() - */ -#if !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - extern f_return_status private_fl_fss_basic_list_write_skip_whitespace(const f_string_static_t buffer, f_string_range_t *range) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - -/** * Private implementation of fl_fss_basic_object_read(). * * Intended to be shared to each of the different implementation variations. @@ -150,6 +129,8 @@ extern "C" { * Errors (with error bit) from: f_utf_buffer_increment(). * 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_delimit(). * Errors (with error bit) from: f_fss_skip_past_space(). * * @see fl_fss_basic_object_read() @@ -157,7 +138,7 @@ extern "C" { * @see fl_fss_extended_content_read() */ #if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) - extern f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_string_lengths_t *delimits) f_gcc_attribute_visibility_internal; + extern f_return_status private_fl_fss_basic_read(const bool object_as, f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_object_t *found, f_fss_quote_t *quoted, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) /** @@ -207,6 +188,56 @@ extern "C" { #endif // !defined(fl_fss_basic_object_write_string) || !defined(fl_fss_extended_object_write_string) || !defined(_di_fl_fss_extended_content_write_string_) /** + * Increase the size of delimits array, but only if necessary. + * + * @param delimits + * The delimits array to increment. + * + * @return + * F_none on success. + * F_memory_reallocation (with error bit) on reallocation error. + * F_buffer_too_large (with error bit) if appended string length is too large to store in the delimits. + * + * @see fl_fss_basic_object_write_string() + * @see fl_fss_basic_content_write_string() + * @see fl_fss_basic_list_object_write_string() + * @see fl_fss_basic_list_content_write_string() + * @see fl_fss_extended_object_write_string() + * @see fl_fss_extended_content_write_string() + * @see fl_fss_extended_list_object_write_string() + * @see fl_fss_extended_list_content_write_string() + */ +#if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + extern f_return_status private_fl_fss_delimits_increase(f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + +/** + * Increase the size of delimits array by the given amount, but only if necessary. + * + * @param amount + * The amount to increase by. + * @param delimits + * The delimits array to increment. + * + * @return + * F_none on success. + * F_memory_reallocation (with error bit) on reallocation error. + * F_buffer_too_large (with error bit) if increased string length is too large to store in the delimits. + * + * @see fl_fss_basic_object_write_string() + * @see fl_fss_basic_content_write_string() + * @see fl_fss_basic_list_object_write_string() + * @see fl_fss_basic_list_content_write_string() + * @see fl_fss_extended_object_write_string() + * @see fl_fss_extended_content_write_string() + * @see fl_fss_extended_list_object_write_string() + * @see fl_fss_extended_list_content_write_string() + */ +#if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + extern f_return_status private_fl_fss_delimits_increase_by(const f_string_length_t amount, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) + +/** * Increase the size of destination buffer, but only if necessary. * * @param destination @@ -241,7 +272,7 @@ extern "C" { * @return * F_none on success. * F_memory_reallocation (with error bit) on reallocation error. - * F_string_too_large (with error bit) if appended string length is too large to store in the destination. + * F_string_too_large (with error bit) if increased string length is too large to store in the destination. * * @see fl_fss_basic_object_write_string() * @see fl_fss_basic_content_write_string() @@ -253,7 +284,7 @@ extern "C" { * @see fl_fss_extended_list_content_write_string() */ #if !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; + extern f_return_status private_fl_fss_destination_increase_by(const f_string_length_t amount, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fl_fss_basic_object_write_string_) || !defined(_di_fl_fss_basic_content_write_string_) || !defined(_di_fl_fss_basic_list_object_write_string_) || !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_object_write_string_) || !defined(_di_fl_fss_extended_content_write_string_) || !defined(_di_fl_fss_extended_list_object_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) /** @@ -268,15 +299,57 @@ extern "C" { * @return * F_none on success. * F_memory_reallocation (with error bit) on reallocation error. - * F_string_too_large (with error bit) if appended string length is too large to store in the destination. + * F_string_too_large (with error bit) if increased string length is too large to store in the destination. * * @see fl_fss_basic_list_content_write_string() * @see fl_fss_extended_list_content_write_string() */ #if !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) - f_return_status private_fl_fss_destination_prepend(const f_string_static_t *prepend, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; + extern f_return_status private_fl_fss_destination_prepend(const f_string_static_t *prepend, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fl_fss_basic_list_content_write_string_) || !defined(_di_fl_fss_extended_list_content_write_string_) +/** + * Increase the size of a given nest buffer, but only if necessary. + * + * @param nest + * The nest buffer to increment. + * + * @return + * F_none on success. + * F_memory_reallocation (with error bit) on reallocation error. + * F_buffer_too_large (with error bit) if increased array length is too large to store in the range. + * + * @see fl_fss_extended_list_object_read() + * @see fl_fss_extended_list_content_read() + */ +#if !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + extern f_return_status private_fl_fss_nest_increase(f_fss_nest_t *nest) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + +/** + * Increase the size of a given range buffer, but only if necessary. + * + * @param ranges + * The range buffer to increment. + * + * @return + * F_none on success. + * F_memory_reallocation (with error bit) on reallocation error. + * F_buffer_too_large (with error bit) if increased array length is too large to store in the range. + * + * @see fl_fss_basic_object_read() + * @see fl_fss_basic_content_read() + * @see fl_fss_extended_object_read() + * @see fl_fss_extended_content_read() + * @see fl_fss_basic_list_object_read() + * @see fl_fss_basic_list_content_read() + * @see fl_fss_extended_list_object_read() + * @see fl_fss_extended_list_content_read() + */ +#if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_basic_content_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) || !defined(_di_fl_fss_basic_list_object_read_) || !defined(_di_fl_fss_basic_list_content_read_) || !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + extern f_return_status private_fl_fss_ranges_increase(f_string_ranges_t *ranges) f_gcc_attribute_visibility_internal; +#endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_basic_content_read_) || !defined(_di_fl_fss_extended_object_read_) || !defined(_di_fl_fss_extended_content_read_) || !defined(_di_fl_fss_basic_list_object_read_) || !defined(_di_fl_fss_basic_list_content_read_) || !defined(_di_fl_fss_extended_list_object_read_) || !defined(_di_fl_fss_extended_list_content_read_) + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_1/fl_status/c/status.c b/level_1/fl_status/c/status.c index 809e337..f57c3fb 100644 --- a/level_1/fl_status/c/status.c +++ b/level_1/fl_status/c/status.c @@ -335,6 +335,12 @@ extern "C" { case F_prohibited: *string = FL_status_string_prohibited; break; + case F_range: + *string = FL_status_string_range; + break; + case F_range_not: + *string = FL_status_string_range_not; + break; case F_read_only: *string = FL_status_string_read_only; break; @@ -371,6 +377,9 @@ extern "C" { case F_utf: *string = FL_status_string_utf; break; + case F_utf_not: + *string = FL_status_string_utf_not; + break; case F_value: *string = FL_status_string_value; break; diff --git a/level_1/fl_status/c/status.h b/level_1/fl_status/c/status.h index 92d4182..87db26a 100644 --- a/level_1/fl_status/c/status.h +++ b/level_1/fl_status/c/status.h @@ -203,6 +203,8 @@ extern "C" { #define FL_status_string_process "F_process" #define FL_status_string_process_too_many "F_process_too_many" #define FL_status_string_prohibited "F_prohibited" + #define FL_status_string_range "F_range" + #define FL_status_string_range_not "F_range_not" #define FL_status_string_read_only "F_read_only" #define FL_status_string_recurse "F_recurse" #define FL_status_string_relative "F_relative" @@ -215,6 +217,7 @@ extern "C" { #define FL_status_string_unknown "F_unknown" #define FL_status_string_unsupported "F_unsupported" #define FL_status_string_utf "F_utf" + #define FL_status_string_utf_not "F_utf_not" #define FL_status_string_value "F_value" #define FL_status_string_value_not "F_value_not" #define FL_status_string_warn "F_warn" @@ -260,6 +263,8 @@ extern "C" { #define FL_status_string_process_length 9 #define FL_status_string_process_too_many_length 18 #define FL_status_string_prohibited_length 12 + #define FL_status_string_range_length 7 + #define FL_status_string_range_not_length 11 #define FL_status_string_read_only_length 11 #define FL_status_string_recurse_length 9 #define FL_status_string_relative_length 10 @@ -272,6 +277,7 @@ extern "C" { #define FL_status_string_unknown_length 9 #define FL_status_string_unsupported_length 13 #define FL_status_string_utf_length 5 + #define FL_status_string_utf_not_length 9 #define FL_status_string_value_length 7 #define FL_status_string_value_not_length 11 #define FL_status_string_warn_length 6 diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index c70a9ee..c0c5a5c 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -5,12 +5,13 @@ extern "C" { #endif #ifndef _di_fll_fss_basic_read_ - f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects) { + f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); + if (!delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; @@ -40,7 +41,7 @@ extern "C" { quoted_object = "ed_objects->array[quoted_objects->used]; } - status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used], quoted_object); + status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used], quoted_object, delimits); if (F_status_is_error(status)) { return status; @@ -83,7 +84,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_basic_content_read(buffer, range, &contents->array[contents->used]); + status = fl_fss_basic_content_read(buffer, range, &contents->array[contents->used], delimits); if (F_status_is_error(status)) return status; break; diff --git a/level_2/fll_fss/c/fss_basic.h b/level_2/fll_fss/c/fss_basic.h index 22d764d..93c6808 100644 --- a/level_2/fll_fss/c/fss_basic.h +++ b/level_2/fll_fss/c/fss_basic.h @@ -43,6 +43,9 @@ extern "C" { * @param quoted_objects * An array of all objects discovered with quotes and the quote discovered. * Set the pointer address to 0 to disable. + * @param delimits + * An array of delimits detected during processing. + * The caller is expected to decide if and when to process them. * * @return * F_none on success. @@ -61,7 +64,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_basic_object_read(). */ #ifndef _di_fll_fss_basic_read_ - extern f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects); + extern f_return_status fll_fss_basic_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_delimits_t *delimits); #endif // _di_fll_fss_basic_read_ /** diff --git a/level_2/fll_fss/c/fss_basic_list.c b/level_2/fll_fss/c/fss_basic_list.c index af1a636..3c129e7 100644 --- a/level_2/fll_fss/c/fss_basic_list.c +++ b/level_2/fll_fss/c/fss_basic_list.c @@ -5,17 +5,19 @@ extern "C" { #endif #ifndef _di_fll_fss_basic_list_read_ - f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents) { + f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); + if (!delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; f_status_t status2 = F_none; f_string_length_t initial_used = objects->used; + bool found_data = F_false; do { @@ -28,7 +30,7 @@ extern "C" { } do { - status = fl_fss_basic_list_object_read(buffer, range, &objects->array[objects->used]); + status = fl_fss_basic_list_object_read(buffer, range, &objects->array[objects->used], delimits); if (F_status_is_error(status)) return status; if (range->start >= range->stop || range->start >= buffer->used) { @@ -63,7 +65,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_basic_list_content_read(buffer, range, &contents->array[contents->used]); + status = fl_fss_basic_list_content_read(buffer, range, &contents->array[contents->used], delimits); if (F_status_is_error(status)) { return status; diff --git a/level_2/fll_fss/c/fss_basic_list.h b/level_2/fll_fss/c/fss_basic_list.h index 0f35fa7..86abeb9 100644 --- a/level_2/fll_fss/c/fss_basic_list.h +++ b/level_2/fll_fss/c/fss_basic_list.h @@ -39,6 +39,9 @@ extern "C" { * This will be populated with all valid objects found. * @param contents * This will be populated with all valid contents found. + * @param delimits + * An array of delimits detected during processing. + * The caller is expected to decide if and when to process them. * * @return * F_none on success. @@ -57,7 +60,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_basic_list_object_read(). */ #ifndef _di_fll_fss_basic_list_read_ - extern f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents); + extern f_return_status fll_fss_basic_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_delimits_t *delimits); #endif // _di_fll_fss_basic_list_read_ /** diff --git a/level_2/fll_fss/c/fss_extended.c b/level_2/fll_fss/c/fss_extended.c index f8fa1ec..480ced1 100644 --- a/level_2/fll_fss/c/fss_extended.c +++ b/level_2/fll_fss/c/fss_extended.c @@ -5,12 +5,13 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_read_ - f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents) { + f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *delimits) { #ifndef _di_level_2_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!objects) return F_status_set_error(F_parameter); if (!contents) return F_status_set_error(F_parameter); + if (!delimits) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status_t status = F_none; @@ -46,7 +47,7 @@ extern "C" { quoted_object = "ed_objects->array[quoted_objects->used]; } - status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used], quoted_object); + status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used], quoted_object, delimits); if (F_status_is_error(status)) { return status; @@ -97,7 +98,7 @@ extern "C" { quoted_content = "ed_contents->array[quoted_contents->used]; } - status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used], quoted_content); + status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used], quoted_content, delimits); if (F_status_is_error(status)) { return status; diff --git a/level_2/fll_fss/c/fss_extended.h b/level_2/fll_fss/c/fss_extended.h index 9392d2f..158b753 100644 --- a/level_2/fll_fss/c/fss_extended.h +++ b/level_2/fll_fss/c/fss_extended.h @@ -44,6 +44,9 @@ extern "C" { * @param quoted_contents * An array of all contents discovered with quotes and the quote discovered. * Set the pointer address to 0 to disable. + * @param delimits + * An array of delimits detected during processing. + * The caller is expected to decide if and when to process them. * * @return * F_none on success. @@ -62,7 +65,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_extended_object_read(). */ #ifndef _di_fll_fss_extended_read_ - extern f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents); + extern f_return_status fll_fss_extended_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_objects_t *objects, f_fss_contents_t *contents, f_fss_quotes_t *quoted_objects, f_fss_quotess_t *quoted_contents, f_fss_delimits_t *delimits); #endif // _di_fll_fss_extended_read_ /** diff --git a/level_2/fll_fss/c/fss_extended_list.c b/level_2/fll_fss/c/fss_extended_list.c index d5201f9..0cca1f5 100644 --- a/level_2/fll_fss/c/fss_extended_list.c +++ b/level_2/fll_fss/c/fss_extended_list.c @@ -5,16 +5,18 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_list_read_ - f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest) { + f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *delimits) { #ifndef _di_level_3_parameter_checking_ if (!buffer) return F_status_set_error(F_parameter); if (!range) return F_status_set_error(F_parameter); if (!nest) return F_status_set_error(F_parameter); + if (!delimits) return F_status_set_error(F_parameter); #endif // _di_level_3_parameter_checking_ f_status_t status = F_none; f_status_t status2 = F_none; f_string_length_t initial_used = 0; + bool found_data = F_false; if (!nest->used) { @@ -32,7 +34,7 @@ extern "C" { if (F_status_is_error(status)) return status; } - status = fl_fss_extended_list_object_read(buffer, range, &nest->depth[0].array[nest->depth[0].used].object); + status = fl_fss_extended_list_object_read(buffer, range, &nest->depth[0].array[nest->depth[0].used].object, delimits); if (F_status_is_error(status)) return status; if (range->start >= range->stop || range->start >= buffer->used) { @@ -61,7 +63,7 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_extended_list_content_read(buffer, range, nest); + status = fl_fss_extended_list_content_read(buffer, range, nest, delimits); break; } diff --git a/level_2/fll_fss/c/fss_extended_list.h b/level_2/fll_fss/c/fss_extended_list.h index f4b3576..d8153bf 100644 --- a/level_2/fll_fss/c/fss_extended_list.h +++ b/level_2/fll_fss/c/fss_extended_list.h @@ -36,6 +36,9 @@ extern "C" { * The range within the buffer that is currently being read. * @param nest * An nested set of all objects and content. + * @param delimits + * An array of delimits detected during processing. + * The caller is expected to decide if and when to process them. * * @return * F_none on success (both valid object and valid content found with start location is at end of content). @@ -61,7 +64,7 @@ extern "C" { * Errors (with error bit) from: fl_fss_extended_list_object_read(). */ #ifndef _di_fll_fss_extended_list_read_ - extern f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest); + extern f_return_status fll_fss_extended_list_read(f_string_dynamic_t *buffer, f_string_range_t *range, f_fss_nest_t *nest, f_fss_delimits_t *delimits); #endif // _di_fll_fss_extended_list_read_ /** diff --git a/level_2/fll_status/c/status.c b/level_2/fll_status/c/status.c index 010a735..8a5e3c2 100644 --- a/level_2/fll_status/c/status.c +++ b/level_2/fll_status/c/status.c @@ -561,6 +561,16 @@ extern "C" { return F_none; } + if (fl_string_compare(string, FL_status_string_range, length, FL_status_string_range_length) == F_equal_to) { + *code = F_range; + return F_none; + } + + if (fl_string_compare(string, FL_status_string_range_not, length, FL_status_string_range_not_length) == F_equal_to) { + *code = F_range_not; + return F_none; + } + if (fl_string_compare(string, FL_status_string_read_only, length, FL_status_string_read_only_length) == F_equal_to) { *code = F_read_only; return F_none; @@ -621,6 +631,11 @@ extern "C" { 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; + return F_none; + } + if (fl_string_compare(string, FL_status_string_value, length, FL_status_string_value_length) == F_equal_to) { *code = F_value; return F_none; diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.c b/level_3/fss_basic_list_read/c/fss_basic_list_read.c index 4c1310c..811d814 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.c @@ -307,6 +307,8 @@ extern "C" { fss_basic_list_read_depths_t depths = fss_basic_list_read_depths_t_initialize; + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_string_length_t original_size = data->quantity.total; if (F_status_is_error_not(status)) { @@ -320,6 +322,7 @@ extern "C" { // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_basic_list_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); @@ -348,7 +351,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_basic_list_read_main_process_file(arguments, data, "-", depths); + status = fss_basic_list_read_main_process_file(arguments, data, "-", depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -404,7 +407,7 @@ extern "C" { break; } - status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); + status = fss_basic_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -425,6 +428,7 @@ extern "C" { } macro_fss_basic_list_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c index 903702f..b490854 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c @@ -170,7 +170,7 @@ extern "C" { #endif // _di_fss_basic_list_read_main_preprocess_depth_ #ifndef _di_fss_basic_list_read_main_process_file_ - f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t filename, const fss_basic_list_read_depths_t depths) { + f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t filename, const fss_basic_list_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; { @@ -179,26 +179,48 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); + delimits->used = 0; + + status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents, delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + return status; } - else if (status == F_data_not_stop || status == F_data_not_eos) { + + if (status == F_data_not_stop || status == F_data_not_eos) { + + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + if (data->parameters[fss_basic_list_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); return F_none; } + return F_status_set_warning(status); + } + + status = fl_fss_apply_delimit(*delimits, &data->buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); - return F_status_set_warning(status); + return status; } } diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h index 7981f93..439b6c9 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h @@ -187,6 +187,8 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. + * @param delimits + * An array of delimits detected during processing. * * @return * F_none on success. @@ -196,7 +198,7 @@ extern "C" { * @see fss_basic_list_read_main_preprocess_depth() */ #ifndef _di_fss_basic_list_read_main_process_file_ - extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t file_name, const fss_basic_list_read_depths_t depths) f_gcc_attribute_visibility_internal; + extern f_return_status fss_basic_list_read_main_process_file(const f_console_arguments_t arguments, fss_basic_list_read_data_t *data, const f_string_t file_name, const fss_basic_list_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_list_read_main_process_file_ /** diff --git a/level_3/fss_basic_read/c/fss_basic_read.c b/level_3/fss_basic_read/c/fss_basic_read.c index a2c0511..6e80642 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -307,6 +307,8 @@ extern "C" { fss_basic_read_depths_t depths = fss_basic_read_depths_t_initialize; + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_string_length_t original_size = data->quantity.total; if (F_status_is_error_not(status)) { @@ -320,6 +322,7 @@ extern "C" { // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_basic_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); @@ -349,7 +352,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_basic_read_main_process_file(arguments, data, "-", depths); + status = fss_basic_read_main_process_file(arguments, data, "-", depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -405,7 +408,7 @@ extern "C" { break; } - status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); + status = fss_basic_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_basic_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -426,6 +429,7 @@ extern "C" { } macro_fss_basic_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-fss_basic_read.c index 477fad4..3a9ac07 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-fss_basic_read.c @@ -170,7 +170,7 @@ extern "C" { #endif // _di_fss_basic_read_main_preprocess_depth_ #ifndef _di_fss_basic_read_main_process_file_ - f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t filename, const fss_basic_read_depths_t depths) { + f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t filename, const fss_basic_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; { @@ -179,26 +179,48 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0); + delimits->used = 0; + + status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0, delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_basic_read", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + return status; } - else if (status == F_data_not_stop || status == F_data_not_eos) { + + if (status == F_data_not_stop || status == F_data_not_eos) { + + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + if (data->parameters[fss_basic_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); return F_none; } + return F_status_set_warning(status); + } + + status = fl_fss_apply_delimit(*delimits, &data->buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); - return F_status_set_warning(status); + return status; } } diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.h b/level_3/fss_basic_read/c/private-fss_basic_read.h index 7cd0138..bf24b88 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.h +++ b/level_3/fss_basic_read/c/private-fss_basic_read.h @@ -188,11 +188,13 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. + * @param delimits + * An array of delimits detected during processing. * * @see fss_basic_read_main_preprocess_depth() */ #ifndef _di_fss_basic_read_main_process_file_ - extern f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t file_name, const fss_basic_read_depths_t depths) f_gcc_attribute_visibility_internal; + extern f_return_status fss_basic_read_main_process_file(const f_console_arguments_t arguments, fss_basic_read_data_t *data, const f_string_t file_name, const fss_basic_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_basic_read_main_process_file_ /** diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 85b4268..5467ddb 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -307,6 +307,8 @@ extern "C" { fss_extended_list_read_depths_t depths = fss_extended_list_read_depths_t_initialize; + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_string_length_t original_size = data->quantity.total; if (F_status_is_error_not(status)) { @@ -336,7 +338,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_extended_list_read_main_process_file(arguments, data, "-", depths); + status = fss_extended_list_read_main_process_file(arguments, data, "-", depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -390,7 +392,7 @@ extern "C" { break; } - status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); + status = fss_extended_list_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_list_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -409,6 +411,7 @@ extern "C" { } macro_fss_extended_list_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index bd82353..1e2c3c0 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -170,7 +170,7 @@ extern "C" { #endif // _di_fss_extended_list_read_main_preprocess_depth_ #ifndef _di_fss_extended_list_read_main_process_file_ - f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depths_t depths) { + f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t filename, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; { @@ -179,25 +179,45 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest); + delimits->used = 0; + + status = fll_fss_extended_list_read(&data->buffer, &input, &data->nest, delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_list_read", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. + f_macro_fss_nest_t_delete_simple(data->nest); + f_macro_string_dynamic_t_delete_simple(data->buffer); + return status; } - else if (status == F_data_not_stop || status == F_data_not_eos) { + + if (status == F_data_not_stop || status == F_data_not_eos) { + + // Clear buffers, then attempt the next file. + f_macro_fss_nest_t_delete_simple(data->nest); + f_macro_string_dynamic_t_delete_simple(data->buffer); + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); return F_none; } + return F_status_set_warning(status); + } + + status = fl_fss_apply_delimit(*delimits, &data->buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. f_macro_fss_nest_t_delete_simple(data->nest); f_macro_string_dynamic_t_delete_simple(data->buffer); - return F_status_set_warning(status); + return status; } } @@ -612,6 +632,15 @@ extern "C" { } #endif // _di_fss_extended_list_read_print_content_end_ +#ifndef _di_fss_extended_list_read_print_content_ignore_ + void fss_extended_list_read_print_content_ignore(const fss_extended_list_read_data_t data) { + + if (data.parameters[fss_extended_list_read_parameter_pipe].result == f_console_result_found) { + fprintf(data.output.stream, "%c", fss_extended_list_read_pipe_content_ignore); + } + } +#endif // _di_fss_extended_list_read_print_content_ignore_ + #ifndef _di_fss_extended_list_read_print_set_end_ void fss_extended_list_read_print_set_end(const fss_extended_list_read_data_t data) { diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h index fb1d31f..c9e15cf 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h @@ -188,12 +188,14 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. + * @param delimits + * An array of delimits detected during processing. * * @see fss_extended_list_read_main_preprocess_depth() * @see fss_extended_list_read_main_process_for_depth() */ #ifndef _di_fss_extended_list_read_main_process_file_ - extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t file_name, const fss_extended_list_read_depths_t depths) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_list_read_main_process_file(const f_console_arguments_t arguments, fss_extended_list_read_data_t *data, const f_string_t file_name, const fss_extended_list_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_list_read_main_process_file_ /** @@ -240,6 +242,18 @@ extern "C" { #endif // _di_fss_extended_list_read_print_content_end_ /** + * Print the ignore character for content. + * + * This is only used in pipe output mode. + * + * @param data + * The program specific data. + */ +#ifndef _di_fss_extended_list_read_print_content_ignore_ + extern void fss_extended_list_read_print_content_ignore(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal; +#endif // _di_fss_extended_list_read_print_content_ignore_ + +/** * Print the end of an object/content set. * * @param data diff --git a/level_3/fss_extended_read/c/fss_extended_read.c b/level_3/fss_extended_read/c/fss_extended_read.c index db54be0..7c69b80 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -307,6 +307,8 @@ extern "C" { fss_extended_read_depths_t depths = fss_extended_read_depths_t_initialize; + f_fss_delimits_t delimits = f_fss_delimits_t_initialize; + f_string_length_t original_size = data->quantity.total; if (F_status_is_error_not(status)) { @@ -317,15 +319,10 @@ extern "C" { } } - if (F_status_is_error(status)) { - macro_fss_extended_read_depths_t_delete_simple(depths); - fss_extended_read_delete_data(data); - return status; - } - // This standard does not support nesting, so any depth greater than 0 can be predicted without processing the file. if (F_status_is_error_not(status) && depths.array[0].depth > 0) { macro_fss_extended_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); @@ -354,7 +351,7 @@ extern "C" { fll_error_file_print(data->error, F_status_set_fine(status), "f_file_read", F_true, "-", "read", fll_error_file_type_pipe); } else { - status = fss_extended_read_main_process_file(arguments, data, "-", depths); + status = fss_extended_read_main_process_file(arguments, data, "-", depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, "-", "read", fll_error_file_type_pipe); @@ -410,7 +407,7 @@ extern "C" { break; } - status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths); + status = fss_extended_read_main_process_file(arguments, data, arguments.argv[data->remaining.array[i]], depths, &delimits); if (F_status_is_error(status)) { fll_error_file_print(data->error, F_status_set_fine(status), "fss_extended_read_main_process_file", F_true, arguments.argv[data->remaining.array[i]], "read", fll_error_file_type_file); @@ -431,6 +428,7 @@ extern "C" { } macro_fss_extended_read_depths_t_delete_simple(depths); + f_macro_fss_delimits_t_delete_simple(delimits); } else { fl_color_print(data->error.to.stream, data->context.set.error, "%sYou failed to specify one or more files.%c", fll_error_print_error, f_string_eol[0]); diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-fss_extended_read.c index 559c742..d333dea 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-fss_extended_read.c @@ -170,7 +170,7 @@ extern "C" { #endif // _di_fss_extended_read_main_preprocess_depth_ #ifndef _di_fss_extended_read_main_process_file_ - f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t filename, const fss_extended_read_depths_t depths) { + f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t filename, const fss_extended_read_depths_t depths, f_fss_delimits_t *delimits) { f_status_t status = F_none; { @@ -179,26 +179,48 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0); + delimits->used = 0; + + status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0, delimits); if (F_status_is_error(status)) { // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(data->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + return status; } - else if (status == F_data_not_stop || status == F_data_not_eos) { + + if (status == F_data_not_stop || status == F_data_not_eos) { + + // Clear buffers, then attempt the next file. + f_macro_fss_contents_t_delete_simple(data->contents); + f_macro_fss_objects_t_delete_simple(data->objects); + f_macro_string_dynamic_t_delete_simple(data->buffer); + if (data->parameters[fss_extended_read_parameter_total].result == f_console_result_found) { fprintf(f_type_output, "0%c", f_string_eol[0]); return F_none; } + return F_status_set_warning(status); + } + + status = fl_fss_apply_delimit(*delimits, &data->buffer); + + if (F_status_is_error(status)) { + fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, filename, "process", fll_error_file_type_file); + // Clear buffers, then attempt the next file. f_macro_fss_contents_t_delete_simple(data->contents); f_macro_fss_objects_t_delete_simple(data->objects); f_macro_string_dynamic_t_delete_simple(data->buffer); - return F_status_set_warning(status); + return status; } } diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.h b/level_3/fss_extended_read/c/private-fss_extended_read.h index 06bb8e8..1acb416 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.h +++ b/level_3/fss_extended_read/c/private-fss_extended_read.h @@ -188,11 +188,13 @@ extern "C" { * The name of the file being processed. * @param depths * The processed depth parameters. + * @param delimits + * An array of delimits detected during processing. * * @see fss_extended_read_main_preprocess_depth() */ #ifndef _di_fss_extended_read_main_process_file_ - extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths) f_gcc_attribute_visibility_internal; + extern f_return_status fss_extended_read_main_process_file(const f_console_arguments_t arguments, fss_extended_read_data_t *data, const f_string_t file_name, const fss_extended_read_depths_t depths, f_fss_delimits_t *delimits) f_gcc_attribute_visibility_internal; #endif // _di_fss_extended_read_main_process_file_ /** -- 1.8.3.1