From: Kevin Day Date: Tue, 25 Feb 2020 03:28:38 +0000 (-0600) Subject: Progress: continue development of FSS Extended List X-Git-Tag: 0.5.0~360 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=ba1a9a2621cd473a7c887473182c16cec5256a52;p=fll Progress: continue development of FSS Extended List In particular: - Remove excessive fl_fss_increment_buffer() uses. - The removed code may be a good idea long term, but for now use a simpler and more efficient approach. - Fix some mistakes in the slash delimiter handling. - Begin the initial work for recursively (or so..) processing the nested lists. --- diff --git a/level_1/fl_fss/c/fss_basic.c b/level_1/fl_fss/c/fss_basic.c index 0e6b0cb..98f4879 100644 --- a/level_1/fl_fss/c/fss_basic.c +++ b/level_1/fl_fss/c/fss_basic.c @@ -139,9 +139,7 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); if (buffer->string[location->start] == f_string_eol) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_object_no_content; } @@ -201,7 +199,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -251,11 +249,7 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = length - 1; - - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - - + location->start++; return fl_fss_found_object_no_content; } @@ -280,7 +274,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -306,9 +300,7 @@ extern "C" { if (buffer->string[location->start] == f_string_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_object_no_content; } else if ((status = fl_fss_is_space(*buffer, *location)) == f_true) { @@ -349,9 +341,7 @@ extern "C" { else if (buffer->string[location->start] == f_string_eol) { f_macro_string_lengths_delete_simple(delimits); - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_no_object; } @@ -401,9 +391,7 @@ extern "C" { // return found nothing if this line only contains whitespace and delimit placeholders if (buffer->string[location->start] == f_string_eol) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_no_content; } @@ -706,7 +694,8 @@ extern "C" { buffer_position.stop++; } - fl_fss_increment_buffer(*buffer, location, 1); + status = fl_fss_increment_buffer(*buffer, location, 1); + if (f_status_is_error(status)) return status; } // while buffer->string[buffer_position.stop] = f_string_eol; diff --git a/level_1/fl_fss/c/fss_basic_list.c b/level_1/fl_fss/c/fss_basic_list.c index 825424f..bb3a1ec 100644 --- a/level_1/fl_fss/c/fss_basic_list.c +++ b/level_1/fl_fss/c/fss_basic_list.c @@ -26,9 +26,7 @@ extern "C" { // return found nothing if this line only contains whitespace and delimit placeholders. if (buffer->string[location->start] == f_string_eol) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_no_object; } @@ -101,7 +99,7 @@ extern "C" { if (slash_count % 2 == 0) { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -194,7 +192,7 @@ extern "C" { f_status status = f_none; - // delimits must only be applied once a valid object is found + // delimits must only be applied once a valid object is found. f_string_lengths delimits = f_string_lengths_initialize; fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*location)) @@ -206,7 +204,7 @@ extern "C" { f_string_length last_newline = location->start; bool found_newline = f_false; - // identify where the content ends + // identify where the content ends. while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { found_newline = f_true; @@ -297,7 +295,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index 288159d..b19bd98 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -143,9 +143,7 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); if (buffer->string[location->start] == f_string_eol) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_object_no_content; } @@ -203,7 +201,7 @@ extern "C" { if (slash_count % 2 == 0) { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -250,10 +248,7 @@ extern "C" { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); found->stop = length - 1; - - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_object_no_content; } @@ -278,7 +273,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -304,9 +299,7 @@ extern "C" { if (buffer->string[location->start] == f_string_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_object_no_content; } else if ((status = fl_fss_is_space(*buffer, *location)) == f_true) { @@ -341,9 +334,7 @@ extern "C" { fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, f_none_on_eos, f_none_on_stop) } else if (buffer->string[location->start] == f_string_eol) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_no_object; } @@ -529,9 +520,7 @@ extern "C" { if (buffer->string[location->start] == f_string_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_content; } @@ -588,7 +577,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -636,11 +625,8 @@ extern "C" { found->array[found->used].stop = length - 1; - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; found->used++; - return fl_fss_found_content; } @@ -664,7 +650,7 @@ extern "C" { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -690,11 +676,8 @@ extern "C" { if (buffer->string[location->start] == f_string_eol) { fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; found->used++; - return fl_fss_found_content; } else if ((status = fl_fss_is_space(*buffer, *location)) == f_true) { @@ -735,9 +718,7 @@ extern "C" { else if (buffer->string[location->start] == f_string_eol) { if (found->used == already_used) { - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) return status; - + location->start++; return fl_fss_found_no_content; } else { diff --git a/level_1/fl_fss/c/fss_extended_list.c b/level_1/fl_fss/c/fss_extended_list.c index 563fa69..b0c1e25 100644 --- a/level_1/fl_fss/c/fss_extended_list.c +++ b/level_1/fl_fss/c/fss_extended_list.c @@ -1,5 +1,5 @@ #include - +#include #ifdef __cplusplus extern "C" { #endif @@ -101,7 +101,7 @@ extern "C" { if (slash_count % 2 == 0) { while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -197,9 +197,10 @@ extern "C" { // delimits must only be applied once a valid object is found. f_string_lengths delimits = f_string_lengths_initialize; f_string_lengths positions_start = f_string_lengths_initialize; + f_fss_objects objects = f_fss_objects_initialize; fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*location)) - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), positions_start, delimits, f_none_on_eos, f_none_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), positions_start, delimits, objects, f_none_on_eos, f_none_on_stop) if (found->used + 1 >= found->size) { f_macro_fss_nest_resize(status, (*found), found->size + f_fss_default_allocation_step + 1); @@ -212,8 +213,8 @@ extern "C" { f_array_length depth = 0; f_string_length position_previous = location->start; + f_string_length line_start = location->start; f_string_length last_newline = location->start; - f_fss_object object = f_fss_object_initialize; f_macro_string_lengths_new(status, positions_start, f_fss_default_allocation_step); if (f_status_is_error(status)) { @@ -222,6 +223,14 @@ extern "C" { return status; } + f_macro_fss_objects_new(status, objects, f_fss_default_allocation_step); + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(positions_start); + f_macro_string_lengths_delete_simple(delimits); + + return status; + } + // initialize depth 1 start position. // positions_start.used is used as a max depth (such that positions_start.used == max depth + 1). positions_start.array[0] = location->start; @@ -230,23 +239,17 @@ extern "C" { while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { last_newline = location->start; - position_previous = location->start; - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - f_macro_string_lengths_delete_simple(positions_start); - - return status; - } + location->start++; if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) + fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_none_on_eos, f_none_on_stop) } + line_start = location->start; continue; } @@ -260,31 +263,34 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } while (location->start < buffer->used && location->start <= location->stop && (buffer->string[location->start] == f_fss_delimit_placeholder || buffer->string[location->start] == f_fss_delimit_slash)) { position_previous = location->start; + + if (buffer->string[location->start] == f_fss_delimit_slash) { + slash_last = location->start; + slash_count++; + } + status = fl_fss_increment_buffer(*buffer, location, 1); if (f_status_is_error(status)) { - if (buffer->string[location->start] == f_fss_delimit_slash) { - slash_last = location->start; - slash_count++; - } - f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } // All slashes for an open are delimited (because it could represent a slash in the object name). @@ -296,8 +302,10 @@ extern "C" { last_newline = location->start; position_previous = location->start; location->start++; + line_start = location->start; } else if (buffer->string[location->start] == f_fss_extended_list_open || buffer->string[location->start] == f_fss_extended_list_close) { + f_string_length before_list_open = position_previous; bool is_open = f_false; if (buffer->string[location->start] == f_fss_extended_list_open) { @@ -309,6 +317,8 @@ extern "C" { while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { + last_newline = location->start; + line_start = location->start + 1; break; } @@ -319,6 +329,7 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -328,21 +339,23 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } // this is a valid object open/close that has been delimited, save the slash delimit positions. if (buffer->string[location->start] == f_string_eol) { - f_string_length location_newline = location->start; + last_newline = location->start; + line_start = location->start + 1; if (is_open) { bool is_object = f_false; @@ -357,8 +370,11 @@ extern "C" { f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); if (f_status_is_error(status)) { + location->start = last_newline; + f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -367,7 +383,7 @@ extern "C" { // apply slash delimits, only slashes and placeholders should be present. while (slash_count > 0) { if (buffer->string[location->start] == f_fss_delimit_slash) { - if (slash_count % 2 != 0) { + if (slash_count % 2 == 1) { delimits.array[delimits.used] = location->start; delimits.used++; } @@ -376,6 +392,7 @@ extern "C" { } // Delimit slashes and placeholders are required to be in the ASCII range. + position_previous = location->start; location->start++; } // while @@ -387,8 +404,11 @@ extern "C" { f_macro_string_lengths_resize(status, positions_start, positions_start.size + f_fss_default_allocation_step); if (f_status_is_error(status)) { + location->start = last_newline; + f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -398,23 +418,22 @@ extern "C" { positions_start.used = depth; } - positions_start.array[depth] = location_newline + 1; + positions_start.array[depth] = last_newline + 1; - object.start = last_newline + 1; - object.stop = position_previous; + objects.array[depth].start = line_start; + objects.array[depth].stop = before_list_open; } - - last_newline = location_newline; } else { - location->start = slash_last; - if (delimits.used + 1 >= delimits.size) { f_macro_string_lengths_resize(status, delimits, delimits.size + f_fss_default_allocation_step); if (f_status_is_error(status)) { + location->start = last_newline; + f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -424,23 +443,25 @@ extern "C" { delimits.used++; } - location->start = location_newline; + location->start = last_newline; } } } else if (buffer->string[location->start] == f_fss_extended_list_open) { - f_string_length location_open = location->start; + f_string_length before_list_open = position_previous; position_previous = location->start; status = fl_fss_increment_buffer(*buffer, location, 1); if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } while (location->start < buffer->used && location->start <= location->stop) { + if (buffer->string[location->start] == f_string_eol) { break; } @@ -452,6 +473,7 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -461,16 +483,17 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } if (buffer->string[location->start] == f_string_eol) { @@ -482,6 +505,17 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); + + return status; + } + + f_macro_fss_objects_resize(status, objects, objects.size + f_fss_default_allocation_step); + + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -493,13 +527,18 @@ extern "C" { positions_start.array[depth] = location->start + 1; - object.start = last_newline + 1; - object.stop = position_previous; + objects.array[depth].start = line_start; + objects.array[depth].stop = before_list_open; + + last_newline = location->start; + line_start = location->start + 1; } // No valid object open found, seek until EOL. else { while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { + last_newline = location->start; + line_start = location->start + 1; break; } @@ -508,32 +547,32 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } } - - last_newline = location->start; } else if (buffer->string[location->start] == f_fss_extended_list_close) { - position_previous = location->start; - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - f_macro_string_lengths_delete_simple(positions_start); + while (location->start < buffer->used && location->start <= location->stop) { + position_previous = location->start; + status = fl_fss_increment_buffer(*buffer, location, 1); + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); - return status; - } + return status; + } - while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { break; } @@ -545,36 +584,27 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); - - return status; - } - - position_previous = location->start; - status = fl_fss_increment_buffer(*buffer, location, 1); - if (f_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } if (buffer->string[location->start] == f_string_eol) { - if (depth == 0) break; - if (depth + 1 >= found->size) { f_macro_fss_nest_resize(status, (*found), found->size + f_fss_default_allocation_step); if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -586,6 +616,7 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } @@ -599,29 +630,61 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } - found->depth[depth].array[position].object.start = object.start; - found->depth[depth].array[position].object.stop = object.stop; + // only assign object positions for nested objects. + if (depth > 0) { + found->depth[depth].array[position].object.start = objects.array[depth].start; + found->depth[depth].array[position].object.stop = objects.array[depth].stop; + } + found->depth[depth].array[position].content.array[0].start = positions_start.array[depth]; found->depth[depth].array[position].content.array[0].stop = last_newline; found->depth[depth].array[position].content.used = 1; - found->depth[depth].used++; - if (depth >= found->used) { + if (position >= found->depth[depth].used) { + found->depth[depth].used++; + } + + if (found->used < depth + 1) { found->used = depth + 1; } last_newline = location->start; + line_start = location->start + 1; + + if (depth == 0) { + status = fl_fss_increment_buffer(*buffer, location, 1); + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); + + return status; + } + + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_none_on_eos, f_none_on_stop) + + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); + + return fl_fss_found_content; + } + depth--; } // No valid object close found, seek until EOL. else { while (location->start < buffer->used && location->start <= location->stop) { if (buffer->string[location->start] == f_string_eol) { + last_newline = location->start; + line_start = location->start + 1; break; } @@ -630,22 +693,36 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while if (depth > 0) { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_unterminated_nest_on_eos, f_unterminated_nest_on_stop) } else { - fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_no_data_on_eos, f_no_data_on_stop) + fl_macro_fss_nest_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, objects, f_no_data_on_eos, f_no_data_on_stop) } } + } + else if (buffer->string[location->start] != f_string_eol) { + position_previous = location->start; + status = fl_fss_increment_buffer(*buffer, location, 1); + if (f_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); + + return status; + } - if (depth > 0) { - last_newline = location->start; + if (location->start >= buffer->used || location->start > location->stop) { + break; } + + continue; } position_previous = location->start; @@ -653,33 +730,29 @@ extern "C" { if (f_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); return status; } } // while - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + f_macro_string_lengths_delete_simple(delimits); + f_macro_string_lengths_delete_simple(positions_start); + f_macro_fss_objects_delete_simple(objects); - location->start = last_newline; - status = fl_fss_decrement_buffer(*buffer, location, 1); - if (f_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - f_macro_string_lengths_delete_simple(positions_start); + if (location->start > location->stop) { + if (depth == 0) { + return f_status_set_error(f_unterminated_on_stop); + } - return status; + return f_status_set_error(f_unterminated_nest_on_stop); } - found->depth[0].array[found->depth[0].used].content.array[0].start = positions_start.array[0]; - found->depth[0].array[found->depth[0].used].content.array[0].stop = location->start; - found->depth[0].used++; - location->start = last_newline + 1; - - fl_macro_fss_nest_delimited_return_on_overflow((*buffer), (*location), (*found), delimits, positions_start, f_none_on_eos, f_none_on_stop) - - f_macro_string_lengths_delete_simple(delimits); - f_macro_string_lengths_delete_simple(positions_start); + if (depth == 0) { + return f_status_set_error(f_unterminated_on_eos); + } - return fl_fss_found_content; + return f_status_set_error(f_unterminated_nest_on_eos); } #endif // _di_fl_fss_extended_list_content_read_ diff --git a/level_1/fl_fss/c/fss_extended_list.h b/level_1/fl_fss/c/fss_extended_list.h index 8653853..ff5064d 100644 --- a/level_1/fl_fss/c/fss_extended_list.h +++ b/level_1/fl_fss/c/fss_extended_list.h @@ -91,10 +91,10 @@ extern "C" { * @return * fl_fss_found_content on success and content was found (start location is at end of content). * fl_fss_found_no_content on success and no content was found (start location is after character designating this is not a content). - * f_none_on_stop on success after reaching stopping point (a valid content is not yet confirmed). - * f_none_on_eos on success after reaching the end of the buffer (a valid content is not yet confirmed). - * f_no_data_on_stop no data found after reaching stopping point (essentially only comments are found). - * f_no_data_on_eos no content found after reaching the end of the buffer (essentially only comments are found). + * f_unterminated_on_eos (with error bit) if end of buffer is reached before a closing bracket is found. + * f_unterminated_on_stop (with error bit) if stop location is reached before a closing bracket is found. + * f_unterminated_nest_on_eos (with error bit) if end of buffer is reached while inside a nested list before a closing bracket is found. + * f_unterminated_nest_on_stop (with error bit) if stop location is reached while inside a nested list before a closing bracket is found. * f_incomplete_utf_on_stop (with error bit) if the stop location 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. * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. diff --git a/level_1/fl_fss/c/fss_macro.h b/level_1/fl_fss/c/fss_macro.h index 22e7143..16a4f60 100644 --- a/level_1/fl_fss/c/fss_macro.h +++ b/level_1/fl_fss/c/fss_macro.h @@ -153,11 +153,12 @@ extern "C" { #endif // _di_fl_macro_fss_allocate_content_if_necessary_ #ifndef _di_fl_macro_fss_nest_return_on_overflow_ - #define fl_macro_fss_nest_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ + #define fl_macro_fss_nest_return_on_overflow(buffer, location, found, delimits, positions, objects, eos_status, stop_status) \ if (location.start >= buffer.used) { \ f_status macro_allocation_status = f_none; \ f_macro_string_lengths_delete(macro_allocation_status, delimits); \ f_macro_string_lengths_delete(macro_allocation_status, positions); \ + f_macro_fss_objects_delete(macro_allocation_status, objects); \ \ /* @todo: found.array[found.used].stop = buffer.used - 1; */ \ return eos_status; \ @@ -166,6 +167,7 @@ extern "C" { f_status macro_allocation_status = f_none; \ f_macro_string_lengths_delete(macro_allocation_status, delimits); \ f_macro_string_lengths_delete(macro_allocation_status, positions); \ + f_macro_fss_objects_delete(macro_allocation_status, objects); \ \ /* @todo: found.array[found.used].stop = location.stop; */ \ return stop_status; \ @@ -173,7 +175,7 @@ extern "C" { #endif // _di_fl_macro_fss_nest_return_on_overflow_ #ifndef _di_fl_macro_fss_nest_delimited_return_on_overflow_ - #define fl_macro_fss_nest_delimited_return_on_overflow(buffer, location, found, delimits, positions, eos_status, stop_status) \ + #define fl_macro_fss_nest_delimited_return_on_overflow(buffer, location, found, delimits, positions, objects, eos_status, stop_status) \ if (location.start >= buffer.used) { \ f_status macro_allocation_status = f_none; \ f_string_length i = 0; \ @@ -184,6 +186,7 @@ extern "C" { } \ f_macro_string_lengths_delete(macro_allocation_status, delimits); \ f_macro_string_lengths_delete(macro_allocation_status, positions); \ + f_macro_fss_objects_delete(macro_allocation_status, objects); \ \ return eos_status; \ } \ @@ -197,6 +200,7 @@ extern "C" { } \ f_macro_string_lengths_delete(macro_allocation_status, delimits); \ f_macro_string_lengths_delete(macro_allocation_status, positions); \ + f_macro_fss_objects_delete(macro_allocation_status, objects); \ \ return stop_status; \ } diff --git a/level_2/fll_fss/c/fss_basic.c b/level_2/fll_fss/c/fss_basic.c index 0ce0914..d97de5c 100644 --- a/level_2/fll_fss/c/fss_basic.c +++ b/level_2/fll_fss/c/fss_basic.c @@ -34,6 +34,10 @@ extern "C" { do { status = fl_fss_basic_object_read(buffer, input, &objects->array[objects->used]); + if (f_status_is_error(status)) { + return status; + } + if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_object_no_content) { objects->used++; @@ -73,6 +77,10 @@ extern "C" { found_data = f_true; status = fl_fss_basic_content_read(buffer, input, &contents->array[contents->used]); + if (f_status_is_error(status)) { + return status; + } + break; } else if (status == fl_fss_found_object_no_content) { diff --git a/level_2/fll_fss/c/fss_basic_list.c b/level_2/fll_fss/c/fss_basic_list.c index ae6d5ce..dbabc18 100644 --- a/level_2/fll_fss/c/fss_basic_list.c +++ b/level_2/fll_fss/c/fss_basic_list.c @@ -34,6 +34,10 @@ extern "C" { do { status = fl_fss_basic_list_object_read(buffer, input, &objects->array[objects->used]); + if (f_status_is_error(status)) { + return status; + } + if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_object_no_content) { objects->used++; @@ -73,6 +77,10 @@ extern "C" { found_data = f_true; status = fl_fss_basic_list_content_read(buffer, input, &contents->array[contents->used]); + if (f_status_is_error(status)) { + return status; + } + break; } else if (status == fl_fss_found_object_no_content) { diff --git a/level_2/fll_fss/c/fss_extended.c b/level_2/fll_fss/c/fss_extended.c index d2d4942..0397c03 100644 --- a/level_2/fll_fss/c/fss_extended.c +++ b/level_2/fll_fss/c/fss_extended.c @@ -34,6 +34,10 @@ extern "C" { do { status = fl_fss_extended_object_read(buffer, input, &objects->array[objects->used]); + if (f_status_is_error(status)) { + return status; + } + if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_object_no_content) { objects->used++; @@ -73,6 +77,10 @@ extern "C" { found_data = f_true; status = fl_fss_extended_content_read(buffer, input, &contents->array[contents->used]); + if (f_status_is_error(status)) { + return status; + } + break; } else if (status == fl_fss_found_object_no_content) { diff --git a/level_2/fll_fss/c/fss_extended_list.c b/level_2/fll_fss/c/fss_extended_list.c index 62a3c0d..f612976 100644 --- a/level_2/fll_fss/c/fss_extended_list.c +++ b/level_2/fll_fss/c/fss_extended_list.c @@ -34,10 +34,13 @@ extern "C" { status = fl_fss_extended_list_object_read(buffer, input, &nest->depth[0].array[nest->depth[0].used].object); + if (f_status_is_error(status)) { + return status; + } + if (input->start >= input->stop || input->start >= buffer->used) { if (status == fl_fss_found_object || status == fl_fss_found_object_no_content) { - nest->depth[0].used++; - + // extended list requires content closure, so this could be an error. return fl_fss_found_object_no_content; } @@ -65,27 +68,23 @@ extern "C" { } else if (status == fl_fss_found_object_no_content) { found_data = f_true; - - if (nest->depth[0].used >= nest->depth[0].size) { - f_status status = f_none; - - f_macro_fss_items_resize(status, nest->depth[0], nest->depth[0].used + f_fss_default_allocation_step); - - if (f_status_is_error(status)) { - return status; - } - } - break; } } while (status == fl_fss_found_no_object); if (status == f_none_on_eos || status == f_none_on_stop) { - nest->depth[0].used++; return status; } else if (status == f_no_data_on_eos || status == f_no_data_on_stop) { + // If at least some valid object was found, then return f_none equivalents. + if (nest->depth[0].used > initial_used) { + if (status == f_no_data_on_eos) return f_none_on_eos; + if (status == f_no_data_on_stop) return f_none_on_stop; + } + return status; + } + else if (status == f_unterminated_on_eos || status == f_unterminated_on_stop || status == f_unterminated_nest_on_eos || status == f_unterminated_nest_on_stop) { // If at least some valid object was found, then return f_none equivalents. if (nest->depth[0].used > initial_used) { if (status == f_no_data_on_eos) return f_none_on_eos; @@ -99,18 +98,12 @@ extern "C" { } // When content is found, the input->start is incremented, if content is found at input->stop, then input->start will be > input.stop. else if (input->start >= input->stop || input->start >= buffer->used) { - if (status == fl_fss_found_object || status == fl_fss_found_content || status == fl_fss_found_no_content || status == fl_fss_found_object_no_content) { - nest->depth[0].used++; - } - if (input->start >= buffer->used) { return f_none_on_eos; } return f_none_on_stop; } - - nest->depth[0].used++; } while (input->start < f_string_max_size); return f_status_is_error(f_number_overflow); diff --git a/level_2/fll_fss/c/fss_extended_list.h b/level_2/fll_fss/c/fss_extended_list.h index 792a31f..05f0ab7 100644 --- a/level_2/fll_fss/c/fss_extended_list.h +++ b/level_2/fll_fss/c/fss_extended_list.h @@ -38,12 +38,19 @@ extern "C" { * An nested set of all objects and content. * * @return - * f_none on success. - * f_none_on_stop on success after reaching stopping point . - * f_none_on_eos on success after reaching the end of the buffer. + * f_none on success (both valid object and valid content found with start location is at end of content). + * f_none_on_stop on success after reaching stopping point (both valid object and valid content found with start location is at stop point). + * f_none_on_eos on success after reaching the end of the buffer (both valid object and valid content found with start location is at end of buffer). * f_no_data_on_stop no data to write due start location being greater than stop location. * f_no_data_on_eos no data to write due start location being greater than or equal to buffer size. * f_no_data_on_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * fl_fss_found_object_no_content on success and object was found but no content was found (start location is at end of object). + * f_unterminated_on_eos (with error bit) if end of buffer is reached before a closing bracket is found (object was found). + * f_unterminated_on_stop (with error bit) if stop location is reached before a closing bracket is found (object was found). + * f_unterminated_nest_on_eos (with error bit) if end of buffer is reached while inside a nested list before a closing bracket is found (object was found). + * f_unterminated_nest_on_stop (with error bit) if stop location is reached while inside a nested list before a closing bracket is found (object was found). + * f_incomplete_utf_on_stop (with error bit) if the stop location 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. * f_incomplete_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. * f_invalid_utf (with error bit) is returned on failure to read/process a UTF-8 character. * f_error_reallocation (with error bit) on reallocation error. diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 91a8ab5..b572efd 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -226,16 +226,6 @@ extern "C" { return status; } - // Requested depths cannot be greater than contents depth. - if (depths.used > data->nest.used) { - if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { - fprintf(f_standard_output, "0%c", f_string_eol); - return f_none; - } - - return f_none; - } - if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_found) { fl_color_print(f_standard_error, data->context.error, data->context.reset, "ERROR: the '"); fl_color_print(f_standard_error, data->context.notable, data->context.reset, "--%s", fss_extended_list_read_long_select); diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c index 27babba..7f3b7bc 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c @@ -257,19 +257,31 @@ extern "C" { } } - f_string_length select = 0; + // Requested depths cannot be greater than contents depth. + if (depths.used > data->nest.used) { + if (data->parameters[fss_extended_list_read_parameter_total].result == f_console_result_found) { + fprintf(f_standard_output, "0%c", f_string_eol); + return f_none; + } - if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) { - status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[data->parameters[fss_extended_list_read_parameter_select].additional.used - 1]], &select); + return f_none; + } - if (f_status_is_error(status)) { - fss_extended_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_select, arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[0]], f_status_set_fine(status)); - return status; - } + { + f_string_length select = 0; - // This standard does not support multiple content groups. - if (select > 0) { - return f_none; + if (data->parameters[fss_extended_list_read_parameter_select].result == f_console_result_additional) { + status = fl_console_parameter_to_number_unsigned(arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[data->parameters[fss_extended_list_read_parameter_select].additional.used - 1]], &select); + + if (f_status_is_error(status)) { + fss_extended_list_read_print_number_argument_error(data->context, "fl_console_parameter_to_number_unsigned", fss_extended_list_read_long_select, arguments.argv[data->parameters[fss_extended_list_read_parameter_select].additional.array[0]], f_status_set_fine(status)); + return status; + } + + // This standard does not support multiple content groups. + if (select > 0) { + return f_none; + } } } @@ -370,7 +382,7 @@ extern "C" { for (f_array_length i = 0; i < items->used; i++) { if (names[i]) { - f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[depth_setting.value_at].object); + f_print_string_dynamic_partial(f_standard_output, data->buffer, items->array[i].object); fprintf(f_standard_output, "%c", f_string_eol); } } // for