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).
#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).
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,
#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,
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_
#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_
#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++) {
#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;
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_
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_
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_
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_
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_
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"
#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).
#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_
* 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.
* 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.
* 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.
* 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"
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_
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;
}
}
}
- // 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;
#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);
{
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
}
#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
#include <level_0/fss.h>
#include <level_0/strings.h>
#include <level_0/types.h>
+#include <level_0/utf.h>
// fll-1 includes
#include <level_1/fss_errors.h>
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
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;
}
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;
}
// 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)
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) {
}
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))
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;
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)
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;
}
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 {
slash_count--;
}
- input->start++;
+ status = fl_fss_increment_buffer(*buffer, input, 1);
+ if (f_error_is_error(status)) return status;
} // while
input->start = location;
}
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)
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)
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))
// 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)
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_
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;
}
// 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_
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);
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) {
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;
}
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;
}
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;
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) {
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;
}
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;
}
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));
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;
}
}
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
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
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;
buffer_position.stop++;
}
- input->start++;
+ fl_fss_increment_buffer(*buffer, input, 1);
} // while
buffer->string[buffer_position.stop] = f_eol;
#include <level_0/strings.h>
#include <level_0/types.h>
#include <level_0/memory.h>
+#include <level_0/utf.h>
// fll-1 includes
#include <level_1/fss.h>
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;
}
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;
}
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)
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)
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);
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)
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;
}
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_
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;
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;
}
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) {
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) {
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;
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) {
continue;
}
- input->start++;
+ status = fl_fss_increment_buffer(*buffer, input, 1);
+ if (f_error_is_error(status)) return status;
} // while
if (found_newline) {
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);
// 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) {
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;
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
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;
}
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;
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);
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) {
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;
}
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;
}
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;
#include <level_0/memory.h>
#include <level_0/strings.h>
#include <level_0/types.h>
+#include <level_0/utf.h>
// fll-1 includes
#include <level_1/fss.h>
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;
}
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;
}
// 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)
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) {
}
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))
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;
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;
}
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 {
slash_count--;
}
- input->start++;
+ status = fl_fss_increment_buffer(*buffer, input, 1);
+ if (f_error_is_error(status)) return status;
} // while
input->start = location;
}
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))
// 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_
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;
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) {
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) {
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) {
}
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))
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;
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;
}
slash_count--;
}
- input->start++;
+ status = fl_fss_increment_buffer(*buffer, input, 1);
+ if (f_error_is_error(status)) return status;
} // while
input->start = location;
}
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) {
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))
// 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_
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);
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;
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;
}
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;
}
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;
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) {
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) {
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;
}
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;
}
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));
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;
}
}
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
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
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;
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;
}
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) {
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;
}
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;
}
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) {
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;
}
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) {
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;
}
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;
}
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;
}
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;
#include <level_0/memory.h>
#include <level_0/strings.h>
#include <level_0/types.h>
+#include <level_0/utf.h>
// fll-1 includes
#include <level_1/fss.h>
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) \
{ \
}
#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) { \
f_file
f_conversion
f_fss
+f_utf
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
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_
#include <level_0/memory.h>
#include <level_0/strings.h>
#include <level_0/types.h>
+#include <level_0/utf.h>
#ifdef __cplusplus
extern "C" {
-f_types
f_errors
-f_strings
+f_types
f_memory
+f_strings
+f_utf
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
}
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;
}
#include <level_0/memory.h>
#include <level_0/strings.h>
#include <level_0/types.h>
+#include <level_0/utf.h>
// fll-1 includes
#include <level_1/fss.h>
}
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;
}
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
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
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
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
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
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
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
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
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
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
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;
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;
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
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
#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
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
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