]> Kevux Git Server - fll/commitdiff
Progress: controller program.
authorKevin Day <thekevinday@gmail.com>
Thu, 19 Nov 2020 04:30:45 +0000 (22:30 -0600)
committerKevin Day <thekevinday@gmail.com>
Thu, 19 Nov 2020 05:15:57 +0000 (23:15 -0600)
Wrap up the current implementation of the rule read functions.

Utilize a (private) cache, reducing the parameters and reducing the amount of allocations.
How I am using the cache changed as I went and I need to come back and review it again before completing this program.

level_3/controller/c/controller.h
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/data/build/dependencies
level_3/controller/data/build/settings

index a45a7c8065815474c3bb7f143e7d3b6785686000..774e74611241969ef371a9ec29a65ff8d34e4f63 100644 (file)
 #include <level_0/console.h>
 #include <level_0/directory.h>
 #include <level_0/file.h>
+#include <level_0/fss.h>
 #include <level_0/pipe.h>
 #include <level_0/print.h>
 
 // fll-1 includes
 #include <level_1/color.h>
 #include <level_1/console.h>
+#include <level_1/fss.h>
 #include <level_1/string.h>
 
 // fll-2 includes
 #include <level_2/error.h>
+#include <level_2/fss.h>
+#include <level_2/fss_basic_list.h>
+#include <level_2/fss_extended.h>
+#include <level_2/fss_extended_list.h>
 #include <level_2/program.h>
 
 #ifdef __cplusplus
@@ -136,15 +142,14 @@ extern "C" {
       F_false, \
       f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
       fll_error_print_t_initialize, \
-      fll_macro_error_print_t_initialize_warning(f_console_verbosity_debug) \
+      fll_macro_error_print_t_initialize_warning(), \
       f_color_context_t_initialize, \
     }
 #endif // _di_controller_data_t_
 
 #ifndef _di_controller_rule_action_t_
   enum {
-    controller_rule_action_type_basic = 1,
-    controller_rule_action_type_extended,
+    controller_rule_action_type_extended = 1,
     controller_rule_action_type_extended_list,
   };
 
