]> Kevux Git Server - fll/commitdiff
Progress: controller program.
authorKevin Day <thekevinday@gmail.com>
Fri, 11 Dec 2020 04:52:05 +0000 (22:52 -0600)
committerKevin Day <thekevinday@gmail.com>
Fri, 11 Dec 2020 04:55:46 +0000 (22:55 -0600)
This fixes some of the problems, but there are several more to go.

This includes some tweaks to the FSS defines.

level_0/f_fss/c/fss-common.h
level_3/controller/c/private-controller.c
level_3/controller/c/private-controller.h
level_3/controller/c/private-entry.c
level_3/controller/c/private-rule.c
level_3/controller/c/private-rule.h
level_3/controller/specifications/entry.txt

index bb30860b0a904db82e6eb74656d8a5e249b414f6..0adfe6c5737783cdc36075a9e981bbca60ce935f 100644 (file)
@@ -20,33 +20,46 @@ extern "C" {
  * FSS-specific types.
  */
 #ifndef _di_f_fss_types_t_
-  #define f_fss_comment                 '#'
-  #define f_fss_eol                     f_string_eol[0]
-  #define f_fss_space                   ' '
-  #define f_fss_space_holder            '_'
-  #define f_fss_basic_open              ' '
-  #define f_fss_basic_close             f_string_eol[0]
-  #define f_fss_extended_open           ' '
-  #define f_fss_extended_next           ' '
-  #define f_fss_extended_close          f_string_eol[0]
-  #define f_fss_basic_list_open         ':'
-  #define f_fss_basic_list_open_end     f_string_eol[0]
-  #define f_fss_basic_list_close        f_string_eol[0]
-  #define f_fss_extended_list_open      '{'
-  #define f_fss_extended_list_open_end  f_string_eol[0]
-  #define f_fss_extended_list_close     '}'
-  #define f_fss_extended_list_close_end f_string_eol[0]
-  #define f_fss_embedded_list_open      '{'
-  #define f_fss_embedded_list_open_end  f_string_eol[0]
-  #define f_fss_embedded_list_close     '}'
-  #define f_fss_embedded_list_close_end f_string_eol[0]
-  #define f_fss_type_header_open        '#'
-  #define f_fss_type_header_part1       ' '
-  #define f_fss_type_header_part2       'f'
-  #define f_fss_type_header_part3       's'
-  #define f_fss_type_header_part4       's'
-  #define f_fss_type_header_part5       '-'
-  #define f_fss_type_header_close       f_string_eol[0]
+  const static f_string_t f_fss_brace_left_s = "{";
+  const static f_string_t f_fss_brace_right_s = "}";
+  const static f_string_t f_fss_colon_s = ":";
+  const static f_string_t f_fss_dash_s = "-";
+  const static f_string_t f_fss_f_s = "f";
+  const static f_string_t f_fss_pound_s = "#";
+  const static f_string_t f_fss_quote_single_s = "'";
+  const static f_string_t f_fss_quote_double_s = "\"";
+  const static f_string_t f_fss_s_s = "s";
+  const static f_string_t f_fss_slash_s = "\\";
+  const static f_string_t f_fss_space_s = " ";
+  const static f_string_t f_fss_underscore_s = "_";
+
+  #define f_fss_comment                 f_fss_pound_s[0]
+  #define f_fss_eol                     f_string_eol_s[0]
+  #define f_fss_space                   f_fss_space_s[0]
+  #define f_fss_space_holder            f_fss_underscore_s[0]
+  #define f_fss_basic_open              f_fss_space_s[0]
+  #define f_fss_basic_close             f_string_eol_s[0]
+  #define f_fss_extended_open           f_fss_space_s[0]
+  #define f_fss_extended_next           f_fss_space_s[0]
+  #define f_fss_extended_close          f_string_eol_s[0]
+  #define f_fss_basic_list_open         f_fss_colon_s[0]
+  #define f_fss_basic_list_open_end     f_string_eol_s[0]
+  #define f_fss_basic_list_close        f_string_eol_s[0]
+  #define f_fss_extended_list_open      f_fss_brace_left_s[0]
+  #define f_fss_extended_list_open_end  f_string_eol_s[0]
+  #define f_fss_extended_list_close     f_fss_brace_right_s[0]
+  #define f_fss_extended_list_close_end f_string_eol_s[0]
+  #define f_fss_embedded_list_open      f_fss_brace_left_s[0]
+  #define f_fss_embedded_list_open_end  f_string_eol_s[0]
+  #define f_fss_embedded_list_close     f_fss_brace_right_s[0]
+  #define f_fss_embedded_list_close_end f_string_eol_s[0]
+  #define f_fss_type_header_open        f_fss_pound_s[0]
+  #define f_fss_type_header_part1       f_fss_space_s[0]
+  #define f_fss_type_header_part2       f_fss_f_s[0]
+  #define f_fss_type_header_part3       f_fss_s_s[0]
+  #define f_fss_type_header_part4       f_fss_s_s[0]
+  #define f_fss_type_header_part5       f_fss_dash_s[0]
+  #define f_fss_type_header_close       f_string_eol_s[0]
 
   typedef unsigned long f_fss_id_t;
 #endif // _di_f_fss_types_t_
@@ -56,9 +69,9 @@ extern "C" {
  */
 #ifndef _di_f_fss_delimiters_
   #define f_fss_delimit_placeholder  f_string_placeholder[0]
-  #define f_fss_delimit_quote_single '\''
-  #define f_fss_delimit_quote_double '"'
-  #define f_fss_delimit_slash        '\\'
+  #define f_fss_delimit_quote_single f_fss_quote_single_s[0]
+  #define f_fss_delimit_quote_double f_fss_quote_double_s[0]
+  #define f_fss_delimit_slash        f_fss_slash_s[0]
 #endif //_di_f_fss_delimiters_
 
 /**
index f7b93d197b94bfb790e0afd4e309aae0abd215f0..532b6be9f67d991a1c3070a1e832ce22298a0fc4 100644 (file)
@@ -51,20 +51,14 @@ extern "C" {
       status = fl_string_append(f_path_separator, f_path_separator_length, &cache->name_file);
     }
 
-    if (F_status_is_error(status)) {
-      fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
-      return status;
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(path_name.string, path_name.used, &cache->name_file);
     }
 
-    status = fl_string_dynamic_append(path_name, &cache->name_file);
-
-    if (F_status_is_error(status)) {
-      fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append", F_true);
-      return status;
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(f_path_extension_separator, f_path_extension_separator_length, &cache->name_file);
     }
 
-    status = fl_string_append(f_path_extension_separator, f_path_extension_separator_length, &cache->name_file);
-
     if (F_status_is_error_not(status)) {
       status = fl_string_append(path_suffix, path_suffix_length, &cache->name_file);
     }
index 06352daf02d914e3344cf37fdc76aad66a8b76a9..03992e608794387849737be187c8b7eb98a3bdc9 100644 (file)
@@ -82,11 +82,17 @@ extern "C" {
  * @return
  *   F_none on success.
  *
+ *   Errors (with error bit) from: f_file_stat().
  *   Errors (with error bit) from: f_file_stream_open().
  *   Errors (with error bit) from: f_file_stream_read().
+ *   Errors (with error bit) from: fl_string_append().
+ *   Errors (with error bit) from: fl_string_dynamic_terminate_after().
  *
+ * @see f_file_stat()
  * @see f_file_stream_open()
  * @see f_file_stream_read()
+ * @see fl_string_append()
+ * @see fl_string_dynamic_terminate_after()
  */
 #ifndef _di_controller_file_load_
   extern f_return_status controller_file_load(const controller_data_t data, const controller_setting_t setting, const f_string_t path_prefix, const f_string_static_t path_name, const f_string_t path_suffix, const f_string_length_t path_prefix_length, const f_string_length_t path_suffix_length, controller_cache_t *cache) f_gcc_attribute_visibility_internal;
index a53be8614d8fa236801cb310b5739f75f4410552..0f6c1033119641726e2f8be54287d7a62e2de989 100644 (file)
@@ -188,8 +188,11 @@ extern "C" {
       }
       else {
         if (data.warning.verbosity == f_console_verbosity_debug) {
-          fprintf(data.warning.to.stream, "%c", f_string_eol_s[0]);
-          fprintf(data.warning.to.stream, "%s%sUnknown entry item type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s, data.warning.context.after->string, f_string_eol_s[0]);
+          fprintf(data.warning.to.stream, "%s%sUnknown entry item action '", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s);
+          fprintf(data.warning.to.stream, "%s%s", data.warning.context.after->string, data.warning.notable.before->string);
+          f_print_dynamic(data.warning.to.stream, cache->name_action);
+          fprintf(data.warning.to.stream, "%s", data.warning.notable.after->string);
+          fprintf(data.warning.to.stream, "%s'.%s%c", data.warning.context.before->string, data.warning.context.after->string, f_string_eol_s[0]);
 
           controller_entry_error_print(data.warning, *cache);
         }
@@ -199,7 +202,7 @@ extern "C" {
 
       if (action->type == controller_entry_action_type_consider || action->type == controller_entry_action_type_rule) {
         allocate = cache->content_actions.array[i].used;
-        at_least = 1;
+        at_least = 2;
         at_most = allocate;
       }
       else if (action->type == controller_entry_action_type_failsafe || action->type == controller_entry_action_type_item) {
@@ -593,6 +596,19 @@ extern "C" {
     cache->delimits.used = 0;
 
     cache->content_action.used = 0;
+
+    {
+      f_array_length_t i = 0;
+
+      for (; i < cache->content_actions.used; ++i) {
+        cache->content_actions.array[i].used = 0;
+      } // for
+
+      for (i = 0; i < cache->content_items.used; ++i) {
+        cache->content_items.array[i].used = 0;
+      } // for
+    }
+
     cache->content_actions.used = 0;
     cache->content_items.used = 0;
 
index bf0dd2fceff82f5f2915f32cc1dba8d5247c689b..24ed727ef185efb506333537a52a05ec910336a1 100644 (file)
@@ -51,6 +51,13 @@ extern "C" {
         return status;
       }
 
+      status = fl_string_dynamic_terminate_after(&action->parameters.array[0]);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+        return status;
+      }
+
       action->parameters.used++;
     }
 
@@ -68,6 +75,13 @@ extern "C" {
           return status;
         }
 
+        status = fl_string_dynamic_terminate_after(&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_terminate_after", F_true);
+          return status;
+        }
+
         action->parameters.used++;
       } // for
     }
@@ -184,6 +198,12 @@ extern "C" {
           if (F_status_is_error(status)) {
             fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true);
           }
+
+          status = fl_string_dynamic_terminate_after(&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_terminate_after", F_true);
+          }
         }
       }
 
@@ -484,8 +504,12 @@ extern "C" {
         }
         else {
           if (data.warning.verbosity == f_console_verbosity_debug) {
-            fprintf(data.warning.to.stream, "%c", f_string_eol_s[0]);
-            fprintf(data.warning.to.stream, "%s%sUnknown rule item action type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s, data.warning.context.after->string, f_string_eol_s[0]);
+            fprintf(data.warning.to.stream, "%s%sUnknown rule item action '", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s);
+            fprintf(data.warning.to.stream, "%s%s", data.warning.context.after->string, data.warning.notable.before->string);
+            f_print_dynamic(data.warning.to.stream, cache->name_action);
+            fprintf(data.warning.to.stream, "%s", data.warning.notable.after->string);
+            fprintf(data.warning.to.stream, "%s'.%s%c", data.warning.context.before->string, data.warning.context.after->string, f_string_eol_s[0]);
+
 
             controller_rule_error_print(data.warning, *cache, F_true);
           }
@@ -497,7 +521,11 @@ extern "C" {
           if (item->actions.type == controller_rule_action_type_create || item->actions.type == controller_rule_action_type_group || item->actions.type == controller_rule_action_type_use || item->actions.type == controller_rule_action_type_user) {
             if (data.error.verbosity != f_console_verbosity_quiet) {
               fprintf(data.error.to.stream, "%c", f_string_eol_s[0]);
-              fprintf(data.error.to.stream, "%s%sFSS Extended List is not allowed for this rule item action type.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s, data.error.context.after->string, f_string_eol_s[0]);
+              fprintf(data.error.to.stream, "%s%sFSS Extended List is not allowed for the rule item action '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s);
+              fprintf(data.error.to.stream, "%s%s", data.error.context.after->string, data.error.notable.before->string);
+              f_print_dynamic(data.error.to.stream, cache->name_action);
+              fprintf(data.error.to.stream, "%s", data.error.notable.after->string);
+              fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]);
             }
 
             status = F_status_set_error(F_supported_not);
@@ -573,6 +601,76 @@ extern "C" {
   }
 #endif // _di_controller_rule_items_increase_by_
 
+#ifndef _di_controller_rule_path_
+  f_return_status controller_rule_path(const controller_data_t data, const controller_setting_t setting, const f_string_static_t path_directory, const f_string_static_t path_name, f_string_dynamic_t *path) {
+    f_status_t status = F_none;
+
+    path->used = 0;
+
+    if (setting.path_setting.used) {
+      status = fl_string_append(setting.path_setting.string, setting.path_setting.used, path);
+
+      if (F_status_is_error_not(status)) {
+        status = fl_string_append(f_path_separator, f_path_separator_length, path);
+      }
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(controller_string_rules, controller_string_rules_length, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(f_path_separator, f_path_separator_length, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(path_directory.string, path_directory.used, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(f_path_separator, f_path_separator_length, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(path_name.string, path_name.used, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(f_path_extension_separator, f_path_extension_separator_length, path);
+    }
+
+    if (F_status_is_error_not(status)) {
+      status = fl_string_append(controller_string_rule, controller_string_rule_length, path);
+    }
+
+    if (F_status_is_error(status)) {
+      fll_error_print(data.error, F_status_set_fine(status), "fl_string_append", F_true);
+      return status;
+    }
+
+    status = fl_string_dynamic_terminate_after(path);
+
+    if (F_status_is_error(status)) {
+      fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+      return status;
+    }
+
+    char path_raw[path->used + 1];
+
+    memcpy(path_raw, path->string, path->used);
+    path_raw[path->used] = 0;
+
+    status = fll_path_canonical(path_raw, path);
+
+    if (F_status_is_error(status)) {
+      fll_error_print(data.error, F_status_set_fine(status), "fll_path_canonical", F_true);
+      return status;
+    }
+
+    return F_none;
+  }
+#endif // _di_controller_rule_path_
+
 #ifndef _di_controller_rule_process_
   f_return_status controller_rule_process(const controller_data_t data, const f_array_length_t index, const bool simulate, controller_setting_t *setting, controller_cache_t *cache) {
 
@@ -884,8 +982,11 @@ extern "C" {
     cache->buffer_item.used = 0;
     cache->buffer_path.used = 0;
 
-    cache->content_items.used = 0;
+    for (f_array_length_t i = 0; i < cache->content_items.used; ++i) {
+      cache->content_items.array[i].used = 0;
+    } // for
 
+    cache->content_items.used = 0;
     cache->object_items.used = 0;
 
     cache->name_action.used = 0;
@@ -898,7 +999,14 @@ extern "C" {
       fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true);
     }
     else {
-      status = controller_file_load(data, setting, controller_string_rules, rule->id, controller_string_rule, controller_string_rules_length, controller_string_rule_length, cache);
+      status = fl_string_dynamic_terminate_after(&rule->id);
+
+      if (F_status_is_error(status)) {
+        fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+      }
+      else {
+        status = controller_file_load(data, setting, controller_string_rules, rule->id, controller_string_rule, controller_string_rules_length, controller_string_rule_length, cache);
+      }
     }
 
     if (F_status_is_error_not(status)) {
@@ -929,7 +1037,10 @@ extern "C" {
         fll_error_print(data.error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true);
       }
       else {
-        for (f_array_length_t i = 0; i < cache->object_items.used; ++i) {
+        f_array_length_t i = 0;
+        f_array_length_t j = 0;
+
+        for (; i < cache->object_items.used; ++i) {
 
           cache->line_item = 0;
           cache->line_action = 0;
@@ -941,8 +1052,12 @@ extern "C" {
           cache->delimits.used = 0;
 
           cache->content_action.used = 0;
-          cache->content_actions.used = 0;
 
+          for (j = 0; j < cache->content_actions.used; ++j) {
+            cache->content_actions.array[j].used = 0;
+          } // for
+
+          cache->content_actions.used = 0;
           cache->object_actions.used = 0;
 
           cache->buffer_item.used = 0;
@@ -990,8 +1105,11 @@ extern "C" {
           }
           else {
             if (data.warning.verbosity == f_console_verbosity_debug) {
-              fprintf(data.warning.to.stream, "%c", f_string_eol_s[0]);
-              fprintf(data.warning.to.stream, "%s%sUnknown rule item type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s, data.warning.context.after->string, f_string_eol_s[0]);
+              fprintf(data.warning.to.stream, "%s%sUnknown rule item '", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s);
+              fprintf(data.warning.to.stream, "%s%s", data.warning.context.after->string, data.warning.notable.before->string);
+              f_print_dynamic(data.warning.to.stream, cache->name_item);
+              fprintf(data.warning.to.stream, "%s", data.warning.notable.after->string);
+              fprintf(data.warning.to.stream, "%s'.%s%c", data.warning.context.before->string, data.warning.context.after->string, f_string_eol_s[0]);
 
               controller_rule_error_print(data.warning, *cache, F_true);
             }
@@ -1006,6 +1124,13 @@ extern "C" {
             break;
           }
 
+          status = fl_string_dynamic_terminate_after(&cache->buffer_item);
+
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+            break;
+          }
+
           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;
@@ -1073,7 +1198,16 @@ extern "C" {
 
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+      }
+      else {
+        status = fl_string_dynamic_terminate_after(&cache->name_item);
 
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+        }
+      }
+
+      if (F_status_is_error(status)) {
         if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
           return status;
         }
@@ -1115,11 +1249,10 @@ extern "C" {
       }
       else {
         if (data.warning.verbosity == f_console_verbosity_debug) {
-          fprintf(data.warning.to.stream, "%c", f_string_eol_s[0]);
-          fprintf(data.warning.to.stream, "%s%sUnknown rule setting.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s, data.warning.context.after->string, f_string_eol_s[0]);
-
           fprintf(data.warning.to.stream, "%s%sUnknown rule setting '", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s);
-          fprintf(data.warning.to.stream, "%s%s%s%s", data.warning.context.after->string, data.warning.notable.before->string, cache->name_item.string, data.warning.notable.after->string);
+          fprintf(data.warning.to.stream, "%s%s", data.warning.context.after->string, data.warning.notable.before->string);
+          f_print_dynamic(data.warning.to.stream, cache->name_item);
+          fprintf(data.warning.to.stream, "%s", data.warning.notable.after->string);
           fprintf(data.warning.to.stream, "%s'.%s%c", data.warning.context.before->string, data.warning.context.after->string, f_string_eol_s[0]);
 
           controller_rule_error_print(data.warning, *cache, F_false);
@@ -1149,6 +1282,16 @@ extern "C" {
 
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+      }
+      else {
+        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);
+        }
+      }
+
+      if (F_status_is_error(status)) {
         controller_rule_error_print(data.error, *cache, F_false);
 
         if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
@@ -1185,9 +1328,6 @@ extern "C" {
           setting_maps = &rule->parameter;
         }
 
-        setting_maps->array[setting_maps->used].name.used = 0;
-        setting_maps->array[setting_maps->used].value.used = 0;
-
         status = fl_string_maps_increase(setting_maps);
 
         if (F_status_is_error(status)) {
@@ -1205,6 +1345,9 @@ extern "C" {
           continue;
         }
 
+        setting_maps->array[setting_maps->used].name.used = 0;
+        setting_maps->array[setting_maps->used].value.used = 0;
+
         status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &setting_maps->array[setting_maps->used].name);
 
         if (F_status_is_error(status)) {
@@ -1226,7 +1369,16 @@ extern "C" {
 
         if (F_status_is_error(status)) {
           fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+        }
+        else {
+          status = fl_string_dynamic_terminate_after(&setting_maps->array[setting_maps->used].value);
 
+          if (F_status_is_error(status)) {
+            fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+          }
+        }
+
+        if (F_status_is_error(status)) {
           if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
             return status;
           }
@@ -1325,7 +1477,16 @@ extern "C" {
 
           if (F_status_is_error(status)) {
             fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+          }
+          else {
+            status = fl_string_dynamic_terminate_after(setting_value);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+            }
+          }
 
+          if (F_status_is_error(status)) {
             if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
               return status;
             }
@@ -1371,9 +1532,18 @@ extern "C" {
           status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[j], &setting_values->array[setting_values->used]);
 
           if (F_status_is_error(status)) {
-            setting_values->array[setting_values->used].used = 0;
-
             fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+          }
+          else {
+            status = fl_string_dynamic_terminate_after(&setting_values->array[setting_values->used]);
+
+            if (F_status_is_error(status)) {
+              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+            }
+          }
+
+          if (F_status_is_error(status)) {
+            setting_values->array[setting_values->used].used = 0;
 
             if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
               return status;
@@ -1447,7 +1617,7 @@ extern "C" {
         setting_values = &rule->wish;
       }
 
-      status = fl_string_dynamics_increase_by(2, setting_values);
+      status = fl_string_dynamics_increase_by(controller_default_allocation_step, setting_values);
 
       if (F_status_is_error(status)) {
         fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase_by", F_true);
@@ -1470,9 +1640,18 @@ extern "C" {
       status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &setting_values->array[setting_values->used]);
 
       if (F_status_is_error(status)) {
-        setting_values->array[setting_values->used].used = 0;
-
         fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+      }
+      else {
+        status = fl_string_dynamic_terminate_after(&setting_values->array[setting_values->used]);
+
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+        }
+      }
+
+      if (F_status_is_error(status)) {
+        setting_values->array[setting_values->used].used = 0;
 
         if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
           return status;
@@ -1489,41 +1668,29 @@ extern "C" {
       status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[1], &setting_values->array[setting_values->used + 1]);
 
       if (F_status_is_error(status)) {
-        setting_values->array[setting_values->used].used = 0;
-        setting_values->array[setting_values->used + 1].used = 0;
-
         fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+      }
+      else {
+        status = fl_string_dynamic_terminate_after(&setting_values->array[setting_values->used + 1]);
 
-        if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
-          return status;
-        }
-
-        if (F_status_is_error_not(status_return)) {
-          status_return = status;
+        if (F_status_is_error(status)) {
+          fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
         }
-
-        controller_rule_error_print(data.error, *cache, F_false);
-        continue;
       }
 
-      // force the path to be canonical (removing all '../' parts).
-      status = fll_path_canonical(setting_values->array[setting_values->used].string, &setting_values->array[setting_values->used]);
-
       if (F_status_is_error(status)) {
         setting_values->array[setting_values->used].used = 0;
         setting_values->array[setting_values->used + 1].used = 0;
 
-        fll_error_print(data.error, F_status_set_fine(status), "fll_path_canonical", F_true);
-
         if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
-          status_return = status;
-          break;
+          return status;
         }
 
         if (F_status_is_error_not(status_return)) {
           status_return = status;
         }
 
+        controller_rule_error_print(data.error, *cache, F_false);
         continue;
       }
 
@@ -1548,43 +1715,24 @@ extern "C" {
 
         continue;
       }
-      else {
-        if (fl_string_dynamic_compare(setting_values->array[setting_values->used + 1], cache->buffer_path) == F_equal_to_not) {
-
-          if (data.error.verbosity != f_console_verbosity_quiet) {
-            status = fl_string_dynamic_terminate_after(&cache->buffer_item);
-
-            if (F_status_is_error(status)) {
-              setting_values->array[setting_values->used].used = 0;
-              setting_values->array[setting_values->used + 1].used = 0;
 
-              fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
-
-              if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) {
-                return status;
-              }
+      if (fl_string_dynamic_compare(setting_values->array[setting_values->used + 1], cache->buffer_path) == F_equal_to_not) {
 
-              if (F_status_is_error_not(status_return)) {
-                status_return = status;
-              }
-
-              controller_rule_error_print(data.error, *cache, F_false);
-              continue;
-            }
-
-            fprintf(data.error.to.stream, "%c", f_string_eol_s[0]);
-            fprintf(data.error.to.stream, "%s%sThe rule item action second parameter '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s);
-            fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, setting_values->array[setting_values->used + 1].string, data.error.notable.after->string);
-            fprintf(data.error.to.stream, "%s' must be a base path name, such as '", data.error.context.before->string);
-            fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, cache->buffer_path.string, data.error.notable.after->string);
-            fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]);
-          }
+        if (data.error.verbosity != f_console_verbosity_quiet) {
+          fprintf(data.error.to.stream, "%c", f_string_eol_s[0]);
+          fprintf(data.error.to.stream, "%s%sThe rule item action second parameter '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s);
+          fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, setting_values->array[setting_values->used + 1].string, data.error.notable.after->string);
+          fprintf(data.error.to.stream, "%s' must be a base path name, such as %llu '", data.error.context.before->string, cache->buffer_path.used);
+          fprintf(data.error.to.stream, "%s%s", data.error.context.after->string, data.error.notable.before->string);
+          f_print_dynamic(data.error.to.stream, cache->buffer_path);
+          fprintf(data.error.to.stream, "%s", data.error.notable.after->string);
+          fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]);
+        }
 
-          setting_values->array[setting_values->used].used = 0;
-          setting_values->array[setting_values->used + 1].used = 0;
+        setting_values->array[setting_values->used].used = 0;
+        setting_values->array[setting_values->used + 1].used = 0;
 
-          continue;
-        }
+        continue;
       }
 
       setting_values->used += 2;
index 86bf3c693567d0b96c9e8382114cacd86a2ee5a2..48d659fecd7b42afc03116e7e575a67a85998baf 100644 (file)
@@ -254,6 +254,40 @@ extern "C" {
 #endif // _di_controller_rule_items_increase_by_
 
 /**
+ * Construct a canonical rule file path from the given path directory and name.
+ *
+ * @param data
+ *   The program data.
+ * @param setting
+ *   The controller settings data.
+ * @param path_directory
+ *   The path directory, such as 'boot' from '/etc/controller/rules/boot/default.rule'.
+ * @param path_name
+ *   The path name, such as 'default' from '/etc/controller/rules/boot/default.rule'.
+ * @param path
+ *   The constructed path.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_file_stream_open().
+ *   Errors (with error bit) from: f_file_stream_read().
+ *   Errors (with error bit) from: fl_string_append().
+ *   Errors (with error bit) from: fl_string_dynamic_terminate_after().
+ *   Errors (with error bit) from: fll_path_canonical().
+ *
+ * @see f_file_stat()
+ * @see f_file_stream_open()
+ * @see f_file_stream_read()
+ * @see fl_string_append()
+ * @see fl_string_dynamic_terminate_after()
+ * @see fll_path_canonical()
+ */
+#ifndef _di_controller_rule_path_
+  extern f_return_status controller_rule_path(const controller_data_t data, const controller_setting_t setting, const f_string_static_t path_directory, const f_string_static_t path_name, f_string_dynamic_t *path) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_path_
+
+/**
  * Process and execute the given rule by the rule id.
  *
  * Any dependent rules are loaded and executed as per "need", "want", and "wish" rule settings.
index c0c322fac97c1a5965ce1d90ce145f73931cd56d..d31dd63e3f583a597e6bb72deb5a34fe79f9e1c9 100644 (file)
@@ -29,7 +29,7 @@ Entry Specification:
       "failsafe": One Content that is a valid Object name, except for the reserved "main".
       "item": One Content that is a valid Object name, except for the reserved "main".
       "ready": Zero Content.
-      "rule": One or more Content.
+      "rule": Two or more Content.
         The first Content that is the relative directory path (without any leading/trailing slashes).
         The second Content that is the basename for a rule file.
         The third and beyond may only be one of\: