From: Kevin Day Date: Tue, 20 Oct 2020 04:55:53 +0000 (-0500) Subject: Update: FSS should allow caller to determine when to apply delimits. X-Git-Tag: 0.5.1~24 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=e6cf07bb1c9b55fb8181661d081e42f413294188;p=fll 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. --- diff --git a/build/level_0/settings b/build/level_0/settings index 4725621ae..770c3fc73 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 4e87cda9b..30ee62082 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 989224b4d..b8129adb8 100644 --- a/level_0/f_fss/c/fss-common.h +++ b/level_0/f_fss/c/fss-common.h @@ -122,33 +122,13 @@ 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. * diff --git a/level_0/f_fss/c/fss.c b/level_0/f_fss/c/fss.c index 9ddc9924b..1b422a6e6 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 2a3e45e18..44e44c55c 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 @@ -34,6 +35,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. * @@ -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 000000000..2eda779e7 --- /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 2dc4f0237..3b8af4928 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 17e05451a..e06e7cd05 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 28990f670..e4e30b926 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 3cdcbb170..f8bd34c3d 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 469b92187..ef7146d6a 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 a3285908b..c331cbe8c 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 559de6767..fc6689f05 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 4425ea67e..01b2bcef4 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 cdb45d4b3..7285c2fff 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 6cafe55da..997693b82 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 4df21161c..084a3b085 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 8364c636e..be6b09485 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 6d9a65136..4a2e02a27 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 @@ -1049,6 +1007,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 644efe787..0a9baed72 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -81,27 +81,6 @@ extern "C" { extern f_return_status private_fl_fss_basic_list_write_object_trim(const f_string_length_t used_start, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; #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(). * @@ -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_) /** @@ -206,6 +187,56 @@ extern "C" { extern f_return_status private_fl_fss_basic_write(const bool object_as, const f_string_static_t object, const f_fss_quote_t quoted, f_string_range_t *range, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; #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. * @@ -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 809e33782..f57c3fb61 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 92d41822f..87db26a7c 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 c70a9ee4a..c0c5a5ca9 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 22d764dd1..93c6808dd 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 af1a636b9..3c129e7f5 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 0f35fa779..86abeb98b 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 f8fa1ec9a..480ced12e 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 9392d2ff1..158b75361 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 d5201f98a..0cca1f56b 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 f4b3576bc..d8153bf8a 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 010a7357b..8a5e3c29c 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 4c1310cc3..811d814f9 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 903702fba..b490854c0 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 7981f939e..439b6c942 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 a2c051151..6e8064280 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 477fad430..3a9ac0705 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 7cd013812..bf24b885b 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 85b4268cf..5467ddb1b 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 bd823534b..1e2c3c08d 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 fb1d31f2d..c9e15cf0a 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_ /** @@ -239,6 +241,18 @@ extern "C" { extern void fss_extended_list_read_print_content_end(const fss_extended_list_read_data_t data) f_gcc_attribute_visibility_internal; #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. * 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 db54be0c3..7c69b80b0 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 559c74274..d333dea16 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 06bb8e8f1..1acb4160d 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_ /**