@@ -161,17 +166,17 @@ extern "C" {
 
   typedef struct {
     f_string_length_t line;
-    f_string_dynamic_t content;
+    f_string_dynamics_t parameters;
   } controller_rule_action_t;
 
   #define controller_rule_action_t_initialize \
     { \
       0, \
-      f_string_dynamic_t_initialize, \
+      f_string_dynamics_t_initialize, \
     }
 
   #define f_macro_controller_rule_action_t_delete_simple(action) \
-    f_macro_string_dynamic_t_delete_simple(action.content)
+    f_macro_string_dynamics_t_delete_simple(action.parameters)
 #endif // _di_controller_rule_action_t_
 
 #ifndef _di_controller_rule_actions_t_
index 828d2f231c2eb4ee7f333e369960d38f5b6195fe..19b5cc60813b22ba394c97d139312e0f2d2944ff 100644 (file)
 extern "C" {
 #endif
 
-#ifndef _di_controller_rule_actions_read_
-  f_return_status controller_rule_actions_read(const controller_data_t data, const bool multiple, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions) {
+#ifndef _di_controller_rule_action_read_
+  f_return_status controller_rule_action_read(const controller_data_t data, const f_string_static_t buffer, f_fss_object_t *object, f_fss_content_t *content, controller_rule_action_t *action) {
     f_status_t status = F_none;
 
-    f_fss_objects_t objects = f_fss_objects_t_initialize;
-    f_fss_contents_t contents = f_fss_contents_t_initialize;
+    if (object && object->start <= object->start) {
+      status = fl_string_dynamics_increase(&action->parameters);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true);
+        return status;
+      }
 
-    f_string_range_t range = cache->range_action;
+      action->parameters.array[0].used = 0;
 
-    if (multiple) {
-      // @todo
-      //fll_fss_extended_list_read();
-    }
-    else {
-      status = f_fss_seek_to_eol(*buffer, range);
+      status = fl_string_dynamic_partial_append_nulless(buffer, *object, &action->parameters.array[0]);
 
       if (F_status_is_error(status)) {
-        fll_error_print(data.error, F_status_set_fine(status), "f_fss_seek_to_eol", F_true);
-        controller_rule_error_print(data.error, *cache);
+        fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+        return status;
       }
 
-      range.stop = range.start;
-      range.start = cache->range_action.start;
+      action->parameters.used++;
+    }
+
+    if (content && content->used) {
+      for (f_array_length_t i = 0; i < content->used; ++i) {
+
+        if (content->array[i].start > content->array[i].start) continue;
 
-      // @fixme I just noticed an inconsistency in the naming, should it be quoted_objects and delimit_objects or instead objects_quoted, and objects_delimit?
-      // @fixme also, I think that the buffer in the fll_fss read functions no longer need to be pointers (it should be possible to make them constants now).
-      status = fll_fss_extended_read(buffer, &range, &objects, &contents, &quoted_objects, &quoted_contents, &delimit_objects, &delimit_contents);
-      // @todo
+        action->parameters.array[action->parameters.used].used = 0;
+
+        status = fl_string_dynamic_partial_append_nulless(buffer, content->array[i], &action->parameters.array[action->parameters.used]);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+          return status;
+        }
+
+        action->parameters.used++;
+      } // for
     }
 
-    if (!content.used) {
-      if (data.warning.verbosity == f_console_verbosity_debug) {
-        fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
+    return F_none;
+  }
+#endif // _di_controller_rule_action_read_
+
+#ifndef _di_controller_rule_actions_increase_by_
+  f_return_status controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) {
+    f_status_t status = F_none;
+    f_string_length_t size = actions->size + amount;
+
+    if (size > f_array_length_t_size) {
+      if (actions->size == f_array_length_t_size) {
+        return F_status_set_error(F_array_too_large);
+      }
+
+      size = actions->size;
+      status = F_array_too_large;
+    }
+
+    const f_status_t status_resize = f_memory_resize((void **) & actions->array, sizeof(controller_rule_actions_t), actions->size, size);
+    if (F_status_is_error(status_resize)) return status_resize;
 
-        if (actions) {
-          fprintf(data.warning.to.stream, "%s%sUnknown action, nothing to do.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
+    actions->size = size;
+    return status;
+  }
+#endif // _di_controller_rule_actions_increase_by_
+
+#ifndef _di_controller_rule_actions_read_
+  f_return_status controller_rule_actions_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) {
+    f_status_t status = F_none;
+
+    actions->used = 0;
+
+    // "script" types use the entire content and can be directly passed through.
+    if (item->type == controller_rule_item_type_script) {
+      status = controller_rule_actions_increase_by(1, actions);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true);
+      }
+      else {
+        actions->array[0].parameters.used = 0;
+
+        status = fl_string_dynamics_increase(&actions->array[0].parameters);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true);
         }
         else {
-          fprintf(data.warning.to.stream, "%s%sAction is empty, nothing to do.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
+          actions->array[0].line = cache->line_action;
+
+          status = fl_string_dynamic_partial_append_nulless(*buffer, cache->range_action, &actions->array[0].parameters.array[0]);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true);
+          }
         }
+      }
 
+      if (F_status_is_error(status)) {
         controller_rule_error_print(data.error, *cache);
       }
 
-      return F_data_not;
+      return status;
     }
 
-    action->type = type;
-    action->line = line;
-    action->content.used = 0;
+    if (actions->type == controller_rule_action_type_extended_list) {
+      cache->comments.used = 0;
+      cache->content.used = 0;
+      cache->contents.used = 0;
+      cache->delimits.used = 0;
+      cache->objects.used = 0;
 
-    // @todo now that the type and intent are known, the content may be loaded.
-    // @todo a "script" type uses basic and a "service" type uses extended because the script is passed to bash whereas the service is directly called.
-    // @todo additional line-by-line processing needs to be performed for multi-line services OR services should not support multiple lines.
-        /*
-        comments.used = 0;
-        status = fl_fss_extended_list_content_read(content, &range, &child_content, &delimits, &comments);
+      status = fl_fss_extended_list_content_read(*buffer, range, &cache->content, &cache->delimits, &cache->comments);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true);
+      }
+      else if (status == FL_fss_found_content) {
+        status = fll_fss_extended_read(*buffer, &cache->content.array[0], &cache->objects, &cache->contents, 0, 0, &cache->delimits, 0);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true, file_name.string, "process", fll_error_file_type_file);
-          controller_rule_error_print(data.error, *cache);
-          break;
+          fll_error_print(data.error, F_status_set_fine(status), "fll_fss_extended_read", F_true);
+        }
+        else {
+          f_array_length_t i = 0;
+          f_array_length_t j = 0;
+
+          for (; i < cache->objects.used; ++i) {
+
+            status = f_fss_count_lines(*buffer, cache->objects.array[i].start, &actions->array[actions->used].line);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
+              break;
+            }
+
+            actions->array[actions->used].line += item->line;
+            actions->array[actions->used].parameters.used = 0;
+
+            status = fl_string_dynamics_increase(&actions->array[actions->used].parameters);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true);
+              break;
+            }
+
+            status = controller_rule_action_read(data, *buffer, &cache->objects.array[i], &cache->contents.array[i], &actions->array[actions->used]);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true);
+            }
+
+            actions->used++;
+          } // for
         }
+      }
+      else {
+        status = F_data_not;
+      }
+    }
+    else {
+      cache->content.used = 0;
+      cache->delimits.used = 0;
+
+      status = fl_fss_extended_content_read(*buffer, range, &cache->content, 0, &cache->delimits);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fll_fss_extended_content_read", F_true);
+      }
+      else if (status == FL_fss_found_content) {
+        status = fl_fss_apply_delimit(cache->delimits, buffer);
 
-        if (status == FL_fss_found_content) {
-          type = controller_rule_item_type_multiple;
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
         }
-        */
-          /*
-          status = fl_fss_basic_content_read(content, &range, &child_content, &delimits);
+        else {
+          status = controller_rule_actions_increase_by(1, actions);
 
           if (F_status_is_error(status)) {
-            fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_basic_content_read", F_true, file_name.string, "process", fll_error_file_type_file);
-            controller_rule_error_print(data.error, *cache);
-            break;
+            fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true);
           }
+          else {
+            status = f_fss_count_lines(*buffer, range->start, &actions->array[0].line);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
+            }
+            else {
+              actions->array[0].line += item->line;
+              actions->array[0].parameters.used = 0;
+
+              status = controller_rule_action_read(data, *buffer, 0, &cache->content, &actions->array[0]);
+
+              if (F_status_is_error(status)) {
+                fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true);
+              }
+
+              actions->used = 1;
+            }
+          }
+        }
+      }
+      else {
+        status = F_data_not;
+      }
+    }
+
+    if (F_status_is_error(status)) {
+      controller_rule_error_print(data.error, *cache);
+    }
+    else if (status == F_data_not) {
+      if (data.warning.verbosity == f_console_verbosity_debug) {
+        fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
+        fprintf(data.warning.to.stream, "%s%sAction is empty, nothing to do.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
 
-          if (status == FL_fss_found_content) {
-            type = controller_rule_action_type_basic;
-          }*/
+        controller_rule_error_print(data.warning, *cache);
+      }
+    }
 
     return status;
   }
