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_