]> Kevux Git Server - fll/commitdiff
Update: basic list fixes and cleanups, including some other cleanups.
authorKevin Day <thekevinday@gmail.com>
Mon, 12 Oct 2020 03:46:06 +0000 (22:46 -0500)
committerKevin Day <thekevinday@gmail.com>
Mon, 12 Oct 2020 03:46:06 +0000 (22:46 -0500)
The EOL handling in FSS Basic List is incorrect/incomplete.

Slashes at the end of an Object must be delimited to avoid escaping the object close character.

Be sure to return an error when a newline is provided in an Object name on basic list object write.

The standard states that controlling character, such as a basic list open, must use ASCII character codes for simplicity and safety.
Therefore, a UTF-8 buffer increment is not necessary.
Use the simpler, more performant C math operator increment.

Cleanup coding strategy in basic list content write to be more consistent with more recent approaches.
Cleanup some comments.

Also cleanup incorrect loop comment in fss_basic.c.

level_1/fl_fss/c/fss_basic.c
level_1/fl_fss/c/fss_basic_list.c
level_3/fss_basic_list_write/c/private-fss_basic_list_write.c
level_3/fss_basic_list_write/c/private-fss_basic_list_write.h

index af633f8fe844ec30a13cb7bc0e5089d41be16129..bae4c1e49c4e86dc8ddd04398a67fbed181bc03c 100644 (file)
@@ -169,7 +169,7 @@ extern "C" {
       }
 
       destination->string[destination->used++] = content.string[range->start];
