From: Kevin Day Date: Thu, 9 Jul 2020 05:13:15 +0000 (-0500) Subject: Progress: add support for determining quotes in use, other fixes and cleanups. X-Git-Tag: 0.5.0~101 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=9ea8bb6428f83e780caa03caaa868be6c44a1656;p=fll Progress: add support for determining quotes in use, other fixes and cleanups. While not enthusiastic about this, I believe that I need to report the quote used to the caller. Make this an optional parameter. This took some significant consideration. Not all standards utilize quotes and I also do not want to make FSS object and content types more complex than ranges. Using a separate variable, while a bit more tedious in having to maintain consistency, is an acceptable approach. FSS-0000 objects, FSS-0001 objects, and FSS-0001 contents all use the same logic for identifying their types. Reduce code by using the same function. Because FSS-0001 contents is an array of contents, move delimit processing outside of the private function. Replace (used + 1 > size) checks with (used == size) checks to increase performance by avoiding arithmetic operations. Replace (used <= 0) checks with (used == 0) checks to remove unnecessary checks. Replace (used != 0) checks with (used) checks to avoid extra processor work. When incrementing and decrementing buffer, do not report used as an error, instead just return F_data_not. Shorten pre_allocate_size to size_allocate. Stop setting F_unterminated_group_stop and F_unterminated_group_eos as warnings. This was not done consistently. Rename buffer to destination for FSS write functions. At some point in the past I was wanting to use while loops more exclusively. After some some significant time and consideration, I have decided to abandon that idea. Use for loops where they make more sense over while loops. Continue work in Featureless Make. --- diff --git a/build/level_0/settings b/build/level_0/settings index 3dd0c74..70efff6 100644 --- a/build/level_0/settings +++ b/build/level_0/settings @@ -22,7 +22,7 @@ build_libraries -lc build_libraries-level build_sources_library console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c memory.c path.c pipe.c print.c serialize.c private-serialize.c socket.c utf.c private-utf.c build_sources_program -build_sources_headers color.h console.h conversion.h directory.h directory_type.h environment.h file.h fss.h fss-common.h fss-named.h fss-nest.h fss-set.h iki.h iki-common.h memory.h memory-structure.h path.h pipe.h print.h serialize.h socket.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 color.h console.h conversion.h directory.h directory_type.h environment.h file.h fss.h fss-common.h fss-named.h fss-nest.h fss-quoted.h fss-set.h iki.h iki-common.h memory.h memory-structure.h path.h pipe.h print.h serialize.h socket.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 c5d58c6..25fabb2 100644 --- a/build/monolithic/settings +++ b/build/monolithic/settings @@ -22,7 +22,7 @@ build_libraries -lc build_libraries-monolithic build_sources_library 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/memory.c level_0/path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.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/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/execute.c level_2/private-execute.c level_2/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/program.c level_2/status.c build_sources_program -build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.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/pipe.h level_0/print.h level_0/serialize.h level_0/socket.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/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/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/program.h level_2/status.h +build_sources_headers level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.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/pipe.h level_0/print.h level_0/serialize.h level_0/socket.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/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/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/program.h level_2/status.h build_sources_script build_sources_setting build_script yes diff --git a/documents/todo.txt b/documents/todo.txt index 5e32720..f439c50 100644 --- a/documents/todo.txt +++ b/documents/todo.txt @@ -99,4 +99,18 @@ Review all level 3 projects and more closely follow the practices in this projec Consider implementing a specification for accessibility characters using non-printing characters as a code word followed by another UTF-8 character to represent its code. Followed by a UTF-8 character s done to ensure type safety. This is likely to be limited to programs/terminals that accept it as to avoid printing extra noise. -A simpler compatible version might be made that only utilies non-printing characters. +A simpler compatible version might be made that only utilizes non-printing characters. + +Improve the FSS write functions as follows: +- allow specifying both object and content at the same time, such as "fss_basic_write -o 'my object' -c 'my content'". + - This adds a new parameter -c/--content. + - This removes the parameter -s/--string. + - Both -o/--object and -c/--content will require a parameter (set an empty sting for an empty value). + - There can be only one -o/--object, but there can be multiple -c/--content (for fss-0000 (basic), multiple content would be appended together). +- allow for designating how the pipe shall be handled, -O/--pipe_object or -C/--pipe_content (pipe data can exclusively only be an object or content but not both). +- look into supporting NULL separation for providing the possibility of having the piped data contain both object and content such that a single null separates the object from the content. + - if the data starts with a null then it is content. ("\0My Content" = content only, "my object" = object only, "my object\0My content" = object and content. + - if implemented, would be designated by the -p/--pipe parameter. + - might not be possible as pipe might naturally terminate on NULL (investigate this). +- Add -d/--double and -s/--single parameters to designate that this is to be quoted and then using single quotes or double quotes. + - consider adding -D/--double_if and -S/--single_if for only adding single or double quotes if quoting is required. diff --git a/level_0/f_console/c/console.c b/level_0/f_console/c/console.c index 0ac63da..f0e8090 100644 --- a/level_0/f_console/c/console.c +++ b/level_0/f_console/c/console.c @@ -78,7 +78,7 @@ extern "C" { if (needs_additional.used > 0) { i = needs_additional.array[0]; - if (parameters.parameter[i].additional.used >= parameters.parameter[i].additional.size) { + if (parameters.parameter[i].additional.used == parameters.parameter[i].additional.size) { f_macro_string_lengths_resize(status, parameters.parameter[i].additional, parameters.parameter[i].additional.size + f_console_default_allocation_step); if (F_status_is_error(status)) { @@ -193,7 +193,7 @@ extern "C" { continue; } - if (parameters.parameter[i].locations.used >= parameters.parameter[i].locations.size) { + if (parameters.parameter[i].locations.used == parameters.parameter[i].locations.size) { f_macro_string_lengths_resize(status, parameters.parameter[i].locations, parameters.parameter[i].locations.size + f_console_default_allocation_step); if (F_status_is_error(status)) { @@ -246,7 +246,7 @@ extern "C" { if (strncmp(arguments.argv[location], parameters.parameter[i].symbol_other, string_length + 1) != 0) continue; - if (parameters.parameter[i].locations.used >= parameters.parameter[i].locations.size) { + if (parameters.parameter[i].locations.used == parameters.parameter[i].locations.size) { f_macro_string_lengths_resize(status, parameters.parameter[i].locations, parameters.parameter[i].locations.size + f_console_default_allocation_step); if (F_status_is_error(status)) { @@ -285,7 +285,7 @@ extern "C" { if (!found) { // populate list of remaining parameters.parameter not associated with anything. - if (remaining->used >= remaining->size) { + if (remaining->used == remaining->size) { f_macro_memory_structure_macro_increment(status, (*remaining), 1, f_console_default_allocation_step, f_macro_string_lengths_resize, F_buffer_too_large); if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(needs_additional); diff --git a/level_0/f_directory/c/directory.c b/level_0/f_directory/c/directory.c index b37bf20..2467f3b 100644 --- a/level_0/f_directory/c/directory.c +++ b/level_0/f_directory/c/directory.c @@ -190,7 +190,7 @@ extern "C" { continue; } - if (names->used >= names->size) { + if (names->used == names->size) { f_macro_memory_structure_macro_increment(status, (*names), 1, f_directory_default_allocation_step, f_macro_string_dynamics_resize, F_buffer_too_large); if (F_status_is_error(status)) break; } diff --git a/level_0/f_fss/c/fss-common.h b/level_0/f_fss/c/fss-common.h index 1589329..64f47cc 100644 --- a/level_0/f_fss/c/fss-common.h +++ b/level_0/f_fss/c/fss-common.h @@ -47,10 +47,10 @@ extern "C" { * FSS-specific delimiters. */ #ifndef _di_f_fss_delimiters_ - #define f_fss_delimit_slash '\\' - #define f_fss_delimit_single_quote '\'' - #define f_fss_delimit_double_quote '"' #define f_fss_delimit_placeholder f_string_placeholder[0] + #define f_fss_delimit_quote_single '\'' + #define f_fss_delimit_quote_double '"' + #define f_fss_delimit_slash '\\' #endif //_di_f_fss_delimiters_ /** diff --git a/level_0/f_fss/c/fss-quoted.h b/level_0/f_fss/c/fss-quoted.h new file mode 100644 index 0000000..faaf307 --- /dev/null +++ b/level_0/f_fss/c/fss-quoted.h @@ -0,0 +1,102 @@ +/** + * 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_quoted_h +#define _F_fss_quoted_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Types for FSS quoted. + */ +#ifndef _di_f_fss_quoted_type_ + enum { + f_fss_quoted_type_single = 1, + f_fss_quoted_type_double, + }; +#endif // _di_f_fss_quoted_type_ + +/** + * Designate an fss quoted. + */ +#ifndef _di_f_fss_quoted_ + typedef uint8_t f_fss_quoted; +#endif // _di_f_fss_quoted_ + +/** + * An array of f_fss_quoted. + * + * array: the array of fss quoted. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_fss_quoteds_ + typedef struct { + f_fss_quoted *array; + + f_array_length size; + f_array_length used; + } f_fss_quoteds; + + #define f_fss_quoteds_initialize {0, 0, 0} + + #define f_macro_fss_quoteds_clear(quoteds) f_macro_memory_structure_clear(quoteds) + + #define f_macro_fss_quoteds_new(status, quoteds, length) f_macro_memory_structure_new(status, quoteds, f_fss_quoted, length) + + #define f_macro_fss_quoteds_delete(status, quoteds) f_macro_memory_structure_delete(status, quoteds, f_fss_quoted) + #define f_macro_fss_quoteds_destroy(status, quoteds) f_macro_memory_structure_destroy(status, quoteds, f_fss_quoted) + + #define f_macro_fss_quoteds_delete_simple(quoteds) f_macro_memory_structure_delete_simple(quoteds, f_fss_quoted) + #define f_macro_fss_quoteds_destroy_simple(quoteds) f_macro_memory_structure_destroy_simple(quoteds, f_fss_quoted) + + #define f_macro_fss_quoteds_resize(status, quoteds, new_length) f_macro_memory_structure_resize(status, quoteds, f_fss_quoted, new_length) + #define f_macro_fss_quoteds_adjust(status, quoteds, new_length) f_macro_memory_structure_adjust(status, quoteds, f_fss_quoted, new_length) +#endif // _di_f_fss_quoteds_ + +/** + * An array of f_fss_quoteds. + * + * array: the array of fss quoteds. + * size: total amount of allocated space. + * used: total number of allocated spaces used. + */ +#ifndef _di_f_fss_quotedss_ + typedef struct { + f_fss_quoteds *array; + + f_array_length size; + f_array_length used; + } f_fss_quotedss; + + #define f_fss_quotedss_initialize {0, 0, 0} + + #define f_macro_fss_quotedss_clear(quotedss) f_macro_memory_structures_clear(quotedss) + + #define f_macro_fss_quotedss_new(status, quotedss, length) f_macro_memory_structures_new(status, quotedss, f_fss_quoteds, length) + + #define f_macro_fss_quotedss_delete(status, quotedss) f_macro_memory_structures_delete(status, quotedss, f_fss_quoted, f_fss_quoteds) + #define f_macro_fss_quotedss_destroy(status, quotedss) f_macro_memory_structures_destroy(status, quotedss, f_fss_quoted, f_fss_quoteds) + + #define f_macro_fss_quotedss_delete_simple(quotedss) f_macro_memory_structures_delete_simple(quotedss, f_fss_quoted, f_fss_quoteds) + #define f_macro_fss_quotedss_destroy_simple(quotedss) f_macro_memory_structures_destroy_simple(quotedss, f_fss_quoted, f_fss_quoteds) + + #define f_macro_fss_quotedss_resize(status, quotedss, new_length) f_macro_memory_structures_resize(status, quotedss, f_fss_quoted, f_fss_quoteds, new_length, f_array_length) + #define f_macro_fss_quotedss_adjust(status, quotedss, new_length) f_macro_memory_structures_adjust(status, quotedss, f_fss_quoted, f_fss_quoteds, new_length, f_array_length) +#endif // _di_f_fss_quotedss_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _F_fss_quoted_h diff --git a/level_0/f_fss/c/fss.c b/level_0/f_fss/c/fss.c index 0b14eb9..d2b244d 100644 --- a/level_0/f_fss/c/fss.c +++ b/level_0/f_fss/c/fss.c @@ -7,7 +7,7 @@ extern "C" { #ifndef _di_f_fss_count_lines_ f_return_status f_fss_count_lines(const f_string_static buffer, const f_string_length before, f_string_length *line) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (before >= buffer.used) return F_status_set_error(F_parameter); if (line == 0) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ @@ -31,7 +31,7 @@ extern "C" { #ifndef _di_f_fss_count_lines_range_ f_return_status f_fss_count_lines_range(const f_string_static buffer, const f_string_range range, const f_string_length before, f_string_length *line) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) 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); @@ -58,7 +58,7 @@ extern "C" { #ifndef _di_f_fss_is_graph_ f_return_status f_fss_is_graph(const f_string_static buffer, const f_string_range range) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) 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); @@ -77,7 +77,7 @@ extern "C" { #ifndef _di_f_fss_is_space_ f_return_status f_fss_is_space(const f_string_static buffer, const f_string_range range) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) 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); @@ -91,7 +91,6 @@ extern "C" { width_max = buffer.used - range.start; } - // Handle (ASCII) zero-width spaces and control characters (isspace() or iscntrl() might consider some of these spaces). status = f_utf_is_zero_width(buffer.string + range.start, width_max); if (status != F_false) { @@ -115,7 +114,7 @@ extern "C" { #ifndef _di_f_fss_is_zero_width_ f_return_status f_fss_is_zero_width(const f_string_static buffer, const f_string_range range) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) 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); @@ -197,9 +196,9 @@ extern "C" { #ifndef _di_f_fss_skip_past_space_ f_return_status f_fss_skip_past_space(const f_string_static buffer, f_string_range *range) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) 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_ @@ -271,9 +270,9 @@ extern "C" { #ifndef _di_f_fss_skip_past_non_graph_ f_return_status f_fss_skip_past_non_graph(const f_string_static buffer, f_string_range *range) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) 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_ diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index eeabe78..bc4726b 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #ifdef __cplusplus diff --git a/level_0/f_fss/data/build/settings b/level_0/f_fss/data/build/settings index ed6c2fd..2aed800 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_utf -lf_memory build_sources_library fss.c build_sources_program -build_sources_headers fss.h fss-common.h fss-named.h fss-nest.h fss-set.h +build_sources_headers fss.h fss-common.h fss-named.h fss-nest.h fss-quoted.h fss-set.h build_sources_script build_sources_setting build_script yes diff --git a/level_0/f_iki/c/iki-common.h b/level_0/f_iki/c/iki-common.h index 6b6ed7e..dfd9e2a 100644 --- a/level_0/f_iki/c/iki-common.h +++ b/level_0/f_iki/c/iki-common.h @@ -203,9 +203,9 @@ extern "C" { #ifndef _di_f_macro_iki_allocate_delimits_if_necessary_ #define f_macro_iki_allocate_delimits_if_necessary(status, delimits) \ status = F_none; \ - if (delimits.used + 1 > delimits.size) { \ + if (delimits.used == delimits.size) { \ if (delimits.used + f_iki_default_allocation_step > f_string_length_size) { \ - if (delimits.used + 1 > f_string_length_size) { \ + if (delimits.used == f_string_length_size) { \ status = F_status_set_error(F_string_too_large); \ } \ else { \ @@ -227,9 +227,9 @@ extern "C" { #ifndef _di_f_macro_iki_allocate_ranges_if_necessary_ #define f_macro_iki_allocate_ranges_if_necessary(status, ranges) \ status = F_none; \ - if (ranges.used + 1 > ranges.size) { \ + if (ranges.used == ranges.size) { \ if (ranges.used + f_iki_default_allocation_step > f_string_length_size) { \ - if (ranges.used + 1 > f_string_length_size) { \ + if (ranges.used == f_string_length_size) { \ status = F_status_set_error(F_string_too_large); \ } \ else { \ diff --git a/level_0/f_iki/c/iki.c b/level_0/f_iki/c/iki.c index 453c2f0..ec5708b 100644 --- a/level_0/f_iki/c/iki.c +++ b/level_0/f_iki/c/iki.c @@ -8,11 +8,11 @@ extern "C" { f_return_status f_iki_read(f_string_static *buffer, f_string_range *range, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content) { #ifndef _di_level_0_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (variable == 0) return F_status_set_error(F_parameter); if (vocabulary == 0) return F_status_set_error(F_parameter); if (content == 0) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ diff --git a/level_0/f_print/c/print.c b/level_0/f_print/c/print.c index 2bb3a58..3499922 100644 --- a/level_0/f_print/c/print.c +++ b/level_0/f_print/c/print.c @@ -28,7 +28,7 @@ extern "C" { #ifndef _di_f_print_string_dynamic_ f_return_status f_print_string_dynamic(FILE *output, const f_string_static buffer) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ register f_string_length i = 0; @@ -50,7 +50,7 @@ extern "C" { #ifndef _di_level_0_parameter_checking_ if (range.start < 0) return F_status_set_error(F_parameter); if (range.start > range.stop) return F_status_set_error(F_parameter); - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (range.start >= buffer.used) return F_status_set_error(F_parameter); if (range.stop >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ diff --git a/level_0/f_status/c/status_array.h b/level_0/f_status/c/status_array.h index 47e87d4..6e766f9 100644 --- a/level_0/f_status/c/status_array.h +++ b/level_0/f_status/c/status_array.h @@ -76,8 +76,8 @@ extern "C" { #define f_macro_statusss_delete_simple(statusss) f_macro_memory_structures_delete_simple(statusss, f_status, f_statuss) #define f_macro_statusss_destroy_simple(statusss) f_macro_memory_structures_destroy_simple(statusss, f_status, f_statuss) - #define f_macro_statusss_resize(status, statusss, new_length) f_macro_memory_structures_resize(status, statusss, f_status, f_statuss, new_length) - #define f_macro_statusss_adjust(status, statusss, new_length) f_macro_memory_structures_adjust(status, statusss, f_status, f_statuss, new_length) + #define f_macro_statusss_resize(status, statusss, new_length) f_macro_memory_structures_resize(status, statusss, f_status, f_statuss, new_length, f_array_length) + #define f_macro_statusss_adjust(status, statusss, new_length) f_macro_memory_structures_adjust(status, statusss, f_status, f_statuss, new_length, f_array_length) #endif // _di_f_statuss_ #ifdef __cplusplus diff --git a/level_0/f_utf/c/utf.c b/level_0/f_utf/c/utf.c index 31412f0..b234fdc 100644 --- a/level_0/f_utf/c/utf.c +++ b/level_0/f_utf/c/utf.c @@ -8,13 +8,14 @@ extern "C" { #ifndef _di_f_utf_buffer_decrement_ f_return_status f_utf_buffer_decrement(const f_string_static buffer, f_string_range *range, const f_string_length step) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used == 0) return F_status_set_error(F_parameter); if (range == 0) 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 (step < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (buffer.used == 0) return F_data_not; + f_string_length i = 0; unsigned short width = 0; @@ -40,13 +41,14 @@ extern "C" { #ifndef _di_f_utf_buffer_increment_ f_return_status f_utf_buffer_increment(const f_string_static buffer, f_string_range *range, const f_string_length step) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used == 0) return F_status_set_error(F_parameter); if (range == 0) 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 (step < 1) return F_status_set_error(F_parameter); #endif // _di_level_0_parameter_checking_ + if (buffer.used == 0) return F_data_not; + f_string_length i = 0; unsigned short width = 0; diff --git a/level_0/f_utf/c/utf.h b/level_0/f_utf/c/utf.h index dcc4757..c7d2935 100644 --- a/level_0/f_utf/c/utf.h +++ b/level_0/f_utf/c/utf.h @@ -76,6 +76,7 @@ extern "C" { * F_none on success. * F_none_stop if the stop range is reached before all steps are completed. * F_none_eos if the end of buffer is reached before all steps are completed. + * F_data_not if buffer is empty. * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. * F_parameter (with error bit) if a parameter is invalid. */ @@ -106,6 +107,7 @@ extern "C" { * F_none on success. * F_none_stop if the stop range is reached before all steps are completed. * F_none_eos if the end of buffer is reached before all steps are completed. + * F_data_not if buffer is empty. * F_incomplete_utf_stop (with error bit) if the stop range is reached before the complete UTF-8 character can be processed. * F_incomplete_utf_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. * F_parameter (with error bit) if a parameter is invalid. diff --git a/level_1/fl_color/c/color.c b/level_1/fl_color/c/color.c index 6eacd4e..ef10197 100644 --- a/level_1/fl_color/c/color.c +++ b/level_1/fl_color/c/color.c @@ -120,7 +120,7 @@ extern "C" { if (string == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (start_color.used != 0) { + if (start_color.used) { f_status status = f_print_string_dynamic(file, start_color); if (F_status_is_error(status)) return status; } @@ -133,7 +133,7 @@ extern "C" { va_end(ap); - if (end_color.used != 0) { + if (end_color.used) { f_status status = f_print_string_dynamic(file, end_color); if (F_status_is_error(status)) return status; @@ -150,7 +150,7 @@ extern "C" { if (string == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (start_color.used != 0) { + if (start_color.used) { f_status status = f_print_string_dynamic(file, start_color); if (F_status_is_error(status)) return status; @@ -166,7 +166,7 @@ extern "C" { va_end(ap); - if (end_color.used != 0) { + if (end_color.used) { f_status status = f_print_string_dynamic(file, end_color); if (F_status_is_error(status)) return status; } @@ -182,7 +182,7 @@ extern "C" { if (string == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (start_color.used != 0) { + if (start_color.used) { f_status status = f_print_string_dynamic(file, start_color); if (F_status_is_error(status)) return status; } @@ -195,7 +195,7 @@ extern "C" { va_end(ap); - if (end_color.used != 0) { + if (end_color.used) { f_status status = f_print_string_dynamic(file, end_color); if (F_status_is_error(status)) return status; } @@ -214,7 +214,7 @@ extern "C" { if (string == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - if (start_color.used != 0) { + if (start_color.used) { f_status status = f_print_string_dynamic(file, start_color); if (F_status_is_error(status)) return status; @@ -230,7 +230,7 @@ extern "C" { va_end(ap); - if (end_color.used != 0) { + if (end_color.used) { f_status status = f_print_string_dynamic(file, end_color); if (F_status_is_error(status)) return status; } @@ -244,7 +244,7 @@ extern "C" { #ifndef _di_fl_color_print_code_ f_return_status fl_color_print_code(FILE *file, const f_string_static color) { - if (color.used != 0) { + if (color.used) { f_status status = f_print_string_dynamic(file, color); if (F_status_is_error(status)) return status; } diff --git a/level_1/fl_directory/c/private-directory.c b/level_1/fl_directory/c/private-directory.c index 5959657..40772ac 100644 --- a/level_1/fl_directory/c/private-directory.c +++ b/level_1/fl_directory/c/private-directory.c @@ -539,7 +539,7 @@ extern "C" { names = &listing->unknown; } - if (names->used >= names->size) { + if (names->used == names->size) { f_macro_string_dynamics_resize(status, (*names), names->size + f_directory_default_allocation_step); if (F_status_is_error(status)) break; } @@ -548,7 +548,7 @@ extern "C" { if (F_status_is_error(status)) break; if (names->array[names->used].used > 0 && names->array[names->used].string[names->array[names->used].used - 1] != 0) { - if (names->array[names->used].used + 1 > f_string_length_size) { + if (names->array[names->used].used == f_string_length_size) { status = F_status_set_error(F_string_too_large); break; } diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index df260e0..9146ece 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -6,17 +6,33 @@ extern "C" { #endif #ifndef _di_fl_fss_basic_object_read_ - f_return_status fl_fss_basic_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) { + f_return_status fl_fss_basic_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ - return private_fl_fss_basic_object_read(F_true, buffer, range, found); + f_status status = F_none; + f_string_lengths delimits = f_string_lengths_initialize; + + status = private_fl_fss_basic_object_read(buffer, range, found, quoted, &delimits); + if (F_status_is_error(status)) { + f_macro_string_lengths_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_delete_simple(delimits); + return status; + } + + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + + return status; } #endif // _di_fl_fss_basic_object_read_ @@ -24,10 +40,10 @@ extern "C" { f_return_status fl_fss_basic_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_content *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ @@ -57,7 +73,7 @@ extern "C" { // search for valid content. for (;;) { 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) + fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); if (buffer->string[range->start] == f_fss_basic_close) break; @@ -76,276 +92,60 @@ extern "C" { #endif // _di_fl_fss_basic_content_read_ #ifndef _di_fl_fss_basic_object_write_ - f_return_status fl_fss_basic_object_write(f_string_dynamic *buffer, const f_string_static object, f_string_range *range) { + f_return_status fl_fss_basic_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status status = F_none; - bool quoted = F_false; - - f_string_range buffer_position = f_string_range_initialize; - f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); - - if (range->start > range->stop) return F_data_not_stop; - else if (range->start >= object.used) return F_data_not_eos; - - start_position = range->start; - - // add an additional 3 to ensure that there is room for the start and stop quotes or a slash delimit and the object open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 3 + f_fss_default_allocation_step_string; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); - if (F_status_is_error(status)) return status; - } - - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; - - if (object.string[range->start] == f_fss_delimit_slash) { - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - else if (object.string[range->start] != f_fss_delimit_slash) { - break; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (object.string[range->start] == f_fss_delimit_single_quote || object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = object.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - } - else if (object.string[range->start] == f_fss_delimit_single_quote || object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = object.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - else if (object.string[range->start] == f_fss_comment) { - quoted = F_true; - } - - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - else if (object.string[range->start] == f_string_eol[0]) { - if (quoted) { - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - } - - buffer->string[buffer_position.stop] = f_fss_basic_open; - buffer->used = buffer_position.stop + 1; - - return F_none_eol; - } - else if ((status = f_fss_is_space(*buffer, *range)) == F_true || quoted) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - // restart the loop searching for f_fss_delimit_double_quote. - range->start = start_position; - buffer_position.stop = buffer_position.start; - - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - else if (object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - } - else if (object.string[range->start] == f_fss_delimit_slash) { - f_string_length slash_count = 0; - - for (;;) { - buffer->string[buffer_position.stop] = object.string[range->start]; - buffer_position.stop++; - slash_count++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); - - if (range->start > range->stop || range->start >= object.used) { - break; - } - - if (object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size += slash_count; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - break; - } - else if (object.string[range->start] != f_fss_delimit_slash) { - slash_count = 0; - break; - } - } // for - - while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - slash_count--; - } // while - - continue; - } - else if (object.string[range->start] == f_string_eol[0]) { - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - - buffer->string[buffer_position.stop] = f_fss_basic_open; - buffer->used = buffer_position.stop + 1; - - return F_none_eol; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - buffer_position.stop++; - } // while - - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer->string[buffer_position.stop + 1] = f_fss_basic_open; - buffer->used = buffer_position.stop + 2; - break; - } - else if (F_status_is_error(status)) { - return status; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - buffer_position.stop++; - } // while - - if (buffer->used < buffer_position.stop) { - buffer->string[buffer_position.stop] = f_fss_basic_open; - buffer->used = buffer_position.stop + 1; - } - - if (range->start > range->stop) return F_none_stop; - else if (range->start >= object.used) return F_none_eos; - - return F_none; + return private_fl_fss_basic_object_write(object, quoted, range, destination); } #endif // _di_fl_fss_basic_object_write_ #ifndef _di_fl_fss_basic_content_write_ - f_return_status fl_fss_basic_content_write(f_string_dynamic *buffer, const f_string_static content, f_string_range *range) { + f_return_status fl_fss_basic_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status status = F_none; - f_string_range input_position = f_string_range_initialize; - f_string_range buffer_position = f_string_range_initialize; - f_string_length pre_allocate_size = 0; - - fl_macro_fss_skip_past_delimit_placeholders(content, (*range)) + fl_macro_fss_skip_past_delimit_placeholders(content, (*range)); if (range->start > range->stop) return F_data_not_stop; else if (range->start >= content.used) return F_data_not_eos; - // add an additional 1 to ensure that there is room for the terminating newline. - pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string; + f_string_range input_position = f_string_range_initialize; + f_string_range buffer_position = f_string_range_initialize; + + // ensure that there is room for the terminating newline. + f_string_length size_allocate = destination->used + content.used + 1 + f_fss_default_allocation_step_string; - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; + buffer_position.start = destination->used; + buffer_position.stop = destination->used; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); if (F_status_is_error(status)) return status; } while (range->start <= range->stop && range->start < content.used) { if (content.string[range->start] == f_string_eol[0]) { - buffer->string[buffer_position.stop] = f_string_eol[0]; - buffer->used = buffer_position.stop + 1; + destination->string[buffer_position.stop] = f_string_eol[0]; + destination->used = buffer_position.stop + 1; return F_none_eos; } if (content.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; } - status = f_utf_buffer_increment(*buffer, range, 1); + status = f_utf_buffer_increment(content, range, 1); if (F_status_is_error(status)) return status; } // while - buffer->string[buffer_position.stop] = f_string_eol[0]; - buffer->used = buffer_position.stop + 1; + destination->string[buffer_position.stop] = f_string_eol[0]; + destination->used = buffer_position.stop + 1; if (range->start > range->stop) return F_none_stop; else if (range->start >= content.used) return F_none_eos; diff --git a/level_1/fl_fss/c/fss_basic.h b/level_1/fl_fss/c/fss_basic.h index 0ef12c5..85d26a2 100644 --- a/level_1/fl_fss/c/fss_basic.h +++ b/level_1/fl_fss/c/fss_basic.h @@ -47,6 +47,9 @@ 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 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. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -55,8 +58,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -70,7 +74,7 @@ extern "C" { * Errors from (with error bit): f_fss_skip_past_space(). */ #ifndef _di_fl_fss_basic_object_read_ - extern f_return_status fl_fss_basic_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found); + extern f_return_status fl_fss_basic_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted); #endif // _di_fl_fss_basic_object_read_ /** @@ -97,8 +101,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -124,11 +129,13 @@ extern "C" { * * @param object * The string to write as (does not stop at NULLS, they are ignored and not written). + * @param quoted + * If 0, then double quotes are auto-inserted, when required. + * Otherwise, this is the type of quote to wrap the object in when writing. * @param range * The start/stop location within the object string to write as an object. - * @param buffer + * @param destination * The buffer where the object is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -144,7 +151,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_basic_object_write_ - extern f_return_status fl_fss_basic_object_write(f_string_dynamic *buffer, const f_string_static object, f_string_range *range); + extern f_return_status fl_fss_basic_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_basic_object_write_ /** @@ -157,10 +164,8 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param range * The start/stop location within the content string to write as an content. - * @param buffer + * @param destination * The buffer where the content is written to. - * This will be auto-incremented and must not be a static string. - * * @return * F_none on success. * F_none_eos on success after reaching the end of the buffer. @@ -175,7 +180,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_basic_content_write_ - extern f_return_status fl_fss_basic_content_write(f_string_dynamic *buffer, const f_string_static content, f_string_range *range); + extern f_return_status fl_fss_basic_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_basic_content_write_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index 4b64d83..667d073 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -9,10 +9,10 @@ extern "C" { f_return_status fl_fss_basic_list_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ @@ -190,10 +190,10 @@ extern "C" { f_return_status fl_fss_basic_list_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_content *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ @@ -389,16 +389,16 @@ extern "C" { #endif // _di_fl_fss_basic_list_content_read_ #ifndef _di_fl_fss_basic_list_object_write_ - f_return_status fl_fss_basic_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer) { + f_return_status fl_fss_basic_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status status = F_none; f_string_range buffer_position = f_string_range_initialize; f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; + f_string_length size_allocate = 0; f_string_length start_buffer = 0; fl_macro_fss_skip_past_delimit_placeholders(object, (*range)) @@ -409,15 +409,15 @@ extern "C" { start_position = range->start; // add an additional 2 to ensure that there is room for the slash delimit and the object open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; + size_allocate = destination->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); if (F_status_is_error(status)) return status; } - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; + buffer_position.start = destination->used; + buffer_position.stop = destination->used; while (range->start <= range->stop && range->start < object.used) { if (object.string[range->start] == f_fss_comment) { @@ -432,7 +432,7 @@ extern "C" { } if (object.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; } @@ -444,7 +444,7 @@ extern "C" { if (object.string[range->start] == f_fss_delimit_slash) { f_string_length slash_count = 1; - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(object, range, 1); @@ -460,7 +460,7 @@ extern "C" { break; } - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(object, range, 1); @@ -470,15 +470,15 @@ extern "C" { } // while if (range->start > range->stop || range->start >= object.used) { - pre_allocate_size += slash_count; + size_allocate += slash_count; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; slash_count--; } // while @@ -495,7 +495,7 @@ extern "C" { } if (object.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; } @@ -503,9 +503,9 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - buffer->string[buffer_position.stop] = f_fss_basic_list_open; - buffer->string[buffer_position.stop + 1] = f_string_eol[0]; - buffer->used = buffer_position.stop + 2; + destination->string[buffer_position.stop] = f_fss_basic_list_open; + destination->string[buffer_position.stop + 1] = f_string_eol[0]; + destination->used = buffer_position.stop + 2; if (range->start > range->stop) return F_none_stop; else if (range->start >= object.used) return F_none_eos; @@ -515,9 +515,9 @@ extern "C" { #endif // _di_fl_fss_basic_list_object_write_ #ifndef _di_fl_fss_basic_list_content_write_ - f_return_status fl_fss_basic_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer) { + f_return_status fl_fss_basic_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status status = F_none; @@ -526,7 +526,7 @@ extern "C" { f_string_range buffer_position = f_string_range_initialize; f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; + f_string_length size_allocate = 0; fl_macro_fss_skip_past_delimit_placeholders(content, (*range)) @@ -536,22 +536,22 @@ extern "C" { start_position = range->start; // add an additional 2 to ensure that there is room for the slash delimit and the content open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; + size_allocate = destination->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); if (F_status_is_error(status)) return status; } - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; + buffer_position.start = destination->used; + buffer_position.stop = destination->used; while (range->start <= range->stop && range->start < content.used) { if (content.string[range->start] == f_fss_delimit_slash && !is_comment) { f_string_length slash_count = 1; - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; has_graph = F_true; @@ -569,7 +569,7 @@ extern "C" { break; } - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(content, range, 1); @@ -597,26 +597,26 @@ extern "C" { } // while if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) { - pre_allocate_size += slash_count + 1; + size_allocate += slash_count + 1; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; slash_count--; } // while - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; has_graph = F_false; is_comment = F_false; } - buffer->string[buffer_position.stop] = f_fss_basic_list_open; + destination->string[buffer_position.stop] = f_fss_basic_list_open; buffer_position.stop++; range->start = start + 1; continue; @@ -643,20 +643,20 @@ extern "C" { } // while if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) { - pre_allocate_size++; + size_allocate++; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; has_graph = F_false; is_comment = F_false; } - buffer->string[buffer_position.stop] = f_fss_basic_list_open; + destination->string[buffer_position.stop] = f_fss_basic_list_open; buffer_position.stop++; range->start = start + 1; continue; @@ -676,7 +676,7 @@ extern "C" { } if (content.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; } @@ -684,8 +684,8 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - buffer->string[buffer_position.stop] = f_string_eol[0]; - buffer->used = buffer_position.stop + 1; + destination->string[buffer_position.stop] = f_string_eol[0]; + destination->used = buffer_position.stop + 1; if (range->start > range->stop) return F_none_stop; else if (range->start >= content.used) return F_none_eos; diff --git a/level_1/fl_fss/c/fss_basic_list.h b/level_1/fl_fss/c/fss_basic_list.h index aa72e14..22aa6d2 100644 --- a/level_1/fl_fss/c/fss_basic_list.h +++ b/level_1/fl_fss/c/fss_basic_list.h @@ -56,8 +56,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -98,8 +99,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -127,9 +129,8 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param range * The start/stop location within the object string to write as an object. - * @param buffer + * @param destination * The buffer where the object is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -145,7 +146,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_basic_list_object_write_ - extern f_return_status fl_fss_basic_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_basic_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_basic_list_object_write_ /** @@ -158,9 +159,8 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param range * The start/stop location within the content string to write as an content. - * @param buffer + * @param destination * The buffer where the content is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -176,7 +176,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_basic_list_content_write_ - extern f_return_status fl_fss_basic_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_basic_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_basic_list_content_write_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index d1640d1..9e438fc 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -6,36 +6,49 @@ extern "C" { #endif #ifndef _di_fl_fss_extended_object_read_ - f_return_status fl_fss_extended_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) { + f_return_status fl_fss_extended_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ - return private_fl_fss_basic_object_read(F_false, buffer, range, found); + f_status status = F_none; + f_string_lengths delimits = f_string_lengths_initialize; + + status = private_fl_fss_basic_object_read(buffer, range, found, quoted, &delimits); + if (F_status_is_error(status)) { + f_macro_string_lengths_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_delete_simple(delimits); + 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 *buffer, f_string_range *range, f_fss_content *found) { + f_return_status fl_fss_extended_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_content *found, f_fss_quoteds *quoteds) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) 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 status = F_none; - // delimits must only be applied once a valid object is found. - f_string_lengths delimits = f_string_lengths_initialize; - status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; @@ -51,1005 +64,113 @@ extern "C" { return F_data_not_stop; } - bool has_delimit = F_false; - int8_t quoted = 0; - - bool continue_main_loop = F_false; + f_string_lengths delimits = f_string_lengths_initialize; - f_string_length location = 0; - f_array_length already_used = found->used; + uint8_t content_found = 0; while (range->start <= range->stop && range->start < buffer->used) { - quoted = 0; + f_string_range content_partial = f_string_range_initialize; + f_fss_quoted quoted = 0; - if (found->used >= found->size) { - f_macro_fss_content_resize(status, (*found), found->size + f_fss_default_allocation_step); + status = private_fl_fss_basic_object_read(buffer, range, &content_partial, "ed, &delimits); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } - - // begin the search. - found->array[found->used].start = range->start; - found->array[found->used].stop = 0; - - // identify where the content begins. - if (buffer->string[range->start] == f_fss_delimit_slash) { - f_string_length last_slash = range->start; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { + 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_size) { f_macro_string_lengths_delete_simple(delimits); - return status; + return F_status_set_error(F_buffer_too_large); } - - continue; - } - - status = f_fss_is_space(*buffer, *range); - - if (status == F_true) { - found->array[found->used].stop = range->start - 1; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - found->used++; - - if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - return FL_fss_found_content; + else { + f_macro_fss_content_resize(status, (*found), found->size + f_fss_default_allocation_step); } - - continue_main_loop = F_true; - break; - } - else if (F_status_is_error(status)) { - return status; } - else if (buffer->string[range->start] != f_fss_delimit_slash) { - break; + else { + f_macro_fss_content_resize(status, (*found), found->size + f_fss_default_allocation_step); } - last_slash = range->start; - - status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; - } // while - if (continue_main_loop) { - continue_main_loop = F_false; - continue; - } - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - - if (buffer->string[range->start] == f_fss_delimit_single_quote || buffer->string[range->start] == f_fss_delimit_double_quote) { - if (delimits.used >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (quoteds) { + f_macro_fss_quoteds_resize(status, (*quoteds), found->size); } - - delimits.array[delimits.used] = last_slash; - delimits.used++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } - } - else if (buffer->string[range->start] == f_fss_delimit_single_quote || buffer->string[range->start] == f_fss_delimit_double_quote) { - quoted = buffer->string[range->start]; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; } - found->array[found->used].start = range->start; - } - - // identify where the content ends. - if (quoted == 0) { - status = F_none; - - for (;;) { - status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - if (status == F_true) break; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - } // for - - found->array[found->used].stop = range->start - 1; + found->array[found->used] = content_partial; found->used++; - if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - range->start++; - return FL_fss_found_content; + if (quoteds) { + quoteds->array[quoteds->used] = quoted; + quoteds->used = found->used; } - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + content_found = 1; - continue; + if (status == FL_fss_found_object_content_not) break; } - else { - while (range->start <= range->stop && range->start < buffer->used) { - - if (buffer->string[range->start] == f_fss_delimit_slash) { - f_string_length first_slash = range->start; - f_string_length slash_count = 1; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - continue; - } - else if (buffer->string[range->start] != f_fss_delimit_slash) { - break; - } - - slash_count++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } // while - - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) - - if (buffer->string[range->start] == quoted) { - location = range->start; - range->start = first_slash; - - // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote and delimits do not apply. - { - f_string_length location = range->start; - - if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { - range->start++; - - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - - 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 quote. - // (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 { - // EOS or EOL was reached, so it is a valid closing quote. - // (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 (slash_count % 2 == 0) { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - 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++; - } - - slash_count--; - } - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } // while - - range->start = location + 1; - - 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_is_graph(*buffer, *range); - - if (status == F_true) { - while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } // while - - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - return F_unterminated_group; - } - else if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - else if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - found->array[found->used].stop = location - 1; - - range->start++; - found->used++; - return FL_fss_found_content; - } - - found->array[found->used].stop = location - 1; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - found->used++; - continue; - } - else { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - 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++; - } - - slash_count--; - } - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } // while - - range->start = location; - } - } - } - } - else if (buffer->string[range->start] == quoted) { - // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote. - { - f_string_length location = range->start; - - status = F_false; - - if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { - range->start++; - - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - - 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 quote. - // (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 { - // EOS or EOL was reached, so it is a valid closing quote. - // (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) { - found->array[found->used].stop = range->start - 1; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - while (range->start <= range->stop && range->start < buffer->used) { - - if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - range->start++; - found->used++; - return FL_fss_found_content; - } - - status = f_fss_is_space(*buffer, *range); - - if (status == F_true) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - found->used++; - continue_main_loop = F_true; - break; - } - else if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - else if (buffer->string[range->start] != f_fss_delimit_placeholder) { - - while (range->start < buffer->used && range->start <= range->stop) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) - - if (buffer->string[range->start] == f_string_eol[0]) break; - } // while - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - return F_unterminated_group; - } - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - } // while - - if (continue_main_loop) break; - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - } - } - else if (buffer->string[range->start] == f_fss_extended_close) { - - if (found->used == already_used) { - range->start++; - return FL_fss_found_content_not; - } - else { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - found->array[found->used].stop = range->start - 1; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - found->used++; - - return FL_fss_found_content; - } - } - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - } // while - - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) + else if (status == FL_fss_found_object_not) { + break; } + else if (status == F_data_not_eos) { + if (content_found) { + status = F_none_eos; + } - if (continue_main_loop) { - continue_main_loop = F_false; - continue; + content_found = 2; + break; } + else if (status == F_data_not_stop) { + if (content_found) { + status = F_none_stop; + } - break; - } // while - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - - // seek to the end of the line when no valid content is found - while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { + content_found = 2; + break; + } + else if (status == F_unterminated_group_eos || status == F_unterminated_group_eos) { + if (content_found) { + content_found = 2; + } + break; + } + else if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } } // while - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) + if (content_found) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - if (found->used == already_used) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); + if (content_found == 2) { return status; } - return FL_fss_found_content_not; + return FL_fss_found_content; } - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - - return FL_fss_found_content; + return FL_fss_found_content_not; } #endif // _di_fl_fss_extended_content_read_ #ifndef _di_fl_fss_extended_object_write_ - f_return_status fl_fss_extended_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer) { +f_return_status fl_fss_extended_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status status = F_none; - bool quoted = F_false; - - f_string_range buffer_position = f_string_range_initialize; - f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)) - - if (range->start > range->stop) return F_data_not_stop; - else if (range->start >= object.used) return F_data_not_eos; - - start_position = range->start; - - // add an additional 3 to ensure that there is room for the start and stop quotes or a slash delimit and the object open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 3 + f_fss_default_allocation_step_string; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); - if (F_status_is_error(status)) return status; - } - - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; - - if (object.string[range->start] == f_fss_delimit_slash) { - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } else if (object.string[range->start] != f_fss_delimit_slash) { - break; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (object.string[range->start] == f_fss_delimit_single_quote || object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = object.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - } - else if (object.string[range->start] == f_fss_delimit_single_quote || object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = object.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - else if (object.string[range->start] == f_fss_comment) { - quoted = F_true; - } - - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - else if (object.string[range->start] == f_string_eol[0]) { - if (quoted) { - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - } - - buffer->string[buffer_position.stop] = f_fss_basic_open; - buffer->used = buffer_position.stop + 1; - - return F_none_eol; - } - else if ((status = f_fss_is_space(*buffer, *range)) == F_true || quoted) { - f_string_length first_space = range->start; - - if (!quoted) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - while (range->start <= range->stop && range->start < object.used && isspace(object.string[range->start])) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (range->start > range->stop || range->start >= object.used) { - buffer->string[first_space] = f_fss_extended_open; - buffer->used = buffer_position.stop + 1; - break; - } - } - - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - - if (F_status_is_error(status)) return status; - } - - // restart the loop searching for f_fss_delimit_double_quote. - range->start = start_position; - buffer_position.stop = buffer_position.start; - - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - - while (range->start <= range->stop && range->start < object.used) { - if (object.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - else if (object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - } - else if (object.string[range->start] == f_fss_delimit_slash) { - f_string_length slash_count = 0; - - for (;;) { - buffer->string[buffer_position.stop] = object.string[range->start]; - buffer_position.stop++; - slash_count++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); - - if (range->start > range->stop || range->start >= object.used) { - break; - } - - if (object.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size += slash_count; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - break; - } - else if (object.string[range->start] != f_fss_delimit_slash) { - slash_count = 0; - break; - } - } // for - - while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - slash_count--; - } // while - - continue; - } - else if (object.string[range->start] == f_string_eol[0]) { - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - - buffer->string[buffer_position.stop] = f_fss_basic_open; - buffer->used = buffer_position.stop + 1; - - return F_none_eol; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - buffer_position.stop++; - } // while - - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer->string[buffer_position.stop + 1] = f_fss_extended_open; - buffer->used = buffer_position.stop + 2; - break; - } - else if (F_status_is_error(status)) { - return status; - } - - buffer->string[buffer_position.stop] = object.string[range->start]; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - buffer_position.stop++; - } // while - - if (buffer->used < buffer_position.stop) { - buffer->string[buffer_position.stop] = f_fss_extended_open; - buffer->used = buffer_position.stop + 1; - } - - if (range->start > range->stop) return F_none_stop; - else if (range->start >= object.used) return F_none_eos; - - return F_none; + return private_fl_fss_basic_object_write(object, quoted, range, destination); } #endif // _di_fl_fss_extended_object_write_ #ifndef _di_fl_fss_extended_content_write_ - f_return_status fl_fss_extended_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer) { + f_return_status fl_fss_extended_content_write(const f_string_static content, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ - f_status status = F_none; - int8_t quoted = 0; - - f_string_range buffer_position = f_string_range_initialize; - f_string_length start_position = 0; - f_string_length pre_allocate_size = 0; - - fl_macro_fss_skip_past_delimit_placeholders(content, (*range)) - - if (range->start > range->stop) return F_data_not_stop; - else if (range->start >= content.used) return F_data_not_eos; - - // add an additional 1 to ensure that there is room for the terminating newline. - pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string; - - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); - if (F_status_is_error(status)) return status; - } - - start_position = range->start; - - // if this first slash is followed by a quote, then that quote must be delimited. - if (content.string[range->start] == f_fss_delimit_slash) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - while (range->start <= range->stop && range->start < content.used) { - if (content.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - - if (content.string[range->start] != f_fss_delimit_slash) { - break; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (range->start > range->stop) { - buffer->string[buffer_position.stop] = ' '; - buffer->used = buffer_position.stop + 1; - return F_none_stop; - } - else if (range->start >= content.used) { - buffer->string[buffer_position.stop] = ' '; - buffer->used = buffer_position.stop + 1; - return F_none_eos; - } - - if (content.string[range->start] == f_fss_delimit_single_quote || content.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = content.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - } - else if (content.string[range->start] == f_fss_delimit_single_quote || content.string[range->start] == f_fss_delimit_double_quote) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = content.string[range->start]; - buffer_position.stop += 2; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } - - while (range->start <= range->stop && range->start < content.used) { - if (content.string[range->start] == f_string_eol[0]) { - buffer->string[buffer_position.stop] = ' '; - buffer->used = buffer_position.stop + 1; - return F_none_eol; - } - - if (content.string[range->start] != f_fss_delimit_placeholder && (status = f_fss_is_space(*buffer, *range)) == F_true) { - quoted = f_fss_delimit_double_quote; - - pre_allocate_size += 2; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - range->start = start_position; - buffer_position.stop = buffer_position.start; - buffer->string[buffer_position.stop] = f_fss_delimit_double_quote; - buffer_position.stop++; - break; - } - else if (F_status_is_error(status)) { - return status; - } - - buffer->string[buffer_position.stop] = content.string[range->start]; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (quoted != 0) { - while (range->start <= range->stop && range->start < content.used) { - if (content.string[range->start] == f_fss_delimit_slash) { - f_string_length slash_count = 1; - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - while (range->start <= range->stop && range->start < content.used) { - if (content.string[range->start] == f_fss_delimit_placeholder) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - - continue; - } - - if (content.string[range->start] != f_fss_delimit_slash) { - break; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - slash_count++; - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - if (content.string[range->start] == quoted || range->start > range->stop || range->start >= content.used) { - pre_allocate_size += slash_count + 1; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer_position.stop++; - slash_count--; - } // while - - if (range->start > range->stop || range->start >= content.used) { - break; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = quoted; - buffer_position.stop += 2; - } - else { - buffer->string[buffer_position.stop] = content.string[range->start]; - buffer_position.stop++; - } - } - else if (content.string[range->start] == quoted) { - pre_allocate_size++; - - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); - if (F_status_is_error(status)) return status; - } - - buffer->string[buffer_position.stop] = f_fss_delimit_slash; - buffer->string[buffer_position.stop + 1] = quoted; - buffer_position.stop += 2; - } - else if (content.string[range->start] == f_string_eol[0]) { - buffer->string[buffer_position.stop] = quoted; - buffer->string[buffer_position.stop + 1] = ' '; - buffer->used = buffer_position.stop + 2; - return F_none_eol; - } - else if (content.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = content.string[range->start]; - buffer_position.stop++; - } - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while - - buffer->string[buffer_position.stop] = quoted; - buffer_position.stop++; - } - - buffer->string[buffer_position.stop] = ' '; - buffer->used = buffer_position.stop + 1; - - if (range->start > range->stop) return F_none_stop; - else if (range->start >= content.used) return F_none_eos; - - return F_none; + // this operates exactly like an object, syntax-wise, so just use the object write. + return private_fl_fss_basic_object_write(content, quoted, range, destination); } #endif // _di_fl_fss_extended_content_write_ diff --git a/level_1/fl_fss/c/fss_extended.h b/level_1/fl_fss/c/fss_extended.h index 95b6125..2a04fa2 100644 --- a/level_1/fl_fss/c/fss_extended.h +++ b/level_1/fl_fss/c/fss_extended.h @@ -47,6 +47,9 @@ 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 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. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -55,8 +58,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -70,7 +74,7 @@ extern "C" { * Errors from (with error bit): f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_object_read_ - extern f_return_status fl_fss_extended_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found); + extern f_return_status fl_fss_extended_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted); #endif // _di_fl_fss_extended_object_read_ /** @@ -89,6 +93,9 @@ 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 quoteds + * 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. * * @return * FL_fss_found_content on success and content was found (start location is at end of content). @@ -97,8 +104,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -112,7 +120,7 @@ extern "C" { * Errors from (with error bit): f_fss_skip_past_space(). */ #ifndef _di_fl_fss_extended_content_read_ - extern f_return_status fl_fss_extended_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_content *found); + extern f_return_status fl_fss_extended_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_content *found, f_fss_quoteds *quoteds); #endif // _di_fl_fss_extended_content_read_ /** @@ -124,11 +132,13 @@ extern "C" { * * @param object * The string to write as (does not stop at NULLS, they are ignored and not written). + * @param quoted + * If 0, then double quotes are auto-inserted, when required. + * Otherwise, this is the type of quote to wrap the object in when writing. * @param range * The start/stop location within the object string to write as an object. - * @param buffer + * @param destination * The buffer where the object is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -144,7 +154,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_extended_object_write_ - extern f_return_status fl_fss_extended_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_extended_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_extended_object_write_ /** @@ -155,11 +165,13 @@ extern "C" { * * @param content * The string to write as (does not stop at NULLS, they are ignored and not written). + * @param quoted + * If 0, then double quotes are auto-inserted, when required. + * Otherwise, this is the type of quote to wrap the object in when writing. * @param range * The start/stop location within the content string to write as an content. - * @param buffer + * @param destination * The buffer where the content is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -175,7 +187,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_extended_content_write_ - extern f_return_status fl_fss_extended_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_extended_content_write(const f_string_static content, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_extended_content_write_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index 40f25a4..53cfc7b 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -9,10 +9,10 @@ extern "C" { f_return_status fl_fss_extended_list_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ @@ -197,10 +197,10 @@ extern "C" { f_return_status fl_fss_extended_list_content_read(f_string_dynamic *buffer, f_string_range *range, f_fss_nest *found) { #ifndef _di_level_1_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); + if (buffer->used == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); if (found == 0) return F_status_set_error(F_parameter); - if (range->stop < range->start) return F_status_set_error(F_parameter); - if (buffer->used == 0) 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_ @@ -622,7 +622,7 @@ extern "C" { } } - if (found->depth[depth].used >= found->depth[depth].size) { + if (found->depth[depth].used == found->depth[depth].size) { f_macro_fss_items_resize(status, found->depth[depth], found->depth[depth].size + f_fss_default_allocation_step); if (F_status_is_error(status)) { @@ -765,16 +765,16 @@ extern "C" { #endif // _di_fl_fss_extended_list_content_read_ #ifndef _di_fl_fss_extended_list_object_write_ - f_return_status fl_fss_extended_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer) { + f_return_status fl_fss_extended_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ f_status status = F_none; f_string_range buffer_position = f_string_range_initialize; f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; + f_string_length size_allocate = 0; f_string_length start_buffer = 0; fl_macro_fss_skip_past_delimit_placeholders(object, (*range)) @@ -785,16 +785,16 @@ extern "C" { start_position = range->start; // add an additional 2 to ensure that there is room for the slash delimit and the object open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; + size_allocate = destination->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); if (F_status_is_error(status)) return status; } - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; + buffer_position.start = destination->used; + buffer_position.stop = destination->used; while (range->start <= range->stop && range->start < object.used) { if (object.string[range->start] == f_fss_comment) { @@ -809,7 +809,7 @@ extern "C" { } if (object.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; } @@ -821,7 +821,7 @@ extern "C" { if (object.string[range->start] == f_fss_delimit_slash) { f_string_length slash_count = 1; - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(object, range, 1); @@ -837,7 +837,7 @@ extern "C" { break; } - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(object, range, 1); @@ -847,15 +847,15 @@ extern "C" { } // while if (range->start > range->stop || range->start >= object.used) { - pre_allocate_size += slash_count; + size_allocate += slash_count; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; slash_count--; } // while @@ -870,7 +870,7 @@ extern "C" { } if (object.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = object.string[range->start]; + destination->string[buffer_position.stop] = object.string[range->start]; buffer_position.stop++; } @@ -878,9 +878,9 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - buffer->string[buffer_position.stop] = f_fss_extended_list_open; - buffer->string[buffer_position.stop + 1] = f_string_eol[0]; - buffer->used = buffer_position.stop + 2; + destination->string[buffer_position.stop] = f_fss_extended_list_open; + destination->string[buffer_position.stop + 1] = f_string_eol[0]; + destination->used = buffer_position.stop + 2; if (range->start > range->stop) return F_none_stop; else if (range->start >= object.used) return F_none_eos; @@ -890,9 +890,9 @@ extern "C" { #endif // _di_fl_fss_extended_list_object_write_ #ifndef _di_fl_fss_extended_list_content_write_ - f_return_status fl_fss_extended_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer) { + f_return_status fl_fss_extended_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination) { #ifndef _di_level_1_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ // @todo @@ -903,7 +903,7 @@ extern "C" { f_string_range buffer_position = f_string_range_initialize; f_string_length start_position = f_string_initialize; - f_string_length pre_allocate_size = 0; + f_string_length size_allocate = 0; fl_macro_fss_skip_past_delimit_placeholders(content, (*range)) @@ -913,21 +913,21 @@ extern "C" { start_position = range->start; // add an additional 2 to ensure that there is room for the slash delimit and the content open character. - pre_allocate_size = buffer->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; + size_allocate = destination->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step_string; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); if (F_status_is_error(status)) return status; } - buffer_position.start = buffer->used; - buffer_position.stop = buffer->used; + buffer_position.start = destination->used; + buffer_position.stop = destination->used; while (range->start <= range->stop && range->start < content.used) { if (content.string[range->start] == f_fss_delimit_slash && !is_comment) { f_string_length slash_count = 1; - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; has_graph = F_true; @@ -945,7 +945,7 @@ extern "C" { break; } - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; status = f_utf_buffer_increment(content, range, 1); @@ -972,26 +972,26 @@ extern "C" { } // while if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) { - pre_allocate_size += slash_count + 1; + size_allocate += slash_count + 1; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } while (slash_count > 0) { - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; slash_count--; } // while - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; has_graph = F_false; is_comment = F_false; } - buffer->string[buffer_position.stop] = f_fss_extended_list_open; + destination->string[buffer_position.stop] = f_fss_extended_list_open; buffer_position.stop++; range->start = start + 1; continue; @@ -1017,21 +1017,21 @@ extern "C" { } // while if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) { - pre_allocate_size++; + size_allocate++; - if (pre_allocate_size > buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } - buffer->string[buffer_position.stop] = f_fss_delimit_slash; + destination->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; has_graph = F_false; is_comment = F_false; } - buffer->string[buffer_position.stop] = f_fss_extended_list_open; + destination->string[buffer_position.stop] = f_fss_extended_list_open; buffer_position.stop++; range->start = start + 1; continue; @@ -1051,7 +1051,7 @@ extern "C" { } if (content.string[range->start] != f_fss_delimit_placeholder) { - buffer->string[buffer_position.stop] = content.string[range->start]; + destination->string[buffer_position.stop] = content.string[range->start]; buffer_position.stop++; } @@ -1059,8 +1059,8 @@ extern "C" { if (F_status_is_error(status)) return status; } // while - buffer->string[buffer_position.stop] = f_string_eol[0]; - buffer->used = buffer_position.stop + 1; + destination->string[buffer_position.stop] = f_string_eol[0]; + destination->used = buffer_position.stop + 1; if (range->start > range->stop) return F_none_stop; else if (range->start >= content.used) return F_none_eos; diff --git a/level_1/fl_fss/c/fss_extended_list.h b/level_1/fl_fss/c/fss_extended_list.h index 51c3913..6e05b82 100644 --- a/level_1/fl_fss/c/fss_extended_list.h +++ b/level_1/fl_fss/c/fss_extended_list.h @@ -56,8 +56,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -102,8 +103,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -131,9 +133,8 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param range * The start/stop location within the object string to write as an object. - * @param buffer + * @param destination * The buffer where the object is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -149,7 +150,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_extended_list_object_write_ - extern f_return_status fl_fss_extended_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_extended_list_object_write(const f_string_static object, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_extended_list_object_write_ /** @@ -162,9 +163,8 @@ extern "C" { * The string to write as (does not stop at NULLS, they are ignored and not written). * @param range * The start/stop location within the content string to write as an content. - * @param buffer + * @param destination * The buffer where the content is written to. - * This will be auto-incremented and must not be a static string. * * @return * F_none on success. @@ -180,7 +180,7 @@ extern "C" { * Errors from (with error bit): f_utf_buffer_increment(). */ #ifndef _di_fl_fss_extended_list_content_write_ - extern f_return_status fl_fss_extended_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *buffer); + extern f_return_status fl_fss_extended_list_content_write(const f_string_static content, f_string_range *range, f_string_dynamic *destination); #endif // _di_fl_fss_extended_list_content_write_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss_macro.h b/level_1/fl_fss/c/fss_macro.h index 52024ba..24b7da6 100644 --- a/level_1/fl_fss/c/fss_macro.h +++ b/level_1/fl_fss/c/fss_macro.h @@ -17,135 +17,108 @@ extern "C" { // 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) \ - { \ - f_status macro_allocation_status = F_none; \ - \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - } + f_macro_string_lengths_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, location) \ - while (buffer.string[location.start] == f_fss_delimit_placeholder) { \ - location.start++;\ + #define fl_macro_fss_skip_past_delimit_placeholders(buffer, range) \ + while (buffer.string[range.start] == f_fss_delimit_placeholder) { \ + range.start++;\ \ - if (location.start >= buffer.used) break; \ - if (location.start > location.stop) break; \ + if (range.start >= buffer.used) break; \ + if (range.start > range.stop) break; \ } // while #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, location, found, delimits, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + #define fl_macro_fss_object_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ found.stop = buffer.used - 1; \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + else if (range.start > range.stop) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.stop = location.stop; \ + 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, location, found, delimits, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + #define fl_macro_fss_object_delimited_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ found.stop = buffer.used - 1; \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + else if (range.start > range.stop) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.stop = location.stop; \ + found.stop = range.stop; \ return stop_status; \ } #endif // _di_fl_macro_fss_object_delimited_return_on_overflow_ #ifndef _di_fl_macro_fss_content_return_on_overflow_ - #define fl_macro_fss_content_return_on_overflow(buffer, location, found, delimits, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + #define fl_macro_fss_content_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ found.array[found.used].stop = buffer.used - 1; \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + else if (range.start > range.stop) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + 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, location, found, delimits, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + #define fl_macro_fss_content_delimited_return_on_overflow(buffer, range, found, delimits, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ found.array[found.used].stop = buffer.used - 1; \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + else if (range.start > range.stop) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + 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) { \ + if (content.used == content.size) { \ f_status status = F_none; \ \ f_macro_fss_content_resize(status, content, content.size + f_fss_default_allocation_step); \ if (F_status_is_error(status)) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ return status; \ } \ @@ -153,73 +126,58 @@ extern "C" { #endif // _di_fl_macro_fss_allocate_content_if_necessary_ #ifndef _di_fl_macro_fss_nest_return_on_overflow_ - #define fl_macro_fss_nest_return_on_overflow(buffer, location, found, delimits, positions, objects, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - f_macro_string_lengths_delete(macro_allocation_status, positions); \ - f_macro_fss_objects_delete(macro_allocation_status, objects); \ + #define fl_macro_fss_nest_return_on_overflow(buffer, range, found, delimits, positions, objects, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + f_macro_string_lengths_delete_simple(delimits); \ + f_macro_string_lengths_delete_simple(positions); \ + f_macro_fss_objects_delete_simple(objects); \ \ - /* @todo: found.array[found.used].stop = buffer.used - 1; */ \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - f_macro_string_lengths_delete(macro_allocation_status, positions); \ - f_macro_fss_objects_delete(macro_allocation_status, objects); \ + else if (range.start > range.stop) { \ + f_macro_string_lengths_delete_simple(delimits); \ + f_macro_string_lengths_delete_simple(positions); \ + f_macro_fss_objects_delete_simple(objects); \ \ - /* @todo: found.array[found.used].stop = location.stop; */ \ return stop_status; \ } #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, location, found, delimits, positions, objects, eos_status, stop_status) \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + #define fl_macro_fss_nest_delimited_return_on_overflow(buffer, range, found, delimits, positions, objects, eos_status, stop_status) \ + if (range.start >= buffer.used) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - f_macro_string_lengths_delete(macro_allocation_status, positions); \ - f_macro_fss_objects_delete(macro_allocation_status, objects); \ + f_macro_string_lengths_delete_simple(delimits); \ + f_macro_string_lengths_delete_simple(positions); \ + f_macro_fss_objects_delete_simple(objects); \ \ return eos_status; \ } \ - else if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + else if (range.start > range.stop) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ - f_macro_string_lengths_delete(macro_allocation_status, positions); \ - f_macro_fss_objects_delete(macro_allocation_status, objects); \ + f_macro_string_lengths_delete_simple(delimits); \ + f_macro_string_lengths_delete_simple(positions); \ + f_macro_fss_objects_delete_simple(objects); \ \ return stop_status; \ } - // @todo: found.array[found.used].stop = location.stop; #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, location, delimits, eos_status, stop_status) \ - while (buffer.string[location.start] != f_string_eol[0]) { \ - location.start++; \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + #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_delete_simple(delimits); \ \ return eos_status; \ } \ - if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + if (range.start > range.stop) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ return stop_status; \ } \ @@ -227,30 +185,22 @@ extern "C" { #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, location, delimits, eos_status, stop_status) \ - while (buffer.string[location.start] != f_string_eol[0]) { \ - location.start++; \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + #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 i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ return eos_status; \ } \ - if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + if (range.start > range.stop) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ return stop_status; \ } \ @@ -258,54 +208,44 @@ extern "C" { #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, location, found, delimits, eos_status, stop_status) \ - while (buffer.string[location.start] != f_string_eol[0]) { \ - location.start++; \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + #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_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + found.array[found.used].stop = range.stop; \ return eos_status; \ } \ - if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + if (range.start > range.stop) { \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + 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, location, found, delimits, eos_status, stop_status) \ - while (buffer.string[location.start] != f_string_eol[0]) { \ - location.start++; \ - if (location.start >= buffer.used) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + #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 i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + found.array[found.used].stop = range.stop; \ return eos_status; \ } \ - if (location.start > location.stop) { \ - f_status macro_allocation_status = F_none; \ - f_array_length i = 0; \ - \ - while (i < delimits.used) { \ + if (range.start > range.stop) { \ + for (f_array_length i = 0; i < delimits.used; i++) { \ buffer.string[delimits.array[i]] = f_fss_delimit_placeholder; \ - i++; \ } \ - f_macro_string_lengths_delete(macro_allocation_status, delimits); \ + f_macro_string_lengths_delete_simple(delimits); \ \ - found.array[found.used].stop = location.stop; \ + found.array[found.used].stop = range.stop; \ return stop_status; \ } \ } // while diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index aacdf2b..2ba89ae 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -5,13 +5,10 @@ extern "C" { #endif -#if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) - f_return_status private_fl_fss_basic_object_read(const bool is_basic, f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) { +#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_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted, f_string_lengths *delimits) { f_status status = F_none; - // delimits must only be applied once a valid object is found. - f_string_lengths delimits = f_string_lengths_initialize; - status = f_fss_skip_past_space(*buffer, range); if (F_status_is_error(status)) return status; @@ -27,16 +24,17 @@ extern "C" { return F_data_not_stop; } - // when handling delimits, the only time they should be applied is when a valid object would exist. - // however, the delimits will appear before a valid object, so remember their positions and only apply them after a would be valid object is confirmed. - bool has_delimit = F_false; - // begin the search. found->start = range->start; // 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); + while (buffer->string[range->start] != f_string_eol[0]) { + 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; @@ -44,8 +42,15 @@ extern "C" { return FL_fss_found_object_not; } - // handle quote support. - int8_t quoted = 0; + // delimits must only be applied once a valid object is found-> + const f_string_length delimit_initial = delimits->used; + + // handle quoted support. + int8_t quote = 0; + + if (quoted) { + *quoted = 0; + } // identify where the object begins. if (buffer->string[range->start] == f_fss_delimit_slash) { @@ -96,29 +101,43 @@ extern "C" { } } // while - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + if (range->start >= buffer->used) { + found->stop = buffer->used - 1; + return F_none_eos; + } + else if (range->start > range->stop) { + found->stop = range->stop; + return F_none_stop; + } - if (buffer->string[range->start] == f_fss_delimit_single_quote || buffer->string[range->start] == f_fss_delimit_double_quote) { + if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) { - // only the first slash before a quote needs to be escaped (or not) as once there is a slash before a quote, this cannot ever be a quoted object. + // 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 + 1 > delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + 1); - if (F_status_is_error(status)) return status; + if (delimits->used == delimits->size) { + if (delimits->size + f_fss_default_allocation_step > f_array_length_size) { + if (delimits->size + 1 > f_array_length_size) { + return F_status_set_error(F_buffer_too_large); + } + + f_macro_string_lengths_resize(status, (*delimits), delimits->size + 1); + if (F_status_is_error(status)) return status; + } + else { + f_macro_string_lengths_resize(status, (*delimits), delimits->size + f_fss_default_allocation_step); + if (F_status_is_error(status)) return status; + } } - delimits.array[delimits.used] = first_slash; - delimits.used++; + delimits->array[delimits->used] = first_slash; + delimits->used++; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } } - else if (buffer->string[range->start] == f_fss_delimit_single_quote || buffer->string[range->start] == f_fss_delimit_double_quote) { - quoted = buffer->string[range->start]; + else if (buffer->string[range->start] == f_fss_delimit_quote_single || buffer->string[range->start] == f_fss_delimit_quote_double) { + quote = buffer->string[range->start]; status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) return status; @@ -127,45 +146,32 @@ extern "C" { } // identify where the object ends. - if (quoted == 0) { + if (quote == 0) { status = F_none; while (range->start <= range->stop && range->start < buffer->used) { status = f_fss_is_space(*buffer, *range); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; if (status == F_true) break; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } // while found->stop = range->start - 1; - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - if (buffer->string[range->start] == f_string_eol[0]) { range->start++; return FL_fss_found_object_content_not; } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; return FL_fss_found_object; } else { - while (range->start <= range->stop && range->start < buffer->used) { if (buffer->string[range->start] == f_fss_delimit_slash) { @@ -173,19 +179,13 @@ extern "C" { f_string_length slash_count = 1; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; while (range->start <= range->stop && range->start < buffer->used) { if (buffer->string[range->start] == f_fss_delimit_placeholder) { status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; continue; } @@ -196,18 +196,24 @@ extern "C" { slash_count++; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_status_set_warning(F_unterminated_group_eos), F_status_set_warning(F_unterminated_group_stop)); + 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) { + found->stop = range->stop; + delimits->used = delimit_initial; + return F_unterminated_group_stop; + } - if (buffer->string[range->start] == quoted) { + if (buffer->string[range->start] == quote) { f_string_length location = range->start; - // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote and delimits do not apply. + // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted and delimits do not apply. if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { range->start++; @@ -215,70 +221,80 @@ extern "C" { if (range->start <= range->stop && range->start < buffer->used) { status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) { - return status; - } + if (F_status_is_error(status)) return status; } else { - // EOS or EOL was reached, so it is a valid closing quote. + // 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 { - // EOS or EOL was reached, so it is a valid closing quote. + // 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; } if (status == F_true) { + if (quoted) { + if (quote == f_fss_delimit_quote_single) { + *quoted = f_fss_quoted_type_single; + } + else if (quote == f_fss_delimit_quote_double) { + *quoted = f_fss_quoted_type_double; + } + } + range->start = first_slash; if (slash_count % 2 == 0) { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (delimits->used + (slash_count / 2) >= delimits->size) { + if (delimits->used + (slash_count / 2) >= f_array_length_size) { + return F_status_set_error(F_buffer_too_large); } + + f_macro_string_lengths_resize(status, (*delimits), delimits->size + (slash_count / 2)); + if (F_status_is_error(status)) 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--; } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } // while range->start = location + 1; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + while (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; + } // while if ((status = f_fss_is_graph(*buffer, *range)) == F_true) { while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + 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); - - f_macro_string_lengths_delete_simple(delimits); + 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); if (F_status_is_error(status)) return status; @@ -286,19 +302,14 @@ extern "C" { return FL_fss_found_object_not; } else if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); return status; } else if (buffer->string[range->start] == f_string_eol[0]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->stop = location - 1; range->start++; return FL_fss_found_object_content_not; } - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - found->stop = location - 1; status = f_utf_buffer_increment(*buffer, range, 1); @@ -307,30 +318,27 @@ extern "C" { return FL_fss_found_object; } else { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (delimits->used + (slash_count / 2) >= delimits->size) { + if (delimits->used + (slash_count / 2) >= f_array_length_size) { + return F_status_set_error(F_buffer_too_large); } + + f_macro_string_lengths_resize(status, (*delimits), delimits->size + (slash_count / 2) + 1); + if (F_status_is_error(status)) 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--; } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } // while range->start = location; @@ -341,8 +349,8 @@ extern "C" { } } } - else if (buffer->string[range->start] == quoted) { - // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote. + else if (buffer->string[range->start] == quote) { + // check to see if there is a whitespace, EOS, or EOL after the quoted, if not, then this is not a closing quoted. { f_string_length location = range->start; @@ -353,19 +361,17 @@ extern "C" { if (range->start <= range->stop && range->start < buffer->used) { status = f_fss_is_space(*buffer, *range); - if (F_status_is_error(status)) { - return status; - } + if (F_status_is_error(status)) return status; } else { - // EOS or EOL was reached, so it is a valid closing quote. + // 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 { - // EOS or EOL was reached, so it is a valid closing quote. - // (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?). + // 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; } @@ -373,47 +379,50 @@ extern "C" { } if (status == F_true) { + if (quoted) { + if (quote == f_fss_delimit_quote_single) { + *quoted = f_fss_quoted_type_single; + } + else if (quote == f_fss_delimit_quote_double) { + *quoted = f_fss_quoted_type_double; + } + } + found->stop = range->start - 1; status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + 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]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - range->start++; return FL_fss_found_object_content_not; } else if ((status = f_fss_is_space(*buffer, *range)) == F_true) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - 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)) { - f_macro_string_lengths_delete_simple(delimits); return status; } else if (buffer->string[range->start] != f_fss_delimit_placeholder) { while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + 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); - - f_macro_string_lengths_delete_simple(delimits); + 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); if (F_status_is_error(status)) return status; @@ -425,38 +434,51 @@ 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 (range->start >= buffer->used) { + found->stop = buffer->used - 1; + return F_none_eos; + } + else if (range->start > range->stop) { + found->stop = range->stop; + return F_none_stop; + } } } else if (buffer->string[range->start] == f_string_eol[0]) { - f_macro_string_lengths_delete_simple(delimits); - range->start++; return FL_fss_found_object_not; } status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_status_set_warning(F_unterminated_group_eos), F_status_set_warning(F_unterminated_group_stop)); + 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) { + 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 + // seek to the end of the line when no valid object is found-> while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + 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); - - f_macro_string_lengths_delete_simple(delimits); + 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); if (F_status_is_error(status)) return status; @@ -465,6 +487,316 @@ extern "C" { } #endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) +#if !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + f_return_status private_fl_fss_basic_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination) { + f_status status = F_none; + + fl_macro_fss_skip_past_delimit_placeholders(object, (*range)); + + if (range->start > range->stop) return F_data_not_stop; + else if (range->start >= object.used) return F_data_not_eos; + + // ensure that there is room for the start and stop quotes or a slash delimit and the object open character. + f_string_length size_allocate = destination->used + (range->stop - range->start) + 3 + f_fss_default_allocation_step_string; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate); + if (F_status_is_error(status)) return status; + } + + const f_string_length position_start = range->start; + + f_string_range destination_position = f_string_range_initialize; + + destination_position.start = destination->used; + destination_position.stop = destination->used; + + bool quote = quoted ? F_true : F_false; + + if (quote) { + if (quoted == f_fss_quoted_type_single) { + destination->string[destination_position.start] = f_fss_delimit_quote_single; + } + else { + destination->string[destination_position.start] = f_fss_delimit_quote_double; + } + + destination_position.stop++; + } + + // @todo: if the string starts with a single or double quoted, it needs to be escaped, but if quotes are detected later on, be sure to re-evaluate escaping. + + if (object.string[range->start] == f_fss_delimit_slash) { + while (range->start <= range->stop && range->start < object.used) { + if (object.string[range->start] == f_fss_delimit_placeholder) { + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + + continue; + } + else if (object.string[range->start] != f_fss_delimit_slash) { + break; + } + + destination->string[destination_position.stop] = object.string[range->start]; + destination_position.stop++; + + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + } // while + + if (range->start <= range->stop && range->start < object.used) { + if ((quoted == f_fss_quoted_type_single && object.string[range->start] == f_fss_delimit_quote_single) || (quoted == f_fss_quoted_type_double && object.string[range->start] == f_fss_delimit_quote_double)) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination->string[destination_position.stop + 1] = object.string[range->start]; + destination_position.stop += 2; + + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + } + } + } + else if ((quoted == f_fss_quoted_type_single && object.string[range->start] == f_fss_delimit_quote_single) || (quoted == f_fss_quoted_type_double && object.string[range->start] == f_fss_delimit_quote_double)) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination->string[destination_position.stop + 1] = object.string[range->start]; + destination_position.stop += 2; + + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + } + + while (range->start <= range->stop && range->start < object.used) { + if (object.string[range->start] == f_fss_delimit_placeholder) { + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + + continue; + } + + if (object.string[range->start] == f_string_eol[0]) { + if (quote) { + destination->string[destination_position.stop] = destination->string[destination_position.start]; + destination_position.stop++; + } + + destination->string[destination_position.stop] = f_fss_basic_open; + destination->used = destination_position.stop + 1; + + return F_none_eol; + } + + if (quote) { + if (object.string[range->start] == f_fss_delimit_slash) { + f_string_range next = *range; + f_string_length slashes = 1; + + bool must_delimit = F_false; + + while (next.start <= next.stop && next.start < object.used) { + if (object.string[next.start] == f_fss_delimit_placeholder) { + status = f_utf_buffer_increment(object, &next, 1); + if (F_status_is_error(status)) return status; + + continue; + } + else if (object.string[next.start] != f_fss_delimit_slash) { + break; + } + + slashes++; + + status = f_utf_buffer_increment(object, &next, 1); + if (F_status_is_error(status)) return status; + } // while + + if (next.start <= next.stop && next.start < object.used) { + // identify if quoted exists and could be considered a valid closing quoted. + if (object.string[next.start] == destination->string[destination_position.start]) { + fl_macro_fss_skip_past_delimit_placeholders(object, next); + + if (next.start <= next.stop && next.start < object.used) { + status = f_fss_is_space(*destination, next); + + if (status == F_true) { + must_delimit = F_true; + } + else if (F_status_is_error(status)) { + return status; + } + } + else { + must_delimit = F_true; + } + } + } + else { + // ensure that the slashes before the closing quoted to not delimit the closing quoted. + must_delimit = F_true; + } + + if (must_delimit) { + for (f_string_length i = 0; i < slashes; i++) { + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination_position.stop++; + } // for + + if (slashes % 2) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination_position.stop++; + } + } + } + else if (object.string[range->start] == destination->string[destination_position.start]) { + f_string_range next = *range; + bool must_delimit = F_false; + + status = f_utf_buffer_increment(object, &next, 1); + if (F_status_is_error(status)) return status; + + fl_macro_fss_skip_past_delimit_placeholders(object, next); + + if (next.start > range->stop || next.start >= object.used) { + must_delimit = F_true; + } + else { + status = f_fss_is_space(object, next); + + if (status == F_true) { + must_delimit = F_true; + } + else if (F_status_is_error(status)) { + return status; + } + } + + if (must_delimit) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination_position.stop++; + } + } + } + else { + status = f_fss_is_space(object, *range); + + if (status == F_true) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + // restart the loop then search for delimit slash or quoted and escape as appropriate. + range->start = position_start; + destination_position.stop = destination_position.start; + + destination->string[destination_position.stop] = f_fss_delimit_quote_double; + destination_position.stop++; + + quote = F_true; + + if (object.string[range->start] == f_fss_delimit_slash) { + while (range->start <= range->stop && range->start < object.used) { + if (object.string[range->start] == f_fss_delimit_placeholder) { + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + + continue; + } + else if (object.string[range->start] != f_fss_delimit_slash) { + break; + } + + destination->string[destination_position.stop] = object.string[range->start]; + destination_position.stop++; + + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + } // while + + if (range->start > range->stop || range->start >= object.used) break; + + if (object.string[range->start] == f_fss_delimit_quote_double) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination_position.stop++; + } + } + else if (object.string[range->start] == f_fss_delimit_quote_double) { + size_allocate++; + + if (size_allocate > destination->size) { + f_macro_string_dynamic_resize(status, (*destination), size_allocate + f_fss_default_allocation_step_string); + if (F_status_is_error(status)) return status; + } + + destination->string[destination_position.stop] = f_fss_delimit_slash; + destination_position.stop++; + } + } + else if (F_status_is_error(status)) { + return status; + } + } + + destination->string[destination_position.stop] = object.string[range->start]; + + status = f_utf_buffer_increment(object, range, 1); + if (F_status_is_error(status)) return status; + + destination_position.stop++; + } // while + + if (quote) { + destination->string[destination_position.stop] = destination->string[destination_position.start]; + destination_position.stop++; + } + + destination->string[destination_position.stop] = f_fss_basic_open; + destination->used = destination_position.stop + 1; + + if (range->start > range->stop) return F_none_stop; + else if (range->start >= object.used) return F_none_eos; + + return F_none; + } +#endif // !defined(_di_fl_fss_basic_object_write_) || !defined(_di_fl_fss_extended_object_write_) + #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 bb9bfdc..0f2385c 100644 --- a/level_1/fl_fss/c/private-fss.h +++ b/level_1/fl_fss/c/private-fss.h @@ -20,9 +20,6 @@ extern "C" { * * Intended to be shared to each of the different implementation variations. * - * @param is_basic - * Set to TRUE if this is a basic read. - * Set to FALSE if this is an extended read. * @param buffer * The buffer to read from. * This will be updated with delimit placeholders as it is being processed. @@ -33,6 +30,12 @@ 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 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 + * An array of delimits detected during processing. + * The caller is expected to decide if and when to process them. * * @return * FL_fss_found_object on success and object was found (start location is at end of object). @@ -41,8 +44,9 @@ extern "C" { * F_none_stop on success after reaching stopping point (a valid object is not yet confirmed). * F_data_not_eos no objects found after reaching the end of the buffer (essentially only comments are found). * F_data_not_stop no data found after reaching stopping point (essentially only comments are found). - * F_unterminated_group_eos (with warning bit) if EOS was reached before the a group termination was reached. - * F_unterminated_group_stop (with warning bit) if stop point was reached before the a group termination was reached. + * 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. @@ -58,9 +62,44 @@ extern "C" { * @see fl_fss_basic_object_read() * @see fl_fss_extended_object_read() */ -#if !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_read_) - extern f_return_status private_fl_fss_basic_object_read(const bool is_basic, f_string_dynamic *buffer, f_string_range *range, f_fss_object *found) f_gcc_attribute_visibility_internal; -#endif // !defined(_di_fl_fss_basic_object_read_) || !defined(_di_fl_fss_extended_object_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_object_read(f_string_dynamic *buffer, f_string_range *range, f_fss_object *found, f_fss_quoted *quoted, f_string_lengths *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_) + +/** + * Private implementation of fl_fss_basic_object_write(). + * + * Intended to be shared to each of the different implementation variations. + * + * @param object + * The string to write as (does not stop at NULLS, they are ignored and not written). + * @param quoted + * If 0, then double quotes are auto-inserted, if needed. + * Otherwise, this is the type of quote to wrap the object in when writing. + * @param range + * The start/stop location within the object string to write as an object. + * @param destination + * The buffer where the object is written to. + * + * @return + * F_none on success. + * F_none_eos on success after reaching the end of the buffer. + * F_data_not_stop no data to write due start location being greater than stop location. + * F_data_not_eos no data to write due start location being greater than or equal to buffer size. + * F_none_stop on success after reaching stopping point . + * 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_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 from (with error bit): f_utf_buffer_increment(). + * + * @see fl_fss_basic_object_write() + * @see fl_fss_extended_object_write() + */ +#if !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) + extern f_return_status private_fl_fss_basic_object_write(const f_string_static object, const f_fss_quoted quoted, f_string_range *range, f_string_dynamic *destination) f_gcc_attribute_visibility_internal; +#endif // !defined(fl_fss_basic_object_write) || !defined(fl_fss_extended_object_write) #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_print/c/print.c b/level_1/fl_print/c/print.c index 7c35d8d..3d2bea3 100644 --- a/level_1/fl_print/c/print.c +++ b/level_1/fl_print/c/print.c @@ -80,7 +80,7 @@ extern "C" { #ifndef _di_fl_print_trim_string_dynamic_ f_return_status fl_print_trim_string_dynamic(FILE *output, const f_string_static buffer) { #ifndef _di_level_1_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ register f_string_length i = 0; @@ -156,7 +156,7 @@ extern "C" { #ifndef _di_level_1_parameter_checking_ if (range.start < 0) return F_status_set_error(F_parameter); if (range.stop < range.start) return F_status_set_error(F_parameter); - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (range.start >= buffer.used) return F_status_set_error(F_parameter); if (range.stop >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ @@ -318,7 +318,7 @@ extern "C" { #ifndef _di_fl_print_trim_utf_string_dynamic_ f_return_status fl_print_trim_utf_string_dynamic(FILE *output, const f_utf_string_static buffer) { #ifndef _di_level_1_parameter_checking_ - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ register f_utf_string_length i = 0; @@ -390,7 +390,7 @@ extern "C" { #ifndef _di_level_1_parameter_checking_ if (range.start < 0) return F_status_set_error(F_parameter); if (range.stop < range.start) return F_status_set_error(F_parameter); - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); if (range.start >= buffer.used) return F_status_set_error(F_parameter); if (range.stop >= buffer.used) return F_status_set_error(F_parameter); #endif // _di_level_1_parameter_checking_ diff --git a/level_1/fl_string/c/string.c b/level_1/fl_string/c/string.c index cc22f21..bd855c9 100644 --- a/level_1/fl_string/c/string.c +++ b/level_1/fl_string/c/string.c @@ -1073,7 +1073,7 @@ extern "C" { if (destination->used && destination->string[destination->used - 1] == 0) return F_none; - if (destination->used + 1 > f_string_length_size) return F_status_set_error(F_string_too_large); + if (destination->used == f_string_length_size) return F_status_set_error(F_string_too_large); const f_string_length total = destination->used + 1; @@ -1105,7 +1105,7 @@ extern "C" { } // for } - if (destination->used + 1 > f_string_length_size) return F_status_set_error(F_string_too_large); + if (destination->used == f_string_length_size) return F_status_set_error(F_string_too_large); const f_string_length total = destination->used + 1; diff --git a/level_1/fl_utf/c/utf.c b/level_1/fl_utf/c/utf.c index 958d3ad..00272d2 100644 --- a/level_1/fl_utf/c/utf.c +++ b/level_1/fl_utf/c/utf.c @@ -956,7 +956,7 @@ extern "C" { return F_none; } - if (destination->used + 1 > f_utf_string_length_size) { + if (destination->used == f_utf_string_length_size) { return F_status_set_error(F_string_too_large); } @@ -990,7 +990,7 @@ extern "C" { } // for } - if (destination->used + 1 > f_utf_string_length_size) { + if (destination->used == f_utf_string_length_size) { return F_status_set_error(F_string_too_large); } diff --git a/level_1/fl_utf_file/c/private-utf_file.c b/level_1/fl_utf_file/c/private-utf_file.c index fa8688b..69c38bc 100644 --- a/level_1/fl_utf_file/c/private-utf_file.c +++ b/level_1/fl_utf_file/c/private-utf_file.c @@ -128,7 +128,7 @@ extern "C" { buffer_write[used] = f_macro_utf_character_to_char_1(string[*written + i]); if (width > 1) { - if (used + 1 > write_size) { + if (used == write_size) { width_written = 1; used += 1; break; diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c index b4ce1b8..c4395c6 100644 --- a/level_2/fll_execute/c/private-execute.c +++ b/level_2/fll_execute/c/private-execute.c @@ -9,7 +9,7 @@ extern "C" { f_return_status private_fll_execute_arguments_add(const f_string source, const f_string_length length, f_string_dynamics *arguments) { f_status status = F_none; - if (arguments->used >= arguments->size) { + if (arguments->used == arguments->size) { if (arguments->size + f_memory_default_allocation_step > f_array_length_size) { if (arguments->size + 1 > f_array_length_size) return F_buffer_too_large; f_macro_string_dynamics_resize(status, (*arguments), arguments->size + 1); diff --git a/level_2/fll_fss/c/fss.c b/level_2/fll_fss/c/fss.c index 029cafe..fa1501b 100644 --- a/level_2/fll_fss/c/fss.c +++ b/level_2/fll_fss/c/fss.c @@ -9,7 +9,7 @@ extern "C" { f_return_status fll_fss_identify(const f_string_static buffer, f_fss_header *header) { #ifndef _di_level_2_parameter_checking_ if (header == 0) return F_status_set_error(F_parameter); - if (buffer.used <= 0) return F_status_set_error(F_parameter); + if (buffer.used == 0) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ return private_fll_fss_identify(buffer, header); @@ -104,6 +104,8 @@ extern "C" { f_status status = F_none; f_string_length length_object = 0; + f_string_dynamics *value = 0; + f_fss_content *content = 0; f_array_length i = 0; f_array_length j = 0; @@ -118,12 +120,39 @@ extern "C" { if (F_status_is_error(status)) return status; if (status == F_equal_to_not) continue; +value = values[j]; +content = &contents.array[i]; if (values[j]->used + contents.array[i].used > values[j]->size) { if (values[j]->used + contents.array[i].used > f_array_length_size) { return F_status_set_error(F_buffer_too_large); } - f_macro_string_dynamics_resize(status, (*values[j]), values[j]->used + contents.array[i].used); + //f_macro_string_dynamics_resize(status, (*values[j]), (values[j]->used + contents.array[i].used)); + //f_macro_string_dynamics_resize(status, (*value), (value->used + content->used)); + f_macro_string_dynamics_resize(status, (*value), (values[j]->used + content->used)); + +/* + status = F_none; + if ((values[j]->used + contents.array[i].used) < values[j]->size) { + f_array_length xxx = values[j]->size - (values[j]->used + contents.array[i].used); + for (; xxx < values[j]->size; xxx++) { + f_macro_string_dynamic_delete(status, values[j]->array[i]); + if (status != F_none) break; + } + } + if (status == F_none) status = f_memory_resize((void **) & values[j]->array, sizeof(f_string_dynamic), values[j]->size, (values[j]->used + contents.array[i].used)); + if (status == F_none) { + if ((values[j]->used + contents.array[i].used) > values[j]->size) { + f_array_length xxx = values[j]->size; + for (; xxx < (values[j]->used + contents.array[i].used); xxx++) { + memset(&values[j]->array[i], 0, sizeof(f_string_dynamic)); + } + } + values[j]->size = (values[j]->used + contents.array[i].used); + if (values[j]->used > values[j]->size) values[j]->used = (values[j]->used + contents.array[i].used); + } +*/ + if (F_status_is_error(status)) return status; } @@ -204,9 +233,9 @@ extern "C" { continue; } - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { f_macro_string_dynamic_delete_simple(name); return F_status_set_error(F_buffer_too_large); } @@ -282,9 +311,9 @@ extern "C" { if (F_status_is_error(status)) return status; if (status == F_equal_to_not) continue; - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { return F_status_set_error(F_buffer_too_large); } @@ -357,9 +386,9 @@ extern "C" { if (F_status_is_error(status)) return status; if (status == F_equal_to_not) continue; - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { return F_status_set_error(F_buffer_too_large); } @@ -457,9 +486,9 @@ extern "C" { map_multi = &values[j]->array[k]; } else { - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { return F_status_set_error(F_buffer_too_large); } @@ -484,8 +513,8 @@ extern "C" { if (contents.array[i].used == 1) continue; } - if (map_multi->value.used + 1 > map_multi->value.size) { - if (map_multi->value.used + 1 > f_array_length_size) { + if (map_multi->value.used == map_multi->value.size) { + if (map_multi->value.used == f_array_length_size) { return F_status_set_error(F_buffer_too_large); } @@ -572,9 +601,9 @@ extern "C" { map = &values[j]->array[k]; } else { - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { f_macro_string_dynamic_delete_simple(name); return F_status_set_error(F_buffer_too_large); } @@ -693,9 +722,9 @@ extern "C" { if (F_status_is_error(status)) return status; if (status == F_equal_to_not) continue; - if (values[j]->used + 1 > values[j]->size) { + if (values[j]->used == values[j]->size) { if (values[j]->used + f_fss_default_allocation_step > f_array_length_size) { - if (values[j]->used + 1 > f_array_length_size) { + if (values[j]->used == f_array_length_size) { return F_status_set_error(F_buffer_too_large); } diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index 9b236a0..48a8833 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -5,7 +5,7 @@ extern "C" { #endif #ifndef _di_fll_fss_basic_read_ - f_return_status fll_fss_basic_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents) { + f_return_status fll_fss_basic_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents, f_fss_quoteds *quoted_objects) { #ifndef _di_level_2_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); @@ -16,26 +16,45 @@ extern "C" { f_status status = F_none; f_status status2 = F_none; f_string_length initial_used = objects->used; + bool found_data = F_false; + f_fss_quoted *quoted_object = 0; + do { - if (objects->used >= objects->size) { + if (objects->used == objects->size) { f_macro_fss_objects_resize(status2, (*objects), objects->used + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; f_macro_fss_contents_resize(status2, (*contents), contents->used + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; + + if (quoted_objects) { + f_macro_fss_quoteds_resize(status2, (*quoted_objects), quoted_objects->used + f_fss_default_allocation_step); + if (F_status_is_error(status2)) return status2; + } } do { - status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used]); - if (F_status_is_error(status)) return status; + if (quoted_objects) { + quoted_object = "ed_objects->array[quoted_objects->used]; + } + + status = fl_fss_basic_object_read(buffer, range, &objects->array[objects->used], quoted_object); + + if (F_status_is_error(status)) { + return status; + } if (range->start >= range->stop || range->start >= buffer->used) { if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { objects->used++; - if (contents->array[contents->used].used >= contents->array[contents->used].size) { + if (quoted_objects) { + quoted_objects->used++; + } + + if (contents->array[contents->used].used == contents->array[contents->used].size) { f_macro_fss_content_resize(status2, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; } @@ -72,7 +91,7 @@ extern "C" { else if (status == FL_fss_found_object_content_not) { found_data = F_true; - if (contents->array[contents->used].used >= contents->array[contents->used].size) { + if (contents->array[contents->used].used == contents->array[contents->used].size) { f_macro_fss_content_resize(status2, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; } @@ -85,6 +104,11 @@ extern "C" { contents->array[contents->used].used++; objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } + return status; } else if (status == F_data_not_eos || status == F_data_not_stop) { @@ -105,6 +129,10 @@ extern "C" { if (status == FL_fss_found_object || status == FL_fss_found_content || status == FL_fss_found_content_not || status == FL_fss_found_object_content_not) { objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } } if (range->start >= buffer->used) { @@ -116,6 +144,10 @@ extern "C" { objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } } while (range->start < f_string_length_size); return F_status_is_error(F_number_overflow); @@ -123,20 +155,17 @@ extern "C" { #endif // _di_fll_fss_basic_read_ #ifndef _di_fll_fss_basic_write_ - f_return_status fll_fss_basic_write(const f_string_static object, const f_string_statics contents, f_string_dynamic *buffer) { + f_return_status fll_fss_basic_write(const f_string_static object, const f_string_statics contents, f_string_dynamic *destination) { #ifndef _di_level_2_parameter_checking_ - if (buffer == 0) return F_status_set_error(F_parameter); + if (destination == 0) return F_status_set_error(F_parameter); if (contents.used > contents.size) return F_status_set_error(F_parameter); #endif // _di_level_2_parameter_checking_ f_status status = 0; f_array_length current = 0; - f_string_range range = f_string_range_initialize; - - range.start = 0; - range.stop = object.used - 1; + f_string_range range = f_macro_string_range_initialize(object.used); - status = fl_fss_basic_object_write(buffer, object, &range); + status = fl_fss_basic_object_write(object, 0, &range, destination); if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { return status; @@ -146,20 +175,20 @@ extern "C" { if (contents.used > 0) { range.start = 0; range.stop = contents.array[0].used - 1; - status = fl_fss_basic_content_write(buffer, contents.array[0], &range); + status = fl_fss_basic_content_write(contents.array[0], &range, destination); if (F_status_is_error(status)) { return status; } } else { - if (buffer->used >= buffer->size) { - f_macro_string_dynamic_resize(status, (*buffer), buffer->size + f_fss_default_allocation_step_string); + if (destination->used == destination->size) { + f_macro_string_dynamic_resize(status, (*destination), destination->size + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } - buffer->string[buffer->used] = f_string_eol[0]; - buffer->used++; + destination->string[destination->used] = f_string_eol[0]; + destination->used++; } } diff --git a/level_2/fll_fss/c/fss_basic.h b/level_2/fll_fss/c/fss_basic.h index 55a30b9..d3656e8 100644 --- a/level_2/fll_fss/c/fss_basic.h +++ b/level_2/fll_fss/c/fss_basic.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 quoted_objects + * An array of all objects discovered with quotes and the quote discovered. + * Set pointer address to 0 to disable. * * @return * F_none on success. @@ -54,7 +57,7 @@ extern "C" { * F_utf (with error bit) is returned on failure to read/process a UTF-8 character. */ #ifndef _di_fll_fss_basic_read_ - extern f_return_status fll_fss_basic_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents); + extern f_return_status fll_fss_basic_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents, f_fss_quoteds *quoted_objects); #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 50265cb..cdb2476 100644 --- a/level_2/fll_fss/c/fss_basic_list.c +++ b/level_2/fll_fss/c/fss_basic_list.c @@ -19,7 +19,7 @@ extern "C" { bool found_data = F_false; do { - if (objects->used >= objects->size) { + if (objects->used == objects->size) { f_macro_fss_objects_resize(status2, (*objects), objects->used + f_fss_default_allocation_step); if (F_status_is_error(status)) { @@ -44,7 +44,7 @@ extern "C" { if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { objects->used++; - if (contents->array[contents->used].used >= contents->array[contents->used].size) { + if (contents->array[contents->used].used == contents->array[contents->used].size) { f_macro_fss_content_resize(status2, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; } @@ -83,7 +83,7 @@ extern "C" { else if (status == FL_fss_found_object_content_not) { found_data = F_true; - if (contents->array[contents->used].used >= contents->array[contents->used].size) { + if (contents->array[contents->used].used == contents->array[contents->used].size) { f_macro_fss_content_resize(status2, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; } @@ -164,7 +164,7 @@ extern "C" { } } else { - if (buffer->used >= buffer->size) { + if (buffer->used == buffer->size) { f_macro_string_dynamic_resize(status, (*buffer), buffer->size + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } diff --git a/level_2/fll_fss/c/fss_extended.c b/level_2/fll_fss/c/fss_extended.c index ba011b1..262075b 100644 --- a/level_2/fll_fss/c/fss_extended.c +++ b/level_2/fll_fss/c/fss_extended.c @@ -5,7 +5,7 @@ extern "C" { #endif #ifndef _di_fll_fss_extended_read_ - f_return_status fll_fss_extended_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents) { + f_return_status fll_fss_extended_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents, f_fss_quoteds *quoted_objects, f_fss_quotedss *quoted_contents) { #ifndef _di_level_2_parameter_checking_ if (buffer == 0) return F_status_set_error(F_parameter); if (range == 0) return F_status_set_error(F_parameter); @@ -16,25 +16,50 @@ extern "C" { f_status status = F_none; f_status status2 = F_none; f_string_length initial_used = objects->used; + bool found_data = F_false; + f_fss_quoted *quoted_object = 0; + f_fss_quoteds *quoted_content = 0; + do { - if (objects->used >= objects->size) { + if (objects->used == objects->size) { f_macro_fss_objects_resize(status2, (*objects), objects->used + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; f_macro_fss_contents_resize(status2, (*contents), contents->used + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; + + if (quoted_objects) { + f_macro_fss_quoteds_resize(status2, (*quoted_objects), quoted_objects->used + f_fss_default_allocation_step); + if (F_status_is_error(status2)) return status2; + } + + if (quoted_contents) { + f_macro_fss_quotedss_resize(status2, (*quoted_contents), quoted_contents->used + f_fss_default_allocation_step); + if (F_status_is_error(status2)) return status2; + } } do { - status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used]); - if (F_status_is_error(status)) return status; + if (quoted_objects) { + quoted_object = "ed_objects->array[quoted_objects->used]; + } + + status = fl_fss_extended_object_read(buffer, range, &objects->array[objects->used], quoted_object); + + if (F_status_is_error(status)) { + return status; + } if (range->start >= range->stop || range->start >= buffer->used) { if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) { objects->used++; + if (quoted_objects) { + quoted_objects->used++; + } + if (contents->array[contents->used].used == contents->array[contents->used].size) { f_macro_fss_content_resize(status2, contents->array[contents->used], contents->array[contents->used].size + f_fss_default_allocation_step); if (F_status_is_error(status2)) return status2; @@ -42,6 +67,10 @@ extern "C" { contents->used++; + if (quoted_contents) { + quoted_contents->used++; + } + return FL_fss_found_object_content_not; } @@ -64,8 +93,15 @@ extern "C" { if (status == FL_fss_found_object) { found_data = F_true; - status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used]); - if (F_status_is_error(status)) return status; + if (quoted_contents) { + quoted_content = "ed_contents->array[quoted_contents->used]; + } + + status = fl_fss_extended_content_read(buffer, range, &contents->array[contents->used], quoted_content); + + if (F_status_is_error(status)) { + return status; + } break; } @@ -84,8 +120,19 @@ extern "C" { if (status == F_none_eos || status == F_none_stop) { contents->array[contents->used].used++; + objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } + + if (quoted_contents) { + quoted_contents->array[quoted_contents->used].used++; + quoted_contents->used++; + } + return status; } else if (status == F_data_not_eos || status == F_data_not_stop || status == F_unterminated_group_eos || status == F_unterminated_group_stop) { @@ -106,6 +153,14 @@ extern "C" { if (status == FL_fss_found_object || status == FL_fss_found_content || status == FL_fss_found_content_not || status == FL_fss_found_object_content_not || status == F_unterminated_group) { objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } + + if (quoted_contents) { + quoted_contents->used++; + } } if (range->start >= buffer->used) { @@ -121,6 +176,14 @@ extern "C" { objects->used++; contents->used++; + + if (quoted_objects) { + quoted_objects->used++; + } + + if (quoted_contents) { + quoted_contents->used++; + } } while (range->start < f_string_length_size); return F_status_is_error(F_number_overflow); @@ -136,12 +199,9 @@ extern "C" { f_status status = 0; f_array_length current = 0; - f_string_range range = f_string_range_initialize; - - range.start = 0; - range.stop = object.used - 1; + f_string_range range = f_macro_string_range_initialize(object.used); - status = fl_fss_extended_object_write(object, &range, buffer); + status = fl_fss_extended_object_write(object, 0, &range, buffer); if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { return status; @@ -151,7 +211,7 @@ extern "C" { while (current < contents.used) { range.start = 0; range.stop = contents.array[current].used - 1; - status = fl_fss_extended_content_write(contents.array[current], &range, buffer); + status = fl_fss_extended_content_write(contents.array[current], 0, &range, buffer); if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { return status; diff --git a/level_2/fll_fss/c/fss_extended.h b/level_2/fll_fss/c/fss_extended.h index 24690c1..b36bb02 100644 --- a/level_2/fll_fss/c/fss_extended.h +++ b/level_2/fll_fss/c/fss_extended.h @@ -38,6 +38,12 @@ extern "C" { * This will be populated with all valid objects found. * @param contents * This will be populated with all valid contents found. + * @param quoted_objects + * An array of all objects discovered with quotes and the quote discovered. + * Set pointer address to 0 to disable. + * @param quoted_contents + * An array of all contents discovered with quotes and the quote discovered. + * Set pointer address to 0 to disable. * * @return * F_none on success. @@ -53,7 +59,7 @@ extern "C" { * F_number_overflow (with error bit) if the maximimum buffer size is reached. */ #ifndef _di_fll_fss_extended_read_ - extern f_return_status fll_fss_extended_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents); + extern f_return_status fll_fss_extended_read(f_string_dynamic *buffer, f_string_range *range, f_fss_objects *objects, f_fss_contents *contents, f_fss_quoteds *quoted_objects, f_fss_quotedss *quoted_contents); #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 0a7ead2..ef2f635 100644 --- a/level_2/fll_fss/c/fss_extended_list.c +++ b/level_2/fll_fss/c/fss_extended_list.c @@ -27,7 +27,7 @@ extern "C" { do { do { - if (nest->depth[0].used >= nest->depth[0].size) { + if (nest->depth[0].used == nest->depth[0].size) { f_macro_fss_items_resize(status2, nest->depth[0], nest->depth[0].used + f_fss_default_allocation_step); if (F_status_is_error(status)) return status; } @@ -139,7 +139,7 @@ extern "C" { } } else { - if (buffer->used >= buffer->size) { + if (buffer->used == buffer->size) { f_macro_string_dynamic_resize(status, (*buffer), buffer->size + f_fss_default_allocation_step_string); if (F_status_is_error(status)) return status; } diff --git a/level_2/fll_program/c/program.c b/level_2/fll_program/c/program.c index ce2fa61..6bbe8cc 100644 --- a/level_2/fll_program/c/program.c +++ b/level_2/fll_program/c/program.c @@ -342,7 +342,7 @@ extern "C" { status = F_none; } else { - if (destination->used >= destination->size) { + if (destination->used == destination->size) { f_macro_string_dynamics_resize(status, (*destination), destination->size + f_console_default_allocation_step); if (F_status_is_error(status)) return status; } diff --git a/level_3/fake/c/private-build.c b/level_3/fake/c/private-build.c index 8f56367..372ad9c 100644 --- a/level_3/fake/c/private-build.c +++ b/level_3/fake/c/private-build.c @@ -1183,7 +1183,7 @@ extern "C" { } } - if (environment->names.used + 1 > environment->names.size) { + if (environment->names.used == environment->names.size) { f_macro_string_dynamics_resize(*status, environment->names, environment->names.size + f_memory_default_allocation_step); if (F_status_is_not_error(*status)) { @@ -1242,7 +1242,7 @@ extern "C" { f_string_range range = f_macro_string_range_initialize(buffer.used); - *status = fll_fss_extended_read(&buffer, &range, &objects, &contents); + *status = fll_fss_extended_read(&buffer, &range, &objects, &contents, 0, 0); if (F_status_is_error(*status)) { fake_print_error_fss(data.context, data.verbosity, *status, "fll_fss_extended_read", data.file_data_build_settings.string, range, F_true); } diff --git a/level_3/fake/c/private-make.c b/level_3/fake/c/private-make.c index 60b1111..1580347 100644 --- a/level_3/fake/c/private-make.c +++ b/level_3/fake/c/private-make.c @@ -76,18 +76,27 @@ extern "C" { continue; } + f_fss_quotedss quoted_contents = f_fss_quotedss_initialize; + content_range = list_contents.array[i].array[0]; - *status = fll_fss_extended_read(&data_make->buffer, &content_range, &settings.objects, &settings.contents); + *status = fll_fss_extended_read(&data_make->buffer, &content_range, &settings.objects, &settings.contents, 0, "ed_contents); if (F_status_is_error(*status)) { fake_print_error_fss(data.context, data.verbosity, *status, "fll_fss_extended_read", data.file_data_build_fakefile.string, content_range, F_true); + f_macro_fss_quotedss_delete_simple(quoted_contents); f_macro_fss_set_delete_simple(settings); f_macro_fss_objects_delete_simple(list_objects); f_macro_fss_contents_delete_simple(list_contents); return; } + if (quoted_contents.used) { + // @todo + } + + f_macro_fss_quotedss_delete_simple(quoted_contents); + missing_settings = F_false; continue; } @@ -105,7 +114,7 @@ extern "C" { content_range = list_contents.array[i].array[0]; - *status = fll_fss_extended_read(&data_make->buffer, &content_range, &data_make->fakefile.array[data_make->fakefile.used].objects, &data_make->fakefile.array[data_make->fakefile.used].contents); + *status = fll_fss_extended_read(&data_make->buffer, &content_range, &data_make->fakefile.array[data_make->fakefile.used].objects, &data_make->fakefile.array[data_make->fakefile.used].contents, 0, 0); if (F_status_is_error(*status)) { fake_print_error_fss(data.context, data.verbosity, *status, "fll_fss_extended_read", data.file_data_build_fakefile.string, content_range, F_true); @@ -300,7 +309,7 @@ extern "C" { break; } - if (arguments->used + 1 > arguments->size) { + if (arguments->used == arguments->size) { if (arguments->used + f_memory_default_allocation_step <= F_buffer_too_large) { f_macro_string_dynamics_resize((*status), (*arguments), arguments->used + f_memory_default_allocation_step); } @@ -378,21 +387,23 @@ extern "C" { *status = fl_string_dynamic_partial_compare_dynamic(map_multis->array[k].name, data_make->buffer, iki_content.array[j]); if (*status == F_equal_to) { - for (l = 0; l < map_multis->array[k].value.used; l++) { - if (l > 0) { - *status = fl_string_append(" ", 1, &arguments->array[arguments->used]); + if (map_multis->array[k].value.used) { + for (l = 0; l < map_multis->array[k].value.used; l++) { + if (l > 0) { + *status = fl_string_append(" ", 1, &arguments->array[arguments->used]); + if (F_status_is_error(*status)) { + fake_print_error(data.context, data.verbosity, F_status_set_fine(*status), "fl_string_append", F_true); + break; + } + } + + *status = fl_string_dynamic_append_nulless(map_multis->array[k].value.array[l], &arguments->array[arguments->used]); if (F_status_is_error(*status)) { - fake_print_error(data.context, data.verbosity, F_status_set_fine(*status), "fl_string_append", F_true); + fake_print_error(data.context, data.verbosity, F_status_set_fine(*status), "fl_string_dynamic_append_nulless", F_true); break; } - } - - *status = fl_string_dynamic_append_nulless(map_multis->array[k].value.array[l], &arguments->array[arguments->used]); - if (F_status_is_error(*status)) { - fake_print_error(data.context, data.verbosity, F_status_set_fine(*status), "fl_string_dynamic_append_nulless", F_true); - break; - } - } // for + } // for + } break; } @@ -582,7 +593,7 @@ extern "C" { *status = F_status_set_error(F_invalid); } else if (operation == fake_make_operation_type_operate) { - if (section_stack->used + 1 > fake_make_section_stack_max) { + if (section_stack->used == fake_make_section_stack_max) { fake_print_error_fakefile_section_operation_stack_max(data.context, data.verbosity, data_make->buffer, section->name, section->objects.array[i], fake_make_section_stack_max); *status = F_status_set_error(F_recurse); @@ -609,7 +620,7 @@ extern "C" { } // for if (F_status_is_fine(*status) && has_error) { - *status = F_status_set_error(F_failure); + *status = F_none; } if (F_status_is_error(*status)) { diff --git a/level_3/fake/data/build/fakefile b/level_3/fake/data/build/fakefile index 49ebd75..6bbeffd 100644 --- a/level_3/fake/data/build/fakefile +++ b/level_3/fake/data/build/fakefile @@ -1,5 +1,4 @@ -# fss-0005 iki-0001 -# @todo consider creating iki-0002 to support both "parameter" and "define" as opposed to "var" as documented below. +# fss-0005 iki-0002 settings: load_build yes @@ -9,12 +8,14 @@ settings: # from this, adding 'parameter:"verbose"' in main would be replaced with '+v' if and when the +V/++verbose parameter is passed to fake otherwise it is removed. # gcc parameter:"verbose" would become gcc +v parameter verbose +v + parameter verbose4 +v and then " some" main: - print This is a line. + print This is a line "(define = 'define:"example"') parameter:"verbose4"." invalid + print This works? 'parameter\:"verbose" parameter:"verbose2' parameter:'verbose3' should_-+miss:"abc" print This is another line. 'parameter\:"verbose" parameter:"verbose2\""' parameter:'verbose3\\' another invalid diff --git a/level_3/firewall/c/private-firewall.c b/level_3/firewall/c/private-firewall.c index 46144f4..5c91ed5 100644 --- a/level_3/firewall/c/private-firewall.c +++ b/level_3/firewall/c/private-firewall.c @@ -649,7 +649,7 @@ f_return_status firewall_perform_commands(const firewall_local_data local, const input.stop = local_buffer.used - 1; - status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents); + status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents, 0); } if (F_status_set_error(status)) { @@ -970,7 +970,7 @@ f_return_status firewall_create_custom_chains(firewall_reserved_chains *reserved } if (new_chain) { - if (data->chains.used >= data->chains.size) { + if (data->chains.used == data->chains.size) { f_macro_string_dynamics_resize(status, data->chains, data->chains.used + firewall_default_allocation_step); if (F_status_is_error(status)) { @@ -1431,7 +1431,7 @@ f_return_status firewall_buffer_rules(const f_string filename, const bool option f_return_status firewall_process_rules(f_string_range *range, firewall_local_data *local, firewall_data *data) { f_status status = F_none; - status = fll_fss_extended_read(&local->buffer, range, &local->rule_objects, &local->rule_contents); + status = fll_fss_extended_read(&local->buffer, range, &local->rule_objects, &local->rule_contents, 0, 0); if (F_status_is_not_error(status)) { status = firewall_perform_commands(*local, *data); diff --git a/level_3/firewall/c/private-firewall.h b/level_3/firewall/c/private-firewall.h index 35538b2..6bac95d 100644 --- a/level_3/firewall/c/private-firewall.h +++ b/level_3/firewall/c/private-firewall.h @@ -87,7 +87,7 @@ typedef struct { // TODO: temporarily added, convert this to a function below. // TODO: also report: fl_color_print_line(f_type_error, data.context.error, data.context.reset, "CRITICAL ERROR: Unable to allocate memory."); #define firewall_macro_append_argument_to_arguments(status, arguments, argument) \ - if (arguments.used >= arguments.size) { \ + if (arguments.used == arguments.size) { \ f_macro_string_dynamics_resize(status, arguments, arguments.used + firewall_default_allocation_step); \ \ if (F_status_is_error(status)) break; \ diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.c b/level_3/fss_basic_list_write/c/fss_basic_list_write.c index cad1862..b17b43f 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.c @@ -16,9 +16,10 @@ extern "C" { printf("%c", f_string_eol[0]); - fll_program_print_help_option(context, fss_basic_list_write_short_object, fss_basic_list_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); - fll_program_print_help_option(context, fss_basic_list_write_short_file, fss_basic_list_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); - fll_program_print_help_option(context, fss_basic_list_write_short_string, fss_basic_list_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); + fll_program_print_help_option(context, fss_basic_list_write_short_file, fss_basic_list_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); + fll_program_print_help_option(context, fss_basic_list_write_short_object, fss_basic_list_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); + fll_program_print_help_option(context, fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output the final end of object or end of content character."); + fll_program_print_help_option(context, fss_basic_list_write_short_string, fss_basic_list_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); fll_program_print_help_usage(context, fss_basic_list_write_name, ""); @@ -36,7 +37,6 @@ extern "C" { f_console_parameter_ids choices = { ids, 3 }; status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context); - if (F_status_is_error(status)) { fss_basic_list_write_delete_data(data); return F_status_set_error(status); @@ -59,7 +59,7 @@ extern "C" { f_string_range range = f_string_range_initialize; if (data->process_pipe) { - f_file file = f_file_initialize; + f_file file = f_file_initialize; f_string_dynamic input = f_string_dynamic_initialize; file.id = f_type_descriptor_input; @@ -85,26 +85,44 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_open()", status); } + f_macro_string_dynamic_delete_simple(buffer); f_macro_string_dynamic_delete_simple(input); fss_basic_list_write_delete_data(data); return F_status_set_error(status); } - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - if (object) { - status = fl_fss_basic_list_object_write(input, &range, &buffer); + if (object) { + status = fl_fss_basic_list_object_write(input, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { - return F_status_set_error(status); - } - } - else { - status = fl_fss_basic_list_content_write(input, &range, &buffer); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_basic_list_write_delete_data(data); + return F_status_set_error(status); + } - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { - return F_status_set_error(status); + // this should remove both the closing newline and the colon. + if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) { + buffer.used -= 2; + } + } + else { + status = fl_fss_basic_list_content_write(input, &range, &buffer); + + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_basic_list_write_delete_data(data); + return F_status_set_error(status); + } + + if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) { + buffer.used--; + } } } @@ -116,21 +134,36 @@ extern "C" { input.string = arguments.argv[data->parameters[fss_basic_list_write_parameter_string].additional.array[0]]; input.used = strlen(input.string); - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - if (object) { - status = fl_fss_basic_list_object_write(input, &range, &buffer); + if (object) { + status = fl_fss_basic_list_object_write(input, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { + f_macro_string_dynamic_delete_simple(buffer); + fss_basic_list_write_delete_data(data); + return F_status_set_error(status); + } + + // this should remove both the closing newline and the colon. + if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) { + buffer.used -= 2; + } } - } - else { - status = fl_fss_basic_list_content_write(input, &range, &buffer); + else { + status = fl_fss_basic_list_content_write(input, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos || status == F_data_not_eol) { + f_macro_string_dynamic_delete_simple(buffer); + fss_basic_list_write_delete_data(data); + return F_status_set_error(status); + } + + if (data->parameters[fss_basic_list_write_parameter_partial].result == f_console_result_found) { + buffer.used--; + } } } @@ -165,6 +198,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_open()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_basic_list_write_delete_data(data); return F_status_set_error(status); } @@ -185,6 +219,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_write()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_basic_list_write_delete_data(data); return F_status_set_error(status); } @@ -192,6 +227,8 @@ extern "C" { else { f_print_string_dynamic(f_type_output, buffer); } + + f_macro_string_dynamic_delete_simple(buffer); } fss_basic_list_write_delete_data(data); diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.h b/level_3/fss_basic_list_write/c/fss_basic_list_write.h index aad3bfe..93a2003 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.h @@ -53,13 +53,15 @@ extern "C" { #endif // _di_fss_basic_list_write_name_ #ifndef _di_fss_basic_list_write_defines_ - #define fss_basic_list_write_short_object "o" - #define fss_basic_list_write_short_file "f" - #define fss_basic_list_write_short_string "s" + #define fss_basic_list_write_short_object "o" + #define fss_basic_list_write_short_file "f" + #define fss_basic_list_write_short_string "s" + #define fss_basic_list_write_short_partial "p" - #define fss_basic_list_write_long_object "object" - #define fss_basic_list_write_long_file "file" - #define fss_basic_list_write_long_string "string" + #define fss_basic_list_write_long_object "object" + #define fss_basic_list_write_long_file "file" + #define fss_basic_list_write_long_string "string" + #define fss_basic_list_write_long_partial "partial" enum { fss_basic_list_write_parameter_help, @@ -68,8 +70,9 @@ extern "C" { fss_basic_list_write_parameter_no_color, fss_basic_list_write_parameter_version, - fss_basic_list_write_parameter_object, fss_basic_list_write_parameter_file, + fss_basic_list_write_parameter_object, + fss_basic_list_write_parameter_partial, fss_basic_list_write_parameter_string, }; @@ -80,12 +83,13 @@ extern "C" { f_console_parameter_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, F_false, f_console_type_inverse), \ - f_console_parameter_initialize(fss_basic_list_write_short_object, fss_basic_list_write_long_object, 0, F_false, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_write_short_file, fss_basic_list_write_long_file, 0, F_true, f_console_type_normal), \ + f_console_parameter_initialize(fss_basic_list_write_short_object, fss_basic_list_write_long_object, 0, F_false, f_console_type_normal), \ + f_console_parameter_initialize(fss_basic_list_write_short_partial, fss_basic_list_write_long_partial, 0, F_true, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_list_write_short_string, fss_basic_list_write_long_string, 0, F_true, f_console_type_normal), \ } - #define fss_basic_list_write_total_parameters 8 + #define fss_basic_list_write_total_parameters 9 #endif // _di_fss_basic_list_write_defines_ #ifndef _di_fss_basic_list_write_data_ 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 88d1707..5f2726c 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 @@ -249,7 +249,7 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents); + status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents, 0); if (F_status_is_error(status)) { status = F_status_set_fine(status); diff --git a/level_3/fss_basic_write/c/fss_basic_write.c b/level_3/fss_basic_write/c/fss_basic_write.c index ba520f6..ef02b35 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.c +++ b/level_3/fss_basic_write/c/fss_basic_write.c @@ -16,9 +16,10 @@ extern "C" { printf("%c", f_string_eol[0]); - fll_program_print_help_option(context, fss_basic_write_short_object, fss_basic_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); - fll_program_print_help_option(context, fss_basic_write_short_file, fss_basic_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); - fll_program_print_help_option(context, fss_basic_write_short_string, fss_basic_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); + fll_program_print_help_option(context, fss_basic_write_short_file, fss_basic_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); + fll_program_print_help_option(context, fss_basic_write_short_object, fss_basic_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); + fll_program_print_help_option(context, fss_basic_write_short_partial, fss_basic_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output the final end of object or end of content character."); + fll_program_print_help_option(context, fss_basic_write_short_string, fss_basic_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); fll_program_print_help_usage(context, fss_basic_write_name, ""); @@ -35,11 +36,10 @@ extern "C" { f_console_parameter_id ids[3] = { fss_basic_write_parameter_no_color, fss_basic_write_parameter_light, fss_basic_write_parameter_dark }; f_console_parameter_ids choices = { ids, 3 }; - status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context); - + status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context); if (F_status_is_error(status)) { fss_basic_write_delete_data(data); - return F_status_set_error(status); + return status; } status = F_none; @@ -90,21 +90,33 @@ extern "C" { return F_status_set_error(status); } - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - if (object) { - status = fl_fss_basic_object_write(&buffer, input, &range); + if (object) { + status = fl_fss_basic_object_write(input, 0, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_basic_write_delete_data(data); + return F_status_set_error(status); + } + } + else { + status = fl_fss_basic_content_write(input, &range, &buffer); + + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_basic_write_delete_data(data); + return F_status_set_error(status); + } } - } - else { - status = fl_fss_basic_content_write(&buffer, input, &range); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) { + buffer.used--; } } @@ -114,23 +126,33 @@ extern "C" { f_string_dynamic input = f_string_dynamic_initialize; input.string = arguments.argv[data->parameters[fss_basic_write_parameter_string].additional.array[0]]; - input.used = strlen(input.string); + input.used = strnlen(input.string, f_console_length_size); - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - if (object) { - status = fl_fss_basic_object_write(&buffer, input, &range); + if (object) { + status = fl_fss_basic_object_write(input, 0, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + fss_basic_write_delete_data(data); + return F_status_set_error(status); + } } - } - else { - status = fl_fss_basic_content_write(&buffer, input, &range); + else { + status = fl_fss_basic_content_write(input, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + fss_basic_write_delete_data(data); + return F_status_set_error(status); + } + } + + if (data->parameters[fss_basic_write_parameter_partial].result == f_console_result_found) { + buffer.used--; } } @@ -165,6 +187,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_open()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_basic_write_delete_data(data); return status; } @@ -185,6 +208,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_write()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_basic_write_delete_data(data); return F_status_set_error(status); } @@ -192,6 +216,8 @@ extern "C" { else { f_print_string_dynamic(f_type_output, buffer); } + + f_macro_string_dynamic_delete_simple(buffer); } fss_basic_write_delete_data(data); @@ -202,13 +228,11 @@ extern "C" { #ifndef _di_fss_basic_write_delete_data_ f_return_status fss_basic_write_delete_data(fss_basic_write_data *data) { f_status status = F_none; - f_string_length i = 0; - while (i < fss_basic_write_total_parameters) { + for (f_string_length i = 0; i < fss_basic_write_total_parameters; i++) { f_macro_string_lengths_delete_simple(data->parameters[i].locations); f_macro_string_lengths_delete_simple(data->parameters[i].additional); - i++; - } // while + } // for f_macro_string_lengths_delete_simple(data->remaining); fl_macro_color_context_delete_simple(data->context); diff --git a/level_3/fss_basic_write/c/fss_basic_write.h b/level_3/fss_basic_write/c/fss_basic_write.h index 85dbcc0..b9f342a 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.h +++ b/level_3/fss_basic_write/c/fss_basic_write.h @@ -52,13 +52,15 @@ extern "C" { #endif // _di_fss_basic_write_name_ #ifndef _di_fss_basic_write_defines_ - #define fss_basic_write_short_object "o" - #define fss_basic_write_short_file "f" - #define fss_basic_write_short_string "s" + #define fss_basic_write_short_object "o" + #define fss_basic_write_short_file "f" + #define fss_basic_write_short_string "s" + #define fss_basic_write_short_partial "p" - #define fss_basic_write_long_object "object" - #define fss_basic_write_long_file "file" - #define fss_basic_write_long_string "string" + #define fss_basic_write_long_object "object" + #define fss_basic_write_long_file "file" + #define fss_basic_write_long_string "string" + #define fss_basic_write_long_partial "partial" enum { fss_basic_write_parameter_help, @@ -67,8 +69,9 @@ extern "C" { fss_basic_write_parameter_no_color, fss_basic_write_parameter_version, - fss_basic_write_parameter_object, fss_basic_write_parameter_file, + fss_basic_write_parameter_object, + fss_basic_write_parameter_partial, fss_basic_write_parameter_string, }; @@ -79,12 +82,13 @@ extern "C" { f_console_parameter_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, F_false, f_console_type_inverse), \ - f_console_parameter_initialize(fss_basic_write_short_object, fss_basic_write_long_object, 0, F_false, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_write_short_file, fss_basic_write_long_file, 0, F_true, f_console_type_normal), \ + f_console_parameter_initialize(fss_basic_write_short_object, fss_basic_write_long_object, 0, F_false, f_console_type_normal), \ + f_console_parameter_initialize(fss_basic_write_short_partial, fss_basic_write_long_partial, 0, F_true, f_console_type_normal), \ f_console_parameter_initialize(fss_basic_write_short_string, fss_basic_write_long_string, 0, F_true, f_console_type_normal), \ } - #define fss_basic_write_total_parameters 8 + #define fss_basic_write_total_parameters 9 #endif // _di_fss_basic_write_defines_ #ifndef _di_fss_basic_write_data_ 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 2b73c1e..d64c7a1 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 @@ -249,7 +249,7 @@ extern "C" { input.start = 0; input.stop = data->buffer.used - 1; - status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents); + status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents, 0, 0); if (F_status_is_error(status)) { status = F_status_set_fine(status); diff --git a/level_3/fss_extended_write/c/fss_extended_write.c b/level_3/fss_extended_write/c/fss_extended_write.c index 770e9f0..583d498 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -16,10 +16,10 @@ extern "C" { printf("%c", f_string_eol[0]); - fll_program_print_help_option(context, fss_extended_write_short_object, fss_extended_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); - fll_program_print_help_option(context, fss_extended_write_short_file, fss_extended_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); - fll_program_print_help_option(context, fss_extended_write_short_string, fss_extended_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); - fll_program_print_help_option(context, fss_extended_write_short_partial, fss_extended_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, " For 'content', do not output the end of content character."); + fll_program_print_help_option(context, fss_extended_write_short_file, fss_extended_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to."); + fll_program_print_help_option(context, fss_extended_write_short_object, fss_extended_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " Write an object instead of content."); + fll_program_print_help_option(context, fss_extended_write_short_partial, fss_extended_write_long_partial, f_console_symbol_short_enable, f_console_symbol_long_enable, "Do not output the final end of object or end of content character."); + fll_program_print_help_option(context, fss_extended_write_short_string, fss_extended_write_long_string, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a string to convert."); fll_program_print_help_usage(context, fss_extended_write_name, ""); @@ -37,41 +37,14 @@ extern "C" { f_console_parameter_ids choices = { ids, 3 }; status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context); - if (F_status_is_error(status)) { fss_extended_write_delete_data(data); - return F_status_set_error(status); + return status; } status = F_none; } - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_data_not) { - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: One of the parameters you passed requires an additional parameter that you did not pass."); - // TODO: there is a way to identify which parameter is incorrect - // to do this, one must look for any "has_additional" and then see if the "additional" location is set to 0 - // nothing can be 0 as that represents the program name, unless arguments.argv[] is improperly created - } - else if (status == F_memory_allocation || status == F_memory_reallocation) { - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "CRITICAL ERROR: Unable to allocate memory."); - } - else if (status == F_utf) { - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ENCODING ERROR: Invalid UTF-8 character in parameter when calling f_console_parameter_process()."); - } - else if (status == F_parameter) { - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling f_console_parameter_process()."); - } - else { - fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_console_parameter_process().", status); - } - - fss_extended_write_delete_data(data); - return F_status_set_error(status); - } - if (data->parameters[fss_extended_write_parameter_help].result == f_console_result_found) { fss_extended_write_print_help(data->context); } @@ -82,7 +55,7 @@ extern "C" { f_array_length counter = 0; bool object = (data->parameters[fss_extended_write_parameter_object].result == f_console_result_found); - f_string_dynamic buffer = f_string_dynamic_initialize; + f_string_dynamic buffer = f_string_dynamic_initialize; f_string_range range = f_string_range_initialize; if (data->process_pipe) { @@ -117,79 +90,114 @@ extern "C" { return F_status_set_error(status); } - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - if (object) { - status = fl_fss_extended_object_write(input, &range, &buffer); + if (object) { + status = fl_fss_extended_object_write(input, 0, &range, &buffer); - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); - } - } - else { - status = fl_fss_extended_content_write(input, &range, &buffer); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_extended_write_delete_data(data); + return F_status_set_error(status); + } - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) { + buffer.used--; + } } + else { + status = fl_fss_extended_content_write(input, 0, &range, &buffer); - if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) { - if (buffer.used >= buffer.size) { - f_macro_string_dynamic_resize(status, buffer, buffer.used + f_fss_default_allocation_step_string); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_extended_write_delete_data(data); + return F_status_set_error(status); + } - if (F_status_is_error(status)) { - return status; - } + // remove the last whitespace separator before possibly appending the newline. + if (buffer.used) { + buffer.used--; } - buffer.string[buffer.used] = f_fss_extended_close; - buffer.used++; + if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) { + if (buffer.used == buffer.size) { + f_macro_string_dynamic_resize(status, buffer, buffer.used + f_fss_default_allocation_step_string); + + if (F_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(buffer); + f_macro_string_dynamic_delete_simple(input); + fss_extended_write_delete_data(data); + return status; + } + } + + buffer.string[buffer.used] = f_fss_extended_close; + buffer.used++; + } } } f_macro_string_dynamic_delete_simple(input); } else if (data->parameters[fss_extended_write_parameter_string].result == f_console_result_additional) { + const f_console_parameter *parameter = &data->parameters[fss_extended_write_parameter_string]; f_string_dynamic input = f_string_dynamic_initialize; if (object) { - input.string = arguments.argv[data->parameters[fss_extended_write_parameter_string].additional.array[0]]; - input.used = strlen(input.string); + input.string = arguments.argv[parameter->additional.array[0]]; + input.used = strnlen(input.string, f_console_length_size); - range.start = 0; - range.stop = input.used - 1; + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - status = fl_fss_extended_object_write(input, &range, &buffer); + status = fl_fss_extended_object_write(input, 0, &range, &buffer); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + fss_extended_write_delete_data(data); + return F_status_set_error(status); + } - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_found) { + buffer.used--; + } } } else { - f_string_length i = 0; + for (f_string_length i = 0; i < parameter->additional.used; i++) { + input.string = arguments.argv[parameter->additional.array[i]]; + input.used = strnlen(input.string, f_console_length_size); - while (i < data->parameters[fss_extended_write_parameter_string].additional.used) { - input.string = arguments.argv[data->parameters[fss_extended_write_parameter_string].additional.array[i]]; - input.used = strlen(input.string); + if (input.used) { + range.start = 0; + range.stop = input.used - 1; - range.start = 0; - range.stop = input.used - 1; + status = fl_fss_extended_content_write(input, 0, &range, &buffer); - status = fl_fss_extended_content_write(input, &range, &buffer); - - if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { - return F_status_set_error(status); + if (F_status_is_error(status) || status == F_data_not_stop || status == F_data_not_eos) { + f_macro_string_dynamic_delete_simple(buffer); + fss_extended_write_delete_data(data); + return F_status_set_error(status); + } } + } // for - i++; - } // while + // remove the last whitespace separator before possibly appending the newline. + if (buffer.used) { + buffer.used--; + } if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) { - if (buffer.used >= buffer.size) { + if (buffer.used == buffer.size) { f_macro_string_dynamic_resize(status, buffer, buffer.used + f_fss_default_allocation_step_string); if (F_status_is_error(status)) { + f_macro_string_dynamic_delete_simple(buffer); + fss_extended_write_delete_data(data); return status; } } @@ -230,6 +238,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_open()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_extended_write_delete_data(data); return status; } @@ -250,6 +259,7 @@ extern "C" { fl_color_print_line(f_type_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occurred while calling f_file_write()", status); } + f_macro_string_dynamic_delete_simple(buffer); fss_extended_write_delete_data(data); return F_status_set_error(status); } @@ -257,6 +267,8 @@ extern "C" { else { f_print_string_dynamic(f_type_output, buffer); } + + f_macro_string_dynamic_delete_simple(buffer); } fss_extended_write_delete_data(data); @@ -267,13 +279,11 @@ extern "C" { #ifndef _di_fss_extended_write_delete_data_ f_return_status fss_extended_write_delete_data(fss_extended_write_data *data) { f_status status = F_none; - f_string_length i = 0; - while (i < fss_extended_write_total_parameters) { + for (f_string_length i = 0; i < fss_extended_write_total_parameters; i++) { f_macro_string_lengths_delete_simple(data->parameters[i].locations); f_macro_string_lengths_delete_simple(data->parameters[i].additional); - i++; - } // while + } // for f_macro_string_lengths_delete_simple(data->remaining); fl_macro_color_context_delete_simple(data->context); diff --git a/level_3/fss_extended_write/c/fss_extended_write.h b/level_3/fss_extended_write/c/fss_extended_write.h index 478b937..374e2a4 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.h +++ b/level_3/fss_extended_write/c/fss_extended_write.h @@ -69,10 +69,10 @@ extern "C" { fss_extended_write_parameter_no_color, fss_extended_write_parameter_version, - fss_extended_write_parameter_object, fss_extended_write_parameter_file, - fss_extended_write_parameter_string, + fss_extended_write_parameter_object, fss_extended_write_parameter_partial, + fss_extended_write_parameter_string, }; #define f_console_parameter_initialize_fss_extended_write \ @@ -82,10 +82,10 @@ extern "C" { f_console_parameter_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, F_false, f_console_type_inverse), \ f_console_parameter_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, F_false, f_console_type_inverse), \ - f_console_parameter_initialize(fss_extended_write_short_object, fss_extended_write_long_object, 0, F_false, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_write_short_file, fss_extended_write_long_file, 0, F_true, f_console_type_normal), \ - f_console_parameter_initialize(fss_extended_write_short_string, fss_extended_write_long_string, 0, F_true, f_console_type_normal), \ + f_console_parameter_initialize(fss_extended_write_short_object, fss_extended_write_long_object, 0, F_false, f_console_type_normal), \ f_console_parameter_initialize(fss_extended_write_short_partial, fss_extended_write_long_partial, 0, F_false, f_console_type_normal), \ + f_console_parameter_initialize(fss_extended_write_short_string, fss_extended_write_long_string, 0, F_true, f_console_type_normal), \ } #define fss_extended_write_total_parameters 9 diff --git a/level_3/init/c/private-init.c b/level_3/init/c/private-init.c index a6049c8..2914e6e 100644 --- a/level_3/init/c/private-init.c +++ b/level_3/init/c/private-init.c @@ -98,7 +98,7 @@ f_status status = F_none; // @todo: resume replacing code below. - status = fll_fss_extended_read(&buffer, input, &local->rule_objects, &local->rule_contents); + status = fll_fss_extended_read(&buffer, input, &local->rule_objects, &local->rule_contents, 0, 0); if (F_status_is_not_error(status)) { //status = init_perform_commands(*local, *data); // @fixme @@ -514,7 +514,7 @@ location.start = objects.array[position].start; location.stop = objects.array[position].stop; - status = fll_fss_extended_read(&buffer, &location, &objects, &contents); + status = fll_fss_extended_read(&buffer, &location, &objects, &contents, 0, 0); position++; } // while @@ -522,7 +522,7 @@ // @fixme: resume here, below is just notes and copy&pasted code as examples/reminders. /* - status = fll_fss_extended_read(&buffer, &location, &objects, &contents); + status = fll_fss_extended_read(&buffer, &location, &objects, &contents, 0, 0); if (F_status_is_error(status_process)) { if (status == F_memory_allocation || status == F_memory_reallocation) { @@ -542,7 +542,7 @@ /* f_status status = F_none; - status = fll_fss_extended_read(buffer, location, objects, contents); + status = fll_fss_extended_read(buffer, location, objects, contents, 0, 0); if (F_status_is_not_error(status)) { // @todo: process objects and contents.