]> Kevux Git Server - fll/commitdiff
Progress: controller program.
authorKevin Day <thekevinday@gmail.com>
Fri, 20 Nov 2020 04:15:16 +0000 (22:15 -0600)
committerKevin Day <thekevinday@gmail.com>
Fri, 20 Nov 2020 04:15:16 +0000 (22:15 -0600)
Update cache usage.
Begin working on the rule settings, adding missing information and documentation.

Combine the rule items and rule settings into a single rule structure.

level_3/controller/c/controller.h
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/documents/rule.txt
level_3/controller/specifications/rule.txt

index 774e74611241969ef371a9ec29a65ff8d34e4f63..62994753ae756ce902142c741887d036116052d1 100644 (file)
@@ -287,29 +287,49 @@ extern "C" {
     }
 #endif // _di_controller_rule_items_t_
 
-#ifndef _di_controller_rule_setting_t_
+#ifndef _di_controller_rule_t_
   typedef struct {
+    f_status_t status;
+
+    f_string_dynamic_t id;
     f_string_dynamic_t name;
     f_string_dynamic_t pid;
 
-    f_string_dynamics_t defines; // @todo this probably should a list of name and value pairs.
+    f_string_maps_t defines;
+
     f_string_dynamics_t environment;
-  } controller_rule_setting_t;
+    f_string_dynamics_t need;
+    f_string_dynamics_t want;
+    f_string_dynamics_t wish;
+
+    controller_rule_items_t items;
+  } controller_rule_t;
 
-  #define controller_rule_setting_t_initialize \
+  #define controller_rule_t_initialize \
     { \
+      F_unknown, \
       f_string_dynamic_t_initialize, \
       f_string_dynamic_t_initialize, \
+      f_string_dynamic_t_initialize, \
+      f_string_maps_t_initialize, \
+      f_string_dynamics_t_initialize, \
+      f_string_dynamics_t_initialize, \
       f_string_dynamics_t_initialize, \
       f_string_dynamics_t_initialize, \
+      controller_rule_items_initialize, \
     }
 
   #define f_macro_controller_rule_setting_t_delete_simple(setting) \
+    f_string_dynamic_t_delete_simple(setting.id) \
     f_string_dynamic_t_delete_simple(setting.name) \
     f_string_dynamic_t_delete_simple(setting.pid) \
