From: Kevin Day Date: Fri, 23 Aug 2019 03:50:50 +0000 (-0500) Subject: Update: implement UTF-8 support in fss processing code and add additional functionality X-Git-Tag: 0.5.0~479 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=ea33cf506266e8afd27a9754b862dd417e40c482;p=fll Update: implement UTF-8 support in fss processing code and add additional functionality Additional functionality includes implementing f_utf_character in f_utf. Includes numerous other small UTF-8 updates. Some macros have been wrapped in parenthesis to avoid unobvious issues such as when adding an exclamation before a macro call (and the possible order of operation issues). --- diff --git a/level_0/f_errors/c/errors.h b/level_0/f_errors/c/errors.h index 0eb0ef6..911a89c 100644 --- a/level_0/f_errors/c/errors.h +++ b/level_0/f_errors/c/errors.h @@ -141,30 +141,29 @@ extern "C" { #ifndef _di_f_error_masks_ // f_status is required to be exactly 16 bits, the first two high order bits represent error and warning respectively. - #define f_error_bit_error 32768 - #define f_error_bit_fine 16383 - #define f_error_bit_mask 49152 - #define f_error_bit_signal 49152 - #define f_error_bit_warning 16384 + #define f_error_bit_error 0x8000 // 1000 0000 0000 0000 + #define f_error_bit_signal 0xc000 // 1100 0000 0000 0000 + #define f_error_bit_warning 0x4000 // 0100 0000 0000 0000 - #define f_error_is_error(status) status & f_error_bit_error - #define f_error_is_fine(status) (status & f_error_bit_mask) == 0 - #define f_error_is_problem(status) status & f_error_bit_mask - #define f_error_is_warning(status) status & f_error_bit_warning + #define f_error_mask_fine 0x3fff // 0011 1111 1111 1111 + #define f_error_mask_code 0xc000 // 1100 0000 0000 0000 - #define f_error_is_not_error(status) (status & f_error_bit_error) == 0 - #define f_error_is_not_signal(status) (status & f_error_bit_signal) == 0 - #define f_error_is_not_warning(status) (status & f_error_bit_warning) == 0 + #define f_error_is_error(status) (status & f_error_bit_error) + #define f_error_is_fine(status) ((status & f_error_mask_code) == 0) + #define f_error_is_problem(status) ((status & f_error_bit_error) || (status & f_error_bit_warning)) + #define f_error_is_signal(status) (status & f_error_bit_signal) + #define f_error_is_warning(status) (status & f_error_bit_warning) - // use both error and warning bits to designate that the response is a signal. - #define f_error_is_signal(status) (status & f_error_bit_signal) == f_error_bit_signal + #define f_error_is_not_error(status) ((status & f_error_bit_error) == 0) + #define f_error_is_not_signal(status) ((status & f_error_bit_signal) == 0) + #define f_error_is_not_warning(status) ((status & f_error_bit_warning) == 0) - #define f_error_set_error(status) status | f_error_bit_error - #define f_error_set_signal(status) status | f_error_bit_signal - #define f_error_set_warning(status) status | f_error_bit_warning + #define f_error_set_error(status) (status | f_error_bit_error) + #define f_error_set_signal(status) (status | f_error_bit_signal) + #define f_error_set_warning(status) (status | f_error_bit_warning) // use f_error_set_fine to remove the error, warning, and signal bits - #define f_error_set_fine(status) status & f_error_bit_fine + #define f_error_set_fine(status) (status & f_error_mask_fine) #endif // _di_f_error_masks_ // use of an enumerator makes more sense here than explicitly defining every error code (or return code). @@ -174,10 +173,6 @@ enum { f_true, #endif // _di_f_errors_booleans_ - #ifndef _di_f_errors_maybe_ - f_maybe = 2, - #endif // _di_f_errors_maybe_ - #ifndef _di_f_errors_signals_ f_signal_hangup = 1, f_signal_interrupt, @@ -249,6 +244,7 @@ enum { #ifndef _di_f_errors_basic_ f_none = 197, // start at 197 to allow compatibility with the reserved bash return codes (keep in mind fss return codes can be larger than 255). + f_maybe, f_dummy, // to only be used as a placeholder f_warn, // warning f_critical, @@ -343,6 +339,8 @@ enum { f_unterminated_group_on_eol, f_unterminated_group_on_eos, f_unterminated_group_on_stop, + f_incomplete_utf_on_eos, + f_incomplete_utf_on_stop, #endif // _di_f_errors_buffers_ #ifndef _di_f_errors_allocation_ diff --git a/level_0/f_fss/c/fss.h b/level_0/f_fss/c/fss.h index 0447579..ef32c26 100644 --- a/level_0/f_fss/c/fss.h +++ b/level_0/f_fss/c/fss.h @@ -83,6 +83,9 @@ enum { #ifndef _di_f_fss_default_allocation_step_ #define f_fss_default_allocation_step f_memory_default_allocation_step + + // set to 4 to be UTF-8 friendlier. + #define f_fss_default_allocation_step_string 4 #endif // _di_f_fss_default_allocation_step_ #ifndef _di_f_fss_delimits_ diff --git a/level_0/f_print/c/print.c b/level_0/f_print/c/print.c index 77e3851..16ea4fb 100644 --- a/level_0/f_print/c/print.c +++ b/level_0/f_print/c/print.c @@ -6,6 +6,11 @@ extern "C" { #ifndef _di_f_print_string_ f_return_status f_print_string(FILE *output, const f_string string, const f_string_length length) { + #ifndef _di_level_0_parameter_checking_ + if (string == 0) return f_error_set_error(f_invalid_parameter); + if (length < 1) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_0_parameter_checking_ + register f_string_length i = 0; for (; i < length; i++) { @@ -23,7 +28,7 @@ extern "C" { #ifndef _di_f_print_dynamic_string_ f_return_status f_print_dynamic_string(FILE *output, const f_dynamic_string buffer) { #ifndef _di_level_0_parameter_checking_ - if (buffer.used <= 0) return f_invalid_parameter; + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); #endif // _di_level_0_parameter_checking_ register f_string_length i = 0; diff --git a/level_0/f_print/c/print.h b/level_0/f_print/c/print.h index f8cbf2f..2d08452 100644 --- a/level_0/f_print/c/print.h +++ b/level_0/f_print/c/print.h @@ -25,36 +25,73 @@ extern "C" { #endif +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * The string is printed as-is without interpretation. + * + * Will not stop at \0. + * Will not print \0. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param string + * The string to output. + * + * @return + * f_none on success. + * f_output_error (with error bit) on failure. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ #ifndef _di_f_print_string_ - /** - * Similar to a c-library printf, except that this will only print a specific range. - * will not stop at \0. - * will not print \0. - * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability. - */ extern f_return_status f_print_string(FILE *output, const f_string string, const f_string_length length); #endif // _di_f_print_string_ +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * The string is printed as-is without interpretation. + * + * Will not stop at \0. + * Will not print \0. + * Will print the entire dynamic string. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * + * @return + * f_none on success. + * f_output_error (with error bit) on failure. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ #ifndef _di_f_print_dynamic_string_ - /** - * Similar to a c-library printf, except that this will only print a specific range. - * will not stop at \0. - * will not print \0. - * will print the entire dynamic string. - * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability. - */ extern f_return_status f_print_dynamic_string(FILE *output, const f_dynamic_string buffer); #endif // _di_f_print_dynamic_string_ - +/** + * Similar to a c-library printf, except that this will only print a specific range. + * + * The string is printed as-is without interpretation. + * + * Will not stop at \0. + * Will not print \0. + * Will print the only the buffer range specified by location. + * + * @param output + * The file to output to, including standard streams such as stdout and stderr. + * @param buffer + * The string to output. + * @param location + * The range within the provided string to print. + * + * @return + * f_none on success. + * f_output_error (with error bit) on failure. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ #ifndef _di_f_print_partial_dynamic_string_ - /** - * Similar to a c-library printf, except that this will only print a specific range. - * will not stop at \0. - * will not print \0. - * will print the only the buffer range specified by location. - * This implementation will not proces special characters, such as %s in the same way as printf functions, I am undecided whether or not to add this capability. - */ extern f_return_status f_print_partial_dynamic_string(FILE *output, const f_dynamic_string buffer, const f_string_location location); #endif // _di_f_print_partial_dynamic_string_ diff --git a/level_0/f_utf/c/utf.c b/level_0/f_utf/c/utf.c index ab589b3..3a947dc 100644 --- a/level_0/f_utf/c/utf.c +++ b/level_0/f_utf/c/utf.c @@ -4,8 +4,8 @@ extern "C" { #endif -#ifndef _di_f_utf_is_bom_ - f_return_status f_utf_is_bom(const f_string character, const f_u_short max_width) { +#ifndef _di_f_utf_is_bom_string_ + f_return_status f_utf_is_bom_string(const f_string character, const f_u_short max_width) { #ifndef _di_level_0_parameter_checking_ if (max_width < 1) return f_error_set_error(f_invalid_parameter); #endif // _di_level_0_parameter_checking_ @@ -28,10 +28,40 @@ extern "C" { return f_false; } -#endif // _di_f_utf_is_bom_ +#endif // _di_f_utf_is_bom_string_ -#ifndef _di_f_utf_is_space_ - f_return_status f_utf_is_space(const f_string character, const f_u_short max_width) { +#ifndef _di_f_utf_is_graph_string_ + f_return_status f_utf_is_graph_string(const f_string character, const f_u_short max_width) { + #ifndef _di_level_0_parameter_checking_ + if (max_width < 1) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_0_parameter_checking_ + + f_u_short width = f_macro_utf_byte_width_is(*character); + + if (width == 0) { + return f_false; + } + + if (width > max_width) { + return f_error_set_error(f_maybe); + } + + // for now, just assume that any non-whitespace, non-substitute utf-8 character is a graph. + + if (f_utf_is_space_string(character, max_width) == f_true) { + return f_false; + } + + if (f_utf_is_bom_string(character, max_width) == f_true) { + return f_false; + } + + return f_true; + } +#endif // _di_f_utf_is_graph_string_ + +#ifndef _di_f_utf_is_space_string_ + f_return_status f_utf_is_space_string(const f_string character, const f_u_short max_width) { #ifndef _di_level_0_parameter_checking_ if (max_width < 1) return f_error_set_error(f_invalid_parameter); #endif // _di_level_0_parameter_checking_ @@ -160,10 +190,10 @@ extern "C" { return f_false; } -#endif // _di_f_utf_is_space_ +#endif // _di_f_utf_is_space_string_ -#ifndef _di_f_utf_is_substitute_ - f_return_status f_utf_is_substitute(const f_string character, const f_u_short max_width) { +#ifndef _di_f_utf_is_substitute_string_ + f_return_status f_utf_is_substitute_string(const f_string character, const f_u_short max_width) { #ifndef _di_level_0_parameter_checking_ if (max_width < 1) return f_error_set_error(f_invalid_parameter); #endif // _di_level_0_parameter_checking_ @@ -208,10 +238,10 @@ extern "C" { return f_false; } -#endif // _di_f_utf_is_substitute_ +#endif // _di_f_utf_is_substitute_string_ -#ifndef _di_f_utf_is_whitespace_ - f_return_status f_utf_is_whitespace(const f_string character, const f_u_short max_width) { +#ifndef _di_f_utf_is_whitespace_string_ + f_return_status f_utf_is_whitespace_string(const f_string character, const f_u_short max_width) { #ifndef _di_level_0_parameter_checking_ if (max_width < 1) return f_error_set_error(f_invalid_parameter); #endif // _di_level_0_parameter_checking_ @@ -320,7 +350,353 @@ extern "C" { return f_false; } -#endif // _di_f_utf_is_whitespace_ +#endif // _di_f_utf_is_whitespace_string_ + +#ifndef _di_f_utf_is_bom_character_ + f_return_status f_utf_is_bom_character(const f_utf_character character) { + f_u_short width = f_macro_utf_byte_width(character.byte_1); + + if (width == 1) { + return f_false; + } + + if (width == 3) { + if (character.byte_1 == f_utf_bom[0] && character.byte_2 == f_utf_bom[1] && character.byte_3 == f_utf_bom[2]) { + return f_true; + } + } + + return f_false; + } +#endif // _di_f_utf_is_bom_character_ + +#ifndef _di_f_utf_is_graph_character_ + f_return_status f_utf_is_graph_character(const f_utf_character character) { + f_u_short width = f_macro_utf_byte_width(character.byte_1); + + if (width == 0) { + return f_false; + } + + // for now, just assume that any non-whitespace, non-substitute utf-8 character is a graph. + + if (f_utf_is_space_character(character) == f_true) { + return f_false; + } + + if (f_utf_is_bom_character(character) == f_true) { + return f_false; + } + + return f_true; + } +#endif // _di_f_utf_is_graph_character_ + +#ifndef _di_f_utf_is_space_character_ + f_return_status f_utf_is_space_character(const f_utf_character character) { + f_u_short width = f_macro_utf_byte_width(character.byte_1); + + if (width == 1) { + return f_false; + } + + if (width == 2) { + if (character.byte_1 == f_utf_space_no_break[0] && character.byte_2 == f_utf_space_no_break[1]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_line_feed_reverse[0] && character.byte_2 == f_utf_space_line_feed_reverse[1]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_line_next[0] && character.byte_2 == f_utf_space_line_next[1]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_middle_dot[0] && character.byte_2 == f_utf_substitute_middle_dot[1]) { + return f_true; + } + + return f_false; + } + + if (width == 3) { + if (character.byte_1 == f_utf_space_no_break_narrow[0] && character.byte_2 == f_utf_space_no_break_narrow[1] && character.byte_3 == f_utf_space_no_break_narrow[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en[0] && character.byte_2 == f_utf_space_en[1] && character.byte_3 == f_utf_space_en[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em[0] && character.byte_2 == f_utf_space_em[1] && character.byte_3 == f_utf_space_em[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_quad[0] && character.byte_2 == f_utf_space_em_quad[1] && character.byte_3 == f_utf_space_em_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_three[0] && character.byte_2 == f_utf_space_em_per_three[1] && character.byte_3 == f_utf_space_em_per_three[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_four[0] && character.byte_2 == f_utf_space_em_per_four[1] && character.byte_3 == f_utf_space_em_per_four[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_six[0] && character.byte_2 == f_utf_space_em_per_six[1] && character.byte_3 == f_utf_space_em_per_six[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_figure[0] && character.byte_2 == f_utf_space_figure[1] && character.byte_3 == f_utf_space_figure[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_punctuation[0] && character.byte_2 == f_utf_space_punctuation[1] && character.byte_3 == f_utf_space_punctuation[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_thin[0] && character.byte_2 == f_utf_space_thin[1] && character.byte_3 == f_utf_space_thin[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_hair[0] && character.byte_2 == f_utf_space_hair[1] && character.byte_3 == f_utf_space_hair[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_separator_line[0] && character.byte_2 == f_utf_space_separator_line[1] && character.byte_3 == f_utf_space_separator_line[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_separator_paragraph[0] && character.byte_2 == f_utf_space_separator_paragraph[1] && character.byte_3 == f_utf_space_separator_paragraph[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_ogham[0] && character.byte_2 == f_utf_space_ogham[1] && character.byte_3 == f_utf_space_ogham[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_ideographic[0] && character.byte_2 == f_utf_space_ideographic[1] && character.byte_3 == f_utf_space_ideographic[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_medium_mathematical[0] && character.byte_2 == f_utf_space_medium_mathematical[1] && character.byte_3 == f_utf_space_medium_mathematical[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_symbol_blank[0] && character.byte_2 == f_utf_substitute_symbol_blank[1] && character.byte_3 == f_utf_substitute_symbol_blank[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_symbol_space[0] && character.byte_2 == f_utf_substitute_symbol_space[1] && character.byte_3 == f_utf_substitute_symbol_space[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_open_box[0] && character.byte_2 == f_utf_substitute_open_box[1] && character.byte_3 == f_utf_substitute_open_box[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_open_box_shouldered[0] && character.byte_2 == f_utf_substitute_open_box_shouldered[1] && character.byte_3 == f_utf_substitute_open_box_shouldered[2]) { + return f_true; + } + + return f_false; + } + + return f_false; + } +#endif // _di_f_utf_is_space_character_ + +#ifndef _di_f_utf_is_substitute_character_ + f_return_status f_utf_is_substitute_character(const f_utf_character character) { + f_u_short width = f_macro_utf_byte_width(character.byte_1); + + if (width == 1) { + return f_false; + } + + if (width == 2) { + if (character.byte_1 == f_utf_substitute_middle_dot[0] && character.byte_2 == f_utf_substitute_middle_dot[1]) { + return f_true; + } + + return f_false; + } + + if (width == 3) { + if (character.byte_1 == f_utf_substitute_symbol_blank[0] && character.byte_2 == f_utf_substitute_symbol_blank[1] && character.byte_3 == f_utf_substitute_symbol_blank[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_symbol_space[0] && character.byte_2 == f_utf_substitute_symbol_space[1] && character.byte_3 == f_utf_substitute_symbol_space[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_open_box[0] && character.byte_2 == f_utf_substitute_open_box[1] && character.byte_3 == f_utf_substitute_open_box[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_substitute_open_box_shouldered[0] && character.byte_2 == f_utf_substitute_open_box_shouldered[1] && character.byte_3 == f_utf_substitute_open_box_shouldered[2]) { + return f_true; + } + + return f_false; + } + + return f_false; + } +#endif // _di_f_utf_is_substitute_character_ + +#ifndef _di_f_utf_is_whitespace_character_ + f_return_status f_utf_is_whitespace_character(const f_utf_character character) { + f_u_short width = f_macro_utf_byte_width(character.byte_1); + + if (width == 1) { + return f_false; + } + + if (width == 2) { + if (character.byte_1 == f_utf_space_no_break[0] && character.byte_2 == f_utf_space_no_break[1]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_line_feed_reverse[0] && character.byte_2 == f_utf_space_line_feed_reverse[1]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_line_next[0] && character.byte_2 == f_utf_space_line_next[1]) { + return f_true; + } + + return f_false; + } + + if (width == 3) { + if (character.byte_1 == f_utf_space_no_break_narrow[0] && character.byte_2 == f_utf_space_no_break_narrow[1] && character.byte_3 == f_utf_space_no_break_narrow[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en[0] && character.byte_2 == f_utf_space_en[1] && character.byte_3 == f_utf_space_en[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_en_quad[0] && character.byte_2 == f_utf_space_en_quad[1] && character.byte_3 == f_utf_space_en_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em[0] && character.byte_2 == f_utf_space_em[1] && character.byte_3 == f_utf_space_em[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_quad[0] && character.byte_2 == f_utf_space_em_quad[1] && character.byte_3 == f_utf_space_em_quad[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_three[0] && character.byte_2 == f_utf_space_em_per_three[1] && character.byte_3 == f_utf_space_em_per_three[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_four[0] && character.byte_2 == f_utf_space_em_per_four[1] && character.byte_3 == f_utf_space_em_per_four[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_em_per_six[0] && character.byte_2 == f_utf_space_em_per_six[1] && character.byte_3 == f_utf_space_em_per_six[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_figure[0] && character.byte_2 == f_utf_space_figure[1] && character.byte_3 == f_utf_space_figure[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_punctuation[0] && character.byte_2 == f_utf_space_punctuation[1] && character.byte_3 == f_utf_space_punctuation[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_thin[0] && character.byte_2 == f_utf_space_thin[1] && character.byte_3 == f_utf_space_thin[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_hair[0] && character.byte_2 == f_utf_space_hair[1] && character.byte_3 == f_utf_space_hair[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_separator_line[0] && character.byte_2 == f_utf_space_separator_line[1] && character.byte_3 == f_utf_space_separator_line[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_separator_paragraph[0] && character.byte_2 == f_utf_space_separator_paragraph[1] && character.byte_3 == f_utf_space_separator_paragraph[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_ogham[0] && character.byte_2 == f_utf_space_ogham[1] && character.byte_3 == f_utf_space_ogham[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_ideographic[0] && character.byte_2 == f_utf_space_ideographic[1] && character.byte_3 == f_utf_space_ideographic[2]) { + return f_true; + } + + if (character.byte_1 == f_utf_space_medium_mathematical[0] && character.byte_2 == f_utf_space_medium_mathematical[1] && character.byte_3 == f_utf_space_medium_mathematical[2]) { + return f_true; + } + + return f_false; + } + + return f_false; + } +#endif // _di_f_utf_is_whitespace_character_ + +#ifndef _di_f_utf_string_to_character_ + f_return_status f_utf_string_to_character(const f_string character_string, const f_u_short max_width, f_utf_character *utf_character) { + #ifndef _di_level_0_parameter_checking_ + if (max_width < 1) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_0_parameter_checking_ + + f_u_short width = f_macro_utf_byte_width_is(character_string[0]); + + if (width >= max_width) { + return f_error_set_error(f_failure); + } + + memset(utf_character, 0, sizeof(f_utf_character)); + + utf_character->byte_1 = character_string[0]; + + if (width < 2) { + return f_none; + } + + utf_character->byte_2 = character_string[1]; + + if (width == 2) { + return f_none; + } + + utf_character->byte_3 = character_string[2]; + + if (width == 3) { + return f_none; + } + + utf_character->byte_4 = character_string[3]; + + return f_none; + } +#endif // _di_f_utf_string_to_character_ #ifdef __cplusplus } // extern "C" diff --git a/level_0/f_utf/c/utf.h b/level_0/f_utf/c/utf.h index 53498de..e3569ec 100644 --- a/level_0/f_utf/c/utf.h +++ b/level_0/f_utf/c/utf.h @@ -61,6 +61,28 @@ extern "C" { #endif // _di_f_utf_bom_ /** + * Provide a basic UTF-8 character. + * + * This is intended to be used so that a single path parameter can be passed to a function instead of an array of characters. + */ +#ifndef _di_f_utf_character_ + typedef struct { + char byte_1; + char byte_2; + char byte_3; + char byte_4; + } f_utf_character; + + #define f_utf_character_initialize \ + { \ + '\0', \ + '\0', \ + '\0', \ + '\0', \ + } +#endif // _di_f_utf_char_ + +/** * Define the UTF-8 bytes. * * The bytes are for checking a single 8-bit character value (specifically, checking the first bits). @@ -93,7 +115,7 @@ extern "C" { #define f_macro_utf_byte_is_3(character) ((character & f_utf_byte_off_3) == f_utf_byte_3) // (1110 xxxx & 1111 0000) == 1110 0000 #define f_macro_utf_byte_is_4(character) ((character & f_utf_byte_off_4) == f_utf_byte_4) // (1111 0xxx & 1111 1000) == 1111 0000 - #define f_macro_utf_byte_width(character) (!f_macro_utf_byte_is(character) || f_macro_utf_byte_is_1(character)) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4)) + #define f_macro_utf_byte_width(character) ((!f_macro_utf_byte_is(character) || f_macro_utf_byte_is_1(character)) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4))) #define f_macro_utf_byte_width_is(character) (f_macro_utf_byte_is(character) ? (f_macro_utf_byte_is_1(character) ? 1 : (f_macro_utf_byte_is_2(character) ? 2 : (f_macro_utf_byte_is_3(character) ? 3 : 4))) : 0) #endif // _di_f_utf_byte_ @@ -201,9 +223,31 @@ extern "C" { * f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough. * f_invalid_parameter (with error bit) if a parameter is invalid. */ -#ifndef _di_f_utf_is_bom_ - extern f_return_status f_utf_is_bom(const f_string character, const f_u_short max_width); -#endif // _di_f_utf_is_bom_ +#ifndef _di_f_utf_is_bom_string_ + extern f_return_status f_utf_is_bom_string(const f_string character, const f_u_short max_width); +#endif // _di_f_utf_is_bom_string_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 printable character. + * + * This does not check non-UTF-8 graph. + * + * @param character + * The character to validate. + * There must be enough space allocated to compare against, as limited by max_width. + * @param max_width + * The maximum width available for checking. + * Can be anything greater than 0. + * + * @return + * f_true if a UTF-8 graph. + * f_false if not a UTF-8 graph. + * f_maybe (with error bit) if this could be a graph but width is not long enough. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_graph_string_ + extern f_return_status f_utf_is_graph_string(const f_string character, const f_u_short max_width); +#endif // _di_f_utf_is_graph_string_ /** * Check to see if the entire byte block of the character is a UTF-8 whitespace or substitute character. @@ -223,9 +267,9 @@ extern "C" { * f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough. * f_invalid_parameter (with error bit) if a parameter is invalid. */ -#ifndef _di_f_utf_is_space_ - extern f_return_status f_utf_is_space(const f_string character, const f_u_short max_width); -#endif // _di_f_utf_is_space_ +#ifndef _di_f_utf_is_space_string_ + extern f_return_status f_utf_is_space_string(const f_string character, const f_u_short max_width); +#endif // _di_f_utf_is_space_string_ /** * Check to see if the entire byte block of the character is a UTF-8 whitespace substitute character. @@ -245,9 +289,9 @@ extern "C" { * f_maybe (with error bit) if this could be a substitute but width is not long enough. * f_invalid_parameter (with error bit) if a parameter is invalid. */ -#ifndef _di_f_utf_is_substitute_ - extern f_return_status f_utf_is_substitute(const f_string character, const f_u_short max_width); -#endif // _di_f_utf_is_substitute_ +#ifndef _di_f_utf_is_substitute_string_ + extern f_return_status f_utf_is_substitute_string(const f_string character, const f_u_short max_width); +#endif // _di_f_utf_is_substitute_string_ /** * Check to see if the entire byte block of the character is a UTF-8 general whitespace character. @@ -267,9 +311,117 @@ extern "C" { * f_maybe (with error bit) if this could be a whitespace but width is not long enough. * f_invalid_parameter (with error bit) if a parameter is invalid. */ -#ifndef _di_f_utf_is_whitespace_ - extern f_return_status f_utf_is_whitespace(const f_string character, const f_u_short max_width); -#endif // _di_f_utf_is_whitespace_ +#ifndef _di_f_utf_is_whitespace_string_ + extern f_return_status f_utf_is_whitespace_string(const f_string character, const f_u_short max_width); +#endif // _di_f_utf_is_whitespace_string_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 BOM. + * + * @param character + * The UTF-8 character to validate. + * + * @return + * f_true if a UTF-8 whitespace or substitute. + * f_false if not a UTF-8 whitespace or substitute. + * f_maybe (with error bit) if this could be a whitespace or substitute but width is not long enough. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_bom_character_ + extern f_return_status f_utf_is_bom_character(const f_utf_character character); +#endif // _di_f_utf_is_bom_character_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 printable character. + * + * This does not check non-UTF-8 graph. + * + * @param character + * The character to validate. + * + * @return + * f_true if a UTF-8 graph. + * f_false if not a UTF-8 graph. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_graph_character_ + extern f_return_status f_utf_is_graph_character(const f_utf_character character); +#endif // _di_f_utf_is_graph_character_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 whitespace or substitute character. + * + * This does not check non-UTF-8 whitespace. + * + * @param character + * The character to validate. + * + * @return + * f_true if a UTF-8 whitespace or substitute. + * f_false if not a UTF-8 whitespace or substitute. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_space_character_ + extern f_return_status f_utf_is_space_character(const f_utf_character character); +#endif // _di_f_utf_is_space_character_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 whitespace substitute character. + * + * This does not check non-UTF-8 whitespace. + * + * @param character + * The character to validate. + * + * @return + * f_true if a UTF-8 substitute. + * f_false if not a UTF-8 substitute. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_substitute_character_ + extern f_return_status f_utf_is_substitute_character(const f_utf_character character); +#endif // _di_f_utf_is_substitute_character_ + +/** + * Check to see if the entire byte block of the character is a UTF-8 general whitespace character. + * + * This does not check non-UTF-8 whitespace. + * + * @param character + * The character to validate. + * + * @return + * f_true if a UTF-8 whitespace. + * f_false if not a UTF-8 whitespace. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_is_whitespace_character_ + extern f_return_status f_utf_is_whitespace_character(const f_utf_character character); +#endif // _di_f_utf_is_whitespace_character_ + +/** + * Convert a UTF-8 character, stored as a string (character buffer), to the specialized f_utf_character type. + * + * This will also convert ASCII characters. + * + * @param character_string + * The character string to be converted to the f_utf_character type. + * There must be enough space allocated to convert against, as limited by max_width. + * @param max_width + * The maximum width available for converting. + * Can be anything greater than 0. + * @param utf_character + * The generated character of type f_utf_character. + * This value may be cleared, even on error. + * + * @return + * f_none if conversion was successful. + * f_failure (with error bit) if width is not long enough to convert. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_f_utf_string_to_character_ + extern f_return_status f_utf_string_to_character(const f_string character_string, const f_u_short max_width, f_utf_character *utf_character); +#endif // _di_f_utf_string_to_character_ #ifdef __cplusplus } // extern "C" diff --git a/level_1/fl_fss/c/fss.c b/level_1/fl_fss/c/fss.c index 1d8e525..73edd32 100644 --- a/level_1/fl_fss/c/fss.c +++ b/level_1/fl_fss/c/fss.c @@ -4,6 +4,40 @@ extern "C" { #endif +#ifndef _di_fl_fss_decrement_buffer_ + f_return_status fl_fss_decrement_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input->start < 0) return f_error_set_error(f_invalid_parameter); + if (input->stop < input->start) return f_error_set_error(f_invalid_parameter); + if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter); + if (step < 1) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + if (input->start < 1) return f_none_on_eos; + + f_string_length i = 0; + f_u_short width = 0; + + do { + width = f_macro_utf_byte_width(buffer.string[input->start - 1]); + + if (width > input->start) { + if (width > 1) { + return f_error_set_error(f_incomplete_utf_on_eos); + } + + return f_none_on_eos; + } + + i++; + input->start -= width; + } while (i < step); + + return f_none; + } +#endif // _di_fl_fss_decrement_buffer_ + #ifndef _di_fl_fss_identify_ f_return_status fl_fss_identify(const f_dynamic_string buffer, f_fss_header *header) { #ifndef _di_level_1_parameter_checking_ @@ -13,17 +47,61 @@ extern "C" { register f_string_length i = 0; - // If this correctly follows the FSS specification, then this should be all that needs to be done (as well as atoh for ascii to hex) - if (buffer.string[i] == f_fss_type_header_open) { i++; - if (buffer.string[i] == f_fss_type_header_part1) { i++; - if (buffer.string[i] == f_fss_type_header_part2) { i++; - if (buffer.string[i] == f_fss_type_header_part3) { i++; - if (buffer.string[i] == f_fss_type_header_part4) { i++; - if (buffer.string[i] == f_fss_type_header_part5) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; + // A single UTF-8 BOM is allowed to exist before the valid FSS identifier. + if (buffer.used > 3) { + f_status status = f_utf_is_bom_string(buffer.string, 4); + + if (f_error_is_error(status)) { + return f_error_set_error(fl_fss_no_header); + } + + if (status == f_true) { + i = f_utf_bom_length; + + if (buffer.used < 10 + f_utf_bom_length) { + return fl_fss_no_header; + } + } + else if (buffer.used < 10) { + // "# fss-0000" without UTF-8 BOM is always 10 characters. + return fl_fss_no_header; + } + } + else { + return fl_fss_no_header; + } + + // If this correctly follows the FSS specification, then this should be all that needs to be done (as well as atoh for ascii to hex). + // All characters used in the identifier are only in the ascii equivalents of the characters, any similarly looking character or number representing in UTF-8 is considered invalid. + if (buffer.string[i] == f_fss_type_header_open) { + i++; + + if (buffer.string[i] == f_fss_type_header_part1) { + i++; + + if (buffer.string[i] == f_fss_type_header_part2) { + i++; + + if (buffer.string[i] == f_fss_type_header_part3) { + i++; + + if (buffer.string[i] == f_fss_type_header_part4) { + i++; + + if (buffer.string[i] == f_fss_type_header_part5) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; f_string_location location = f_string_location_initialize; @@ -55,16 +133,31 @@ extern "C" { } } } - // people can miss spaces, so lets accept in an attempt to interpret the file anyway, but return values at this point are to be flagged as invalid } - else if (buffer.string[i] == f_fss_type_header_part2) { i++; - if (buffer.string[i] == f_fss_type_header_part3) { i++; - if (buffer.string[i] == f_fss_type_header_part4) { i++; - if (buffer.string[i] == f_fss_type_header_part5) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; - if (f_is_hexdigit(buffer.string[i]) == f_true) { i++; + // people can miss spaces, so lets accept in an attempt to interpret the file anyway, but return values at this point are to be flagged as invalid + else if (buffer.string[i] == f_fss_type_header_part2) { + i++; + + if (buffer.string[i] == f_fss_type_header_part3) { + i++; + + if (buffer.string[i] == f_fss_type_header_part4) { + i++; + + if (buffer.string[i] == f_fss_type_header_part5) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; + + if (f_is_hexdigit(buffer.string[i]) == f_true) { + i++; f_string_location location = f_string_location_initialize; @@ -98,8 +191,8 @@ extern "C" { #ifndef _di_level_1_parameter_checking_ if (file_information == 0) return f_error_set_error(f_invalid_parameter); if (header == 0) return f_error_set_error(f_invalid_parameter); - if (file_information->file == 0) return f_file_not_open; - if (ferror(file_information->file) != 0) return f_file_error; + if (file_information->file == 0) return f_error_set_error(f_file_not_open); + if (ferror(file_information->file) != 0) return f_error_set_error(f_file_error); #endif // _di_level_1_parameter_checking_ clearerr(file_information->file); @@ -112,7 +205,7 @@ extern "C" { { f_s_int seek_result = f_file_seek_from_beginning(file_information->file, 0); - if (seek_result != 0) return f_file_seek_error; + if (seek_result != 0) return f_error_set_error(f_file_seek_error); } // 1: Prepare the buffer to handle a size of f_fss_max_header_length @@ -138,47 +231,251 @@ extern "C" { } #endif // _di_fl_fss_identify_file_ -#ifndef _di_fl_fss_shift_delimiters_ -f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location location) { - #ifndef _di_level_1_parameter_checking_ - if (buffer->used <= 0) return f_error_set_error(f_invalid_parameter); - if (location.start < 0) return f_error_set_error(f_invalid_parameter); - if (location.stop < location.start) return f_error_set_error(f_invalid_parameter); - if (location.start >= buffer->used) return f_error_set_error(f_invalid_parameter); - #endif // _di_level_1_parameter_checking_ +#ifndef _di_fl_fss_increment_buffer_ + f_return_status fl_fss_increment_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input->start < 0) return f_error_set_error(f_invalid_parameter); + if (input->stop < input->start) return f_error_set_error(f_invalid_parameter); + if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter); + if (step < 1) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + f_string_length i = 0; + f_u_short width = 0; + + do { + width = f_macro_utf_byte_width(buffer.string[input->start]); + + if (input->start + width > input->stop) { + if (width > 1) { + return f_error_set_error(f_incomplete_utf_on_stop); + } - f_string_length position = 0; - f_string_length distance = 0; + input->start += width; + return f_none_on_stop; + } + else if (input->start + width >= buffer.used) { + if (width > 1) { + return f_error_set_error(f_incomplete_utf_on_eos); + } + + input->start += width; + return f_none_on_eos; + } - position = location.start; + i++; + input->start += width; + } while (i < step); - while (position < buffer->used && position <= location.stop) { - if (buffer->string[position] == f_fss_delimit_placeholder) { - distance++; + return f_none; + } +#endif // _di_fl_fss_increment_buffer_ + +#ifndef _di_fl_fss_is_graph_ + f_return_status fl_fss_is_graph(const f_dynamic_string buffer, const f_string_location input) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input.start < 0) return f_error_set_error(f_invalid_parameter); + if (input.stop < input.start) return f_error_set_error(f_invalid_parameter); + if (input.start >= buffer.used) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + f_u_short utf_width = f_macro_utf_byte_width_is(buffer.string[input.start]); + + if (utf_width == 0) { + if (isgraph(buffer.string[input.start])) { + return f_true; + } + + return f_false; } - // do not waste time trying to process what is only going to be replaced with a delimit placeholder - if (position + distance >= buffer->used || position + distance > location.stop) { - break; + f_string_length max_width = (input.stop - input.start) + 1; + + if (max_width > buffer.used - input.start) { + max_width = buffer.used - input.start; } - // shift everything down one for each placeholder found - if (distance > 0) { - buffer->string[position] = buffer->string[position + distance]; + f_status status = f_utf_is_space_string(buffer.string + input.start, max_width); + + if (f_error_is_error(status)) { + return status; + } + + if (status == f_true) { + return f_false; } - ++position; + return f_true; } +#endif // _di_fl_fss_is_graph_ + +#ifndef _di_fl_fss_is_space_ + f_return_status fl_fss_is_space(const f_dynamic_string buffer, const f_string_location input) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input.start < 0) return f_error_set_error(f_invalid_parameter); + if (input.stop < input.start) return f_error_set_error(f_invalid_parameter); + if (input.start >= buffer.used) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + f_u_short utf_width = f_macro_utf_byte_width_is(buffer.string[input.start]); + + if (utf_width == 0) { + if (isspace(buffer.string[input.start])) { + return f_true; + } + + return f_false; + } + + f_string_length max_width = (input.stop - input.start) + 1; - if (distance > 0) { - while (position < buffer->used + distance && position <= location.stop) { - buffer->string[position] = f_fss_delimit_placeholder; - ++position; + if (max_width > buffer.used - input.start) { + max_width = buffer.used - input.start; } + + f_status status = f_utf_is_space_string(buffer.string + input.start, max_width); + + if (f_error_is_error(status)) { + return status; + } + + if (status == f_true) { + return f_true; + } + + return f_false; + } +#endif // _di_fl_fss_is_space_ + +#ifndef _di_fl_fss_skip_past_whitespace_ + f_return_status fl_fss_skip_past_whitespace(const f_dynamic_string buffer, f_string_location *input) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input->start < 0) return f_error_set_error(f_invalid_parameter); + if (input->stop < input->start) return f_error_set_error(f_invalid_parameter); + if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + f_status status = f_none; + f_u_short max_width = 0; + + while (input->start < buffer.used && input->start > input->stop) { + if (isgraph(buffer.string[input->start])) break; + + if (buffer.string[input->start] == f_eol) break; + + if (buffer.string[input->start] != f_fss_delimit_placeholder) { + max_width = (input->stop - input->start) + 1; + + if (f_utf_is_space_string(buffer.string +input->start, max_width) != f_true) { + if (f_utf_is_bom_string(buffer.string + input->start, max_width) != f_true) { + break; + } + } + } + + input->start++; + } // while + + return f_none; } +#endif // _di_fl_fss_skip_past_whitespace_ + +#ifndef _di_fl_fss_skip_past_all_whitespace_ + f_return_status fl_fss_skip_past_all_whitespace(const f_dynamic_string buffer, f_string_location *input) { + #ifndef _di_level_1_parameter_checking_ + if (buffer.used <= 0) return f_error_set_error(f_invalid_parameter); + if (input->start < 0) return f_error_set_error(f_invalid_parameter); + if (input->stop < input->start) return f_error_set_error(f_invalid_parameter); + if (input->start >= buffer.used) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ - return f_none; -} + f_status status = f_none; + f_u_short max_width = 0; + + while (input->start < buffer.used && input->start > input->stop) { + if (isgraph(buffer.string[input->start])) break; + + if (buffer.string[input->start] != f_fss_delimit_placeholder) { + max_width = (input->stop - input->start) + 1; + + if (f_utf_is_space_string(buffer.string + input->start, max_width) != f_true) { + if (f_utf_is_bom_string(buffer.string + input->start, max_width) != f_true) { + break; + } + } + } + + input->start++; + } // while + + return f_none; + } +#endif // _di_fl_fss_skip_past_all_whitespace_ + +#ifndef _di_fl_fss_shift_delimiters_ + f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location input) { + #ifndef _di_level_1_parameter_checking_ + if (buffer->used <= 0) return f_error_set_error(f_invalid_parameter); + if (input.start < 0) return f_error_set_error(f_invalid_parameter); + if (input.stop < input.start) return f_error_set_error(f_invalid_parameter); + if (input.start >= buffer->used) return f_error_set_error(f_invalid_parameter); + #endif // _di_level_1_parameter_checking_ + + f_string_length position = 0; + f_string_length distance = 0; + f_u_short utf_width = 0; + f_u_short i = 0; + + position = input.start; + + while (position < buffer->used && position <= input.stop) { + if (buffer->string[position] == f_fss_delimit_placeholder) { + distance++; + } + + // do not waste time trying to process what is only going to be replaced with a delimit placeholder + if (position + distance >= buffer->used || position + distance > input.stop) { + break; + } + + utf_width = f_macro_utf_byte_width_is(buffer->string[position]); + if (utf_width > 1) { + // not enough space in buffer or in input range to process UTF-8 character. + if (position + utf_width >= buffer->used || position + utf_width > input.stop) { + return f_error_set_error(f_invalid_utf); + } + + if (distance > 0) { + while (utf_width > 0) { + buffer->string[position] = buffer->string[position + distance]; + utf_width--; + position++; + } + } + } + else { + // shift everything down one for each placeholder found + if (distance > 0) { + buffer->string[position] = buffer->string[position + distance]; + } + + position++; + } + } + + if (distance > 0) { + while (position < buffer->used + distance && position <= input.stop) { + buffer->string[position] = f_fss_delimit_placeholder; + ++position; + } + } + + return f_none; + } #endif // _di_fl_fss_shift_delimiters_ #ifdef __cplusplus diff --git a/level_1/fl_fss/c/fss.h b/level_1/fl_fss/c/fss.h index a0c26b3..43a896c 100644 --- a/level_1/fl_fss/c/fss.h +++ b/level_1/fl_fss/c/fss.h @@ -19,6 +19,7 @@ #include #include #include +#include // fll-1 includes #include @@ -27,29 +28,203 @@ extern "C" { #endif +/** + * Continue to the previous character, based on step and character width. + * + * The start position must be at the start of a valid UTF-8 block. + * + * @param buffer + * The string to process. + * @param input + * The start and stop positions to be incremented. + * The start position will be incremented by step. + * @param step + * The number of steps to decrement the start position. + * The steps refer to characters and not integers. + * Essentially this number is considered against the width of every character found. + * (For ASCII each step would be (sizeof(char)). + * (For UTF-8 character of width 3, each step would be (3 * sizeof(char)). + * + * @return + * f_none on success. + * f_none_on_stop if the stop point is reached before all steps are completed. + * f_none_on_eos if the end of buffer is reached before all steps are completed. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_incomplete_utf_on_stop (with error bit) if the stop point is reached before the complete UTF-8 character can be processed. + * f_incomplete_utf_on_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. + */ +#ifndef _di_fl_fss_decrement_buffer_ + extern f_return_status fl_fss_decrement_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step); +#endif // _di_fl_fss_decrement_buffer_ + +/** + * Identify FSS type from a buffered string. + * + * The UTF-8 BOM is allowed to exist as the first character of the FSS header, but not anywhere else. + * + * @param buffer + * The string to process. + * @param header + * The header data to populate with results of this function. + * + * @return + * fl_fss_no_header if no header is found. + * fl_fss_no_header (with error bit) if the an error occured prior to identifying a valid header. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ #ifndef _di_fl_fss_identify_ - /** - * Identify FSS type from a buffered string. - */ extern f_return_status fl_fss_identify(const f_dynamic_string buffer, f_fss_header *header); #endif // _di_fl_fss_identify_ +/** + * Identify FSS type from a file. + * + * @param file_information + * The file information. + * @param header + * The header data to populate with results of this function. + * + * @return + * f_none on success. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * + * Errors from (with error bit): f_file_read(). + * Errors from (with error bit): fl_fss_identify() + * File errors (with error bit): f_file_seek_error, f_file_not_open. + * + * @see f_file_read() + * @see fl_fss_identify() + */ #ifndef _di_fl_fss_identify_file_ - /** - * Ideentify FSS type from a file. - */ extern f_return_status fl_fss_identify_file(f_file *file_information, f_fss_header *header); #endif // _di_fl_fss_identify_file_ +/** + * Continue to the next character, based on step and character width. + * + * The start position must be at the start of a valid UTF-8 block. + * + * @param buffer + * The string to process. + * @param input + * The start and stop positions to be incremented. + * The start position will be incremented by step. + * @param step + * The number of steps to increment the start position. + * The steps refer to characters and not integers. + * Essentially this number is considered against the width of every character found. + * (For ASCII each step would be (sizeof(char)). + * (For UTF-8 character of width 3, each step would be (3 * sizeof(char)). + * + * @return + * f_none on success. + * f_none_on_stop if the stop point is reached before all steps are completed. + * f_none_on_eos if the end of buffer is reached before all steps are completed. + * f_invalid_parameter (with error bit) if a parameter is invalid. + * f_incomplete_utf_on_stop (with error bit) if the stop point is reached before the complete UTF-8 character can be processed. + * f_incomplete_utf_on_eos (with error bit) if the end of buffer is reached before the complete UTF-8 character can be processed. + */ +#ifndef _di_fl_fss_increment_buffer_ + extern f_return_status fl_fss_increment_buffer(const f_dynamic_string buffer, f_string_location *input, const f_string_length step); +#endif // _di_fl_fss_increment_buffer_ + +/** + * Identify whether or not a character in the buffer is a graph (ASCII or UTF-8) character. + * + * @param buffer + * The string to process. + * @param input + * The character at the start position will be checked against the graph. + * @param header + * The header data to populate with results of this function. + * + * @return + * f_true if the character in the buffer is a graph character. + * f_false if the character in the buffer is not a graph character. + * f_maybe (with error bit) if the character width is outside the stop position. + * f_failure (with error bit) if the buffer is not wide enough or the width is outside the stop position. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_is_graph_ + extern f_return_status fl_fss_is_graph(const f_dynamic_string buffer, const f_string_location input); +#endif // _di_fl_fss_is_graph_ + +/** + * Identify whether or not a character in the buffer is a space (ASCII or UTF-8) character. + * + * @param buffer + * The string to process. + * @param input + * The character at the start position will be checked against the graph. + * @param header + * The header data to populate with results of this function. + * + * @return + * f_true if the character in the buffer is a space character. + * f_false if the character in the buffer is not a space character. + * f_maybe (with error bit) if the character width is outside the stop position. + * f_failure (with error bit) if the buffer is not wide enough or the width is outside the stop position. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_is_space_ + extern f_return_status fl_fss_is_space(const f_dynamic_string buffer, const f_string_location input); +#endif // _di_fl_fss_is_space_ + +/** + * Shift all of the delimiters to the end of the used buffer. + * + * This allows one to do a printf on the dynamic string without the delimiters arbitrarily stopping the output. + * No reallocations are performed, this will only shift characters. + * + * @param buffer + * The string to process. + * This gets updated. + * @param input + * A restriction on where within the buffer the shifting happens. + * + * @return + * f_none on success. + * f_invalid_utf (with error bit) if UTF-8 cannot be fully processed (buffer or location range not long enough). + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ #ifndef _di_fl_fss_shift_delimiters_ - /** - * This provides a means to shift all of the delimiters to the end of the used buffer. - * This allows one to do a printf on the dynamic string without the delimiters arbitrarily stopping the output. - * No reallocations are performed, this will only shift characters. - */ - extern f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location location); + extern f_return_status fl_fss_shift_delimiters(f_dynamic_string *buffer, const f_string_location input); #endif // _di_fl_fss_shift_delimiters_ +/** + * Skip past all whitespace and control characters, except newline. + * + * @param buffer + * The string to process. + * @param input + * The start and stop positions in the buffer being processed. + * This increments location->start. + * + * @return + * f_none on success. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_skip_past_whitespace_ + extern f_return_status fl_fss_skip_past_whitespace(const f_dynamic_string buffer, f_string_location *input); +#endif // _di_fl_fss_skip_past_whitespace_ + +/** + * Skip past all whitespace and control characters. + * + * @param buffer + * The string to process. + * @param input + * The start and stop positions in the buffer being processed. + * This increments input->start. + * + * @return + * f_none on success. + * f_invalid_parameter (with error bit) if a parameter is invalid. + */ +#ifndef _di_fl_fss_skip_past_all_whitespace_ + extern f_return_status fl_fss_skip_past_all_whitespace(const f_dynamic_string buffer, f_string_location *input); +#endif // _di_fl_fss_skip_past_all_whitespace_ + #ifdef __cplusplus } // extern "C" #endif diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index 20d67d4..cdd12cf 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -16,15 +16,19 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_fss_skip_past_whitespace(*buffer, input); fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[input->start] == f_fss_basic_close) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -39,7 +43,9 @@ extern "C" { if (buffer->string[input->start] == f_fss_comment) { fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -49,24 +55,41 @@ extern "C" { // identify where the object begins if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length last_slash = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } - else if (!isgraph(buffer->string[input->start])) { - found->stop = input->start - 1; - input->start++; - return fl_fss_found_object; - } - else if (buffer->string[input->start] != f_fss_delimit_slash) { - break; + else { + status = fl_fss_is_graph(*buffer, *input); + if (status == f_false) { + found->stop = input->start - 1; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + + return fl_fss_found_object; + } + else if (f_error_is_error(status)) { + return status; + } + else if (buffer->string[input->start] != f_fss_delimit_slash) { + break; + } } last_slash = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) @@ -85,46 +108,70 @@ extern "C" { delimits.array[delimits.used] = last_slash; delimits.used++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { quoted = buffer->string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->start = input->start; } // identify where the object ends if (quoted == f_eos) { - while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = f_none; + while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) } // while - if (isspace(buffer->string[input->start])) { + if (f_error_is_error(status)) return status; + + status = fl_fss_is_space(*buffer, *input); + if (status == f_true) { found->stop = input->start - 1; fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); if (buffer->string[input->start] == f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object_no_content; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } + else if (f_error_is_error(status)) { + return status; + } } else { while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length first_slash = input->start; f_string_length slash_count = 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (buffer->string[input->start] != f_fss_delimit_slash) { @@ -132,7 +179,9 @@ extern "C" { } slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -164,7 +213,9 @@ extern "C" { slash_count--; } - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location + 1; @@ -172,9 +223,10 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) - if (isgraph(buffer->string[input->start])) { + if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) @@ -185,14 +237,22 @@ extern "C" { f_delete_string_lengths(allocation_status, delimits); } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object_no_content; } @@ -200,7 +260,10 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } else { @@ -225,7 +288,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location; @@ -234,22 +298,36 @@ extern "C" { } else if (buffer->string[input->start] == quoted) { found->stop = input->start - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object_no_content; } - else if (isspace(buffer->string[input->start])) { + else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] != f_fss_delimit_placeholder) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) @@ -260,11 +338,15 @@ extern "C" { f_delete_string_lengths(allocation_status, delimits); } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) @@ -276,11 +358,15 @@ extern "C" { f_delete_string_lengths(allocation_status, delimits); } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -288,7 +374,8 @@ extern "C" { // seek to the end of the line when no valid object is found while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) @@ -299,7 +386,10 @@ extern "C" { f_delete_string_lengths(allocation_status, delimits); } - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } #endif // _di_fl_fss_basic_object_read_ @@ -316,15 +406,19 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_fss_skip_past_whitespace(*buffer, input); fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[input->start] == f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_content; } @@ -344,7 +438,10 @@ extern "C" { // Save the stop point found->array[found->used].stop = input->start - 1; found->used++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_content; } #endif // _di_fl_fss_basic_content_read_ @@ -374,7 +471,7 @@ extern "C" { start_position = input->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 + (input->stop - input->start) + 3 + f_fss_default_allocation_step; + pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step_string; if (pre_allocate_size > buffer->size) { f_resize_dynamic_string(status, (*buffer), pre_allocate_size); @@ -388,7 +485,9 @@ extern "C" { if (object.string[input->start] == f_fss_delimit_slash) { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] != f_fss_delimit_slash) { @@ -397,14 +496,16 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -412,14 +513,16 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = object.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -427,7 +530,9 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = object.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } else if (object.string[input->start] == f_fss_comment) { quoted = f_true; @@ -435,7 +540,9 @@ extern "C" { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] == f_eol) { @@ -449,11 +556,11 @@ extern "C" { return f_none_on_eol; } - else if (isspace(object.string[input->start]) || quoted) { + else if ((status = fl_fss_is_space(*buffer, *input)) == f_true || quoted) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -467,14 +574,16 @@ extern "C" { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -489,7 +598,10 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + fl_macro_fss_skip_past_delimit_placeholders(object, (*input)); @@ -501,7 +613,7 @@ extern "C" { pre_allocate_size += slash_count; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -533,7 +645,10 @@ extern "C" { } buffer->string[buffer_position.stop] = object.string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + buffer_position.stop++; } // while @@ -542,9 +657,15 @@ extern "C" { buffer->used = buffer_position.stop + 2; break; } + else if (f_error_is_error(status)) { + return status; + } buffer->string[buffer_position.stop] = object.string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + buffer_position.stop++; } // while @@ -577,7 +698,7 @@ extern "C" { f_string_length pre_allocate_size = 0; // 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; + pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string; buffer_position.start = buffer->used; buffer_position.stop = buffer->used; @@ -600,7 +721,7 @@ extern "C" { buffer_position.stop++; } - input->start++; + fl_fss_increment_buffer(*buffer, input, 1); } // while buffer->string[buffer_position.stop] = f_eol; diff --git a/level_1/fl_fss/c/fss_basic.h b/level_1/fl_fss/c/fss_basic.h index eaf227f..bc913f3 100644 --- a/level_1/fl_fss/c/fss_basic.h +++ b/level_1/fl_fss/c/fss_basic.h @@ -20,6 +20,7 @@ #include #include #include +#include // fll-1 includes #include diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index a3d090a..db5d3e1 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -16,15 +16,19 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_fss_skip_past_whitespace(*buffer, input); fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[input->start] == f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -35,7 +39,9 @@ extern "C" { if (buffer->string[input->start] == f_fss_comment) { fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -45,14 +51,16 @@ extern "C" { f_string_length first_slash = input->start; f_string_length slash_count = 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop && (buffer->string[input->start] == f_fss_delimit_placeholder || buffer->string[input->start] == f_fss_delimit_slash)) { if (buffer->string[input->start] == f_fss_delimit_slash) { slash_count++; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) @@ -60,14 +68,18 @@ extern "C" { if (buffer->string[input->start] == f_fss_basic_list_open) { f_string_length stop_point = input->start - 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop) { - if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) { + if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) @@ -99,7 +111,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); @@ -120,14 +133,18 @@ extern "C" { else if (buffer->string[input->start] == f_fss_basic_list_open) { f_string_length stop_point = input->start - 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop) { - if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) { + if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) @@ -136,7 +153,9 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = stop_point; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; return fl_fss_found_object; } @@ -144,17 +163,21 @@ extern "C" { continue; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while // seek to the end of the line when no valid object is found while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } #endif // _di_fl_fss_basic_list_object_read_ @@ -171,6 +194,8 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; @@ -188,7 +213,12 @@ extern "C" { if (buffer->string[input->start] == f_eol) { found_newline = f_true; last_newline = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + + fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) + continue; } @@ -196,14 +226,16 @@ extern "C" { f_string_length first_slash = input->start; f_string_length slash_count = 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop && (buffer->string[input->start] == f_fss_delimit_placeholder || buffer->string[input->start] == f_fss_delimit_slash)) { if (buffer->string[input->start] == f_fss_delimit_slash) { slash_count++; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (found_newline) { @@ -216,14 +248,18 @@ extern "C" { if (buffer->string[input->start] == f_fss_basic_list_open) { f_string_length stop_point = input->start - 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop) { - if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) { + if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (found_newline) { @@ -274,7 +310,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while found_newline = f_true; @@ -285,14 +322,18 @@ extern "C" { continue; } else if (buffer->string[input->start] == f_fss_basic_list_open) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start < buffer->used && input->start <= input->stop) { - if (buffer->string[input->start] == f_eol || isgraph(buffer->string[input->start])) { + if (buffer->string[input->start] == f_eol || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (found_newline) { @@ -323,7 +364,8 @@ extern "C" { continue; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (found_newline) { @@ -369,7 +411,7 @@ extern "C" { start_position = input->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 + (input->stop - input->start) + 2 + f_fss_default_allocation_step; + pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step_string; if (pre_allocate_size > buffer->size) { f_resize_dynamic_string(status, (*buffer), pre_allocate_size); @@ -385,16 +427,20 @@ extern "C" { // comments are not allowed and this format has no way of "wrapping" a comment. return f_invalid_data; } - else if (isgraph(object.string[input->start])) { + else if ((status = fl_fss_is_graph(object, *input)) == f_true) { break; } + else if (f_error_is_error(status)) { + return status; + } if (object.string[input->start] != f_fss_delimit_placeholder) { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; } - input->start++; + status = fl_fss_increment_buffer(object, input, 1); + if (f_error_is_error(status)) return status; } // while while (input->start <= input->stop && input->start < object.used) { @@ -404,11 +450,14 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; - input->start++; + status = fl_fss_increment_buffer(object, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(object, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] != f_fss_delimit_slash) { break; @@ -416,7 +465,10 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(object, input, 1); + if (f_error_is_error(status)) return status; + slash_count++; } // while @@ -424,7 +476,7 @@ extern "C" { pre_allocate_size += slash_count; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -451,7 +503,8 @@ extern "C" { buffer_position.stop++; } - input->start++; + status = fl_fss_increment_buffer(object, input, 1); + if (f_error_is_error(status)) return status; } // while buffer->string[buffer_position.stop] = f_fss_basic_list_open; @@ -495,7 +548,7 @@ extern "C" { start_position = input->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 + (input->stop - input->start) + 2 + f_fss_default_allocation_step; + pre_allocate_size = buffer->used + (input->stop - input->start) + 2 + f_fss_default_allocation_step_string; if (pre_allocate_size > buffer->size) { f_resize_dynamic_string(status, (*buffer), pre_allocate_size); @@ -514,11 +567,14 @@ extern "C" { buffer_position.stop++; has_graph = f_true; - input->start++; + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < content.used) { if (content.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (content.string[input->start] != f_fss_delimit_slash) { @@ -527,28 +583,35 @@ extern "C" { buffer->string[buffer_position.stop] = content.string[input->start]; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; + slash_count++; } // while if (content.string[input->start] == f_fss_basic_list_open) { f_string_length location = input->start; - input->start++; + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; while (input->start < content.used && input->start <= input->stop) { - if (content.string[input->start] == f_eol || isgraph(content.string[input->start])) { + if (content.string[input->start] == f_eol || (status = fl_fss_is_graph(content, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; } // while if (content.string[input->start] == f_eol || input->start >= content.used || input->start > input->stop) { pre_allocate_size += slash_count + 1; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -575,21 +638,26 @@ extern "C" { f_string_length location = input->start; has_graph = f_true; - input->start++; + + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; while (input->start < content.used && input->start <= input->stop) { - if (content.string[input->start] == f_eol || isgraph(content.string[input->start])) { + if (content.string[input->start] == f_eol || (status = fl_fss_is_graph(content, *input)) == f_true) { break; } - input->start++; + if (f_error_is_error(status)) return status; + + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; } // while if (content.string[input->start] == f_eol || input->start >= content.used || input->start > input->stop) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -612,16 +680,20 @@ extern "C" { has_graph = f_false; is_comment = f_false; } - else if (isgraph(content.string[input->start])) { + else if ((status = fl_fss_is_graph(content, *input)) == f_true) { has_graph = f_true; } + else if (f_error_is_error(status)) { + return status; + } if (content.string[input->start] != f_fss_delimit_placeholder) { buffer->string[buffer_position.stop] = content.string[input->start]; buffer_position.stop++; } - input->start++; + status = fl_fss_increment_buffer(content, input, 1); + if (f_error_is_error(status)) return status; } // while buffer->string[buffer_position.stop] = f_eol; diff --git a/level_1/fl_fss/c/fss_basic_list.h b/level_1/fl_fss/c/fss_basic_list.h index a1d5f5f..ae16b07 100644 --- a/level_1/fl_fss/c/fss_basic_list.h +++ b/level_1/fl_fss/c/fss_basic_list.h @@ -20,6 +20,7 @@ #include #include #include +#include // fll-1 includes #include diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index da86914..7c6a6a5 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -16,15 +16,19 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_fss_skip_past_whitespace(*buffer, input); fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[input->start] == f_fss_extended_close) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -39,7 +43,9 @@ extern "C" { if (buffer->string[input->start] == f_fss_comment) { fl_macro_fss_object_seek_till_newline((*buffer), (*input), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } @@ -49,24 +55,36 @@ extern "C" { // identify where the object begins if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length last_slash = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } - else if (!isgraph(buffer->string[input->start])) { + else if ((status = fl_fss_is_graph(*buffer, *input)) == f_false) { found->stop = input->start - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] != f_fss_delimit_slash) { break; } last_slash = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) @@ -85,46 +103,67 @@ extern "C" { delimits.array[delimits.used] = last_slash; delimits.used++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { quoted = buffer->string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->start = input->start; } // identify where the object ends if (quoted == f_eos) { - while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = f_none; + while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) } // while - if (isspace(buffer->string[input->start])) { + if (f_error_is_error(status)) return status; + + if ((status = fl_fss_is_space(*buffer, *input)) == f_true) { found->stop = input->start - 1; fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); if (buffer->string[input->start] == f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object_no_content; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } + else if (f_error_is_error(status)) { + return status; + } } else { while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length first_slash = input->start; f_string_length slash_count = 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (buffer->string[input->start] != f_fss_delimit_slash) { @@ -132,7 +171,9 @@ extern "C" { } slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -164,7 +205,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location + 1; @@ -172,21 +214,29 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) - if (isgraph(buffer->string[input->start])) { + if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; return fl_fss_found_object_no_content; } @@ -194,7 +244,10 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } else { @@ -219,7 +272,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location; @@ -228,43 +282,59 @@ extern "C" { } else if (buffer->string[input->start] == quoted) { found->stop = input->start - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object_no_content; } - else if (isspace(buffer->string[input->start])) { + else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_object; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] != f_fss_delimit_placeholder) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) } else if (buffer->string[input->start] == f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -272,12 +342,15 @@ extern "C" { // seek to the end of the line when no valid object is found while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_object_return_on_overflow((*buffer), (*input), (*found), delimits, f_no_data_on_eos, f_no_data_on_stop) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_object; } #endif // _di_fl_fss_extended_object_read_ @@ -294,19 +367,22 @@ extern "C" { if (input->start >= buffer->used) return f_error_set_error(f_invalid_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; - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_fss_skip_past_whitespace(*buffer, input); fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[input->start] == f_fss_extended_close) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_content; } - f_status status = f_none; f_bool has_delimit = f_false; char quoted = f_eos; @@ -337,16 +413,23 @@ extern "C" { if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length last_slash = input->start; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } - else if (!isgraph(buffer->string[input->start])) { + else if ((status = fl_fss_is_graph(*buffer, *input)) == f_false) { found->array[found->used].stop = input->start - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; if (buffer->string[input->start] == f_eol) { @@ -358,12 +441,17 @@ extern "C" { continue_main_loop = f_true; break; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] != f_fss_delimit_slash) { break; } last_slash = input->start; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (continue_main_loop) { @@ -387,47 +475,68 @@ extern "C" { delimits.array[delimits.used] = last_slash; delimits.used++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { quoted = buffer->string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->array[found->used].start = input->start; } // identify where the content ends if (quoted == f_eos) { - while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = f_none; + while (buffer->string[input->start] == f_fss_delimit_placeholder || (status = fl_fss_is_graph(*buffer, *input)) == f_true) { + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) } // while - if (isspace(buffer->string[input->start])) { + if (f_error_is_error(status)) return status; + + if ((status = fl_fss_is_space(*buffer, *input)) == f_true) { found->array[found->used].stop = input->start - 1; found->used++; if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_content; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } + else if (f_error_is_error(status)) { + return status; + } } else { while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_slash) { f_string_length first_slash = input->start; f_string_length slash_count = 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (buffer->string[input->start] != f_fss_delimit_slash) { @@ -435,7 +544,9 @@ extern "C" { } slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -466,7 +577,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location + 1; @@ -474,28 +586,40 @@ extern "C" { fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) - if (isgraph(buffer->string[input->start])) { + if ((status = fl_fss_is_graph(*buffer, *input)) == f_true) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return f_error_is_warning(f_unterminated_group); } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->array[found->used].stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; return fl_fss_found_content; } found->array[found->used].stop = location - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; continue; } @@ -521,7 +645,8 @@ extern "C" { slash_count--; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while input->start = location; @@ -530,35 +655,48 @@ extern "C" { } else if (buffer->string[input->start] == quoted) { found->array[found->used].stop = input->start - 1; - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + while (input->start <= input->stop && input->start < buffer->used) { if (buffer->string[input->start] == f_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; return fl_fss_found_content; } - else if (isspace(buffer->string[input->start])) { - input->start++; + else if ((status = fl_fss_is_space(*buffer, *input)) == f_true) { + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; continue_main_loop = f_true; break; } + else if (f_error_is_error(status)) { + return status; + } else if (buffer->string[input->start] != f_fss_delimit_placeholder) { while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return f_error_is_warning(f_unterminated_group); } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (continue_main_loop) { @@ -570,21 +708,27 @@ extern "C" { else if (buffer->string[input->start] == f_eol) { if (found->used == already_used) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_content; } else { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->array[found->used].stop = input->start - 1; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + found->used++; return fl_fss_found_content; } } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), delimits, f_error_is_warning(f_unterminated_group_on_eos), f_error_is_warning(f_unterminated_group_on_stop)) @@ -602,19 +746,24 @@ extern "C" { // seek to the end of the line when no valid content is found while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*input), (*found), delimits, f_none_on_eos, f_none_on_stop) if (found->used == already_used) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_no_content; } fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + return fl_fss_found_content; } #endif // _di_fl_fss_extended_content_read_ @@ -644,7 +793,7 @@ extern "C" { start_position = input->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 + (input->stop - input->start) + 3 + f_fss_default_allocation_step; + pre_allocate_size = buffer->used + (input->stop - input->start) + 3 + f_fss_default_allocation_step_string; if (pre_allocate_size > buffer->size) { f_resize_dynamic_string(status, (*buffer), pre_allocate_size); @@ -658,7 +807,9 @@ extern "C" { if (object.string[input->start] == f_fss_delimit_slash) { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] != f_fss_delimit_slash) { break; @@ -666,14 +817,16 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -681,14 +834,16 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = object.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (object.string[input->start] == f_fss_delimit_single_quote || object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -696,7 +851,9 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = object.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } else if (object.string[input->start] == f_fss_comment) { quoted = f_true; @@ -704,7 +861,9 @@ extern "C" { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] == f_eol) { @@ -718,14 +877,16 @@ extern "C" { return f_none_on_eol; } - else if (isspace(object.string[input->start]) || quoted) { + else if ((status = fl_fss_is_space(*buffer, *input)) == f_true || quoted) { f_string_length first_space = input->start; if (!quoted) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < object.used && isspace(object.string[input->start])) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (input->start > input->stop || input->start >= object.used) { @@ -738,7 +899,7 @@ extern "C" { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -752,14 +913,16 @@ extern "C" { while (input->start <= input->stop && input->start < object.used) { if (object.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } else if (object.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -774,7 +937,10 @@ extern "C" { buffer->string[buffer_position.stop] = object.string[input->start]; buffer_position.stop++; slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + fl_macro_fss_skip_past_delimit_placeholders(object, (*input)); @@ -786,7 +952,7 @@ extern "C" { pre_allocate_size += slash_count; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -818,7 +984,10 @@ extern "C" { } buffer->string[buffer_position.stop] = object.string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + buffer_position.stop++; } // while @@ -827,9 +996,15 @@ extern "C" { buffer->used = buffer_position.stop + 2; break; } + else if (f_error_is_error(status)) { + return status; + } buffer->string[buffer_position.stop] = object.string[input->start]; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + buffer_position.stop++; } // while @@ -863,7 +1038,7 @@ extern "C" { f_string_length pre_allocate_size = 0; // 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; + pre_allocate_size = buffer->used + (content.used) + 1 + f_fss_default_allocation_step_string; buffer_position.start = buffer->used; buffer_position.stop = buffer->used; @@ -889,11 +1064,15 @@ extern "C" { if (content.string[input->start] == f_fss_delimit_slash) { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < content.used) { if (content.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } @@ -903,7 +1082,9 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (input->start > input->stop) { @@ -921,7 +1102,7 @@ extern "C" { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -929,14 +1110,16 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = content.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } } else if (content.string[input->start] == f_fss_delimit_single_quote || content.string[input->start] == f_fss_delimit_double_quote) { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -944,7 +1127,9 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer->string[buffer_position.stop + 1] = content.string[input->start]; buffer_position.stop += 2; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } while (input->start <= input->stop && input->start < content.used) { @@ -954,13 +1139,13 @@ extern "C" { return f_none_on_eol; } - if (content.string[input->start] != f_fss_delimit_placeholder && !isgraph(content.string[input->start])) { + if (content.string[input->start] != f_fss_delimit_placeholder && (status = fl_fss_is_graph(*buffer, *input)) == f_false) { quoted = f_fss_delimit_double_quote; pre_allocate_size += 2; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -971,10 +1156,15 @@ extern "C" { buffer_position.stop++; break; } + else if (f_error_is_error(status)) { + return status; + } buffer->string[buffer_position.stop] = content.string[input->start]; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (quoted != f_eos) { @@ -984,11 +1174,15 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; while (input->start <= input->stop && input->start < content.used) { if (content.string[input->start] == f_fss_delimit_placeholder) { - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; + continue; } @@ -999,14 +1193,16 @@ extern "C" { buffer->string[buffer_position.stop] = f_fss_delimit_slash; buffer_position.stop++; slash_count++; - input->start++; + + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while if (content.string[input->start] == quoted || input->start > input->stop || input->start >= content.used) { pre_allocate_size += slash_count + 1; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -1034,7 +1230,7 @@ extern "C" { pre_allocate_size++; if (pre_allocate_size > buffer->size) { - f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), pre_allocate_size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } @@ -1054,7 +1250,8 @@ extern "C" { buffer_position.stop++; } - input->start++; + status = fl_fss_increment_buffer(*buffer, input, 1); + if (f_error_is_error(status)) return status; } // while buffer->string[buffer_position.stop] = quoted; diff --git a/level_1/fl_fss/c/fss_extended.h b/level_1/fl_fss/c/fss_extended.h index 5216d60..6594d11 100644 --- a/level_1/fl_fss/c/fss_extended.h +++ b/level_1/fl_fss/c/fss_extended.h @@ -20,6 +20,7 @@ #include #include #include +#include // fll-1 includes #include diff --git a/level_1/fl_fss/c/fss_macro.h b/level_1/fl_fss/c/fss_macro.h index 29a1790..148742d 100644 --- a/level_1/fl_fss/c/fss_macro.h +++ b/level_1/fl_fss/c/fss_macro.h @@ -14,6 +14,7 @@ extern "C" { #endif +// TODO: check if character to be replaced is UTF and apply placeholder to entire width. #ifndef _di_fl_macro_fss_apply_delimit_placeholders_ #define fl_macro_fss_apply_delimit_placeholders(buffer, delimits) \ { \ @@ -30,28 +31,6 @@ extern "C" { } #endif // _di_fl_macro_fss_apply_delimit_placeholders_ -#ifndef _di_fl_macro_fss_skip_past_whitespace_ - #define fl_macro_fss_skip_past_whitespace(buffer, input) \ - while (!isgraph(buffer.string[input.start]) || buffer.string[input.start] == f_fss_delimit_placeholder) { \ - if (buffer.string[input.start] == f_eol) break; \ - \ - ++input.start;\ - \ - if (input.start >= buffer.used) break; \ - if (input.start > input.stop) break; \ - } // while -#endif // _di_fl_macro_fss_skip_past_whitespace_ - -#ifndef _di_fl_macro_fss_skip_past_all_whitespace_ - #define fl_macro_fss_skip_past_all_whitespace(buffer, input) \ - while (!isgraph(buffer.string[input.start]) || buffer.string[input.start] == f_fss_delimit_placeholder) { \ - ++input.start;\ - \ - if (input.start >= buffer.used) break; \ - if (input.start > input.stop) break; \ - } // while -#endif // _di_fl_macro_fss_skip_past_all_whitespace_ - #ifndef _di_fl_macro_fss_skip_past_delimit_placeholders_ #define fl_macro_fss_skip_past_delimit_placeholders(buffer, input) \ while (buffer.string[input.start] == f_fss_delimit_placeholder) { \ diff --git a/level_1/fl_fss/data/build/dependencies b/level_1/fl_fss/data/build/dependencies index 33cb18b..5dd4d0c 100644 --- a/level_1/fl_fss/data/build/dependencies +++ b/level_1/fl_fss/data/build/dependencies @@ -5,3 +5,4 @@ f_memory f_file f_conversion f_fss +f_utf diff --git a/level_1/fl_fss/data/build/settings b/level_1/fl_fss/data/build/settings index deade3e..d4b1e3c 100644 --- a/level_1/fl_fss/data/build/settings +++ b/level_1/fl_fss/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lf_conversion -lf_file -lf_memory +build_libraries_fll -lf_conversion -lf_file -lf_memory -lf_utf build_sources_library fss.c fss_basic.c fss_basic_list.c fss_extended.c build_sources_program build_sources_headers fss.h fss_basic.h fss_basic_list.h fss_errors.h fss_extended.h fss_macro.h diff --git a/level_1/fl_strings/c/strings.c b/level_1/fl_strings/c/strings.c index 0e4cd2c..a7d8387 100644 --- a/level_1/fl_strings/c/strings.c +++ b/level_1/fl_strings/c/strings.c @@ -4,6 +4,8 @@ extern "C" { #endif +// TODO: this file needs to be rewriten with UTF-8 support. + #ifndef _di_fl_rip_string_ f_return_status fl_rip_string(const f_dynamic_string buffer, const f_string_location position, f_dynamic_string *results) { #ifndef _di_level_1_parameter_checking_ diff --git a/level_1/fl_strings/c/strings.h b/level_1/fl_strings/c/strings.h index 831d2ef..a8027da 100644 --- a/level_1/fl_strings/c/strings.h +++ b/level_1/fl_strings/c/strings.h @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/level_1/fl_strings/data/build/dependencies b/level_1/fl_strings/data/build/dependencies index a2496a1..7d0693b 100644 --- a/level_1/fl_strings/data/build/dependencies +++ b/level_1/fl_strings/data/build/dependencies @@ -1,4 +1,5 @@ -f_types f_errors -f_strings +f_types f_memory +f_strings +f_utf diff --git a/level_1/fl_strings/data/build/settings b/level_1/fl_strings/data/build/settings index 28ad104..5bdbe19 100644 --- a/level_1/fl_strings/data/build/settings +++ b/level_1/fl_strings/data/build/settings @@ -10,9 +10,9 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lf_memory +build_libraries_fll -lf_memory -lf_utf build_sources_library strings.c -build_sources_program +build_sources_program build_sources_headers strings.h build_sources_bash build_sources_settings diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index d9012f8..095d311 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -165,7 +165,7 @@ extern "C" { } else { if (buffer->used >= buffer->size) { - f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } diff --git a/level_2/fll_fss/c/fss_basic.h b/level_2/fll_fss/c/fss_basic.h index 0d892c5..7ad05f7 100644 --- a/level_2/fll_fss/c/fss_basic.h +++ b/level_2/fll_fss/c/fss_basic.h @@ -16,6 +16,7 @@ #include #include #include +#include // fll-1 includes #include diff --git a/level_2/fll_fss/c/fss_basic_list.c b/level_2/fll_fss/c/fss_basic_list.c index 42df25c..bda34b5 100644 --- a/level_2/fll_fss/c/fss_basic_list.c +++ b/level_2/fll_fss/c/fss_basic_list.c @@ -165,7 +165,7 @@ extern "C" { } else { if (buffer->used >= buffer->size) { - f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step); + f_resize_dynamic_string(status, (*buffer), buffer->size + f_fss_default_allocation_step_string); if (f_error_is_error(status)) return status; } diff --git a/level_2/fll_fss/data/build/settings b/level_2/fll_fss/data/build/settings index 28488eb..fcd0561 100644 --- a/level_2/fll_fss/data/build/settings +++ b/level_2/fll_fss/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfl_errors -lfl_fss -lf_conversion -lf_file -lf_memory +build_libraries_fll -lfl_errors -lfl_fss -lf_conversion -lf_file -lf_memory -lf_utf build_sources_library fss_basic.c fss_basic_list.c fss_extended.c fss_errors.c build_sources_program build_sources_headers fss_basic.h fss_basic_list.h fss_extended.h fss_errors.h diff --git a/level_3/firewall/data/build/settings b/level_3/firewall/data/build/settings index 2acfc5d..28b5513 100644 --- a/level_3/firewall/data/build/settings +++ b/level_3/firewall/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_fss -lfl_program -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_fss -lfl_program -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library firewall.c private-firewall.c diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.c b/level_3/fss_basic_list_read/c/fss_basic_list_read.c index 141d9d1..141694f 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.c @@ -329,31 +329,37 @@ extern "C" { input.stop = data->buffer.used - 1; status = fll_fss_basic_list_read(&data->buffer, &input, &data->objects, &data->contents); - } - if (f_error_is_error(status)) { - status = f_error_set_fine(status); + if (f_error_is_error(status)) { + status = f_error_set_fine(status); - if (status == f_invalid_parameter) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); - } - else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); - } - else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename); - } + if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); + } + else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + } + else if (status == f_incomplete_utf_on_stop) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start); + } + else if (status == f_incomplete_utf_on_eos) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start); + } + else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename); + } - fss_basic_list_read_delete_data(data); - return f_error_set_error(status); - } - else if (f_macro_test_for_no_data_errors(status)) { - // clear buffers, then attempt the next file - f_delete_fss_contents(status2, data->contents); - f_delete_fss_objects(status2, data->objects); - f_delete_dynamic_string(status2, data->buffer); + fss_basic_list_read_delete_data(data); + return f_error_set_error(status); + } + else if (f_macro_test_for_no_data_errors(status)) { + // clear buffers, then attempt the next file + f_delete_fss_contents(status2, data->contents); + f_delete_fss_objects(status2, data->objects); + f_delete_dynamic_string(status2, data->buffer); - return f_error_set_warning(status); + return f_error_set_warning(status); + } } // now that all of the files have been read, process the objects and contents diff --git a/level_3/fss_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings index eeb45c9..e3d412d 100644 --- a/level_3/fss_basic_list_read/data/build/settings +++ b/level_3/fss_basic_list_read/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_basic_list_read.c diff --git a/level_3/fss_basic_list_write/data/build/settings b/level_3/fss_basic_list_write/data/build/settings index 91b61e3..8c1e854 100644 --- a/level_3/fss_basic_list_write/data/build/settings +++ b/level_3/fss_basic_list_write/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_basic_list_write.c diff --git a/level_3/fss_basic_read/c/fss_basic_read.c b/level_3/fss_basic_read/c/fss_basic_read.c index 5f88489..ce1770f 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -323,31 +323,37 @@ extern "C" { input.stop = data->buffer.used - 1; status = fll_fss_basic_read(&data->buffer, &input, &data->objects, &data->contents); - } - if (f_error_is_error(status)) { - status = f_error_set_fine(status); + if (f_error_is_error(status)) { + status = f_error_set_fine(status); - if (status == f_invalid_parameter) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); - } - else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); - } - else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename); - } + if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_basic_list_read() for the file '%s'", filename); + } + else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + } + else if (status == f_incomplete_utf_on_stop) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start); + } + else if (status == f_incomplete_utf_on_eos) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start); + } + else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_basic_list_read() for the file '%s'", f_error_set_error(status), filename); + } - fss_basic_read_delete_data(data); - return f_error_set_error(status); - } - else if (f_macro_test_for_no_data_errors(status)) { - // clear buffers, then attempt the next file - f_delete_fss_contents(status2, data->contents); - f_delete_fss_objects(status2, data->objects); - f_delete_dynamic_string(status2, data->buffer); + fss_basic_read_delete_data(data); + return f_error_set_error(status); + } + else if (f_macro_test_for_no_data_errors(status)) { + // clear buffers, then attempt the next file + f_delete_fss_contents(status2, data->contents); + f_delete_fss_objects(status2, data->objects); + f_delete_dynamic_string(status2, data->buffer); - return f_error_set_warning(status); + return f_error_set_warning(status); + } } // now that the file has been read, process the objects and contents diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings index af30786..ba964b6 100644 --- a/level_3/fss_basic_read/data/build/settings +++ b/level_3/fss_basic_read/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_print -lf_file -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_print -lf_file -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_basic_read.c diff --git a/level_3/fss_basic_write/data/build/settings b/level_3/fss_basic_write/data/build/settings index 19f44bb..accc86f 100644 --- a/level_3/fss_basic_write/data/build/settings +++ b/level_3/fss_basic_write/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_basic_write.c diff --git a/level_3/fss_extended_read/c/fss_extended_read.c b/level_3/fss_extended_read/c/fss_extended_read.c index c03314c..0043fe9 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -336,31 +336,37 @@ extern "C" { input.stop = data->buffer.used - 1; status = fll_fss_extended_read(&data->buffer, &input, &data->objects, &data->contents); - } - if (f_error_is_error(status)) { - status = f_error_set_fine(status); + if (f_error_is_error(status)) { + status = f_error_set_fine(status); - if (status == f_invalid_parameter) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", filename); - } - else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); - } - else { - fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", f_error_set_error(status), filename); - } + if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_fss_extended_read() for the file '%s'", filename); + } + else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "CRITICAL ERROR: unable to allocate memory"); + } + else if (status == f_incomplete_utf_on_stop) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at stop position (at %d).", input.start); + } + else if (status == f_incomplete_utf_on_eos) { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "ENCODING ERROR: error occured on invalid UTF-8 character at end of string (at %d).", input.start); + } + else { + fl_print_color_line(f_standard_error, data->context.error, data->context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_fss_extended_read() for the file '%s'", f_error_set_error(status), filename); + } - fss_extended_read_delete_data(data); - return f_error_set_error(status); - } - else if (f_macro_test_for_no_data_errors(status)) { - // clear buffers, then attempt the next file - f_delete_fss_contents(status2, data->contents); - f_delete_fss_objects(status2, data->objects); - f_delete_dynamic_string(status2, data->buffer); + fss_extended_read_delete_data(data); + return f_error_set_error(status); + } + else if (f_macro_test_for_no_data_errors(status)) { + // clear buffers, then attempt the next file + f_delete_fss_contents(status2, data->contents); + f_delete_fss_objects(status2, data->objects); + f_delete_dynamic_string(status2, data->buffer); - return f_error_set_warning(status); + return f_error_set_warning(status); + } } // now that all of the files have been read, process the objects and contents diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings index a9624dc..5491abd 100644 --- a/level_3/fss_extended_read/data/build/settings +++ b/level_3/fss_extended_read/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_extended_read.c 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 08013ea..a7282e9 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -203,7 +203,7 @@ extern "C" { if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) { if (buffer.used >= buffer.size) { - f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step); + f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step_string); if (f_error_is_error(status)) { return status; @@ -254,7 +254,7 @@ extern "C" { if (data->parameters[fss_extended_write_parameter_partial].result == f_console_result_none) { if (buffer.used >= buffer.size) { - f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step); + f_resize_dynamic_string(status, buffer, buffer.used + f_fss_default_allocation_step_string); if (f_error_is_error(status)) { return status; diff --git a/level_3/fss_extended_write/data/build/settings b/level_3/fss_extended_write/data/build/settings index 68978a0..1797d04 100644 --- a/level_3/fss_extended_write/data/build/settings +++ b/level_3/fss_extended_write/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_file -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_file -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_extended_write.c diff --git a/level_3/fss_return_code/data/build/settings b/level_3/fss_return_code/data/build/settings index aad1f03..c342031 100644 --- a/level_3/fss_return_code/data/build/settings +++ b/level_3/fss_return_code/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfl_fss -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library fss_return_code.c diff --git a/level_3/init/c/init.h b/level_3/init/c/init.h index 7567fa2..cee48ab 100644 --- a/level_3/init/c/init.h +++ b/level_3/init/c/init.h @@ -212,15 +212,15 @@ extern "C" { #endif // _di_init_argument_ #ifndef _di_init_print_version_ - f_extern f_return_status init_print_version(const init_argument data); + extern f_return_status init_print_version(const init_argument data); #endif // _di_init_print_version_ #ifndef _di_init_print_help_ - f_extern f_return_status init_print_help(const init_argument data); + extern f_return_status init_print_help(const init_argument data); #endif // _di_init_print_help_ #ifndef _di_init_main_ - f_extern f_return_status init_main(const f_s_int argc, const f_string argv[], init_argument *data); + extern f_return_status init_main(const f_s_int argc, const f_string argv[], init_argument *data); #endif // _di_init_main_ #ifdef __cplusplus diff --git a/level_3/init/data/build/settings b/level_3/init/data/build/settings index 034e2f8..254ae05 100644 --- a/level_3/init/data/build/settings +++ b/level_3/init/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfll_fss -lfll_execute -lfl_directory -lfl_colors -lfl_strings -lfl_file -lfl_console -lfl_program -lfl_fss -lf_pipe -lf_file -lf_print -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library init.c private-init.c diff --git a/level_3/return_code/data/build/settings b/level_3/return_code/data/build/settings index 79346fb..2e6284f 100644 --- a/level_3/return_code/data/build/settings +++ b/level_3/return_code/data/build/settings @@ -10,7 +10,7 @@ version_micro 0 build_compiler gcc build_linker ar build_libraries -lc -build_libraries_fll -lfll_colors -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory +build_libraries_fll -lfll_colors -lfl_errors -lfl_colors -lfl_console -lfl_program -lf_print -lf_pipe -lf_conversion -lf_console -lf_memory -lf_utf #build_libraries_fll-level -lfll_2 -lfll_1 -lfll_0 #build_libraries_fll-monolithic -lfll build_sources_library return_code.c