From 5839eb301d196415f6bfd33afd41bd44c6e33372 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 7 Sep 2021 22:15:35 -0500 Subject: [PATCH] Bugfix: Embedded List slash processing problems. The slash count must be recorded per-depth. Fix a mistake in the specification documentation. --- level_1/fl_fss/c/fss_embedded_list.c | 103 ++++++++++++++++++++++------------- level_1/fl_fss/c/private-fss_macro.h | 8 ++- specifications/fss-0003.txt | 2 +- 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/level_1/fl_fss/c/fss_embedded_list.c b/level_1/fl_fss/c/fss_embedded_list.c index 35df6c3..737b8ec 100644 --- a/level_1/fl_fss/c/fss_embedded_list.c +++ b/level_1/fl_fss/c/fss_embedded_list.c @@ -317,13 +317,11 @@ extern "C" { f_array_lengths_t positions_start = f_array_lengths_t_initialize; - macro_f_array_lengths_t_clear(positions_start) macro_f_array_lengths_t_resize(status, positions_start, state.step_small) if (F_status_is_error(status)) return status; f_fss_objects_t objects = f_fss_objects_t_initialize; - macro_f_fss_objects_t_clear(objects) macro_f_fss_objects_t_resize(status, objects, state.step_small) if (F_status_is_error(status)) { @@ -332,6 +330,17 @@ extern "C" { return status; } + f_array_lengths_t slashes = f_array_lengths_t_initialize; + + macro_f_array_lengths_t_resize(status, slashes, state.step_small) + + if (F_status_is_error(status)) { + macro_f_array_lengths_t_delete_simple(positions_start); + macro_f_fss_objects_t_delete_simple(objects); + + return status; + } + const f_array_length_t delimits_used = delimits->used; const f_array_length_t comments_used = comments->used; @@ -345,7 +354,6 @@ extern "C" { f_array_length_t slash_first = 0; f_array_length_t slash_last = 0; - f_array_length_t slash_count = 0; f_array_length_t before_list_open = position_previous; @@ -358,6 +366,9 @@ extern "C" { positions_start.array[0] = range->start; positions_start.used = 1; + slashes.array[0] = 0; + slashes.used = 1; + while (range->start <= range->stop && range->start < buffer.used) { if (state.interrupt) { @@ -381,11 +392,11 @@ extern "C" { position_previous = range->start++; graph_first = 0x1; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow_delimited((buffer), (*range), (*found), positions_start, objects, F_none_eos, F_none_stop); + private_macro_fl_fss_nest_return_on_overflow_delimited((buffer), (*range), (*found), positions_start, objects, slashes, F_none_eos, F_none_stop); } line_start = range->start; @@ -395,12 +406,9 @@ extern "C" { if (buffer.string[range->start] == f_fss_delimit_slash) { slash_first = range->start; slash_last = range->start; - slash_count = 1; - - position_previous = range->start; + slashes.array[depth] = 1; - status = f_utf_buffer_increment(buffer, range, 1); - if (F_status_is_error(status)) break; + position_previous = range->start++; while (range->start <= range->stop && range->start < buffer.used && (buffer.string[range->start] == f_fss_delimit_placeholder || buffer.string[range->start] == f_fss_delimit_slash)) { @@ -417,19 +425,21 @@ extern "C" { if (buffer.string[range->start] == f_fss_delimit_slash) { slash_last = range->start++; + ++slashes.array[depth]; + } + else { + status = f_utf_buffer_increment(buffer, range, 1); + if (F_status_is_error(status)) break; } - - status = f_utf_buffer_increment(buffer, range, 1); - if (F_status_is_error(status)) break; } // while if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop); + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop); } // All slashes for an open are delimited (because it could represent a slash in the object name). @@ -501,11 +511,11 @@ extern "C" { if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop); + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop); } // this is a valid object open/close that has been delimited, save the slash delimit positions. @@ -517,24 +527,22 @@ extern "C" { if (is_open) { bool is_object = F_false; - if (slash_count % 2 == 0) { + if (slashes.array[depth] % 2 == 0) { is_object = F_true; } range->start = slash_first; - macro_f_fss_delimits_t_increase_by(status, (*delimits), (slash_count / 2) + 1); + macro_f_fss_delimits_t_increase_by(status, (*delimits), (slashes.array[depth] / 2) + 1); if (F_status_is_error(status)) break; // apply slash delimits, only slashes and placeholders should be present. - while (slash_count > 0) { + while (slashes.array[depth]) { if (buffer.string[range->start] == f_fss_delimit_slash) { - if (slash_count % 2 == 1) { + if (slashes.array[depth]-- % 2 == 1) { delimits->array[delimits->used++] = range->start; } - - --slash_count; } // Delimit slashes and placeholders are required to be in the ASCII range. @@ -550,16 +558,25 @@ extern "C" { if (depth > positions_start.size) { macro_f_array_lengths_t_resize(status, positions_start, positions_start.size + state.step_small); if (F_status_is_error(status)) break; + + macro_f_fss_objects_t_resize(status, objects, objects.size + state.step_small); + if (F_status_is_error(status)) break; + + macro_f_array_lengths_t_resize(status, slashes, slashes.size + state.step_small); + if (F_status_is_error(status)) break; } if (positions_start.used < depth) { positions_start.used = depth; + slashes.used = depth; } positions_start.array[depth] = newline_last + 1; objects.array[depth].start = line_start; objects.array[depth].stop = before_list_open; + + slashes.array[depth] = 0; } } else { @@ -616,11 +633,11 @@ extern "C" { if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop); + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop); } if (buffer.string[range->start] == f_fss_eol) { @@ -632,10 +649,14 @@ extern "C" { macro_f_fss_objects_t_resize(status, objects, objects.size + state.step_small); if (F_status_is_error(status)) break; + + macro_f_array_lengths_t_resize(status, slashes, slashes.size + state.step_small); + if (F_status_is_error(status)) break; } if (positions_start.used <= depth) { positions_start.used = depth + 1; + slashes.used = depth + 1; } positions_start.array[depth] = range->start + 1; @@ -643,6 +664,8 @@ extern "C" { objects.array[depth].start = line_start; objects.array[depth].stop = before_list_open; + slashes.array[depth] = 0; + if (graph_first == 0x2) { macro_f_fss_delimits_t_increase(status, state.step_small, (*delimits)); if (F_status_is_error(status)) break; @@ -696,11 +719,11 @@ extern "C" { if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop); + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop); } } } @@ -739,11 +762,11 @@ extern "C" { if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop); + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop); } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop); + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop); } if (buffer.string[range->start] == f_fss_eol) { @@ -797,10 +820,11 @@ extern "C" { status = f_utf_buffer_increment(buffer, range, 1); if (F_status_is_error(status)) break; - private_macro_fl_fss_nest_return_on_overflow_delimited((buffer), (*range), (*found), positions_start, objects, F_none_eos, F_none_stop) + private_macro_fl_fss_nest_return_on_overflow_delimited((buffer), (*range), (*found), positions_start, objects, slashes, F_none_eos, F_none_stop) macro_f_array_lengths_t_delete_simple(positions_start); macro_f_fss_objects_t_delete_simple(objects); + macro_f_array_lengths_t_delete_simple(slashes); return FL_fss_found_content; } @@ -843,11 +867,11 @@ extern "C" { if (F_status_is_error(status)) break; - if (depth > 0) { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_terminated_not_nest_eos, F_terminated_not_nest_stop) + if (depth) { + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_terminated_not_nest_eos, F_terminated_not_nest_stop) } else { - private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, F_data_not_eos, F_data_not_stop) + private_macro_fl_fss_nest_return_on_overflow((buffer), (*range), (*found), (*delimits), delimits_used, (*comments), comments_used, positions_start, objects, slashes, F_data_not_eos, F_data_not_stop) } } } @@ -909,6 +933,7 @@ extern "C" { macro_f_array_lengths_t_delete_simple(positions_start); macro_f_fss_objects_t_delete_simple(objects); + macro_f_array_lengths_t_delete_simple(slashes); delimits->used = delimits_used; comments->used = comments_used; diff --git a/level_1/fl_fss/c/private-fss_macro.h b/level_1/fl_fss/c/private-fss_macro.h index 574b667..66d6469 100644 --- a/level_1/fl_fss/c/private-fss_macro.h +++ b/level_1/fl_fss/c/private-fss_macro.h @@ -83,12 +83,13 @@ extern "C" { #endif // _di_macro_fl_fss_content_return_on_overflow_delimited_ #ifndef _di_macro_fl_fss_nest_return_on_overflow_ - #define private_macro_fl_fss_nest_return_on_overflow(buffer, range, found, delimits, delimits_used, comments, comments_used, positions, objects, eos_status, stop_status) \ + #define private_macro_fl_fss_nest_return_on_overflow(buffer, range, found, delimits, delimits_used, comments, comments_used, positions, objects, slashes, eos_status, stop_status) \ if (range.start >= buffer.used) { \ delimits.used = delimits_used; \ comments.used = comments_used; \ macro_f_array_lengths_t_delete_simple(positions); \ macro_f_fss_objects_t_delete_simple(objects); \ + macro_f_array_lengths_t_delete_simple(slashes); \ return eos_status; \ } \ else if (range.start > range.stop) { \ @@ -96,20 +97,23 @@ extern "C" { comments.used = comments_used; \ macro_f_array_lengths_t_delete_simple(positions); \ macro_f_fss_objects_t_delete_simple(objects); \ + macro_f_array_lengths_t_delete_simple(slashes); \ return stop_status; \ } #endif // _di_macro_fl_fss_nest_return_on_overflow_ #ifndef _di_macro_fl_fss_nest_return_on_overflow_delimited_ - #define private_macro_fl_fss_nest_return_on_overflow_delimited(buffer, range, found, positions, objects, eos_status, stop_status) \ + #define private_macro_fl_fss_nest_return_on_overflow_delimited(buffer, range, found, positions, objects, slashes, eos_status, stop_status) \ if (range.start >= buffer.used) { \ macro_f_array_lengths_t_delete_simple(positions); \ macro_f_fss_objects_t_delete_simple(objects); \ + macro_f_array_lengths_t_delete_simple(slashes); \ return eos_status; \ } \ else if (range.start > range.stop) { \ macro_f_array_lengths_t_delete_simple(positions); \ macro_f_fss_objects_t_delete_simple(objects); \ + macro_f_array_lengths_t_delete_simple(slashes); \ return stop_status; \ } #endif // _di_macro_fl_fss_nest_return_on_overflow_delimited_ diff --git a/specifications/fss-0003.txt b/specifications/fss-0003.txt index 47d6c6e..2a20ee0 100644 --- a/specifications/fss-0003.txt +++ b/specifications/fss-0003.txt @@ -16,7 +16,7 @@ Featureless Settings Specification: 0003 - Extended List: When not inside any potentially valid Content (that is, there is no previous unclosed Object), then the Object may be delimited. Likelwise, the close-brace may only be delimited if it is within any potentially valid Content. - Each delimit slash in a delimitable open-brace is treated as a potential delimit such that two slashes represents a single delimited slash ('\\\{' would represent '\{'). + Each delimit slash in a delimitable open-brace is treated as a potential delimit such that two slashes represents a single delimited slash ('\\{' would represent '\{'). Only the first delimit slash in a delimitable close-brace is treated as a potential delimit ('\\\}' would represent '\\}'). Empty Objects are allowed, that is, the length of the object may be 0. -- 1.8.3.1