-    f_string_dynamics_t_delete_simple(setting.defines) \
-    f_string_dynamics_t_delete_simple(setting.environments)
-#endif // _di_controller_rule_setting_t_
+    f_string_maps_t_delete_simple(setting.defines) \
+    f_string_dynamics_t_delete_simple(setting.environments) \
+    f_string_dynamics_t_delete_simple(setting.need) \
+    f_string_dynamics_t_delete_simple(setting.want) \
+    f_string_dynamics_t_delete_simple(setting.wish) \
+    f_macro_controller_rule_item_t_delete_simple(setting.items)
+#endif // _di_controller_rule_t_
 
 /**
  * Print help.
index 19b5cc60813b22ba394c97d139312e0f2d2944ff..4607ba15ebd12ad6cb4a3971f343b83336382497 100644 (file)
@@ -74,7 +74,7 @@ extern "C" {
 #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_return_status controller_rule_actions_read(const controller_data_t data, 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;
@@ -97,7 +97,7 @@ extern "C" {
         else {
           actions->array[0].line = cache->line_action;
 
-          status = fl_string_dynamic_partial_append_nulless(*buffer, cache->range_action, &actions->array[0].parameters.array[0]);
+          status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, 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);
@@ -114,53 +114,59 @@ extern "C" {
 
     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;
+      cache->contents_action.used = 0;
+      cache->objects_action.used = 0;
 
-      status = fl_fss_extended_list_content_read(*buffer, range, &cache->content, &cache->delimits, &cache->comments);
+      status = fl_fss_extended_list_content_read(cache->buffer_item, range, &cache->content_action, &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);
+        status = fll_fss_extended_read(cache->buffer_item, &cache->content_action.array[0], &cache->objects_action, &cache->contents_action, 0, 0, &cache->delimits, 0);
 
         if (F_status_is_error(status)) {
           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;
+          status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
 
-          for (; i < cache->objects.used; ++i) {
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
+          }
+          else {
+            f_array_length_t i = 0;
+            f_array_length_t j = 0;
 
-            status = f_fss_count_lines(*buffer, cache->objects.array[i].start, &actions->array[actions->used].line);
+            for (; i < cache->objects_action.used; ++i) {
 
-            if (F_status_is_error(status)) {
-              fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
-              break;
-            }
+              status = f_fss_count_lines(cache->buffer_item, cache->objects_action.array[i].start, &actions->array[actions->used].line);
 
-            actions->array[actions->used].line += item->line;
-            actions->array[actions->used].parameters.used = 0;
+              if (F_status_is_error(status)) {
+                fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
+                break;
+              }
 
-            status = fl_string_dynamics_increase(&actions->array[actions->used].parameters);
+              actions->array[actions->used].line += item->line;
+              actions->array[actions->used].parameters.used = 0;
 
-            if (F_status_is_error(status)) {
-              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true);
-              break;
-            }
+              status = fl_string_dynamics_increase(&actions->array[actions->used].parameters);
 
-            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), "fl_string_dynamics_increase", F_true);
+                break;
+              }
 
-            if (F_status_is_error(status)) {
-              fll_error_print(data.error, F_status_set_fine(status), "controller_rule_action_read", F_true);
-            }
+              status = controller_rule_action_read(data, cache->buffer_item, &cache->objects_action.array[i], &cache->contents_action.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
+              actions->used++;
+            } // for
+          }
         }
       }
       else {
@@ -168,16 +174,16 @@ extern "C" {
       }
     }
     else {
-      cache->content.used = 0;
+      cache->content_action.used = 0;
       cache->delimits.used = 0;
 
-      status = fl_fss_extended_content_read(*buffer, range, &cache->content, 0, &cache->delimits);
+      status = fl_fss_extended_content_read(cache->buffer_item, range, &cache->content_action, 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);
+        status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
@@ -189,7 +195,7 @@ extern "C" {
             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);
+            status = f_fss_count_lines(cache->buffer_item, 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);
@@ -198,7 +204,7 @@ extern "C" {
               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]);
+              status = controller_rule_action_read(data, cache->buffer_item, 0, &cache->content_action, &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);
@@ -260,26 +266,26 @@ extern "C" {
 #endif // _di_controller_rule_error_print_
 
 #ifndef _di_controller_rule_item_read_
-  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_return_status controller_rule_item_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item) {
     f_status_t status = F_none;
 
-    f_string_range_t range = f_macro_string_range_t_initialize(buffer->used);
+    f_string_range_t range = f_macro_string_range_t_initialize(cache->buffer_item.used);
     f_fss_quote_t quote = 0;
 
     controller_rule_actions_t *actions = 0;
 
     bool multiple = F_false;
 
-    for (range.start = 0; range.start < buffer->used && range.start <= range.stop; cache->delimits.used = 0, cache->comments.used = 0) {
+    for (range.start = 0; range.start < cache->buffer_item.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, &cache->delimits);
+      status = fl_fss_extended_list_object_read(cache->buffer_item, &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);
         break;
       }
 
-      if (range.start >= range.stop || range.start >= buffer->used) {
+      if (range.start >= range.stop || range.start >= cache->buffer_item.used) {
         if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) {
           if (data.error.verbosity != f_console_verbosity_quiet) {
             fprintf(data.error.to.stream, "%c", f_string_eol[0]);
@@ -300,7 +306,7 @@ extern "C" {
         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, &cache->delimits);
+        status = fl_fss_basic_object_read(cache->buffer_item, &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);
@@ -308,20 +314,20 @@ extern "C" {
         }
       }
 
-      if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= buffer->used) {
+      if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= cache->buffer_item.used) {
         // object ended without any content.
         break;
       }
 
       if (status == FL_fss_found_object) {
-        status = fl_fss_apply_delimit(cache->delimits, buffer);
+        status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
 
         if (F_status_is_error(status)) {
           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(cache->buffer_item, 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);
@@ -331,7 +337,7 @@ extern "C" {
         cache->line_action += item->line;
         cache->name_action.used = 0;
 
-        status = fl_string_dynamic_rip_nulless(*buffer, cache->range_action, &cache->name_action);
+        status = fl_string_dynamic_rip_nulless(cache->buffer_item, 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);
@@ -407,7 +413,7 @@ extern "C" {
           actions->type = controller_rule_action_type_extended;
         }
 
-        status = controller_rule_actions_read(data, buffer, cache, item, actions, &range);
+        status = controller_rule_actions_read(data, cache, item, actions, &range);
         if (F_status_is_error(status)) break;
       }
     } // for
@@ -443,11 +449,22 @@ extern "C" {
 #endif // _di_controller_rule_items_increase_by_
 
 #ifndef _di_controller_rule_read_
-  f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) {
+  f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) {
     f_status_t status = F_none;
-    f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
 
-    items->used = 0;
+    rule->items.used = 0;
+
+    cache->delimits.used = 0;
+    cache->comments.used = 0;
+
+    cache->buffer_items.used = 0;
+    cache->contents_items.used = 0;
+    cache->objects_items.used = 0;
+
+    rule->status = F_found_not;
+
+    // @todo construct the rule->id from the file path name, strip the ".rule" extension and only accept the relative part of the path (relative to the base settings directory).
+    // @todo the base settings directory should be a configurable string, such as with a "-s/--settings" parameter which defaults to a compiled in value (such as /etc/controller/rules/)".
 
     {
       f_file_t file = f_file_t_initialize;
@@ -458,38 +475,32 @@ extern "C" {
         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);
+        status = f_file_stream_read(file, 1, &cache->buffer_items);
 
         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);
         }
+        else {
+          // Setting to F_none from F_unknown distinguishes the two such that F_none suggests a valid rule and F_unknown is just that, unknown.
+          rule->status = F_none;
+        }
       }
 
       f_file_stream_close(F_true, &file);
 
-      if (F_status_is_error(status)) {
-        f_macro_string_dynamic_t_delete_simple(buffer);
-        return F_false;
-      }
+      if (F_status_is_error(status)) return F_false;
     }
 
-    // @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);
-
-      cache->delimits.used = 0;
-      cache->comments.used = 0;
+    if (cache->buffer_items.used) {
+      f_string_range_t range = f_macro_string_range_t_initialize(cache->buffer_items.used);
 
-      status = fll_fss_basic_list_read(buffer, &range, &objects, &contents, &cache->delimits, 0, &cache->comments);
+      status = fll_fss_basic_list_read(cache->buffer_items, &range, &cache->objects_items, &cache->contents_items, &cache->delimits, 0, &cache->comments);
 
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true);
       }
       else {
-        status = fl_fss_apply_delimit(cache->delimits, &buffer);
+        status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_items);
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
@@ -497,44 +508,44 @@ extern "C" {
       }
     }
 
-    if (F_status_is_error_not(status) && objects.used) {
-      status = controller_rule_items_increase_by(objects.used, items);
+    if (F_status_is_error_not(status) && cache->objects_items.used) {
+      status = controller_rule_items_increase_by(cache->objects_items.used, &rule->items);
 
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true);
       }
       else {
-        f_string_dynamic_t content = f_string_dynamic_t_initialize;
-
-        for (f_array_length_t i = 0; i < objects.used; ++i) {
+        for (f_array_length_t i = 0; i < cache->objects_items.used; ++i) {
 
           cache->line_item = 0;
           cache->line_action = 0;
 
-          cache->range_item = objects.array[i];
           cache->range_action.start = 1;
           cache->range_action.stop = 0;
+          cache->range_item = cache->objects_items.array[i];
 
           cache->comments.used = 0;
-          cache->content.used = 0;
-          cache->contents.used = 0;
           cache->delimits.used = 0;
-          cache->objects.used = 0;
 
+          cache->content_action.used = 0;
+          cache->objects_action.used = 0;
+
+          cache->buffer_item.used = 0;
+
+          cache->name_action.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);
+          status = f_fss_count_lines(cache->buffer_items, cache->range_item.start, &cache->line_item);
 
           if (F_status_is_error(status)) {
             fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
             break;
           }
 
-          items->array[items->used].line = cache->line_item;
+          rule->items.array[rule->items.used].line = cache->line_item;
 
-          status = fl_string_dynamic_rip_nulless(buffer, cache->range_item, &cache->name_item);
+          status = fl_string_dynamic_rip_nulless(cache->buffer_items, cache->range_item, &cache->name_item);
 
           if (F_status_is_error(status)) {
             fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true);
@@ -548,8 +559,7 @@ extern "C" {
             break;
           }
 
-          content.used = 0;
-          status = fl_string_dynamic_partial_append(buffer, contents.array[i].array[0], &content);
+          status = fl_string_dynamic_partial_append(cache->buffer_items, cache->contents_items.array[i].array[0], &cache->buffer_item);
 
           if (F_status_is_error(status)) {
             fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append", F_true);
@@ -557,16 +567,16 @@ extern "C" {
           }
 
           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;
+            rule->items.array[rule->items.used].type = 0;
           }
           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;
+            rule->items.array[rule->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) {
-            items->array[items->used].type = controller_rule_item_type_script;
+            rule->items.array[rule->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) {
-            items->array[items->used].type = controller_rule_item_type_service;
+            rule->items.array[rule->items.used].type = controller_rule_item_type_service;
           }
           else {
             if (data.warning.verbosity == f_console_verbosity_debug) {
@@ -579,33 +589,41 @@ extern "C" {
             continue;
           }
 
-          if (items->array[items->used].type) {
-            status = controller_rule_item_read(data, &content, cache, &items->array[items->used]);
+          if (rule->items.array[rule->items.used].type) {
+            status = controller_rule_item_read(data, cache, &rule->items.array[rule->items.used]);
             if (F_status_is_error(status)) break;
 
-            items->used++;
+            rule->items.used++;
           }
           else {
-            // @todo handle rule settings population.
+            status = controller_rule_setting_read(data, cache, rule);
+            if (F_status_is_error(status)) break;
           }
         } // for
-
-        f_macro_string_dynamic_t_delete_simple(content);
       }
     }
 
-    f_macro_fss_objects_t_delete_simple(objects);
-    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);
+
+      // designate that the rule is invalid, for any failure.
+      rule->status = F_status_set_error(F_invalid);
     }
 
     return status;
   }
 #endif // _di_controller_rule_read_
 
+#ifndef _di_controller_rule_setting_read_
+  f_return_status controller_rule_setting_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) {
+    f_status_t status = F_none;
+
+    // @todo
+
+    return status;
+  }
+#endif // _di_controller_rule_setting_read_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 6b269213ffcde6d97965c9509d31d599c348ada0..1778ab5fbce31ad18f43dd355a5567dfafe09878 100644 (file)
@@ -14,21 +14,27 @@ extern "C" {
 
 #ifndef _di_controller_rule_cache_t_
   typedef struct {
-    f_string_length_t line_item;
     f_string_length_t line_action;
+    f_string_length_t line_item;
 
-    f_string_range_t range_item;
     f_string_range_t range_action;
+    f_string_range_t range_item;
 
     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_fss_content_t content_action;
+    f_fss_contents_t contents_action;
+    f_fss_contents_t contents_items;
+    f_fss_objects_t objects_action;
+    f_fss_objects_t objects_items;
+
+    f_string_dynamic_t buffer_item;
+    f_string_dynamic_t buffer_items;
+
+    f_string_dynamic_t name_action;
     f_string_dynamic_t name_file;
     f_string_dynamic_t name_item;
-    f_string_dynamic_t name_action;
   } controller_rule_cache_t;
 
   #define controller_rule_cache_t_initialize \
@@ -37,25 +43,33 @@ extern "C" {
       0, \
       0, \
       0, \
+      f_fss_comments_t_initialize, \
       f_fss_delimits_t_initialize, \
       f_fss_content_t_initialize, \
       f_fss_contents_t_initialize, \
-      f_fss_comments_t_initialize, \
+      f_fss_contents_t_initialize, \
+      f_fss_objects_t_initialize, \
       f_fss_objects_t_initialize, \
       f_string_dynamic_t_initialize, \
       f_string_dynamic_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_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_fss_content_t_delete_simple(cache.content_action) \
+    f_macro_fss_contents_t_delete_simple(cache.contents_action) \
+    f_macro_fss_contents_t_delete_simple(cache.contents_items) \
+    f_macro_fss_objects_t_delete_simple(cache.objects_action) \
+    f_macro_fss_objects_t_delete_simple(cache.objects_items) \
+    f_macro_string_dynamic_t_delete_simple(cache.buffer_item) \
+    f_macro_string_dynamic_t_delete_simple(cache.buffer_items) \
+    f_macro_string_dynamic_t_delete_simple(cache.name_action) \
     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)
+    f_macro_string_dynamic_t_delete_simple(cache.name_item)
 #endif // _di_controller_rule_cache_t_
 
 /**
@@ -116,10 +130,8 @@ extern "C" {
  *
  * @param data
  *   The program data.
- * @param buffer
- *   The buffer containing the content.
  * @param cache
- *   A structure for containing and caching the file name, item name, and action name.
+ *   A structure for containing and caching relevant data.
  * @param item
  *   The processed item.
  * @param actions
@@ -140,7 +152,7 @@ extern "C" {
  * @see f_fss_count_lines()
  */
 #ifndef _di_controller_rule_actions_read_
