]> Kevux Git Server - fll/commitdiff
Update: rewrite fss extended content read function
authorKevin Day <kevin@kevux.org>
Sat, 24 Mar 2012 21:46:56 +0000 (16:46 -0500)
committerKevin Day <kevin@kevux.org>
Sat, 24 Mar 2012 21:46:56 +0000 (16:46 -0500)
This was rewritten to follow the same style that the object read uses.
Because content can have multiple "groups", an outer loop had to be added.
For some reason I feel like I am forgetting something or doing something wrong here, but I cannot tell what that is and so I note my concern here.

level_1/fl_fss/c/fss_extended.c

index 972f8e07cf1818b1e5500ec75119a2de85ca061b..ace09b2968b9afdc773f1871f73557059baeae81 100644 (file)
@@ -232,167 +232,255 @@ extern "C"{
       if (input->stop   < input->start) return f_invalid_parameter;
       if (buffer->used <= 0)            return f_invalid_parameter;
       if (input->start >= buffer->used) return f_invalid_parameter;
-      if (found->used   > found->size)  return f_invalid_parameter;
     #endif // _di_level_1_parameter_checking_
 
-    f_autochar      quoted   = f_eos;
-    f_string_length original = found->used;
+    fl_macro_fss_skip_past_whitespace((*buffer), (*input))
+    fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_error_on_eos, f_error_on_stop)
+
+    // return found nothing if this line only contains whitespace and delimit placeholders
+    if (buffer->string[input->start] == f_fss_extended_close) {
+      input->start++;
+      return fl_fss_found_no_content;
+    }
 
-    fl_macro_fss_allocate_content_if_necessary((*found))
-    found->array[found->used].start = input->start;
+    f_status   status      = f_status_initialize;
+    f_bool     has_delimit = f_false;
+    f_autochar quoted      = f_eos;
 
-    while (input->start <= input->stop) {
-      // get past all leading spaces/tabs (allowed)
-      fl_macro_fss_skip_past_whitespace((*buffer), (*input))
-      fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+    f_bool continue_main_loop = f_false;
 
-      if (buffer->string[input->start] == f_eol) {
-        break;
+    f_string_length location     = f_string_length_initialize;
+    f_array_length  already_used = found->used;
+
+    while (input->start <= input->stop && input->start < buffer->used) {
+      quoted = f_eos;
+
+      if (found->used >= found->size) {
+        f_resize_fss_content(status, (*found), found->size + f_fss_default_allocation_step);
+
+        if (f_macro_test_for_allocation_errors(status)) return status;
       }
 
-      fl_macro_fss_allocate_content_if_necessary((*found))
+      // begin the search
       found->array[found->used].start = input->start;
+      found->array[found->used].stop = 0;
 
-      // this inner loop should read until whitespace is found then mark the end of a specific content field
-      do {
-        fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-        fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+      // identify where the content begins
+      if (buffer->string[input->start] == f_fss_delimit_slash) {
+        f_string_length last_slash = input->start;
 
-        // handle delimited quotes, single quotes, and double quotes
-        if (buffer->string[input->start] == f_fss_delimit_slash) {
-          do {
-            f_string_length first_slash = input->start;
-            ++input->start;
+        input->start++;
 
-            fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-            fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+        while (input->start <= input->stop && input->start < buffer->used) {
+          if (buffer->string[input->start] == f_fss_delimit_placeholder) {
+            input->start++;
+            continue;
+          } else if (!isgraph(buffer->string[input->start])) {
+            found->array[found->used].stop = input->start - 1;
+            input->start++;
+            found->used++;
 
-            // A slash only delimits if a delimit quote would follow the slash (or a slash and a delimit quote follows)
-            if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
-              // because the slash properly delimited the quote, the quote then becomes the start of the content
-              found->array[found->used].start = input->start;
-              buffer->string[first_slash]     = f_fss_delimit_placeholder;
-              break;
-            } else if (buffer->string[input->start] == f_fss_delimit_slash) {
-              f_string_length second_slash = input->start;
-              ++input->start;
+            if (buffer->string[input->start] == f_eol) {
+              return fl_fss_found_content;
+            }
 
-              fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-              fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+            continue_main_loop = f_true;
+            break;
+          } else if (buffer->string[input->start] != f_fss_delimit_slash) {
+            break;
+          }
 
-              if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
-                buffer->string[first_slash] = f_fss_delimit_placeholder;
+          last_slash = input->start;
+          input->start++;
+        } // while
 
-                quoted = buffer->string[input->start];
-                input->start++;
+        if (continue_main_loop) {
+          continue_main_loop = f_false;
+          continue;
+        }
 
-                fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-                fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop)
+        fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
 
-                found->array[found->used].start = input->start;
-                break;
-              } else {
-                // return to the second slash, this way if there is a third or more, the quote test can be repeated
-                input->start = second_slash;
-                ++input->start;
-              }
-            } else {
-              break;
-            }
-          } while (f_true);
-        } else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
-          quoted = buffer->string[input->start];
+        if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
+          buffer->string[last_slash] = f_fss_delimit_placeholder;
+          input->start++;
+        }
+      } else if (buffer->string[input->start] == f_fss_delimit_single_quote || buffer->string[input->start] == f_fss_delimit_double_quote) {
+        quoted = buffer->string[input->start];
+        input->start++;
+        found->array[found->used].start = input->start;
+      }
+
+      // identify where the content ends
+      if (quoted == f_eos) {
+        while (isgraph(buffer->string[input->start]) || buffer->string[input->start] == f_fss_delimit_placeholder) {
           input->start++;
+          fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+        } // while
+
+        if (isspace(buffer->string[input->start])) {
+          found->array[found->used].stop = input->start - 1;
+          found->used++;
 
-          fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-          fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop)
+          if (buffer->string[input->start] == f_eol) {
+            input->start++;
+            return fl_fss_found_content;
+          }
 
-          found->array[found->used].start = input->start;
+          input->start++;
+          continue;
         }
