For lists, if the start of a line is a combining/joiner, then it must be treated as Content even if it would otherwise be a valid Object on that line.
The unit test actually has to handle when `F_okay_eos` or `F_okay_stop` is returned on content read.
The basic list doesn't know if the content is a valid object or not.
It can be assumed, but the function does not do this.
The caller must handle incrementing found.used when either `F_okay_eos` or `F_okay_stop` is returned.
Update the comment on this as well.
Properly verify that `newline_last` is in fact a new line by checking it against the `begin` position.
The basic list already has `begin`, but extended list has `begin` added to perform this check.
uint8_t flag_fl = ___fl_flag_has_graph_first___;
+ // The start position with a combining/joiner must be treated as Content and not as an Object.
+ if (f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) return;
+
// Identify where the content ends.
while (range->start <= range->stop && range->start < buffer.used) {
flag_fl &= ~___fl_flag_has_delimit_comment___;
++range->start;
+ // Any line that starts with a combining/joiner must be treated as Content and not as an Object.
+ f_fss_skip_past_delimit(buffer, range, state);
+
+ if (F_status_is_error_not(state->status) && f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) break;
+
continue;
}
if (F_status_is_error(state->status)) break;
if (range->start > range->stop || range->start >= buffer.used) break;
- // Found a valid object, set stop point to last newline.
+ // Found a valid object, set stop point to last newline (if newline_last is begin, there newline_last is not a new line).
if (state->status == F_okay_eol) {
- if (newline_last == found->array[found->used].start) {
+ if (begin != newline_last && newline_last == found->array[found->used].start) {
found->array[found->used].start = 1;
found->array[found->used++].stop = 0;
range->start = newline_last;
return;
}
- // The EOS and stop cases only happen here when content is not found, so do not increment found.used.
+ // The EOS and stop cases only happen here when the next object is not found, so do not increment found.used and let caller handle.
if (range->start >= buffer.used) {
found->array[found->used].stop = buffer.used - 1;
state->status = F_okay_eos;
cache->slashes->array[0] = 0;
cache->slashes->used = 1;
+ // The start position with a combining/joiner must be treated as Content and not as an Object.
+ if (f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) return;
+
while (range->start <= range->stop && range->start < buffer.used) {
if (state->interrupt) {
newline_last = previous = range->start++;
line_start = range->start;
flag_fl |= ___fl_flag_has_graph_first___;
+
+ // Any line that starts with a combining/joiner must be treated as Content and not as an Object.
+ f_fss_skip_past_delimit(buffer, range, state);
+
+ if (F_status_is_error_not(state->status) && f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) break;
}
else if (buffer.string[range->start] == f_fss_slash_s.string[0] && (flag_fl & ___fl_flag_has_graph_first___)) {
previous = range->start++;
#define ___fl_flag_has_slash___ 0x1
+ const f_number_unsigned_t begin = range->start;
const f_number_unsigned_t delimits_used = delimits->used;
const f_number_unsigned_t comments_used = comments->used;
- f_number_unsigned_t line_start = range->start;
- f_number_unsigned_t newline_last = range->start;
+ f_number_unsigned_t line_start = begin;
+ f_number_unsigned_t newline_last = begin;
f_number_unsigned_t previous = 0;
f_number_unsigned_t slash_first = 0;
f_number_unsigned_t comment_start = 0;
found->array[found->used].start = range->start;
+ // The start position with a combining/joiner must be treated as Content and not as an Object.
+ if (f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) return;
+
// Identify where the content ends.
while (range->start <= range->stop && range->start < buffer.used) {
newline_last = range->start++;
line_start = range->start;
+ // Any line that starts with a combining/joiner must be treated as Content and not as an Object.
+ f_fss_skip_past_delimit(buffer, range, state);
+
+ if (F_status_is_error_not(state->status) && f_fss_is_combining_joiner(buffer, *range, state) == F_true) {
+ f_fss_seek_to_eol(buffer, range, state);
+ }
+
+ if (F_status_is_error(state->status)) break;
+
continue;
}
++range->start;
- // If the last newline is the entire start, then there is no Content.
- if (newline_last == found->array[found->used].start) {
+ // If the last newline is the entire start, then there is no Content (if newline_last is begin, there newline_last is not a new line).
+ if (begin != newline_last && newline_last == found->array[found->used].start) {
found->array[found->used].start = 1;
found->array[found->used++].stop = 0;
assert_true(state.status == F_fss_found_content || state.status == F_okay_eos || state.status == F_okay_stop || state.status == F_data_not);
if (state.status == F_fss_found_content || state.status == F_okay_eos || state.status == F_okay_stop) {
+
+ // The caller must handle these cases (for basic list only) and the unit test is expecting this.
+ if (state.status == F_okay_eos || state.status == F_okay_stop) {
+ ++found_content.used;
+ }
+
if (!found_content.used) {
printf("[ -------> ] --- [12] Failure with fl_fss_basic_list_content_read(), with set %lu, expected found_content.used (%lu) <> 0.\n", set, found_content.used);
}