-  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;
+  extern f_return_status controller_rule_actions_read(const controller_data_t data, 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_
 
 /**
@@ -151,7 +163,7 @@ extern "C" {
  * @param output
  *   The error or warning output structure.
  * @param cache
- *   A structure for containing and caching the file name, item name, and action name.
+ *   A structure for containing and caching relevant data.
  *
  * @see controller_rule_actions_read()
  * @see controller_rule_items_read()
@@ -168,10 +180,8 @@ extern "C" {
  *
  * @param data
  *   The program data.
- * @param buffer
- *   The buffer containing the content.
  * @param cache
- *   A structure for containing and caching the file name, item name, and action name.
+ *   A structure for containing and caching relevant data.
  * @param item
  *   The processed item.
  *
@@ -188,7 +198,7 @@ extern "C" {
  * @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;
+  extern f_return_status controller_rule_item_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_item_t *item) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_item_read_
 
 /**
@@ -219,9 +229,9 @@ extern "C" {
  * @param data
  *   The program data.
  * @param cache
- *   A structure for containing and caching the file name, item name, and action name.
- * @param items
- *   The processed array of items.
+ *   A structure for containing and caching relevant data.
+ * @param rule
+ *   The processed rule.
  *
  * @return
  *   F_none on success.
@@ -249,9 +259,32 @@ extern "C" {
  * @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;
+  extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal;
 #endif // _di_controller_rule_read_
 
+/**
+ * Read the content within the buffer, extracting all valid settings.
+ *
+ * This will perform additional FSS read functions as appropriate.
+ *
+ * @param data
+ *   The program data.
+ * @param cache
+ *   A structure for containing and caching relevant data.
+ * @param rule
+ *   The processed rule.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_fss_count_lines().
+ *
+ * @see f_fss_count_lines()
+ */
+#ifndef _di_controller_rule_setting_read_
+  extern f_return_status controller_rule_setting_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_t *rule) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_setting_read_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index b7d55ded20fa167a3d66798fafc1caa09b4ba9d5..c6aff672ae4d259b6a89bac47cf61f74b69434e6 100644 (file)
@@ -11,9 +11,16 @@ Rule Documentation:
   The "settings" outer most list Object has the following FSS-0001 (Extended) Content:
     "define": Define a custom environment variable with a given variable, and automatically expose it to processes executed within this rule.
     "environment": A set of environment variables to expose to the processes executed within this rule (PATH is always exposed).