@@ -96,7 +236,7 @@ extern "C" {
     if (output.verbosity != f_console_verbosity_quiet) {
       fprintf(output.to.stream, "%s%sWhile processing ", output.context.before->string, output.prefix ? output.prefix : "");
 
-      if (cache.name_action) {
+      if (cache.name_action.used) {
         fprintf(output.to.stream, "action '");
         fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_action.string, output.notable.after->string);
         fprintf(output.to.stream, "%s' on line ", output.context.before->string);
@@ -104,7 +244,7 @@ extern "C" {
         fprintf(output.to.stream, "%s for ", output.context.before->string);
       }
 
-      if (cache.name_item) {
+      if (cache.name_item.used) {
         fprintf(output.to.stream, "item '");
         fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_item.string, output.notable.after->string);
         fprintf(output.to.stream, "%s' on line ", output.context.before->string);
@@ -124,27 +264,24 @@ extern "C" {
     f_status_t status = F_none;
 
     f_string_range_t range = f_macro_string_range_t_initialize(buffer->used);
-
-    f_fss_delimits_t delimits = f_fss_delimits_t_initialize;
-    f_fss_comments_t comments = f_fss_comments_t_initialize;
-    f_fss_quote_t quote = f_fss_quote_t_initialize;
+    f_fss_quote_t quote = 0;
 
     controller_rule_actions_t *actions = 0;
 
-    bool multiple = f_false;
+    bool multiple = F_false;
 
-    for (range.start = 0; range.start < buffer->used && range.start <= range.stop; delimits.used = 0, comments.used = 0) {
+    for (range.start = 0; range.start < buffer->used && range.start <= range.stop; cache->delimits.used = 0, cache->comments.used = 0) {
 
-      status = fl_fss_extended_list_object_read(buffer, &range, &cache->range_action, &delimits);
+      status = fl_fss_extended_list_object_read(*buffer, &range, &cache->range_action, &cache->delimits);
 
       if (F_status_is_error(status)) {
-        fll_error_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true);
+        fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true);
         break;
       }
 
       if (range.start >= range.stop || range.start >= buffer->used) {
         if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) {
-          if (error.verbosity != f_console_verbosity_quiet) {
+          if (data.error.verbosity != f_console_verbosity_quiet) {
             fprintf(data.error.to.stream, "%c", f_string_eol[0]);
             fprintf(data.error.to.stream, "%s%sUnterminated FSS Extended List at end of rule file.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]);
           }
@@ -159,13 +296,14 @@ extern "C" {
         multiple = F_true;
       }
       else {
-        multiple = f_false;
+        multiple = F_false;
+        cache->delimits.used = 0;
 
         // The current line is not an Extended List object, so the next possibility is a Basic List (and Extended List, both use the same Object structure).
-        status = fl_fss_basic_object_read(buffer, &range, &cache->range_action, &quote, &delimits);
+        status = fl_fss_basic_object_read(*buffer, &range, &cache->range_action, &quote, &cache->delimits);
 
         if (F_status_is_error(status)) {
-          fll_error_print(data->error, F_status_set_fine(status), "fl_fss_basic_object_read", F_true);
+          fll_error_print(data.error, F_status_set_fine(status), "fl_fss_basic_object_read", F_true);
           break;
         }
       }
@@ -176,14 +314,14 @@ extern "C" {
       }
 
       if (status == FL_fss_found_object) {
-        status = fl_fss_apply_delimit(delimits, &data_make->buffer);
+        status = fl_fss_apply_delimit(cache->delimits, buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
+          fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
           break;
         }
 
-        status = f_fss_count_lines(buffer, cache->range_action.start, &cache->line_action);
+        status = f_fss_count_lines(*buffer, cache->range_action.start, &cache->line_action);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
@@ -191,16 +329,16 @@ extern "C" {
         }
 
         cache->line_action += item->line;
+        cache->name_action.used = 0;
 
-        action_name->used = 0;
-        status = fl_string_dynamic_rip_nulless(buffer, cache->range_action, action_name);
+        status = fl_string_dynamic_rip_nulless(*buffer, cache->range_action, &cache->name_action);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true);
           break;
         }
 
-        status = fl_string_dynamic_terminate_after(action_name);
+        status = fl_string_dynamic_terminate_after(&cache->name_action);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
@@ -209,35 +347,35 @@ extern "C" {
 
         actions = 0;
 
-        if (fl_string_dynamic_compare_string(controller_string_create, *action_name, controller_string_create_length) == f_equal_to) {
+        if (fl_string_dynamic_compare_string(controller_string_create, cache->name_action, controller_string_create_length) == F_equal_to) {
           actions = &item->create;
           actions->intent = controller_rule_action_intent_create;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_group, *action_name, controller_string_group_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_group, cache->name_action, controller_string_group_length) == F_equal_to) {
           actions = &item->group;
           actions->intent = controller_rule_action_intent_group;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_restart, *action_name, controller_string_restart_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_restart, cache->name_action, controller_string_restart_length) == F_equal_to) {
           actions = &item->restart;
           actions->intent = controller_rule_action_intent_restart;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_reload, *action_name, controller_string_reload_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_reload, cache->name_action, controller_string_reload_length) == F_equal_to) {
           actions = &item->reload;
           actions->intent = controller_rule_action_intent_reload;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_start, *action_name, controller_string_start_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_start, cache->name_action, controller_string_start_length) == F_equal_to) {
           actions = &item->start;
           actions->intent = controller_rule_action_intent_start;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_stop, *action_name, controller_string_stop_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_stop, cache->name_action, controller_string_stop_length) == F_equal_to) {
           actions = &item->stop;
           actions->intent = controller_rule_action_intent_stop;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_use, *action_name, controller_string_use_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_use, cache->name_action, controller_string_use_length) == F_equal_to) {
           actions = &item->use;
           actions->intent = controller_rule_action_intent_use;
         }
-        else if (fl_string_dynamic_compare_string(controller_string_user, *action_name, controller_string_user_length) == f_equal_to) {
+        else if (fl_string_dynamic_compare_string(controller_string_user, cache->name_action, controller_string_user_length) == F_equal_to) {
           actions = &item->user;
           actions->intent = controller_rule_action_intent_user;
         }
@@ -254,7 +392,7 @@ extern "C" {
 
         if (multiple) {
           if (actions->intent == controller_rule_action_intent_create || actions->intent == controller_rule_action_intent_group || actions->intent == controller_rule_action_intent_use || actions->intent == controller_rule_action_intent_user) {
-            if (error.verbosity != f_console_verbosity_quiet) {
+            if (data.error.verbosity != f_console_verbosity_quiet) {
               fprintf(data.error.to.stream, "%c", f_string_eol[0]);
               fprintf(data.error.to.stream, "%s%sFSS Extended List is not allowed for this item action type.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]);
             }
@@ -262,16 +400,18 @@ extern "C" {
             status = F_status_set_error(F_unsupported);
             break;
           }
+
+          actions->type = controller_rule_action_type_extended_list;
+        }
+        else {
+          actions->type = controller_rule_action_type_extended;
         }
 
-        status = controller_rule_actions_read(data, multiple, buffer, cache, item, actions);
+        status = controller_rule_actions_read(data, buffer, cache, item, actions, &range);
         if (F_status_is_error(status)) break;
       }
     } // for
 
-    f_macro_fss_delimits_t_delete_simple(delimits);
-    f_macro_fss_comments_t_delete_simple(comments);
-
     if (F_status_is_error(status)) {
       controller_rule_error_print(data.error, *cache);
     }
@@ -294,10 +434,10 @@ extern "C" {
       status = F_array_too_large;
     }
 
-    const f_status_t status_resize = f_memory_resize((void **) & items.array, sizeof(controller_rule_items_t), items.size, size);
+    const f_status_t status_resize = f_memory_resize((void **) & items->array, sizeof(controller_rule_items_t), items->size, size);
     if (F_status_is_error(status_resize)) return status_resize;
 
-    items.size = size;
+    items->size = size;
     return status;
   }
 #endif // _di_controller_rule_items_increase_by_
@@ -312,16 +452,16 @@ extern "C" {
     {
       f_file_t file = f_file_t_initialize;
 
-      status = f_file_stream_open(arguments.argv[data->remaining.array[i]], 0, &file);
+      status = f_file_stream_open(cache->name_file.string, 0, &file);
 
       if (F_status_is_error(status)) {
-        fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_open", F_true, cache->name_file.string, "open", fll_error_file_type_file);
+        fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_open", F_true, cache->name_file.string, "open", fll_error_file_type_file);
       }
       else {
         status = f_file_stream_read(file, 1, &buffer);
 
         if (F_status_is_error(status)) {
-          fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_read", F_true, cache->name_file.string, "read", fll_error_file_type_file);
+          fll_error_file_print(data.error, F_status_set_fine(status), "f_file_stream_read", F_true, cache->name_file.string, "read", fll_error_file_type_file);
         }
       }
 
@@ -333,29 +473,28 @@ extern "C" {
       }
     }
 
+    // @todo add these to the cache without conflicting with the actions use of objects and contents.
     f_fss_objects_t objects = f_fss_objects_t_initialize;
     f_fss_contents_t contents = f_fss_contents_t_initialize;
 
     if (buffer.used) {
       f_string_range_t range = f_macro_string_range_t_initialize(buffer.used);
-      f_fss_delimits_t delimits = f_fss_delimits_t_initialize;
-      f_fss_comments_t comments = f_fss_comments_t_initialize;
 
-      status = fll_fss_basic_list_read(&data_make->buffer, &range, &objects, &contents, &delimits, 0, &comments);
+      cache->delimits.used = 0;
+      cache->comments.used = 0;
+
+      status = fll_fss_basic_list_read(buffer, &range, &objects, &contents, &cache->delimits, 0, &cache->comments);
 
       if (F_status_is_error(status)) {
-        fake_print_error_fss(data, status, "fll_fss_basic_list_read", data.file_data_build_fakefile.string, range, F_true);
+        fll_error_print(data.error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true);
       }
       else {
-        status = fl_fss_apply_delimit(delimits, &data_make->buffer);
+        status = fl_fss_apply_delimit(cache->delimits, &buffer);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
         }
       }
-
-      f_macro_fss_delimits_t_delete_simple(delimits);
-      f_macro_fss_comments_t_delete_simple(comments);
     }
 
     if (F_status_is_error_not(status) && objects.used) {
@@ -369,15 +508,22 @@ extern "C" {
 
         for (f_array_length_t i = 0; i < objects.used; ++i) {
 
-          cache->name_file.used = 0;
-          cache->name_item.used = 0;
-          cache->name_action.used = 0;
-
           cache->line_item = 0;
           cache->line_action = 0;
 
           cache->range_item = objects.array[i];
-          cache->range_action = 0;
+          cache->range_action.start = 1;
+          cache->range_action.stop = 0;
+
+          cache->comments.used = 0;
+          cache->content.used = 0;
+          cache->contents.used = 0;
+          cache->delimits.used = 0;
+          cache->objects.used = 0;
+
+          cache->name_file.used = 0;
+          cache->name_item.used = 0;
+          cache->name_action.used = 0;
 
           status = f_fss_count_lines(buffer, cache->range_item.start, &cache->line_item);
 
@@ -410,20 +556,20 @@ extern "C" {
             break;
           }
 
-          if (fl_string_dynamic_compare_string(controller_string_settings, cache->name_item, controller_string_settings_length) == f_equal_to) {
+          if (fl_string_dynamic_compare_string(controller_string_settings, cache->name_item, controller_string_settings_length) == F_equal_to) {
             items->array[items->used].type = 0;
           }
-          else if (fl_string_dynamic_compare_string(controller_string_command, cache->name_item, controller_string_command_length) == f_equal_to) {
+          else if (fl_string_dynamic_compare_string(controller_string_command, cache->name_item, controller_string_command_length) == F_equal_to) {
             items->array[items->used].type = controller_rule_item_type_command;
           }
-          else if (fl_string_dynamic_compare_string(controller_string_script, cache->name_item, controller_string_script_length) == f_equal_to) {
+          else if (fl_string_dynamic_compare_string(controller_string_script, cache->name_item, controller_string_script_length) == F_equal_to) {
             items->array[items->used].type = controller_rule_item_type_script;
           }
-          else if (fl_string_dynamic_compare_string(controller_string_service, cache->name_item, controller_string_service_length) == f_equal_to) {
+          else if (fl_string_dynamic_compare_string(controller_string_service, cache->name_item, controller_string_service_length) == F_equal_to) {
             items->array[items->used].type = controller_rule_item_type_service;
           }
           else {
-            if (warning.verbosity == f_console_verbosity_debug) {
+            if (data.warning.verbosity == f_console_verbosity_debug) {
               fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
               fprintf(data.warning.to.stream, "%s%sUnknown item type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
 
@@ -452,6 +598,10 @@ extern "C" {
     f_macro_fss_contents_t_delete_simple(contents);
     f_macro_string_dynamic_t_delete_simple(buffer);
 
+    if (F_status_is_error(status)) {
+      controller_rule_error_print(data.error, *cache);
+    }
+
     return status;
   }
 #endif // _di_controller_rule_read_
index 8783f2c55ccdc8afc80cfd96ab2d4ff831f482fa..6b269213ffcde6d97965c9509d31d599c348ada0 100644 (file)
@@ -20,9 +20,15 @@ extern "C" {
     f_string_range_t range_item;
     f_string_range_t range_action;
 
+    f_fss_comments_t comments;
+    f_fss_content_t content;
+    f_fss_contents_t contents;
+    f_fss_delimits_t delimits;
+    f_fss_objects_t objects;
+
     f_string_dynamic_t name_file;
     f_string_dynamic_t name_item;
-    f_string_dynamic_t name_action
+    f_string_dynamic_t name_action;
   } controller_rule_cache_t;
 
   #define controller_rule_cache_t_initialize \
@@ -31,25 +37,85 @@ extern "C" {
       0, \
       0, \
       0, \
+      f_fss_delimits_t_initialize, \
+      f_fss_content_t_initialize, \
+      f_fss_contents_t_initialize, \
+      f_fss_comments_t_initialize, \
+      f_fss_objects_t_initialize, \
       f_string_dynamic_t_initialize, \
       f_string_dynamic_t_initialize, \
       f_string_dynamic_t_initialize, \
     }
 
   #define f_macro_controller_rule_name_t_delete_simple(cache) \
-    f_string_dynamic_t_delete_simple(cache.name_file) \
-    f_string_dynamic_t_delete_simple(cache.name_item) \
-    f_string_dynamic_t_delete_simple(cache.name_action)
+    f_macro_fss_comments_t_delete_simple(cache.comments) \
+    f_macro_fss_content_t_delete_simple(cache.content) \
+    f_macro_fss_contents_t_delete_simple(cache.contents) \
+    f_macro_fss_delimits_t_delete_simple(cache.delimits) \
+    f_macro_fss_objects_t_delete_simple(cache.objects) \
+    f_macro_string_dynamic_t_delete_simple(cache.name_file) \
+    f_macro_string_dynamic_t_delete_simple(cache.name_item) \
+    f_macro_string_dynamic_t_delete_simple(cache.name_action)
 #endif // _di_controller_rule_cache_t_
 
 /**
+ * Read the rule action.
+ *
+ * The object and content ranges are merged together (in that order) as the action parameters.
+ *
+ * @param data
+ *   The program data.
+ * @param buffer
+ *   The buffer containing the content.
+ * @param object
+ *   (optional) The range representing where the object is found within the buffer.
+ *   Set pointer address to 0 to disable.
+ * @param content
+ *   (optional) The ranges representing where the content is found within the buffer.
+ *   Set pointer address to 0 to disable.
+ * @param action
+ *   The processed action.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_fss_count_lines().
+ *   Errors (with error bit) from: fl_string_dynamic_partial_append_nulless().
+ *   Errors (with error bit) from: fl_string_dynamics_increase().
+ *
+ * @see f_fss_count_lines()
+ * @see fl_string_dynamic_partial_append_nulless()
+ * @see fl_string_dynamics_increase()
+ */
+#ifndef _di_controller_rule_action_read_
+  extern f_return_status controller_rule_action_read(const controller_data_t data, const f_string_static_t buffer, f_fss_object_t *object, f_fss_content_t *content, controller_rule_action_t *action) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_action_read_
+
+/**
+ * Increase the size of the rule actions array by the specified amount, but only if necessary.
+ *
+ * This only increases size if the current used plus amount is greater than the currently allocated size.
+ *
+ * @param amount
+ *   A positive number representing how much to increase the size by.
+ * @param actions
+ *   The actions to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_array_too_large on success, but requested size is too small (resize is smaller than requested length).
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_controller_rule_actions_increase_by_
+  extern f_return_status controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_actions_increase_by_
+
+/**
  * Read the content within the buffer, extracting all valid actions for the current processed item.
  *
  * @param data
  *   The program data.
- * @param multiple
- *   If TRUE, then the Object expects multiple lines of Content (which ends up being an extended list).
- *   If FALSE, then the Object expects only a single line of Content (which is either basic or extended).
  * @param buffer
  *   The buffer containing the content.
  * @param cache
@@ -58,15 +124,23 @@ extern "C" {
  *   The processed item.
  * @param actions
  *   The processed actions.
+ * @param range
+ *   The current positions within the buffer being operated on.
+ *   This is expected to be set to a position immediately after a valid object read.
  *
  * @return
  *   F_none on success.
- *   @todo add response codes.
  *
+ *   Errors (with error bit) from: controller_rule_action_read().
+ *   Errors (with error bit) from: controller_rule_actions_increase_by().
  *   Errors (with error bit) from: f_fss_count_lines().
+ *
+ * @see controller_rule_action_read()
+ * @see controller_rule_actions_increase_by()
+ * @see f_fss_count_lines()
  */
 #ifndef _di_controller_rule_actions_read_
-  f_return_status controller_rule_actions_read(const controller_data_t data, const bool multiple, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions) f_gcc_attribute_visibility_internal;
+  extern f_return_status controller_rule_actions_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_actions_read_
 
 /**
@@ -109,6 +183,9 @@ extern "C" {
  *   Errors (with error bit) from: fl_string_dynamic_terminate_after().
  *
  * @see controller_rule_actions_read()
+ * @see f_fss_count_lines()
+ * @see fl_string_dynamic_partial_append_nulless()
+ * @see fl_string_dynamic_terminate_after()
  */
 #ifndef _di_controller_rule_item_read_
   extern f_return_status controller_rule_item_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item) f_gcc_attribute_visibility_internal;
@@ -129,6 +206,8 @@ extern "C" {
  *   F_array_too_large on success, but requested size is too small (resize is smaller than requested length).
  *
  *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
  */
 #ifndef _di_controller_rule_items_increase_by_
   extern f_return_status controller_rule_items_increase_by(const f_array_length_t amount, controller_rule_items_t *items) f_gcc_attribute_visibility_internal;
@@ -158,7 +237,16 @@ extern "C" {
  *   Errors (with error bit) from: fl_string_dynamic_terminate_after().
  *   Errors (with error bit) from: fll_fss_basic_list_read().
  *
- * @see controller_rule_item_read()
+ * @see controller_rule_items_increase_by().
+ * @see controller_rule_item_read().
+ * @see f_file_stream_open().
+ * @see f_file_stream_read().
+ * @see f_fss_count_lines().
+ * @see fl_fss_apply_delimit().
+ * @see fl_string_dynamic_partial_append().
+ * @see fl_string_dynamic_partial_append_nulless().
+ * @see fl_string_dynamic_terminate_after().
+ * @see fll_fss_basic_list_read().
  */
 #ifndef _di_controller_rule_read_
   extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) f_gcc_attribute_visibility_internal;
index 3b53a6c7f25e2bde063c201eccd5127f9e8bbbf5..977a55ca1361fddb8b4ce7f2d908f8632c783d0b 100644 (file)
@@ -8,11 +8,14 @@ f_utf
 f_color
 f_console
 f_file
+f_fss
 f_pipe
 f_print
 fl_color
 fl_console
+fl_fss
 fl_string
 fll_error
+fll_fss
 fll_program
 fll_status
index 0e4ddb8d498de3bd2adb54de6cf1f3a62d76f3fe..218975b5a2d8337d202acf7e80c37064c64bf3d8 100644 (file)
@@ -19,7 +19,7 @@ build_compiler gcc
 build_indexer ar
 build_language c
 build_libraries -lc
-build_libraries-individual -lfll_error -lfll_program -lfll_status -lfl_color -lfl_console -lfl_status -lfl_string -lf_console -lf_conversion -lf_file -lf_memory -lf_pipe -lf_print -lf_utf
+build_libraries-individual -lfll_error -lfll_fss -lfll_program -lfll_status -lfl_color -lfl_console -lfl_conversion -lfl_fss -lfl_status -lfl_string -lf_console -lf_conversion -lf_file -lf_fss -lf_memory -lf_pipe -lf_print -lf_utf
 build_libraries-level -lfll_2 -lfll_1 -lfll_0
 build_libraries-monolithic -lfll
 build_sources_library controller.c private-controller.c private-entry.c private-rule.c