From 584c02cb474b528f28c0c78a088f693168125bb0 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Thu, 2 Jul 2020 22:58:27 -0500 Subject: [PATCH] Bugfix: FSS-0000 and FSS-0001 are handling not explicitly follow standard for quote delimit requirements. In the case where a quote is provided that could potentially be a valid quote, that quote should only be considered a quote (including for delimited purposes) if a valid whitespace, end of string, or end of line is reached. The code needs to check after the closing quote to confirm that it is actually a valid closing quote before acting on it. Update the FSS specification to make this behavior more explicitly clear. --- level_1/fl_fss/c/fss_extended.c | 288 ++++++++++++++++++++++++---------------- level_1/fl_fss/c/private-fss.c | 265 ++++++++++++++++++++++-------------- specifications/fss.txt | 60 +++++++-- 3 files changed, 388 insertions(+), 225 deletions(-) diff --git a/level_1/fl_fss/c/fss_extended.c b/level_1/fl_fss/c/fss_extended.c index 19b546e..d1640d1 100644 --- a/level_1/fl_fss/c/fss_extended.c +++ b/level_1/fl_fss/c/fss_extended.c @@ -252,42 +252,57 @@ extern "C" { location = range->start; range->start = first_slash; - if (slash_count % 2 == 0) { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote and delimits do not apply. + { + f_string_length location = range->start; - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { + range->start++; + + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + + if (range->start <= range->stop && range->start < buffer->used) { + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) { + return status; + } } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; } - while (slash_count > 0) { - if (buffer->string[range->start] == f_fss_delimit_slash) { - if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; - } + range->start = location; + } - slash_count--; - } + if (status == F_true) { + if (slash_count % 2 == 0) { + if (delimits.used + (slash_count / 2) >= delimits.size) { + f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } } - } // while - range->start = location + 1; - - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) + while (slash_count > 0) { + if (buffer->string[range->start] == f_fss_delimit_slash) { + if (slash_count % 2 == 1) { + delimits.array[delimits.used] = range->start; + delimits.used++; + } - status = f_fss_is_graph(*buffer, *range); + slash_count--; + } - if (status == F_true) { - while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); @@ -295,121 +310,180 @@ extern "C" { } } // while - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) + range->start = location + 1; - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - return F_unterminated_group; - } - else if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - else if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + status = f_fss_is_graph(*buffer, *range); - found->array[found->used].stop = location - 1; - - range->start++; - found->used++; - return FL_fss_found_content; - } - - found->array[found->used].stop = location - 1; + if (status == F_true) { + while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } // while - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) - found->used++; - continue; - } - else { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } - if (F_status_is_error(status)) { + return F_unterminated_group; + } + else if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - } + else if (buffer->string[range->start] == f_fss_extended_close) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - while (slash_count > 0) { - if (buffer->string[range->start] == f_fss_delimit_slash) { - if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; - } + found->array[found->used].stop = location - 1; - slash_count--; + range->start++; + found->used++; + return FL_fss_found_content; } + found->array[found->used].stop = location - 1; + status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - } // while - range->start = location; + found->used++; + continue; + } + else { + if (delimits.used + (slash_count / 2) >= delimits.size) { + f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } + + while (slash_count > 0) { + if (buffer->string[range->start] == f_fss_delimit_slash) { + if (slash_count % 2 == 1) { + delimits.array[delimits.used] = range->start; + delimits.used++; + } + + slash_count--; + } + + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } // while + + range->start = location; + } } } } else if (buffer->string[range->start] == quoted) { - found->array[found->used].stop = range->start - 1; + // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote. + { + f_string_length location = range->start; - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + status = F_false; - while (range->start <= range->stop && range->start < buffer->used) { + if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { + range->start++; - if (buffer->string[range->start] == f_fss_extended_close) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - range->start++; - found->used++; - return FL_fss_found_content; + if (range->start <= range->stop && range->start < buffer->used) { + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) { + return status; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; } - status = f_fss_is_space(*buffer, *range); + range->start = location; + } - if (status == F_true) { - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (status == F_true) { + found->array[found->used].stop = range->start - 1; - found->used++; - continue_main_loop = F_true; - break; - } - else if (F_status_is_error(status)) { + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - else if (buffer->string[range->start] != f_fss_delimit_placeholder) { - while (range->start < buffer->used && range->start <= range->stop) { + while (range->start <= range->stop && range->start < buffer->used) { + + if (buffer->string[range->start] == f_fss_extended_close) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + + range->start++; + found->used++; + return FL_fss_found_content; + } + + status = f_fss_is_space(*buffer, *range); + + if (status == F_true) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) + found->used++; + continue_main_loop = F_true; + break; + } + else if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + else if (buffer->string[range->start] != f_fss_delimit_placeholder) { + + while (range->start < buffer->used && range->start <= range->stop) { + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + + fl_macro_fss_content_return_on_overflow((*buffer), (*range), (*found), delimits, F_unterminated_group_eos, F_unterminated_group_stop) + + if (buffer->string[range->start] == f_string_eol[0]) break; + } // while + + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } - if (buffer->string[range->start] == f_string_eol[0]) break; - } // while + return F_unterminated_group; + } status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { @@ -417,21 +491,13 @@ extern "C" { return status; } - return F_unterminated_group; - } + fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) + } // while - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (continue_main_loop) break; fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) - } // while - - if (continue_main_loop) break; - - fl_macro_fss_content_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop) + } } else if (buffer->string[range->start] == f_fss_extended_close) { diff --git a/level_1/fl_fss/c/private-fss.c b/level_1/fl_fss/c/private-fss.c index 3dab2ac..aacdf2b 100644 --- a/level_1/fl_fss/c/private-fss.c +++ b/level_1/fl_fss/c/private-fss.c @@ -205,45 +205,55 @@ extern "C" { fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_status_set_warning(F_unterminated_group_eos), F_status_set_warning(F_unterminated_group_stop)); if (buffer->string[range->start] == quoted) { - f_string_length length = range->start; + f_string_length location = range->start; - range->start = first_slash; + // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote and delimits do not apply. + if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { + range->start++; - if (slash_count % 2 == 0) { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + if (range->start <= range->stop && range->start < buffer->used) { + status = f_fss_is_space(*buffer, *range); if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); return status; } } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } - while (slash_count > 0) { - if (buffer->string[range->start] == f_fss_delimit_slash) { - if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; - } + if (status == F_true) { + range->start = first_slash; - slash_count--; - } + if (slash_count % 2 == 0) { + if (delimits.used + (slash_count / 2) >= delimits.size) { + f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } } - } // while - - range->start = length + 1; - fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + while (slash_count > 0) { + if (buffer->string[range->start] == f_fss_delimit_slash) { + if (slash_count % 2 == 1) { + delimits.array[delimits.used] = range->start; + delimits.used++; + } - if ((status = f_fss_is_graph(*buffer, *range)) == F_true) { + slash_count--; + } - while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { status = f_utf_buffer_increment(*buffer, range, 1); if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); @@ -251,121 +261,172 @@ extern "C" { } } // while - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); - - f_macro_string_lengths_delete_simple(delimits); - - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + range->start = location + 1; - return FL_fss_found_object_not; - } - else if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } - else if (buffer->string[range->start] == f_string_eol[0]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); + fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); - found->stop = length - 1; - range->start++; - return FL_fss_found_object_content_not; - } + if ((status = f_fss_is_graph(*buffer, *range)) == F_true) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } // while - found->stop = length - 1; + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + f_macro_string_lengths_delete_simple(delimits); - return FL_fss_found_object; - } - else { - if (delimits.used + (slash_count / 2) >= delimits.size) { - f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) return status; - if (F_status_is_error(status)) { + return FL_fss_found_object_not; + } + else if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - } - - while (slash_count > 0) { - if (buffer->string[range->start] == f_fss_delimit_slash) { - if (slash_count % 2 == 1) { - delimits.array[delimits.used] = range->start; - delimits.used++; - } + else if (buffer->string[range->start] == f_string_eol[0]) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - slash_count--; + found->stop = location - 1; + range->start++; + return FL_fss_found_object_content_not; } + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + + found->stop = location - 1; + status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; + if (F_status_is_error(status)) return status; + + return FL_fss_found_object; + } + else { + if (delimits.used + (slash_count / 2) >= delimits.size) { + f_macro_string_lengths_resize(status, delimits, delimits.size + (slash_count / 2) + f_fss_default_allocation_step); + + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } } - } // while - range->start = length; + while (slash_count > 0) { + if (buffer->string[range->start] == f_fss_delimit_slash) { + if (slash_count % 2 == 1) { + delimits.array[delimits.used] = range->start; + delimits.used++; + } + + slash_count--; + } + + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + } // while + + range->start = location; + } + } + else { + range->start = location; } } } else if (buffer->string[range->start] == quoted) { - found->stop = range->start - 1; + // check to see if there is a whitespace, EOS, or EOL after the quote, if not, then this is not a closing quote. + { + f_string_length location = range->start; - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (range->start + 1 <= range->stop && range->start + 1 < buffer->used) { + range->start++; - while (range->start <= range->stop && range->start < buffer->used) { - if (buffer->string[range->start] == f_string_eol[0]) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*range)); - range->start++; - return FL_fss_found_object_content_not; + if (range->start <= range->stop && range->start < buffer->used) { + status = f_fss_is_space(*buffer, *range); + if (F_status_is_error(status)) { + return status; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; + } + } + else { + // EOS or EOL was reached, so it is a valid closing quote. + // (for EOL, this is always TRUE, for EOS this could be false but there is no way to know this, so assume TRUE (@todo maybe none on stop?). + status = F_true; } - else if ((status = f_fss_is_space(*buffer, *range)) == F_true) { - fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + range->start = location; + } - return FL_fss_found_object; - } - else if (F_status_is_error(status)) { + if (status == F_true) { + found->stop = range->start - 1; + + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { f_macro_string_lengths_delete_simple(delimits); return status; } - else if (buffer->string[range->start] != f_fss_delimit_placeholder) { - while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { + while (range->start <= range->stop && range->start < buffer->used) { + if (buffer->string[range->start] == f_string_eol[0]) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + + range->start++; + return FL_fss_found_object_content_not; + } + else if ((status = f_fss_is_space(*buffer, *range)) == F_true) { + fl_macro_fss_apply_delimit_placeholders((*buffer), delimits); + status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) { - f_macro_string_lengths_delete_simple(delimits); - return status; - } + if (F_status_is_error(status)) return status; - } // while + return FL_fss_found_object; + } + else if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } + else if (buffer->string[range->start] != f_fss_delimit_placeholder) { - fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); + while (range->start < buffer->used && range->start <= range->stop && buffer->string[range->start] != f_string_eol[0]) { + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) { + f_macro_string_lengths_delete_simple(delimits); + return status; + } - f_macro_string_lengths_delete_simple(delimits); + } // while - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; + fl_macro_fss_object_return_on_overflow((*buffer), (*range), (*found), delimits, F_data_not_eos, F_data_not_stop); - return FL_fss_found_object_not; - } + f_macro_string_lengths_delete_simple(delimits); - status = f_utf_buffer_increment(*buffer, range, 1); - if (F_status_is_error(status)) return status; - } // while + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) return status; + + return FL_fss_found_object_not; + } - fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + status = f_utf_buffer_increment(*buffer, range, 1); + if (F_status_is_error(status)) return status; + } // while + + fl_macro_fss_object_delimited_return_on_overflow((*buffer), (*range), (*found), delimits, F_none_eos, F_none_stop); + } } else if (buffer->string[range->start] == f_string_eol[0]) { f_macro_string_lengths_delete_simple(delimits); diff --git a/specifications/fss.txt b/specifications/fss.txt index 6a0e02f..b03de73 100644 --- a/specifications/fss.txt +++ b/specifications/fss.txt @@ -37,24 +37,54 @@ Featureless Settings Specifications: This simplifies identifying the object, use quoted objects to support whitespace before/after an object. Unless explicitly defined, quotes may only be either a single quote (') or a double quote (") and only a backslash '\' may be used as a delimiter. + For example, FSS-0000 (Basic)\: + \"Object 1" has content starting at the '1', with an Object named '"Object'. + \\"Object 1" has content starting at the '1', with an Object named '\"Object'. + "Object 1\" is an unterminated object due to the escaped closing quote. + "Object 1\\" has content starting at the 'has', with an Object named "Object 1\". Unless explicitly defined by the specification, character/data delimits are performed only when required and not unilaterally. In the case of Objects, delimits would only apply when that object could be potentially identified as an object when it otherwise should not. For example, FSS-0001 (Extended) needs quotes to group parts that include spaces, if there is no initial quote, then a quote following the data must not be delimited. - Such as these following two lines\: - "Object 1" "This is a single quoted Content." \"Additional unquoted Content" + Such as these following three lines\: + "Object 1" "This is a single quoted Content." \"Additional unquoted Content." Object_2 This is multiple" Contents and the trailing quote does not need to be delimited. + "Object \"3" 'Wouldn't require delimits if no whitespace or end of string after.' - Unlike this specification, a more traditional delimit process would have the above two lines instead represented as\: - "Object 1" "This is a single quoted Content." \"Additional unquoted Content\" + Unlike this specification, a more traditional delimit process would have the above three lines instead represented as\: + "Object 1" "This is a single quoted Content." \"Additional unquoted Content.\" Object_2 This is multiple\" Contents and the trailing quote does not need to be delimited. - - Unless explicitly defined, delimits may be delimited by the delimit character (a backslash '\'). - For example, FSS-0000 (Basic): - \"Object 1" has content starting at the '1', with an Object named '"Object'. - \\"Object 1" has content starting at the '1', with an Object named '\"Object'. - "Object 1\" is an unterminated object due to the escaped closing quote. - "Object 1\\" has content starting at the 'has', with an Object named "Object 1\". + "Object \\"3" 'Wouldn\'t require delimits if no whitespace or end of string after.' + + These examples would resolve as follows\: + 1) Object\: + - Object 1 + Content\: + - This is a single quoted Content. + - "Additional + - unquoted + - Content" + 2) Object\: + - Object_2 + Content\: + - This + - is + - multiple" + - Contents + - and + - the + - trailing + - quote + - does + - not + - need + - to + - be + - delimited. + 3) Object\: + - Object \"3 + Content\: + - Wouldn't require delimits if no whitespace or end of string after. All specifications are expected to support or be of the character encoding UTF-8; however, there is no imposed restriction on supporting or using any other encoding. Those encodings must only support the appropriate characters required by a given standard for differentiating Objects, Contents, and delimits. @@ -70,7 +100,13 @@ Featureless Settings Specifications: Whitespace used for designation characters must include support for UTF-8 whitespace characters, unless explicitly designated not to by a standard. Control characters used for designation characters must include support UTF-8 control character support, unless explicitly designated not to by a standard. - The UTF-8 BOM is not allowed as a Byte Order Mark; instead, it must always be treated as the character represented by its code (unless explicitly allowed by a standard). + The UTF-8 BOM is not allowed as a Byte Order Mark; instead, it must always be treated as the character represented by its code (unless explicitly allowed to represent a BOM by a standard). + + Unless explicitly defined, whitespace is to be considered all not visible characters that take up space (including newlines '\n'). + Any visible/graph character that is considered a whitespace (such as U+1680 ' ') is not to be considered a whitespace by the FSS. + + @todo document that certain special UTF-8 characters are not allowed in certain terminology groups, such as "word characters", "number characters", etc.. so that potential confusion can be avoided. + This is a common behavior for character security reasons, each character used for any special purposes must be visibly distinct, with whitespace and non-printing characters as the exception. The follow specifications are defined in this project. Each of these specifications has a common name associated with the specification number. -- 1.8.3.1