]> Kevux Git Server - fll/commitdiff
Bugfix: iki didn't handle all cases
authorKevin Day <thekevinday@gmail.com>
Tue, 23 Jun 2020 02:25:27 +0000 (21:25 -0500)
committerKevin Day <thekevinday@gmail.com>
Tue, 23 Jun 2020 02:25:27 +0000 (21:25 -0500)
I forgot to review the delimit cases and when I did I found the implementation a bit sloppy.
I also found some ways to improve the code.

The content slash total should start at 0 and not 1 because it increments it later on.

The fl_ik_read() needs to check the range.

level_0/f_iki/c/iki-common.h
level_0/f_iki/c/iki.c
level_1/fl_iki/c/iki.c

index 67000ff2e930aa9f2c78dcda541dec3bec51e15e..fc65b614002f5dc633ba3440d3383533f5cc41ac 100644 (file)
@@ -256,39 +256,33 @@ extern "C" {
       width_max = buffer->used - range->start; \
     }
 #endif // _di_f_macro_iki_determine_width_max_
+
 /**
- * Seek until whitespace is found.
+ * Seek until whitespace is found or not found.
  *
- * status: The return status to use.
- * buffer: (A pointer) The buffer to seek through.
- * range:  (A pointer) The range within that buffer to seek through.
+ * This will ignore the delimit placeholder.
+ *
+ * status:    The return status to use.
+ * buffer:    (A pointer) The buffer to seek through.
+ * range:     (A pointer) The range within that buffer to seek through.
+ * condition: Set to TRUE to seek until whitespace is found and FALSE to seek until non-whitespace.
  */
 #ifndef _di_f_macro_iki_seek_whitespace_
-  #define f_macro_iki_seek_whitespace(status, buffer, range, width_max) \
+  #define f_macro_iki_seek_whitespace(status, buffer, range, width_max, condition) \
     while (range->start <= range->stop && range->start < buffer->used) { \
+      if (buffer->string[range->start] == f_iki_syntax_placeholder) { \
+        range->start++; \
+        continue; \
+      } \
       f_macro_iki_determine_width_max(buffer, range, width_max); \
       status = f_utf_is_whitespace(buffer->string + range->start, width_max); \
-      if (status == F_true) break; \
+      if (status == condition) break; \
       else if (F_status_is_error(status)) break; \
       status = f_utf_buffer_increment(*buffer, range, 1); \
       if (F_status_is_error(status)) break; \
     }
 #endif // _di_f_macro_iki_seek_whitespace_
 
-/**
- * Skip past all delimit placeholders.
- *
- * status: The return status to use.
- * buffer: (A pointer) The buffer to skip through.
- * range:  (A pointer) The range within that buffer to skip through.
- */
-#ifndef _di_f_macro_iki_skip_past_delimit_placeholders_
-  #define f_macro_iki_skip_past_delimit_placeholders(status, buffer, range) \
-    do { \
-      status = f_utf_buffer_increment(*buffer, range, 1); \
-    } while (F_status_is_fine(status) && buffer->string[range->start] == f_iki_syntax_placeholder);
-#endif // _di_f_macro_iki_skip_past_delimit_placeholders_
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 0c5c7667d2af42766b3a919a22e631a35da6f31e..15330316d702bfa69001f86c806e62cdd72eff7f 100644 (file)
@@ -27,17 +27,22 @@ extern "C" {
 
     // skip past all initial non-word, non-dash, and non-plus.
     while (range->start <= range->stop && range->start < buffer->used) {
+      if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+        range->start++;
+        continue;
+      }
+
+      f_macro_iki_determine_width_max(buffer, range, width_max);
 
-      if (buffer->string[range->start] != f_iki_syntax_placeholder) {
-        f_macro_iki_determine_width_max(buffer, range, width_max);
+      status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+      if (F_status_is_error(status)) return status;
 
-        status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
-        if (F_status_is_error(status)) return status;
+      if (status == F_true) break;
 
-        if (status == F_true) break;
-      }
+      f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true);
+      if (F_status_is_error(status)) return status;
 
