From d1f75b687d57cbf32ea92242c3e2b0b29bde84a2 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 24 Mar 2012 16:46:56 -0500 Subject: [PATCH] Update: rewrite fss extended content read function This was rewritten to follow the same style that the object read uses. Because content can have multiple "groups", an outer loop had to be added. For some reason I feel like I am forgetting something or doing something wrong here, but I cannot tell what that is and so I note my concern here. --- level_1/fl_fss/c/fss_extended.c | 316 +++++++++++++++++++++++++--------------- 1 file changed, 202 insertions(+), 114 deletions(-) diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index 972f8e0..ace09b2 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -232,167 +232,255 @@ extern "C"{ if (input->stop < input->start) return f_invalid_parameter; if (buffer->used <= 0) return f_invalid_parameter; if (input->start >= buffer->used) return f_invalid_parameter; - if (found->used > found->size) return f_invalid_parameter; #endif // _di_level_1_parameter_checking_ - f_autochar quoted = f_eos; - f_string_length original = found->used; + fl_macro_fss_skip_past_whitespace((*buffer), (*input)) + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_error_on_eos, f_error_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++; + return fl_fss_found_no_content; + } - fl_macro_fss_allocate_content_if_necessary((*found)) - found->array[found->used].start = input->start; + f_status status = f_status_initialize; + f_bool has_delimit = f_false; + f_autochar quoted = f_eos; - while (input->start <= input->stop) { - // get past all leading spaces/tabs (allowed) - fl_macro_fss_skip_past_whitespace((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + f_bool continue_main_loop = f_false; - if (buffer->string[input->start] == f_eol) { - break; + f_string_length location = f_string_length_initialize; + f_array_length already_used = found->used; + + while (input->start <= input->stop && input->start < buffer->used) { + quoted = f_eos; + + if (found->used >= found->size) { + f_resize_fss_content(status, (*found), found->size + f_fss_default_allocation_step); + + if (f_macro_test_for_allocation_errors(status)) return status; } - fl_macro_fss_allocate_content_if_necessary((*found)) + // begin the search found->array[found->used].start = input->start; + found->array[found->used].stop = 0; - // this inner loop should read until whitespace is found then mark the end of a specific content field - do { - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + // identify where the content begins + if (buffer->string[input->start] == f_fss_delimit_slash) { + f_string_length last_slash = input->start; - // handle delimited quotes, single quotes, and double quotes - if (buffer->string[input->start] == f_fss_delimit_slash) { - do { - f_string_length first_slash = input->start; - ++input->start; + input->start++; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + while (input->start <= input->stop && input->start < buffer->used) { + if (buffer->string[input->start] == f_fss_delimit_placeholder) { + input->start++; + continue; + } else if (!isgraph(buffer->string[input->start])) { + found->array[found->used].stop = input->start - 1; + input->start++; + found->used++; - // A slash only delimits if a delimit quote would follow the slash (or a slash and a delimit quote follows) - if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { - // because the slash properly delimited the quote, the quote then becomes the start of the content - found->array[found->used].start = input->start; - buffer->string[first_slash] = f_fss_delimit_placeholder; - break; - } else if (buffer->string[input->start] == f_fss_delimit_slash) { - f_string_length second_slash = input->start; - ++input->start; + if (buffer->string[input->start] == f_eol) { + return fl_fss_found_content; + } - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + continue_main_loop = f_true; + break; + } else if (buffer->string[input->start] != f_fss_delimit_slash) { + break; + } - if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { - buffer->string[first_slash] = f_fss_delimit_placeholder; + last_slash = input->start; + input->start++; + } // while - quoted = buffer->string[input->start]; - input->start++; + if (continue_main_loop) { + continue_main_loop = f_false; + continue; + } - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop) + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) - found->array[found->used].start = input->start; - break; - } else { - // return to the second slash, this way if there is a third or more, the quote test can be repeated - input->start = second_slash; - ++input->start; - } - } else { - break; - } - } while (f_true); - } 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]; + if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) { + buffer->string[last_slash] = f_fss_delimit_placeholder; + input->start++; + } + } 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++; + 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++; + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + } // while + + if (isspace(buffer->string[input->start])) { + found->array[found->used].stop = input->start - 1; + found->used++; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop) + if (buffer->string[input->start] == f_eol) { + input->start++; + return fl_fss_found_content; + } - found->array[found->used].start = input->start; + input->start++; + continue; } + } 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++; - // when quoted is null, then spaces will end the content, otherwise the quote defined in quoted will end the content (or a newline) - if (quoted == f_eos) { - do { - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + while (input->start <= input->stop && input->start < buffer->used) { + if (buffer->string[input->start] == f_fss_delimit_placeholder) { + input->start++; + continue; + } else if (buffer->string[input->start] != f_fss_delimit_slash) { + break; + } - if (buffer->string[input->start] == f_fss_extended_close) { - // Save the stop point - found->array[found->used].stop = input->start - 1; - found->used++; + slash_count++; input->start++; - return fl_fss_found_content; - } + } // while - if (isspace(buffer->string[input->start])) break; + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop) - ++input->start; - } while (f_true); - } else { - do { - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + if (buffer->string[input->start] == quoted) { + location = input->start; + input->start = first_slash; - if (buffer->string[input->start] == f_fss_extended_close) { - input->start++; - return f_unterminated_group; - } + if (slash_count % 2 == 0) { + while (slash_count > 0) { + if (buffer->string[input->start] == f_fss_delimit_slash) { + if (slash_count % 2 != 0) { + buffer->string[input->start] = f_fss_delimit_placeholder; + } - // handle delimited quotes - if (buffer->string[input->start] == f_fss_delimit_slash) { - f_string_length first_slash = input->start; - ++input->start; + slash_count--; + } - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) - fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + input->start++; + } // while - // A slash only delimits if a delimit quote would follow the slash (or a slash and a delimit quote follows) - if (buffer->string[input->start] == quoted) { - buffer->string[first_slash] = f_fss_delimit_placeholder; - ++input->start; - continue; - } else if (buffer->string[input->start] == f_fss_delimit_slash) { - f_string_length second_slash = input->start; - ++input->start; + input->start = location + 1; fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input)) fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop) - if (buffer->string[input->start] == quoted) { - buffer->string[first_slash] = f_fss_delimit_placeholder; - quoted = f_eos; - break; - } else { - // return to the second slash, this way if there is a third or more, the quote test can be repeated - input->start = second_slash; - ++input->start; - continue; + if (isgraph(buffer->string[input->start])) { + while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) { + input->start++; + } // while + + input->start++; + return f_unterminated_group; + } else if (buffer->string[input->start] == f_eol) { + found->array[found->used].stop = input->start - 1; + input->start++; + found->used++; + + return fl_fss_found_content; } + + found->array[found->used].stop = input->start - 1; + input->start++; + found->used++; + continue; + } else { + while (slash_count > 0) { + if (buffer->string[input->start] == f_fss_delimit_slash) { + if (slash_count % 2 != 0) { + buffer->string[input->start] = f_fss_delimit_placeholder; + } + + slash_count--; + } + + input->start++; + } // while + + input->start = location; + } + } + } else if (buffer->string[input->start] == quoted) { + found->array[found->used].stop = input->start - 1; + input->start++; + + while (input->start <= input->stop && input->start < buffer->used) { + if (buffer->string[input->start] == f_eol) { + input->start++; + found->used++; + + return fl_fss_found_content; + } else if (isspace(buffer->string[input->start])) { + input->start++; + found->used++; + continue_main_loop = f_true; + break; + } 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++; + } // while + + input->start++; + return f_unterminated_group; } - } else if (buffer->string[input->start] == quoted) { - quoted = f_eos; + + input->start++; + } // while + + if (continue_main_loop) { break; } - ++input->start; - } while (f_true); - } + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop) + } else if (buffer->string[input->start] == f_eol) { - // Save the stop point - found->array[found->used].stop = input->start - 1; - found->used++; - break; - } while (f_true); + if (found->used == already_used) { + input->start++; + return fl_fss_found_no_content; + } else { + found->array[found->used].stop = input->start - 1; + input->start++; + found->used++; + + return fl_fss_found_content; + } + } + + input->start++; + } // while + + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop) + } + + if (continue_main_loop) { + continue_main_loop = f_false; + continue; + } + + break; + } // while - ++input->start; + fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_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++; } - // When original is the same as the current found->used, then there was no data found - if (original == found->used) { + if (found->used == already_used) { input->start++; return fl_fss_found_no_content; } + input->start++; return fl_fss_found_content; } #endif // _di_fl_fss_extended_content_read_ -- 1.8.3.1