-    } // while
+    } // for
 
     if (complete == f_fss_complete_full || complete == f_fss_complete_end) {
       destination->string[destination->used++] = f_fss_basic_close;
index 2c47a013130babd1cad1716b784d5c4a730a849c..50e0bf4a80b064b23931725f68e943dddf13d0c9 100644 (file)
@@ -466,18 +466,18 @@ extern "C" {
         break;
       }
 
-      if (object.string[range->start] == f_fss_eol) {
-        status = F_status_set_error(F_none_eol);
-        break;
-      }
-
       status = f_fss_is_graph(object, *range);
       if (F_status_is_error(status)) break;
 
       if (status == F_true) break;
 
-      // objects will not have leading whitespaces, but having this does not generate an invalid object, so just write the spaces.
+      // objects will not have leading whitespaces, but having this does not result in an invalid object, so just write the provided spaces.
       if (object.string[range->start] != f_fss_delimit_placeholder) {
+        if (object.string[range->start] == f_fss_eol) {
+          status = F_status_set_error(F_none_eol);
+          break;
+        }
+
         status = f_fss_is_space(object, *range);
         if (F_status_is_error(status)) break;
 
@@ -520,6 +520,12 @@ extern "C" {
 
         if (F_status_is_error(status)) break;
 
+        if (range->start > range->stop || range->start >= object.used) {
+
+          // slashes at the end of the object must be delimited to avoid delimiting the object close character.
+          slash_count *= 2;
+        }
+
         status = private_fl_fss_destination_increase_by(slash_count, destination);
         if (F_status_is_error(status)) break;
 
@@ -531,15 +537,13 @@ extern "C" {
           break;
         }
       }
-      else if (object.string[range->start] == f_fss_eol) {
-        if (destination->used == used_start) {
-          return F_data_not_eol;
-        }
-
-        return F_none_eol;
-      }
 
       if (object.string[range->start] != f_fss_delimit_placeholder) {
+        if (object.string[range->start] == f_fss_eol) {
+          status = F_status_set_error(F_none_eol);
+          break;
+        }
+
         width = f_macro_utf_byte_width(object.string[range->start]);
 
         status = private_fl_fss_destination_increase_by(width, destination);
@@ -560,6 +564,13 @@ extern "C" {
     }
 
     if (complete == f_fss_complete_partial || complete == f_fss_complete_full) {
+      status = private_fl_fss_destination_increase_by(2, destination);
+
+      if (F_status_is_error(status)) {
+        destination->used = used_start;
+        return status;
+      }
+
       destination->string[destination->used++] = f_fss_basic_list_open;
       destination->string[destination->used++] = f_fss_eol;
     }
@@ -584,82 +595,59 @@ extern "C" {
     #endif // _di_level_1_parameter_checking_
 
     f_status_t status = F_none;
-    bool is_comment = F_false;
-    bool has_graph = F_false;
-
-    f_string_range_t buffer_position = f_string_range_t_initialize;
-    f_string_length_t start_position = f_string_t_initialize;
-    f_string_length_t size_allocate = 0;
-    f_string_length_t slash_count = 0;
-    f_string_length_t start = 0;
 
     fl_macro_fss_skip_past_delimit_placeholders(content, (*range));
 
     if (range->start > range->stop) {
-      if (destination->used + f_fss_default_allocation_step > f_string_length_t_size) {
-        if (destination->used + 1 > f_string_length_t_size) {
-          return F_status_set_error(F_string_too_large);
-        }
-
-        f_macro_string_dynamic_t_resize(status, (*destination), destination->used + 1);
-        if (F_status_is_error(status)) return status;
-      }
-      else {
-        f_macro_string_dynamic_t_resize(status, (*destination), destination->used + f_fss_default_allocation_step);
-        if (F_status_is_error(status)) return status;
-      }
-
-      destination->string[destination->used++] = f_fss_extended_close;
-      return F_data_not_stop;
+      status = F_data_not_stop;
+    }
+    else if (range->start >= content.used) {
+      status = F_data_not_eos;
     }
 
-    if (range->start >= content.used) {
-      return F_data_not_eos;
+    if (status == F_data_not_stop || status == F_data_not_eos) {
+      return status;
     }
 
-    start_position = range->start;
+    // ensure that there is room for a slash delimit and possibly the end of line character.
+    status = private_fl_fss_destination_increase_by(destination->used + (range->stop - range->start) + 2, destination);
+    if (F_status_is_error(status)) return status;
 
-    // add an additional 2 to ensure that there is room for the slash delimit and the content open character.
-    size_allocate = destination->used + (range->stop - range->start) + 2 + f_fss_default_allocation_step;
+    const f_string_length_t input_start = range->start;
+    const f_string_length_t used_start = destination->used;
 
-    if (size_allocate > destination->size) {
-      f_macro_string_dynamic_t_resize(status, (*destination), size_allocate);
-      if (F_status_is_error(status)) return status;
-    }
+    bool is_comment = F_false;
+    bool has_graph = F_false;
+
+    f_string_length_t i = 0;
+    f_string_length_t slash_count = 0;
+    f_string_length_t start = 0;
 
-    buffer_position.start = destination->used;
-    buffer_position.stop = destination->used;
+    uint8_t width = 0;
 
     while (range->start <= range->stop && range->start < content.used) {
 
       if (content.string[range->start] == f_fss_delimit_slash && !is_comment) {
         slash_count = 1;
 
-        destination->string[buffer_position.stop++] = content.string[range->start];
+        destination->string[destination->used++] = content.string[range->start];
         has_graph = F_true;
 
         status = f_utf_buffer_increment(content, range, 1);
         if (F_status_is_error(status)) return status;
 
-        while (range->start <= range->stop && range->start < content.used) {
+        for (; range->start <= range->stop && range->start < content.used; range->start++) {
 
           if (content.string[range->start] == f_fss_delimit_placeholder) {
-            status = f_utf_buffer_increment(content, range, 1);
-            if (F_status_is_error(status)) return status;
-
             continue;
           }
           else if (content.string[range->start] != f_fss_delimit_slash) {
             break;
           }
 
-          destination->string[buffer_position.stop++] = content.string[range->start];
-
-          status = f_utf_buffer_increment(content, range, 1);
-          if (F_status_is_error(status)) return status;
-
+          destination->string[destination->used++] = f_fss_delimit_slash;
           slash_count++;
-        } // while
+        } // for
 
         if (content.string[range->start] == f_fss_basic_list_open) {
           start = range->start;
@@ -669,7 +657,7 @@ extern "C" {
 
           while (range->start < content.used && range->start <= range->stop) {
 
-            if (content.string[range->start] == f_string_eol[0]) break;
+            if (content.string[range->start] == f_fss_eol) break;
 
             status = f_fss_is_space(content, *range);
             if (F_status_is_error(status)) return status;
@@ -680,38 +668,37 @@ extern "C" {
             if (F_status_is_error(status)) return status;
           } // while
 
-          if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) {
-            size_allocate += slash_count + 1;
+          if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) {
 
-            if (size_allocate > destination->size) {
-              f_macro_string_dynamic_t_resize(status, (*destination), size_allocate + f_fss_default_allocation_step);
-              if (F_status_is_error(status)) return status;
-            }
+            // increase by total slashes + 1, along with the basic list open.
+            status = private_fl_fss_destination_increase_by(slash_count + 2, destination);
+            if (F_status_is_error(status)) return status;
 
             while (slash_count--) {
-              destination->string[buffer_position.stop++] = f_fss_delimit_slash;
+              destination->string[destination->used++] = f_fss_delimit_slash;
             } // while
 
-            destination->string[buffer_position.stop++] = f_fss_delimit_slash;
+            destination->string[destination->used++] = f_fss_delimit_slash;
             has_graph = F_false;
             is_comment = F_false;
           }
+          else {
+            status = private_fl_fss_destination_increase(destination);
+            if (F_status_is_error(status)) return status;
+          }
 
-          destination->string[buffer_position.stop++] = f_fss_basic_list_open;
+          destination->string[destination->used++] = f_fss_basic_list_open;
           range->start = start + 1;
           continue;
         }
       }
       else if (content.string[range->start] == f_fss_basic_list_open && !is_comment) {
-        start = range->start;
+        start = range->start++;
         has_graph = F_true;
 
-        status = f_utf_buffer_increment(content, range, 1);
-        if (F_status_is_error(status)) return status;
-
         while (range->start < content.used && range->start <= range->stop) {
 
-          if (content.string[range->start] == f_string_eol[0]) break;
+          if (content.string[range->start] == f_fss_eol) break;
 
           status = f_fss_is_space(content, *range);
           if (F_status_is_error(status)) return status;
@@ -722,27 +709,29 @@ extern "C" {
           if (F_status_is_error(status)) return status;
         } // while
 
-        if (content.string[range->start] == f_string_eol[0] || range->start >= content.used || range->start > range->stop) {
-          size_allocate++;
+        if (content.string[range->start] == f_fss_eol || range->start >= content.used || range->start > range->stop) {
 
-          if (size_allocate > destination->size) {
-            f_macro_string_dynamic_t_resize(status, (*destination), size_allocate + f_fss_default_allocation_step);
-            if (F_status_is_error(status)) return status;
-          }
+          // increase by slash and basic list open.
+          status = private_fl_fss_destination_increase_by(2, destination);
+          if (F_status_is_error(status)) return status;
 
-          destination->string[buffer_position.stop++] = f_fss_delimit_slash;
+          destination->string[destination->used++] = f_fss_delimit_slash;
           has_graph = F_false;
           is_comment = F_false;
         }
+        else {
+          status = private_fl_fss_destination_increase(destination);
+          if (F_status_is_error(status)) return status;
+        }
 
-        destination->string[buffer_position.stop++] = f_fss_basic_list_open;
+        destination->string[destination->used++] = f_fss_basic_list_open;
         range->start = start + 1;
         continue;
       }
       else if (content.string[range->start] == f_fss_comment && !has_graph) {
         is_comment = F_true;
       }
-      else if (content.string[range->start] == f_string_eol[0]) {
+      else if (content.string[range->start] == f_fss_eol) {
         has_graph = F_false;
         is_comment = F_false;
       }
@@ -754,18 +743,27 @@ extern "C" {
       }
 
       if (content.string[range->start] != f_fss_delimit_placeholder) {
-        destination->string[buffer_position.stop++] = content.string[range->start];
+        width = f_macro_utf_byte_width(content.string[range->start]);
+
+        status = private_fl_fss_destination_increase_by(width, destination);
+        if (F_status_is_error(status)) break;
+
+        for (i = 0; i < width; i++) {
+          destination->string[destination->used++] = content.string[range->start + i];
+        } // for
       }
 
       status = f_utf_buffer_increment(content, range, 1);
       if (F_status_is_error(status)) return status;
     } // while
 
-    destination->string[buffer_position.stop] = f_string_eol[0];
-    destination->used = buffer_position.stop + 1;
+    if (range->start > range->stop) {
+      return F_none_stop;
+    }
 
-    if (range->start > range->stop) return F_none_stop;
-    else if (range->start >= content.used) return F_none_eos;
+    if (range->start >= content.used) {
+      return F_none_eos;
+    }
 
     return F_none;
   }
index 95324eea312cb8c54f43c519cdf5438ea8a919a7..564831a4e2599e8cf72fe1a77915b949978cc702 100644 (file)
@@ -23,6 +23,20 @@ extern "C" {
   }
 #endif // _di_fss_basic_list_write_error_parameter_same_times_print_
 
+#ifndef _di_fss_basic_list_write_error_parameter_unsupported_eol_print_
+  void fss_basic_list_write_error_parameter_unsupported_eol_print(const fss_basic_list_write_data_t data) {
+
+    if (data.error.verbosity == f_console_verbosity_quiet) {
+      return;
+    }
+
+    fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+    fl_color_print(data.error.to.stream, data.context.set.error, "%sThis standard does not support end of line character '", fll_error_print_error);
+    fl_color_print(data.error.to.stream, data.context.set.notable, "\\n");
+    fl_color_print(data.error.to.stream, data.context.set.error, "' in objects.%c", f_string_eol[0]);
+  }
+#endif // _di_fss_basic_list_write_error_parameter_unsupported_eol_print_
+
 #ifndef _di_fss_basic_list_write_error_parameter_value_missing_print_
   void fss_basic_list_write_error_parameter_value_missing_print(const fss_basic_list_write_data_t data, const f_string_t symbol, const f_string_t parameter) {
 
@@ -55,6 +69,12 @@ extern "C" {
 
       status = fl_fss_basic_list_object_write(*object, content ? f_fss_complete_full : f_fss_complete_partial, &range, buffer);
 
+      if (F_status_set_fine(status) == F_none_eol) {
+        fss_basic_list_write_error_parameter_unsupported_eol_print(data);
+
+        return F_status_set_error(F_unsupported);
+      }
+
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_list_object_write", F_true);
         return status;
index bb18a92b961fc6de38af1d3f8089c10833c06ace..9a9a7eba5f35fb6fe68509a0ff5f93d96f228c0f 100644 (file)
@@ -27,6 +27,20 @@ extern "C" {
 #endif // _di_fss_basic_list_write_error_parameter_same_times_print_
 
 /**
+ * Print an message about a parameter EOL being unsupported.
+ *
+ * @param data
+ *   The program data.
+ *
+ * @return
+ *   F_none on success.
+ *   F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_fss_basic_list_write_error_parameter_unsupported_eol_print_
+  void fss_basic_list_write_error_parameter_unsupported_eol_print(const fss_basic_list_write_data_t data) f_gcc_attribute_visibility_internal;
+#endif // _di_fss_basic_list_write_error_parameter_unsupported_eol_print_
+
+/**
  * Print an message about a parameter missing a value.
  *
  * @param data