-    "name": A name used to represent this rule, which is printing to the user, screen, logs, etc...
+    "name": A name used to represent this rule, which is printing to the user, screen, logs, etc.. (this is required).
+    "need": A list of relative rule path names that represent any given rule required to be executed (must exist and must succeed) before this rule starts.
+    "path": A single Content used to set a custom PATH environment variable value.
     "pid": A path to a directory where the PID file is expected to be stored in.
-    @todo: consider adding "path" to allow specifying a custom environment PATH variable (or even go a step further and instead provide "environment" or "variable").
+    "want": A list of relative rule path names that represent any given rule desired to be executed (may exist and must succeed) before this rule starts.
+    "wish": A list of relative rule path names that represent any given rule desired to be executed (may exist and not required to succeed) before this rule starts.
+
+  In the case of "want" and "wish", if the desired rule is either not found or is otherwise disabled, then this will not fail or otherwise block the wanting or wishing rule.
+
+  In the case of "path", when specified, the PATH environment variable is automatically added to the "environment" setting.
 
   The "command" outer most part provides a simple command to run under the different circumstances: "start", "stop", "restart", and "reload".
   A "command" always operates in the foreground.
index 70a2e1dd0650e403410e4b0de34144a16cddffed..e2f072c4f0b2fc94c7422113e22cfb366162a8f5 100644 (file)
@@ -6,18 +6,22 @@ Rule Specification:
   A rule file name is expected to have the file extension ".rule".
 
   The outer most part, which is essentially FSS-0002 (Basic List), has the following Objects\:
-    "settings": Required.
     "command": A Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: "group", "restart", "reload", "start", "stop", and "user".
     "script": A Basic List of FSS-0003 (Extended List) Object and Content, supporting the following Objects: "restart", "reload", "start", and "stop" and A Basic List of FSS-0001 (Extended) Object and Content, supporting the following: "group" and "user".
     "service": A Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: ""create", "group", "use", "restart", "reload", "start", "stop", "timeout", and "user".
+    "settings": A (Required) Basic List of FSS-0001 (Extended) Object and Content, supporting the following Objects: "define", "environment", "name", "need", "pid", "want", "wish".
 
   For the above Basic List Objects, "main" may be specified only once whereas the others may be specifed multiple times.
 
   The "settings" outer most list Object has the following FSS-0001 (Extended) Content:
     "define": Two Content, the first Content must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits).
     "environment": Zero or more Content, each must be a case-sensitive valid environment variable name (alpha-numeric or underscore, but no leading digits).
-    "name": One Content, must have at least 1 non-whitespace printing character.
-    "pid": One Content representing the path to a PID file directory.
+    "name": (Required) One Content, must have at least 1 non-whitespace printing character.
+    "need": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules").
+    "path": Zero or One Content representing a valid PATH environment string (such as "/bin:/sbin:/usr/bin").
+    "pid": One Content representing the full path to a PID file directory (such as "/var/run/service/ssh.pid").
+    "want": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules").
+    "wish": Zero or more Content, each being a partial path and the rule file name without extension (such as "boot/modules").
 
   For the inner parts, these are the Extended Objects\:
     "create": One Content representing the path to a PID file.