+      } else {
+        while (input->start <= input->stop && input->start < buffer->used) {
+          if (buffer->string[input->start] == f_fss_delimit_slash) {
+            f_string_length first_slash = input->start;
+            f_string_length slash_count = 1;
+            input->start++;
 
-        // when quoted is null, then spaces will end the content, otherwise the quote defined in quoted will end the content (or a newline)
-        if (quoted == f_eos) {
-          do {
-            fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-            fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+            while (input->start <= input->stop && input->start < buffer->used) {
+              if (buffer->string[input->start] == f_fss_delimit_placeholder) {
+                input->start++;
+                continue;
+              } else if (buffer->string[input->start] != f_fss_delimit_slash) {
+                break;
+              }
 
-            if (buffer->string[input->start] == f_fss_extended_close) {
-              // Save the stop point
-              found->array[found->used].stop = input->start - 1;
-              found->used++;
+              slash_count++;
               input->start++;
-              return fl_fss_found_content;
-            }
+            } // while
 
-            if (isspace(buffer->string[input->start])) break;
+            fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop)
 
-            ++input->start;
-          } while (f_true);
-        } else {
-          do {
-            fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-            fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+            if (buffer->string[input->start] == quoted) {
+              location     = input->start;
+              input->start = first_slash;
 
-            if (buffer->string[input->start] == f_fss_extended_close) {
-              input->start++;
-              return f_unterminated_group;
-            }
+              if (slash_count % 2 == 0) {
+                while (slash_count > 0) {
+                  if (buffer->string[input->start] == f_fss_delimit_slash) {
+                    if (slash_count % 2 != 0) {
+                      buffer->string[input->start] = f_fss_delimit_placeholder;
+                    }
 
-            // handle delimited quotes
-            if (buffer->string[input->start] == f_fss_delimit_slash) {
-              f_string_length first_slash = input->start;
-              ++input->start;
+                    slash_count--;
+                  }
 
-              fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
-              fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+                  input->start++;
+                } // while
 
-              // A slash only delimits if a delimit quote would follow the slash (or a slash and a delimit quote follows)
-              if (buffer->string[input->start] == quoted) {
-                buffer->string[first_slash] = f_fss_delimit_placeholder;
-                ++input->start;
-                continue;
-              } else if (buffer->string[input->start] == f_fss_delimit_slash) {
-                f_string_length second_slash = input->start;
-                ++input->start;
+                input->start = location + 1;
 
                 fl_macro_fss_skip_past_delimit_placeholders((*buffer), (*input))
                 fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop)
 
-                if (buffer->string[input->start] == quoted) {
-                  buffer->string[first_slash] = f_fss_delimit_placeholder;
-                  quoted = f_eos;
-                  break;
-                } else {
-                  // return to the second slash, this way if there is a third or more, the quote test can be repeated
-                  input->start = second_slash;
-                  ++input->start;
-                  continue;
+                if (isgraph(buffer->string[input->start])) {
+                  while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
+                    input->start++;
+                  } // while
+
+                  input->start++;
+                  return f_unterminated_group;
+                } else if (buffer->string[input->start] == f_eol) {
+                  found->array[found->used].stop = input->start - 1;
+                  input->start++;
+                  found->used++;
+
+                  return fl_fss_found_content;
                 }
+
+                found->array[found->used].stop = input->start - 1;
+                input->start++;
+                found->used++;
+                continue;
+              } else {
+                while (slash_count > 0) {
+                  if (buffer->string[input->start] == f_fss_delimit_slash) {
+                    if (slash_count % 2 != 0) {
+                      buffer->string[input->start] = f_fss_delimit_placeholder;
+                    }
+
+                    slash_count--;
+                  }
+
+                  input->start++;
+                } // while
+
+                input->start = location;
+              }
+            }
+          } else if (buffer->string[input->start] == quoted) {
+            found->array[found->used].stop = input->start - 1;
+            input->start++;
+
+            while (input->start <= input->stop && input->start < buffer->used) {
+              if (buffer->string[input->start] == f_eol) {
+                input->start++;
+                found->used++;
+
+                return fl_fss_found_content;
+              } else if (isspace(buffer->string[input->start])) {
+                input->start++;
+                found->used++;
+                continue_main_loop = f_true;
+                break;
+              } else if (buffer->string[input->start] != f_fss_delimit_placeholder) {
+                while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
+                  input->start++;
+                } // while
+
+                input->start++;
+                return f_unterminated_group;
               }
-            } else if (buffer->string[input->start] == quoted) {
-              quoted = f_eos;
+
+              input->start++;
+            } // while
+
+            if (continue_main_loop) {
               break;
             }
 
-            ++input->start;
-          } while (f_true);
-        }
+            fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_unterminated_group_on_eos, f_unterminated_group_on_stop)
+          } else if (buffer->string[input->start] == f_eol) {
 
-        // Save the stop point
-        found->array[found->used].stop = input->start - 1;
-        found->used++;
-        break;
-      } while (f_true);
+            if (found->used == already_used) {
+              input->start++;
+              return fl_fss_found_no_content;
+            } else {
+              found->array[found->used].stop = input->start - 1;
+              input->start++;
+              found->used++;
+
+              return fl_fss_found_content;
+            }
+          }
+
+          input->start++;
+        } // while
+
+        fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+      }
+
+      if (continue_main_loop) {
+        continue_main_loop = f_false;
+        continue;
+      }
+
+      break;
+    } // while
 
-      ++input->start;
+    fl_macro_fss_content_return_on_overflow((*buffer), (*input), (*found), f_none_on_eos, f_none_on_stop)
+
+    // seek to the end of the line when no valid content is found
+    while (input->start < buffer->used && input->start <= input->stop && buffer->string[input->start] != f_eol) {
+      input->start++;
     }
 
-    // When original is the same as the current found->used, then there was no data found
-    if (original == found->used) {
+    if (found->used == already_used) {
       input->start++;
       return fl_fss_found_no_content;
     }
 
+    input->start++;
     return fl_fss_found_content;
   }
 #endif // _di_fl_fss_extended_content_read_