-      status = f_utf_buffer_increment(*buffer, range, 1);
+      f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_false);
       if (F_status_is_error(status)) return status;
     } // while
 
@@ -58,6 +63,7 @@ extern "C" {
     uint8_t quote = 0;
 
     bool vocabulary_delimited = F_false;
+    bool find_next = F_false;
 
     // delimits must only be applied once a valid object is found.
     f_string_lengths delimits = f_string_lengths_initialize;
@@ -84,7 +90,10 @@ extern "C" {
           vocabulary_delimited = F_false;
           found_vocabulary.stop = range->start - 1;
 
-          f_macro_iki_skip_past_delimit_placeholders(status, buffer, range);
+          do {
+            status = f_utf_buffer_increment(*buffer, range, 1);
+          } while (F_status_is_fine(status) && buffer->string[range->start] == f_iki_syntax_placeholder);
+
           if (F_status_is_error(status)) {
             f_macro_string_lengths_delete(status, delimits);
             return status;
@@ -98,7 +107,7 @@ extern "C" {
           }
 
           // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
-          f_macro_iki_seek_whitespace(status, buffer, range, width_max);
+          f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true);
           if (F_status_is_error(status)) {
             f_macro_string_lengths_delete(status, delimits);
             return status;
@@ -113,6 +122,7 @@ extern "C" {
 
           // the slash only needs to be delimited if it were to otherwise be a valid vocabulary name.
           while (range->start <= range->stop && range->start < buffer->used) {
+
             if (buffer->string[range->start] == f_iki_syntax_placeholder) {
               range->start++;
               continue;
@@ -127,31 +137,15 @@ extern "C" {
                 break;
               }
               else {
-                range->start = vocabulary_slash_first;
-
-                // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
-                f_macro_iki_seek_whitespace(status, buffer, range, width_max);
-                if (F_status_is_error(status)) {
-                  f_macro_string_lengths_delete(status, delimits);
-                  return status;
-                }
-
+                find_next = F_true;
                 break;
               }
             }
             else if (buffer->string[range->start] == f_iki_syntax_separator) {
               separator_found = F_true;
             }
-            else {
-              range->start = vocabulary_slash_first;
-
-              // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
-              f_macro_iki_seek_whitespace(status, buffer, range, width_max);
-              if (F_status_is_error(status)) {
-                f_macro_string_lengths_delete(status, delimits);
-                return status;
-              }
-
+            else if (buffer->string[range->start] != f_iki_syntax_slash) {
+              find_next = F_true;
               break;
             }
 
@@ -161,6 +155,8 @@ extern "C" {
               return status;
             }
           } // while
+
+          break;
         }
         else {
           f_macro_iki_determine_width_max(buffer, range, width_max);
@@ -178,6 +174,7 @@ extern "C" {
               return status;
             }
 
+            find_next = F_true;
             break;
           }
         }
@@ -200,6 +197,7 @@ extern "C" {
           }
 
           if (buffer->string[range->start] == quote) {
+
             // this is a valid vocabulary name and content, but if it is delimited, save the delimit and ignore.
             if (vocabulary_delimited) {
               f_macro_iki_allocate_delimits_if_necessary(status, delimits);
@@ -211,36 +209,12 @@ extern "C" {
               delimits.array[delimits.used] = vocabulary_slash_first;
               delimits.used++;
 
+              find_next = F_true;
               vocabulary_delimited = F_false;
               quote = 0;
 
               range->start++;
-
-              // skip past all initial non-word, non-dash, and non-plus.
-              while (range->start <= range->stop && range->start < buffer->used) {
-                if (buffer->string[range->start] == f_iki_syntax_placeholder) {
-                  range->start++;
-                  continue;
-                }
-
-                f_macro_iki_determine_width_max(buffer, range, width_max);
-
-                status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
-                if (F_status_is_error(status)) {
-                  f_macro_string_lengths_delete(status, delimits);
-                  return status;
-                }
-
-                if (status == F_true) break;
-
-                status = f_utf_buffer_increment(*buffer, range, 1);
-                if (F_status_is_error(status)) {
-                  f_macro_string_lengths_delete(status, delimits);
-                  return status;
-                }
-              } // while
-
-              found_vocabulary.start = range->start;
+              break;
             }
             else {
               f_macro_iki_allocate_ranges_if_necessary(status, (*variable));
@@ -292,7 +266,7 @@ extern "C" {
           }
           else if (buffer->string[range->start] == f_iki_syntax_slash) {
             f_string_length content_slash_first = range->start;
-            f_array_length content_slash_total = 1;
+            f_array_length content_slash_total = 0;
 
             while (range->start <= range->stop && range->start < buffer->used) {
               if (buffer->string[range->start] == f_iki_syntax_placeholder) {
@@ -387,18 +361,25 @@ extern "C" {
                     found_vocabulary.start = range->start;
                   }
                   else {
-                    f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary));
-                    if (F_status_is_error(status)) {
-                      f_macro_string_lengths_delete(status, delimits);
-                      return status;
+                    f_macro_iki_allocate_ranges_if_necessary(status, (*variable));
+
+                    if (F_status_is_fine(status)) {
+                      f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary));
+                    }
+
+                    if (F_status_is_fine(status)) {
+                      f_macro_iki_allocate_ranges_if_necessary(status, (*content));
                     }
 
-                    f_macro_iki_allocate_ranges_if_necessary(status, (*content));
                     if (F_status_is_error(status)) {
                       f_macro_string_lengths_delete(status, delimits);
                       return status;
                     }
 
+                    variable->array[variable->used].start = found_vocabulary.start;
+                    variable->array[variable->used].stop = range->start;
+                    variable->used++;
+
                     vocabulary->array[vocabulary->used].start = found_vocabulary.start;
                     vocabulary->array[vocabulary->used].stop = found_vocabulary.stop;
                     vocabulary->used++;
@@ -431,7 +412,6 @@ extern "C" {
                 break;
               }
               else if (buffer->string[range->start] != f_iki_syntax_slash) {
-                range->start++;
                 break;
               }
 
@@ -453,13 +433,31 @@ extern "C" {
         } // while
       }
       else {
+
+        status = f_utf_buffer_increment(*buffer, range, 1);
+        if (F_status_is_error(status)) {
+          f_macro_string_lengths_delete(status, delimits);
+          return status;
+        }
+
         vocabulary_delimited = F_false;
+        find_next = F_true;
+      }
+
+      if (find_next) {
 
-        // skip past all initial non-word, non-dash, and non-plus.
         while (range->start <= range->stop && range->start < buffer->used) {
-          if (buffer->string[range->start] == f_iki_syntax_placeholder) {
-            range->start++;
-            continue;
+
+          f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_true);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+
+          f_macro_iki_seek_whitespace(status, buffer, range, width_max, F_false);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
           }
 
           f_macro_iki_determine_width_max(buffer, range, width_max);
@@ -480,6 +478,7 @@ extern "C" {
         } // while
 
         found_vocabulary.start = range->start;
+        find_next = F_false;
       }
     } while (range->start <= range->stop && range->start < buffer->used);
 
index c9c4ea4fc919dddd6d805c2e011ce70951ff7f5e..506acf8b785a186b81bcde4cc8de0ed5ea35716e 100644 (file)
@@ -8,7 +8,7 @@ extern "C" {
   f_return_status fl_iki_read(f_string_static *buffer, f_string_range *range, f_iki_variable *variable, f_iki_vocabulary *vocabulary, f_iki_content *content) {
     f_status status = F_none;
 
-    for (;;) {
+    do {
       status = f_iki_read(buffer, range, variable, vocabulary, content);
       if (F_status_is_error(status)) return status;
 
@@ -19,7 +19,7 @@ extern "C" {
       if (status == F_none_eos || status == F_none_stop) {
         return status;
       }
-    } // for
+    } while (range->start <= range->stop && range->start < buffer->used);
 
     return F_none;
   }