From: Kevin Day Date: Sun, 13 Dec 2020 04:09:40 +0000 (-0600) Subject: Progress: contoller program. X-Git-Tag: 0.5.2~22 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=512a190eb6276aa08f1e3e171d1246e407a93349;p=fll Progress: contoller program. This focuses on getting the simulation code working as desired. While --test is what triggers simulation mode, if --validate is specified, then additional information on rules are provided. Break apart the default pid file name to operate on a per entry basis. This will allow for multiple controllers to co-exist with different pid files (and likewise eventually socket files). This fixes a lot of bugs/mistakes that cropped up during the previous codestorming as well as restructures some of the data types. --- diff --git a/level_3/controller/c/controller.c b/level_3/controller/c/controller.c index 56d5758..a795524 100644 --- a/level_3/controller/c/controller.c +++ b/level_3/controller/c/controller.c @@ -28,13 +28,20 @@ extern "C" { fll_program_print_help_option(output, context, controller_short_daemon, controller_long_daemon, f_console_symbol_short_enable, f_console_symbol_long_enable, " Run in daemon only mode (do not process the entry)."); fll_program_print_help_option(output, context, controller_short_interruptable, controller_long_interruptable, f_console_symbol_short_enable, f_console_symbol_long_enable, "Designate that this program can be interrupted."); - fll_program_print_help_option(output, context, controller_short_pid, controller_long_pid, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom pid file path, such as '" controller_path_pid "'."); + fll_program_print_help_option(output, context, controller_short_pid, controller_long_pid, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom pid file path, such as '" controller_path_pid controller_string_default controller_path_suffix "'."); fll_program_print_help_option(output, context, controller_short_settings, controller_long_settings, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a custom settings path, such as '" controller_path_settings "'."); - fll_program_print_help_option(output, context, controller_short_test, controller_long_test, f_console_symbol_short_enable, f_console_symbol_long_enable, " Run in test mode, where nothing is actually run (a simulation)."); - fll_program_print_help_option(output, context, controller_short_validate, controller_long_validate, f_console_symbol_short_enable, f_console_symbol_long_enable, " Validate the settings (entry and rules) without running (or simulating)."); + fll_program_print_help_option(output, context, controller_short_test, controller_long_test, f_console_symbol_short_enable, f_console_symbol_long_enable, " Run in test mode, where nothing is actually run but is instead simulated."); + fll_program_print_help_option(output, context, controller_short_validate, controller_long_validate, f_console_symbol_short_enable, f_console_symbol_long_enable, " Validate the settings (entry and rules) without running (does not simulate)."); fll_program_print_help_usage(output, context, controller_name, "entry"); + fprintf(output.stream, " When both the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, controller_long_test); + fprintf(output.stream, " operation and the "); + fl_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable, controller_long_validate); + fprintf(output.stream, " operation are specified, then additional information on each would be executed rule is printed."); + fprintf(output.stream, "%c", f_string_eol[0]); + return F_none; } #endif // _di_controller_print_help_ @@ -230,6 +237,14 @@ extern "C" { if (!setting.path_pid.used) { status = fl_string_append(controller_path_pid, controller_path_pid_length, &setting.path_pid); + if (F_status_is_error_not(status)) { + status = fl_string_append(entry_name.string, entry_name.used, &setting.path_pid); + } + + if (F_status_is_error_not(status)) { + status = fl_string_append(controller_path_suffix, controller_path_suffix_length, &setting.path_pid); + } + if (F_status_is_error(status)) { if (data->error.verbosity != f_console_verbosity_quiet) { fll_error_print(data->error, F_status_set_fine(status), "fl_string_append", F_true); @@ -282,7 +297,7 @@ extern "C" { else { status = controller_preprocess_entry(*data, &setting, &cache); - if (data->parameters[controller_parameter_validate].result == f_console_result_none) { + if (data->parameters[controller_parameter_validate].result == f_console_result_none || data->parameters[controller_parameter_test].result == f_console_result_found) { if (f_file_exists(setting.path_pid.string) == F_true) { if (data->error.verbosity != f_console_verbosity_quiet) { diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h index 1ded520..da4d165 100644 --- a/level_3/controller/c/controller.h +++ b/level_3/controller/c/controller.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -72,18 +73,20 @@ extern "C" { // This specifically must be at least 2 for this project. #define controller_default_allocation_step 4 - #define controller_path_pid "/var/run/controller/controller.pid" + #define controller_path_pid "/var/run/controller/controller-" #define controller_path_settings "/etc/controller" + #define controller_path_suffix ".pid" - #define controller_path_pid_length 34 + #define controller_path_pid_length 31 #define controller_path_settings_length 15 + #define controller_path_suffix_length 4 #define controller_short_daemon "d" #define controller_short_interruptable "i" #define controller_short_pid "p" #define controller_short_settings "s" #define controller_short_test "t" - #define controller_short_validate "V" + #define controller_short_validate "v" #define controller_long_daemon "daemon" #define controller_long_interruptable "interruptable" diff --git a/level_3/controller/c/private-common.h b/level_3/controller/c/private-common.h index 5208035..0508ca4 100644 --- a/level_3/controller/c/private-common.h +++ b/level_3/controller/c/private-common.h @@ -14,6 +14,7 @@ extern "C" { #ifndef _di_controller_string_ #define controller_string_action "action" + #define controller_string_actions "actions" #define controller_string_asynchronous "asynchronous" #define controller_string_create "create" #define controller_string_command "command" @@ -55,6 +56,7 @@ extern "C" { #define controller_string_wish "wish" #define controller_string_action_length 6 + #define controller_string_actions_length 7 #define controller_string_asynchronous_length 12 #define controller_string_create_length 6 #define controller_string_command_length 7 @@ -121,6 +123,9 @@ extern "C" { }; typedef struct { + uint8_t method; + uint8_t type; + f_string_length_t line; f_status_t status; @@ -131,6 +136,8 @@ extern "C" { #define controller_rule_action_t_initialize \ { \ 0, \ + 0, \ + 0, \ F_known_not, \ f_string_dynamics_t_initialize, \ } @@ -141,9 +148,6 @@ extern "C" { #ifndef _di_controller_rule_actions_t_ typedef struct { - uint8_t method; - uint8_t type; - controller_rule_action_t *array; f_array_length_t size; @@ -155,8 +159,6 @@ extern "C" { 0, \ 0, \ 0, \ - 0, \ - 0, \ } #define controller_macro_rule_actions_t_delete_simple(actions) \ diff --git a/level_3/controller/c/private-controller.c b/level_3/controller/c/private-controller.c index 532b6be..ee07570 100644 --- a/level_3/controller/c/private-controller.c +++ b/level_3/controller/c/private-controller.c @@ -9,16 +9,23 @@ extern "C" { #endif +#ifndef _di_controller_string_dynamic_rip_nulless_terminated_ + f_return_status controller_string_dynamic_rip_nulless_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) { + + f_status_t status = fl_string_dynamic_rip_nulless(source, range, destination); + if (F_status_is_error(status)) return status; + + return fl_string_dynamic_terminate_after(destination); + } +#endif // _di_controller_string_dynamic_rip_nulless_terminated_ + #ifndef _di_controller_string_dynamic_append_terminated_ f_return_status controller_string_dynamic_append_terminated(const f_string_static_t source, f_string_dynamic_t *destination) { f_status_t status = fl_string_dynamic_append(source, destination); - if (F_status_is_error(status)) return status; - status = fl_string_dynamic_terminate_after(destination); - - return status; + return fl_string_dynamic_terminate_after(destination); } #endif // _di_controller_string_dynamic_append_terminated_ @@ -26,12 +33,9 @@ extern "C" { f_return_status controller_string_dynamic_partial_append_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) { f_status_t status = fl_string_dynamic_partial_append(source, range, destination); - if (F_status_is_error(status)) return status; - status = fl_string_dynamic_terminate_after(destination); - - return status; + return fl_string_dynamic_terminate_after(destination); } #endif // _di_controller_string_dynamic_partial_append_terminated_ @@ -48,7 +52,7 @@ extern "C" { status = fl_string_append(path_prefix, path_prefix_length, &cache->name_file); if (F_status_is_error_not(status)) { - status = fl_string_append(f_path_separator, f_path_separator_length, &cache->name_file); + status = fl_string_append(f_path_separator_s, f_path_separator_length, &cache->name_file); } if (F_status_is_error_not(status)) { @@ -82,7 +86,7 @@ extern "C" { memcpy(path, setting.path_setting.string, setting.path_setting.used); memcpy(path + setting.path_setting.used + f_path_separator_length, cache->name_file.string, cache->name_file.used); - path[setting.path_setting.used] = f_path_separator[0]; + path[setting.path_setting.used] = f_path_separator_s[0]; } path[path_length] = 0; @@ -271,6 +275,7 @@ extern "C" { return status; } + // utilize the ats cache as an item execution stack (at_i is for item index, and at_j (at_i + 1) is for action index). cache->ats.array[0] = 0; cache->ats.array[1] = 0; cache->ats.used = 2; @@ -492,6 +497,7 @@ extern "C" { return status; } + // utilize the ats cache as an item execution stack (at_i is for item index, and at_j (at_i + 1) is for action index). cache->ats.array[0] = 0; cache->ats.array[1] = 0; cache->ats.used = 2; @@ -508,6 +514,13 @@ extern "C" { return status; } + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Processing entry item rule '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, controller_string_main, data.context.set.title.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } + for (;;) { actions = &setting->entry.items.array[cache->ats.array[at_i]].actions; @@ -529,10 +542,25 @@ extern "C" { if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_ready) { if (setting->ready == controller_setting_ready_wait) { - setting->ready = controller_setting_ready_yes; - controller_perform_ready(data, setting, cache); - if (F_status_is_error(status)) return status; + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Processing entry item action '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, controller_string_ready, data.context.set.title.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } + else { + controller_perform_ready(data, setting, cache); + if (F_status_is_error(status)) return status; + } + + setting->ready = controller_setting_ready_yes; + } + else if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Ignoring entry item action '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, controller_string_ready, data.context.set.title.after->string); + fprintf(data.output.stream, "', state is already ready.%c", f_string_eol_s[0]); } } else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_item) { @@ -562,20 +590,21 @@ extern "C" { } // continue into the requested item. + cache->ats.array[cache->ats.used] = actions->array[cache->ats.array[at_j]].number; + cache->ats.array[cache->ats.used + 1] = 0; + at_i = cache->ats.used; at_j = cache->ats.used + 1; - cache->ats.array[at_i] = actions->array[cache->ats.array[at_j]].number; - cache->ats.array[at_j] = 0; cache->ats.used += 2; cache->name_action.used = 0; cache->line_action = 0; cache->name_item.used = 0; - cache->line_item = setting->entry.items.array[actions->array[cache->ats.array[at_j]].number].line; + cache->line_item = setting->entry.items.array[cache->ats.array[at_i]].line; - status = controller_string_dynamic_append_terminated(setting->entry.items.array[actions->array[cache->ats.array[at_j]].number].name, &cache->name_item); + status = controller_string_dynamic_append_terminated(setting->entry.items.array[cache->ats.array[at_i]].name, &cache->name_item); if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "controller_string_dynamic_append_terminated", F_true); @@ -584,6 +613,14 @@ extern "C" { return status; } + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Processing entry item '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, cache->name_item.string, data.context.set.title.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } + + // exit inner loop to force restarting and start processing the requested item. break; } else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_consider || actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_rule) { @@ -596,85 +633,111 @@ extern "C" { return status; } - else { - const f_string_length_t rule_id_length = actions->array[cache->ats.array[at_j]].parameters.array[0].used + actions->array[cache->ats.array[at_j]].parameters.array[1].used + 1; - char rule_id_name[rule_id_length + 1]; - const f_string_static_t rule_id = f_macro_string_static_t_initialize(rule_id_name, rule_id_length); - memcpy(rule_id_name, actions->array[cache->ats.array[at_j]].parameters.array[0].string, actions->array[cache->ats.array[at_j]].parameters.array[0].used); - memcpy(rule_id_name + actions->array[cache->ats.array[at_j]].parameters.array[0].used + 1, actions->array[cache->ats.array[at_j]].parameters.array[1].string, actions->array[cache->ats.array[at_j]].parameters.array[1].used); + const f_string_length_t rule_id_length = actions->array[cache->ats.array[at_j]].parameters.array[0].used + actions->array[cache->ats.array[at_j]].parameters.array[1].used + 1; + char rule_id_name[rule_id_length + 1]; + const f_string_static_t rule_id = f_macro_string_static_t_initialize(rule_id_name, rule_id_length); - rule_id_name[actions->array[cache->ats.array[at_j]].parameters.array[0].used] = f_path_separator[0]; - rule_id_name[rule_id_length] = 0; + memcpy(rule_id_name, actions->array[cache->ats.array[at_j]].parameters.array[0].string, actions->array[cache->ats.array[at_j]].parameters.array[0].used); + memcpy(rule_id_name + actions->array[cache->ats.array[at_j]].parameters.array[0].used + 1, actions->array[cache->ats.array[at_j]].parameters.array[1].string, actions->array[cache->ats.array[at_j]].parameters.array[1].used); - at = controller_rule_find_loaded(data, *setting, rule_id); + rule_id_name[actions->array[cache->ats.array[at_j]].parameters.array[0].used] = f_path_separator_s[0]; + rule_id_name[rule_id_length] = 0; - if (at == setting->rules.used) { - status = controller_rule_read(data, *setting, rule_id, cache, &setting->rules.array[setting->rules.used]); + at = controller_rule_find_loaded(data, *setting, rule_id); - if (F_status_is_error(status)) { - controller_entry_error_print(data.error, *cache); + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "%s entry item rule '", actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_rule ? "Processing" : "Considering"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, rule_id.string, data.context.set.title.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } - if (!simulate) break; - } - else { - setting->rules.used++; - } + if (at == setting->rules.used) { + status = controller_rule_read(data, *setting, rule_id, cache, &setting->rules.array[setting->rules.used]); + + if (F_status_is_error(status)) { + controller_entry_error_print(data.error, *cache); + + if (!simulate) break; } + else { + setting->rules.used++; + } + } - if (F_status_is_error_not(status)) { + if (F_status_is_error_not(status)) { - // rule execution will re-use the existing cache, so save the current cache. - const f_array_length_t cache_line_action = cache->line_action; - const f_array_length_t cache_line_item = cache->line_item; + // rule execution will re-use the existing cache, so save the current cache. + const f_array_length_t cache_line_action = cache->line_action; + const f_array_length_t cache_line_item = cache->line_item; - const f_string_length_t cache_name_action_used = cache->name_action.used; - const f_string_length_t cache_name_item_used = cache->name_item.used; - const f_string_length_t cache_name_file_used = cache->name_file.used; + const f_string_length_t cache_name_action_used = cache->name_action.used; + const f_string_length_t cache_name_item_used = cache->name_item.used; + const f_string_length_t cache_name_file_used = cache->name_file.used; - char cache_name_action[cache_name_action_used]; - char cache_name_item[cache_name_item_used]; - char cache_name_file[cache_name_file_used]; + char cache_name_action[cache_name_action_used]; + char cache_name_item[cache_name_item_used]; + char cache_name_file[cache_name_file_used]; - memcpy(cache_name_action, cache->name_action.string, cache->name_action.used); - memcpy(cache_name_item, cache->name_item.string, cache->name_item.used); - memcpy(cache_name_file, cache->name_file.string, cache->name_file.used); + memcpy(cache_name_action, cache->name_action.string, cache->name_action.used); + memcpy(cache_name_item, cache->name_item.string, cache->name_item.used); + memcpy(cache_name_file, cache->name_file.string, cache->name_file.used); - if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_rule) { - // @todo: this will also need to support the asynchronous/wait behavior. - status = controller_rule_process(data, at, simulate, setting, cache); - } + if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_rule) { + // @todo: this will also need to support the asynchronous/wait behavior. + status = controller_rule_process(data, at, simulate, setting, cache); + } - // restore cache. - memcpy(cache->name_action.string, cache_name_action, cache_name_action_used); - memcpy(cache->name_item.string, cache_name_item, cache_name_item_used); - memcpy(cache->name_file.string, cache_name_file, cache_name_file_used); + // restore cache. + memcpy(cache->name_action.string, cache_name_action, cache_name_action_used); + memcpy(cache->name_item.string, cache_name_item, cache_name_item_used); + memcpy(cache->name_file.string, cache_name_file, cache_name_file_used); - cache->name_action.string[cache_name_action_used] = 0; - cache->name_item.string[cache_name_item_used] = 0; - cache->name_file.string[cache_name_file_used] = 0; + cache->name_action.string[cache_name_action_used] = 0; + cache->name_item.string[cache_name_item_used] = 0; + cache->name_file.string[cache_name_file_used] = 0; - cache->name_action.used = cache_name_action_used; - cache->name_item.used = cache_name_item_used; - cache->name_file.used = cache_name_file_used; + cache->name_action.used = cache_name_action_used; + cache->name_item.used = cache_name_item_used; + cache->name_file.used = cache_name_file_used; - cache->line_action = cache_line_action; - cache->line_item = cache_line_item; - } + cache->line_action = cache_line_action; + cache->line_item = cache_line_item; + } - if (F_status_is_error(status)) { - controller_entry_error_print(data.error, *cache); + if (F_status_is_error(status)) { + controller_entry_error_print(data.error, *cache); - if (!simulate || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { - break; - } + if (!simulate || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { + break; } } } else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_timeout) { + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Processing entry item action '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, controller_string_timeout, data.context.set.title.after->string); + fprintf(data.output.stream, "' setting '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.important.before->string, "@todo", data.context.set.important.after->string); + fprintf(data.output.stream, "' to '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.important.before->string, "@todo", data.context.set.important.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } + // @todo set the appropriate timeout value (set the entry actions timeouts which are later used as the initial defaults as the rule timeouts). } else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_failsafe) { + if (simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + fprintf(data.output.stream, "Processing entry item action '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.title.before->string, controller_string_failsafe, data.context.set.title.after->string); + fprintf(data.output.stream, "' setting value to '"); + fprintf(data.output.stream, "%s%s%s", data.context.set.important.before->string, "@todo", data.context.set.important.after->string); + fprintf(data.output.stream, "'.%c", f_string_eol_s[0]); + } + // @todo set the failsafe rule to this rule id (find the rule and then assign by the rule id and then assign by the array index). } @@ -715,6 +778,10 @@ extern "C" { } } // for + if (F_status_is_error_not(status) && simulate) { + fprintf(data.output.stream, "%c", f_string_eol_s[0]); + } + return status; } #endif // _di_controller_process_entry_ diff --git a/level_3/controller/c/private-controller.h b/level_3/controller/c/private-controller.h index 03992e6..72d8db9 100644 --- a/level_3/controller/c/private-controller.h +++ b/level_3/controller/c/private-controller.h @@ -13,6 +13,27 @@ extern "C" { #endif /** + * Rip a string fromt he source and then add a NULL after the end of the string. + * + * @param source + * The string to copy from. + * @param destination + * The string to copy to. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: fl_string_dynamic_rip_nulless(). + * Errors (with error bit) from: fl_string_dynamic_terminate_after(). + * + * @see fl_string_dynamic_rip_nulless() + * @see fl_string_dynamic_terminate_after() + */ +#ifndef _di_controller_string_dynamic_rip_nulless_terminated_ + extern f_return_status controller_string_dynamic_rip_nulless_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) f_gcc_attribute_visibility_internal; +#endif // _di_controller_string_dynamic_rip_nulless_terminated_ + +/** * Append a string and then add a NULL after the end of the string. * * @param source diff --git a/level_3/controller/c/private-entry.c b/level_3/controller/c/private-entry.c index 0f6c103..5ef7a96 100644 --- a/level_3/controller/c/private-entry.c +++ b/level_3/controller/c/private-entry.c @@ -154,17 +154,10 @@ extern "C" { action->line = ++cache->line_action; - status = fl_string_dynamic_rip_nulless(cache->buffer_file, cache->object_actions.array[i], &cache->name_action); + status = controller_string_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_actions.array[i], &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(&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); + fll_error_print(data.error, F_status_set_fine(status), "controller_string_dynamic_rip_nulless_terminated", F_true); break; } diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index 24ed727..4c19ed3 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -30,35 +30,37 @@ extern "C" { } #endif // _di_controller_rule_action_method_name_ -#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) { +#ifndef _di_controller_rule_parameters_read_ + f_return_status controller_rule_parameters_read(const controller_data_t data, const f_string_static_t buffer, f_fss_object_t *object, f_fss_content_t *content, f_string_dynamics_t *parameters) { f_status_t status = F_none; + parameters->used = 0; + if (object && object->start <= object->start) { - status = fl_string_dynamics_increase(&action->parameters); + status = fl_string_dynamics_increase(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; } - action->parameters.array[0].used = 0; + parameters->array[parameters->used].used = 0; - status = fl_string_dynamic_partial_append_nulless(buffer, *object, &action->parameters.array[0]); + status = fl_string_dynamic_partial_append_nulless(buffer, *object, ¶meters->array[0]); 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; } - status = fl_string_dynamic_terminate_after(&action->parameters.array[0]); + status = fl_string_dynamic_terminate_after(¶meters->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++; + parameters->used++; } if (content && content->used) { @@ -66,29 +68,36 @@ extern "C" { if (content->array[i].start > content->array[i].start) continue; - action->parameters.array[action->parameters.used].used = 0; + status = fl_string_dynamics_increase(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; + } + + parameters->array[parameters->used].used = 0; - status = fl_string_dynamic_partial_append_nulless(buffer, content->array[i], &action->parameters.array[action->parameters.used]); + status = fl_string_dynamic_partial_append_nulless(buffer, content->array[i], ¶meters->array[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; } - status = fl_string_dynamic_terminate_after(&action->parameters.array[action->parameters.used]); + status = fl_string_dynamic_terminate_after(¶meters->array[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++; + parameters->used++; } // for } return F_none; } -#endif // _di_controller_rule_action_read_ +#endif // _di_controller_rule_parameters_read_ #ifndef _di_controller_rule_action_type_name_ f_string_static_t controller_rule_action_type_name(const uint8_t type) { @@ -169,59 +178,63 @@ 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, controller_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) { +#ifndef _di_controller_rule_action_read_ + f_return_status controller_rule_action_read(const controller_data_t data, const uint8_t type, const uint8_t method, controller_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; + if (method == controller_rule_action_method_extended_list) { + cache->comments.used = 0; + cache->delimits.used = 0; + cache->content_action.used = 0; + cache->content_actions.used = 0; + cache->object_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(controller_default_allocation_step, actions); + if (actions->size) { + actions->array[actions->used].parameters.used = 0; + } + + 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), "controller_rule_actions_increase_by", F_true); + fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true); } - else { - actions->array[0].parameters.used = 0; - - status = fl_string_dynamics_increase(&actions->array[0].parameters); + else if (status == FL_fss_found_content) { - if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); - } - else { - actions->array[0].line = cache->line_action; + // "script" types use the entire content and can be directly passed through. + if (item->type == controller_rule_item_type_script) { + actions->array[actions->used].parameters.used = 0; - status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->range_action, &actions->array[0].parameters.array[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_dynamic_append_nulless", F_true); + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamics_increase", F_true); } + else { + actions->array[actions->used].type = type; + actions->array[actions->used].method = method; + actions->array[actions->used].line = cache->line_action; - status = fl_string_dynamic_terminate_after(&actions->array[0].parameters.array[0]); + status = fl_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_action.array[0], &actions->array[actions->used].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); - } - } - } + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_append_nulless", F_true); + } - return status; - } + status = fl_string_dynamic_terminate_after(&actions->array[actions->used].parameters.array[0]); - if (actions->method == controller_rule_action_method_extended_list) { - cache->comments.used = 0; - cache->delimits.used = 0; - cache->content_actions.used = 0; - cache->object_actions.used = 0; + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true); + } + else { + actions->array[actions->used].parameters.used = 1; + actions->used++; + } + } - status = fl_fss_extended_list_content_read(cache->buffer_item, range, &cache->content_action, &cache->delimits, &cache->comments); + return status; + } - 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) { + // the object_actions and content_actions caches are being used for the purposes of getting the parameters a given the action. status = fll_fss_extended_read(cache->buffer_item, &cache->content_action.array[0], &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0); if (F_status_is_error(status)) { @@ -239,6 +252,13 @@ extern "C" { for (; i < cache->object_actions.used; ++i) { + status = controller_rule_actions_increase_by(controller_default_allocation_step, actions); + + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true); + break; + } + status = f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &actions->array[actions->used].line); if (F_status_is_error(status)) { @@ -246,6 +266,8 @@ extern "C" { break; } + actions->array[actions->used].type = type; + actions->array[actions->used].method = method; actions->array[actions->used].line += ++item->line; actions->array[actions->used].parameters.used = 0; actions->array[actions->used].status = F_known_not; @@ -259,11 +281,13 @@ extern "C" { break; } - status = controller_rule_action_read(data, cache->buffer_item, &cache->object_actions.array[i], &cache->content_actions.array[i], &actions->array[actions->used]); + status = controller_rule_parameters_read(data, cache->buffer_item, &cache->object_actions.array[i], &cache->content_actions.array[i], &actions->array[actions->used].parameters); actions->array[actions->used].status = controller_status_simplify(F_status_set_fine(status)); actions->used++; } // for + + range->start = cache->content_action.array[0].start; } } } @@ -287,35 +311,30 @@ extern "C" { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); } else { - status = controller_rule_actions_increase_by(controller_default_allocation_step, actions); + status = f_fss_count_lines(cache->buffer_item, range->start, &actions->array[actions->used].line); if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true); + fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); } else { - status = f_fss_count_lines(cache->buffer_item, range->start, &actions->array[0].line); + actions->array[actions->used].type = type; + actions->array[actions->used].method = method; + actions->array[actions->used].line += ++item->line; + actions->array[actions->used].parameters.used = 0; + actions->array[actions->used].status = F_known_not; + + status = controller_rule_parameters_read(data, cache->buffer_item, 0, &cache->content_action, &actions->array[actions->used].parameters); if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true); + fll_error_print(data.error, F_status_set_fine(status), "controller_rule_parameters_read", F_true); + + actions->array[actions->used].status = controller_status_simplify(F_status_set_fine(status)); } else { - actions->array[0].line += ++item->line; - actions->array[0].parameters.used = 0; - actions->array[0].status = F_known_not; - - 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); - - actions->array[0].status = controller_status_simplify(F_status_set_fine(status)); - } - else { - actions->array[0].status = status; - } - - actions->used = 1; + actions->array[actions->used].status = status; } + + actions->used++; } } } @@ -335,7 +354,7 @@ extern "C" { return status; } -#endif // _di_controller_rule_actions_read_ +#endif // _di_controller_rule_action_read_ #ifndef _di_controller_rule_error_print_ void controller_rule_error_print(const fll_error_print_t output, const controller_cache_t cache, const bool item) { @@ -369,19 +388,32 @@ extern "C" { } #endif // _di_controller_rule_error_print_ +#ifndef _di_controller_rule_error_need_want_wish_print_ + void controller_rule_error_need_want_wish_print(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) { + + if (output.verbosity != f_console_verbosity_quiet) { + fprintf(output.to.stream, "%c", f_string_eol_s[0]); + fprintf(output.to.stream, "%s%sThe %s rule '", output.context.before->string, output.prefix ? output.prefix : f_string_empty_s, need_want_wish); + fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, value, output.notable.after->string); + fprintf(output.to.stream, "%s' %s.%s%c", output.context.before->string, why, output.context.after->string, f_string_eol_s[0]); + } + } +#endif // _di_controller_rule_error_need_want_wish_print_ + #ifndef _di_controller_rule_execute_ f_return_status controller_rule_execute(const controller_data_t data, const controller_cache_t cache, const f_array_length_t index, controller_setting_t *setting) { + // @todo this needs the "action" in which to perform, such as "start", "stop", "restart", etc.. // @todo } #endif // _di_controller_rule_execute_ #ifndef _di_controller_rule_find_loaded_ f_array_length_t controller_rule_find_loaded(const controller_data_t data, const controller_setting_t setting, const f_string_static_t rule_id) { + f_array_length_t i = 0; for (; i < setting.rules.used; ++i) { - - if (fl_string_dynamic_compare(setting.rules.array[i].id, rule_id) == F_equal_to) { + if (fl_string_dynamic_compare(rule_id, setting.rules.array[i].id) == F_equal_to) { return i; } } // for @@ -390,17 +422,57 @@ extern "C" { } #endif // _di_controller_rule_find_loaded_ +#ifndef _di_controller_rule_id_construct_ + f_return_status controller_rule_id_construct(const controller_data_t data, const f_string_static_t source, const f_string_range_t directory, const f_string_range_t basename, f_string_dynamic_t *id) { + f_status_t status = F_none; + + id->used = 0; + + status = fl_string_dynamic_partial_append_nulless(source, directory, id); + + 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; + } + + status = fl_string_append(f_path_separator_s, f_path_separator_length, id); + + 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_partial_append_nulless(source, basename, id); + + 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; + } + + status = fl_string_dynamic_terminate_after(id); + + 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; + } +#endif // _di_controller_rule_id_construct_ + #ifndef _di_controller_rule_item_read_ f_return_status controller_rule_item_read(const controller_data_t data, controller_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(cache->buffer_item.used); + f_string_length_t last = 0; - controller_rule_actions_t *actions = 0; - + uint8_t type = 0; + uint8_t method = 0; bool multiple = F_false; - for (range.start = 0; range.start < cache->buffer_item.used && range.start <= range.stop; cache->delimits.used = 0, cache->comments.used = 0) { + item->actions.used = 0; + + for (; range.start < cache->buffer_item.used && range.start <= range.stop; last = range.start, cache->delimits.used = 0, cache->comments.used = 0) { status = fl_fss_extended_list_object_read(cache->buffer_item, &range, &cache->range_action, &cache->delimits); @@ -409,23 +481,11 @@ extern "C" { break; } - 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_s[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 : f_string_empty_s, data.error.context.after->string, f_string_eol_s[0]); - } - - status = F_status_set_error(FL_fss_found_object_content_not); - } - - break; - } - if (status == FL_fss_found_object) { multiple = F_true; } else { + range.start = last; multiple = F_false; cache->delimits.used = 0; @@ -436,111 +496,107 @@ extern "C" { fll_error_print(data.error, F_status_set_fine(status), "fl_fss_extended_object_read", F_true); break; } - } - if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= cache->buffer_item.used) { - // object ended without any content. - break; + // Nothing of importance here, so continue onto the next line. + // @todo present an error if this line is anything but whitespace. + if (status != FL_fss_found_object) continue; } - if (status == FL_fss_found_object) { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); + 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(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), "fl_fss_apply_delimit", F_true); + break; + } - 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->range_action.start, &cache->line_action); - cache->line_action += ++item->line; - cache->name_action.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_dynamic_rip_nulless(cache->buffer_item, cache->range_action, &cache->name_action); + cache->line_action += ++item->line; + cache->name_action.used = 0; - 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 = controller_string_dynamic_rip_nulless_terminated(cache->buffer_item, cache->range_action, &cache->name_action); - 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), "controller_string_dynamic_rip_nulless_terminated", F_true); + break; + } - 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 (fl_string_dynamic_compare_string(controller_string_create, cache->name_action, controller_string_create_length) == F_equal_to) { + type = controller_rule_action_type_create; + } + else if (fl_string_dynamic_compare_string(controller_string_group, cache->name_action, controller_string_group_length) == F_equal_to) { + type = controller_rule_action_type_group; + } + else if (fl_string_dynamic_compare_string(controller_string_kill, cache->name_action, controller_string_kill_length) == F_equal_to) { + type = controller_rule_action_type_kill; + } + else if (fl_string_dynamic_compare_string(controller_string_restart, cache->name_action, controller_string_restart_length) == F_equal_to) { + type = controller_rule_action_type_restart; + } + else if (fl_string_dynamic_compare_string(controller_string_reload, cache->name_action, controller_string_reload_length) == F_equal_to) { + type = controller_rule_action_type_reload; + } + else if (fl_string_dynamic_compare_string(controller_string_start, cache->name_action, controller_string_start_length) == F_equal_to) { + type = controller_rule_action_type_start; + } + else if (fl_string_dynamic_compare_string(controller_string_stop, cache->name_action, controller_string_stop_length) == F_equal_to) { + type = controller_rule_action_type_stop; + } + else if (fl_string_dynamic_compare_string(controller_string_use, cache->name_action, controller_string_use_length) == F_equal_to) { + type = controller_rule_action_type_use; + } + else if (fl_string_dynamic_compare_string(controller_string_user, cache->name_action, controller_string_user_length) == F_equal_to) { + type = controller_rule_action_type_user; + } + else { + if (data.warning.verbosity == f_console_verbosity_debug) { + 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]); - if (fl_string_dynamic_compare_string(controller_string_create, cache->name_action, controller_string_create_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_create; - } - else if (fl_string_dynamic_compare_string(controller_string_group, cache->name_action, controller_string_group_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_group; - } - else if (fl_string_dynamic_compare_string(controller_string_kill, cache->name_action, controller_string_kill_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_kill; - } - else if (fl_string_dynamic_compare_string(controller_string_restart, cache->name_action, controller_string_restart_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_restart; - } - else if (fl_string_dynamic_compare_string(controller_string_reload, cache->name_action, controller_string_reload_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_reload; + controller_rule_error_print(data.warning, *cache, F_true); } - else if (fl_string_dynamic_compare_string(controller_string_start, cache->name_action, controller_string_start_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_start; - } - else if (fl_string_dynamic_compare_string(controller_string_stop, cache->name_action, controller_string_stop_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_stop; - } - else if (fl_string_dynamic_compare_string(controller_string_use, cache->name_action, controller_string_use_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_use; - } - else if (fl_string_dynamic_compare_string(controller_string_user, cache->name_action, controller_string_user_length) == F_equal_to) { - item->actions.type = controller_rule_action_type_user; - } - else { - if (data.warning.verbosity == f_console_verbosity_debug) { - 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]); + continue; + } - controller_rule_error_print(data.warning, *cache, F_true); + if (multiple) { + if (type == controller_rule_action_type_create || type == controller_rule_action_type_group || type == controller_rule_action_type_use || 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 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]); } - continue; + status = F_status_set_error(F_supported_not); + break; } - if (multiple) { - 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 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); - break; - } + method = controller_rule_action_method_extended_list; + } + else { + method = controller_rule_action_method_extended; + } - item->actions.method = controller_rule_action_method_extended_list; - } - else { - item->actions.method = controller_rule_action_method_extended; - } + status = controller_rule_actions_increase_by(controller_default_allocation_step, &item->actions); - status = controller_rule_actions_read(data, cache, item, &item->actions, &range); - if (F_status_is_error(status)) break; + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true); + break; } + + status = controller_rule_action_read(data, type, method, cache, item, &item->actions, &range); + if (F_status_is_error(status)) break; } // for return status; @@ -611,7 +667,7 @@ extern "C" { 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); + status = fl_string_append(f_path_separator_s, f_path_separator_length, path); } } @@ -620,7 +676,7 @@ extern "C" { } if (F_status_is_error_not(status)) { - status = fl_string_append(f_path_separator, f_path_separator_length, path); + status = fl_string_append(f_path_separator_s, f_path_separator_length, path); } if (F_status_is_error_not(status)) { @@ -628,7 +684,7 @@ extern "C" { } if (F_status_is_error_not(status)) { - status = fl_string_append(f_path_separator, f_path_separator_length, path); + status = fl_string_append(f_path_separator_s, f_path_separator_length, path); } if (F_status_is_error_not(status)) { @@ -716,7 +772,7 @@ extern "C" { status = fl_string_append(controller_string_rules, controller_string_rules_length, &cache->name_file); if (F_status_is_error_not(status)) { - status = fl_string_append(f_path_separator, f_path_separator_length, &cache->name_file); + status = fl_string_append(f_path_separator_s, f_path_separator_length, &cache->name_file); } if (F_status_is_error(status)) { @@ -761,6 +817,10 @@ extern "C" { controller_rule_t *rule = &setting->rules.array[index]; + if (simulate && data.parameters[controller_parameter_validate].result == f_console_result_found) { + controller_rule_simulate(data, *cache, index, setting); + } + { f_array_length_t j = 0; f_array_length_t k = 0; @@ -772,6 +832,12 @@ extern "C" { &rule->wish, }; + const f_string_t strings[] = { + "needed", + "wanted", + "wished for", + }; + for (i = 0; i < 3; ++i) { for (j = 0; j < dynamics[i]->used; ++j) { @@ -779,27 +845,16 @@ extern "C" { if (at == setting->rules.used) { if (i == 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 needed rule '", 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, dynamics[i]->array[j].string, data.error.notable.after->string); - fprintf(data.error.to.stream, "%s' was not found.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - - controller_rule_error_print(data.error, *cache, F_true); - } + controller_rule_error_need_want_wish_print(data.error, strings[i], dynamics[i]->array[j].string, "was not found"); status = F_status_set_error(F_found_not); + controller_rule_error_print(data.error, *cache, F_true); if (!simulate) break; } 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%sThe %s rule '", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : f_string_empty_s, i == 1 ? "wanted" : "wished for"); - fprintf(data.warning.to.stream, "%s%s%s%s", data.warning.context.after->string, data.error.notable.before->string, dynamics[i]->array[j].string, data.warning.notable.after->string); - fprintf(data.warning.to.stream, "%s' was not found.%s%c", data.warning.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - + controller_rule_error_need_want_wish_print(data.warning, strings[i], dynamics[i]->array[j].string, "was not found"); controller_rule_error_print(data.warning, *cache, F_true); } } @@ -817,6 +872,7 @@ extern "C" { if (F_status_is_error(status)) { fll_error_print(data.error, F_status_set_fine(status), "fl_type_array_lengths_increase_by", F_true); + controller_rule_error_print(data.error, *cache, F_true); // always exit on memory errors, even in simulate mode. break; @@ -859,14 +915,8 @@ extern "C" { if (F_status_is_error(status)) { if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { - 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 %s rule '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s, i ? "wanted" : "needed"); - fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, dynamics[i]->array[j].string, data.error.notable.after->string); - fprintf(data.error.to.stream, "%s' failed during execution.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - - controller_rule_error_print(data.error, *cache, F_true); - } + controller_rule_error_need_want_wish_print(data.error, strings[i], dynamics[i]->array[j].string, "failed during execution"); + controller_rule_error_print(data.error, *cache, F_true); if (!simulate || F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_memory_allocation || F_status_set_fine(status) == F_memory_reallocation) { break; @@ -874,11 +924,7 @@ 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%sThe wished for rule '", 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.error.notable.before->string, dynamics[i]->array[j].string, data.warning.notable.after->string); - fprintf(data.warning.to.stream, "%s' failed during execution.%s%c", data.warning.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - + controller_rule_error_need_want_wish_print(data.warning, strings[i], dynamics[i]->array[j].string, "failed during execution"); controller_rule_error_print(data.warning, *cache, F_true); } } @@ -887,51 +933,32 @@ extern "C" { else if (F_status_is_error(setting->rules.array[at].status)) { if (i == 0 || i == 1) { - - 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 %s rule '", data.error.context.before->string, data.error.prefix ? data.error.prefix : f_string_empty_s, i ? "wanted" : "needed"); - fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, dynamics[i]->array[j].string, data.error.notable.after->string); - fprintf(data.error.to.stream, "%s' is in a failed state.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - - controller_rule_error_print(data.error, *cache, F_true); - } + controller_rule_error_need_want_wish_print(data.error, strings[i], dynamics[i]->array[j].string, "is in a failed state"); status = F_status_set_error(F_found_not); + controller_rule_error_print(data.error, *cache, F_true); if (!simulate) break; } 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%sThe wished for rule '", 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.error.notable.before->string, dynamics[i]->array[j].string, data.warning.notable.after->string); - fprintf(data.warning.to.stream, "%s' is in a failed state.%s%c", data.warning.context.before->string, data.error.context.after->string, f_string_eol_s[0]); - + controller_rule_error_need_want_wish_print(data.warning, strings[i], dynamics[i]->array[j].string, "is in a failed state"); controller_rule_error_print(data.warning, *cache, F_true); } } } } - } + } // for - if (F_status_is_error(status)) break; + if (F_status_is_error(status) && !simulate) break; } // for } - if (F_status_is_error_not(status)) { - if (simulate) { - controller_rule_simulate(data, *cache, index, setting); - } - else { - status = controller_rule_execute(data, *cache, index, setting); - - if (F_status_is_error(status)) { - fll_error_print(data.error, F_status_set_fine(status), "controller_rule_execute", F_true); - controller_rule_error_print(data.error, *cache, F_true); + if (!simulate && F_status_is_error_not(status)) { + status = controller_rule_execute(data, *cache, index, setting); - return status; - } + if (F_status_is_error(status)) { + fll_error_print(data.error, F_status_set_fine(status), "controller_rule_execute", F_true); } } @@ -1077,17 +1104,10 @@ extern "C" { rule->items.array[rule->items.used].line = ++cache->line_item; - status = fl_string_dynamic_rip_nulless(cache->buffer_file, cache->object_items.array[i], &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); - break; - } - - status = fl_string_dynamic_terminate_after(&cache->name_item); + status = controller_string_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_items.array[i], &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); + fll_error_print(data.error, F_status_set_fine(status), "controller_string_dynamic_rip_nulless_terminated", F_true); break; } @@ -1422,13 +1442,12 @@ extern "C" { setting_value->used = 0; if (type == controller_rule_setting_type_control_group || type == controller_rule_setting_type_name) { - status = fl_string_dynamic_rip_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value); + + status = controller_string_dynamic_rip_nulless_terminated(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value); if (F_status_is_error(status)) { setting_value->used = 0; - fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", 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; } @@ -1447,7 +1466,9 @@ extern "C" { if (status == F_false) { fprintf(data.error.to.stream, "%c", f_string_eol_s[0]); fprintf(data.error.to.stream, "%s%sRule setting has an invalid name '", 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_value->string, data.error.notable.after->string); + fprintf(data.error.to.stream, "%s%s", data.error.context.after->string, data.error.notable.before->string); + f_print_dynamic(data.error.to.stream, *setting_value); + fprintf(data.error.to.stream, "%s", data.error.notable.after->string); fprintf(data.error.to.stream, "%s', there must be at least 1 graph character.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]); controller_rule_error_print(data.error, *cache, F_false); @@ -1634,21 +1655,7 @@ extern "C" { continue; } - setting_values->array[setting_values->used].used = 0; - setting_values->array[setting_values->used + 1].used = 0; - - 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)) { - 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); - } - } + status = controller_rule_id_construct(data, cache->buffer_item, cache->content_actions.array[i].array[0], cache->content_actions.array[i].array[1], &setting_values->array[setting_values->used]); if (F_status_is_error(status)) { setting_values->array[setting_values->used].used = 0; @@ -1665,42 +1672,12 @@ extern "C" { continue; } - 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)) { - 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_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; - setting_values->array[setting_values->used + 1].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; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - controller_rule_error_print(data.error, *cache, F_false); - continue; - } - cache->buffer_path.used = 0; - status = f_file_name_base(setting_values->array[setting_values->used + 1].string, setting_values->array[setting_values->used + 1].used, &cache->buffer_path); + status = f_file_name_base(setting_values->array[setting_values->used].string, setting_values->array[setting_values->used + 1].used, &cache->buffer_path); 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), "f_file_name_base", F_true); @@ -1716,12 +1693,14 @@ extern "C" { continue; } - if (fl_string_dynamic_compare(setting_values->array[setting_values->used + 1], cache->buffer_path) == F_equal_to_not) { + if (fl_string_dynamic_partial_compare_string(cache->buffer_item.string, cache->buffer_path, cache->buffer_item.used, cache->content_actions.array[i].array[1]) == F_equal_to_not) { 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%s", data.error.context.after->string, data.error.notable.before->string); + f_print_dynamic_partial(data.error.to.stream, cache->buffer_item, cache->content_actions.array[i].array[1]); + fprintf(data.error.to.stream, "%s", 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); @@ -1730,12 +1709,11 @@ extern "C" { } setting_values->array[setting_values->used].used = 0; - setting_values->array[setting_values->used + 1].used = 0; continue; } - setting_values->used += 2; + setting_values->used++; } // for return status_return; @@ -1745,6 +1723,8 @@ extern "C" { #ifndef _di_controller_rule_simulate_ void controller_rule_simulate(const controller_data_t data, const controller_cache_t cache, const f_array_length_t index, controller_setting_t *setting) { + // @todo this needs the "action" in which to perform, such as "start", "stop", "restart", etc.. + controller_rule_t * const rule = &setting->rules.array[index]; fprintf(data.output.stream, "%c", f_string_eol_s[0]); @@ -1832,38 +1812,65 @@ extern "C" { fprintf(data.output.stream, " }%c", f_string_eol_s[0]); - fprintf(data.output.stream, " %s%s%s {%c", data.context.set.important.before->string, controller_string_item, data.context.set.important.after->string, f_string_eol_s[0]); - if (rule->items.used) { controller_rule_action_t *action = 0; controller_rule_item_t *item = 0; + f_string_dynamic_t *parameter = 0; f_array_length_t j = 0; + f_array_length_t k = 0; for (i = 0; i < rule->items.used; ++i) { item = &rule->items.array[i]; - fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_type, data.context.set.important.after->string, controller_rule_item_type_name(item->type).string, f_string_eol_s[0]); + fprintf(data.output.stream, " %s%s%s {%c", data.context.set.important.before->string, controller_string_item, data.context.set.important.after->string, f_string_eol_s[0]); - fprintf(data.output.stream, " %s%s%s {%c", data.context.set.important.before->string, controller_string_action, data.context.set.important.after->string, f_string_eol_s[0]); + fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_type, data.context.set.important.after->string, controller_rule_item_type_name(item->type).string, f_string_eol_s[0]); for (j = 0; j < item->actions.used; ++j) { action = &item->actions.array[j]; - // action method - // action type - // action parameters - } + fprintf(data.output.stream, " %s%s%s {%c", data.context.set.important.before->string, controller_string_action, data.context.set.important.after->string, f_string_eol_s[0]); - fprintf(data.output.stream, " }%c", f_string_eol_s[0]); - } // for + fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_type, data.context.set.important.after->string, controller_rule_action_type_name(action->type).string, f_string_eol_s[0]); + fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_method, data.context.set.important.after->string, controller_rule_action_method_name(action->method).string, f_string_eol_s[0]); + + if (action->method == controller_rule_action_method_extended_list && item->type == controller_rule_item_type_script) { + fprintf(data.output.stream, " %s%s%s {%c", data.context.set.important.before->string, controller_string_parameter, data.context.set.important.after->string, f_string_eol_s[0]); + + parameter = &action->parameters.array[0]; + + if (parameter->used) { + fprintf(data.output.stream, " "); + + for (k = 0; k < parameter->used; ++k) { + + fprintf(data.output.stream, "%c", parameter->string[k]); + + if (parameter->string[k] == f_fss_eol && k + 1 < parameter->used) { + fprintf(data.output.stream, " "); + } + } // for + } - fprintf(data.output.stream, " }%c", f_string_eol_s[0]); + fprintf(data.output.stream, " }%c", f_string_eol_s[0]); + } + else { + for (k = 0; k < action->parameters.used; ++k) { + fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_parameter, data.context.set.important.after->string, action->parameters.array[k].string, f_string_eol_s[0]); + } // for + } + + fprintf(data.output.stream, " }%c", f_string_eol_s[0]); + } // for + + fprintf(data.output.stream, " }%c", f_string_eol_s[0]); + } // for } - fprintf(data.output.stream, "}%c%c", f_string_eol_s[0], f_string_eol_s[0]); + fprintf(data.output.stream, "}%c", f_string_eol_s[0]); setting->rules.array[index].status = F_complete; } diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h index 48d659f..42eba62 100644 --- a/level_3/controller/c/private-rule.h +++ b/level_3/controller/c/private-rule.h @@ -27,7 +27,7 @@ extern "C" { #endif // _di_controller_rule_action_method_name_ /** - * Read the rule action. + * Read the parameters for some rule action. * * The object and content ranges are merged together (in that order) as the action parameters. * @@ -41,8 +41,8 @@ extern "C" { * @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. + * @param parameters + * The processed parameters. * * @return * F_none on success. @@ -55,9 +55,9 @@ extern "C" { * @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_ +#ifndef _di_controller_rule_parameters_read_ + extern f_return_status controller_rule_parameters_read(const controller_data_t data, const f_string_static_t buffer, f_fss_object_t *object, f_fss_content_t *content, f_string_dynamics_t *parameters) f_gcc_attribute_visibility_internal; +#endif // _di_controller_rule_parameters_read_ /** * Get a string representing the rule action type. @@ -94,10 +94,16 @@ extern "C" { #endif // _di_controller_rule_actions_increase_by_ /** - * Read the content within the buffer, extracting all valid actions for the current processed item. + * Read the content within the buffer, processing the action (or a set of within a list) for the given item. + * + * This will automatically increase the size of the actions array as needed. * * @param data * The program data. + * @param type + * The action type for this action or set of actions. + * @param method + * The action method for this action or set of actions. * @param cache * A structure for containing and caching relevant data. * @param item @@ -111,17 +117,17 @@ extern "C" { * @return * F_none on success. * - * Errors (with error bit) from: controller_rule_action_read(). * Errors (with error bit) from: controller_rule_actions_increase_by(). + * Errors (with error bit) from: controller_rule_parameters_read(). * Errors (with error bit) from: f_fss_count_lines(). * - * @see controller_rule_action_read() * @see controller_rule_actions_increase_by() + * @see controller_rule_parameters_read() * @see f_fss_count_lines() */ -#ifndef _di_controller_rule_actions_read_ - extern f_return_status controller_rule_actions_read(const controller_data_t data, controller_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_ +#ifndef _di_controller_rule_action_read_ + extern f_return_status controller_rule_action_read(const controller_data_t data, const uint8_t type, const uint8_t method, controller_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_action_read_ /** * Print additional error/warning information in addition to existing error. @@ -136,7 +142,7 @@ extern "C" { * If TRUE, then this error is associated with an item. * If FALSE, then this error is associated with a rule setting. * - * @see controller_rule_actions_read() + * @see controller_rule_action_read() * @see controller_rule_item_read() * @see controller_rule_items_read() * @see controller_rule_read() @@ -147,6 +153,22 @@ extern "C" { #endif // _di_controller_rule_error_print_ /** + * Print an error or warning message related to need/want/wish settings of some rule. + * + * @param output + * The error or warning output structure. + * @param need_want_wish + * The appropriate string, such as "needs", "wants", or "wishes for" to print when describing this error/warning. + * @param value + * The value that is the error or warning. + * @param why + * A short explanation on why this is an error or warning. + */ +#ifndef _di_controller_rule_error_need_want_wish_print_ + extern void controller_rule_error_need_want_wish_print(const fll_error_print_t output, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) f_gcc_attribute_visibility_internal; +#endif // _di_controller_rule_error_need_want_wish_print_ + +/** * Perform an execution of the given rule. * * @param data @@ -190,6 +212,34 @@ extern "C" { #endif // _di_controller_rule_find_loaded_ /** + * Construct an id from two distinct strings found within a single given source. + * + * @param data + * The program data. + * @param source + * The source string that both the directory and basename are copied from. + * @param directory + * A range within the source representing the directory part of a rule id. + * @param basename + * A range within the source representing the basename part of a rule id. + * @param id + * The constructed id. + * + * @return + * F_none on success. + * + * Errors (with error bit) from: fl_string_dynamic_partial_append_nulless(). + * Errors (with error bit) from: fl_string_dynamic_terminate_after(). + * + * @see f_string_append() + * @see fl_string_dynamic_partial_append_nulless() + * @see fl_string_dynamic_terminate_after() + */ +#ifndef _di_controller_rule_id_construct_ + extern f_return_status controller_rule_id_construct(const controller_data_t data, const f_string_static_t source, const f_string_range_t directory, const f_string_range_t basename, f_string_dynamic_t *id) f_gcc_attribute_visibility_internal; +#endif // _di_controller_rule_id_construct_ + +/** * Read the content within the buffer, extracting all valid items after determining their type for some rule file. * * This will perform additional FSS read functions as appropriate. @@ -208,7 +258,7 @@ extern "C" { * Errors (with error bit) from: fl_string_dynamic_partial_append_nulless(). * Errors (with error bit) from: fl_string_dynamic_terminate_after(). * - * @see controller_rule_actions_read() + * @see controller_rule_action_read() * @see f_fss_count_lines() * @see fl_string_dynamic_partial_append_nulless() * @see fl_string_dynamic_terminate_after() diff --git a/level_3/controller/documents/entry.txt b/level_3/controller/documents/entry.txt index 6da0273..f6d755e 100644 --- a/level_3/controller/documents/entry.txt +++ b/level_3/controller/documents/entry.txt @@ -33,17 +33,18 @@ Entry Documentation: Adding "ready" essentially specifies a point in time in the Entry in which things are expected to be safe for such basic operations. The "rule" Action immediately executes a named rule file. - The first Action Parameter represents the rule ID, which is a relative path the rule file is to be found, without the file extension. - - Do not include leading or trailing slashes in the name. + The first Action Parameter represents the rule directory, which is a relative directory path the rule file is to be found. + - Do not include leading or trailing slashes. - This is relative to the settings rules directory. - - For example the rule ID "example/my" would be found in "/etc/controller/settings/rules/example/my.rule" (assuming the directory structure). - The second Action Parameter represents the basename for the file representing the desired rule. - The directory is relative to the settings, such that if the controller rule settings are found in "/etc/controller/rules/", then for a directory called "[directory]" and a rule basename of "[filename]", the resulting path would be: "/etc/controller/rules/[directory]/[filename].rule" + The second Action Parameter represents the basename for the rule file, without the file extension. + - This must not have any directory paths. The remaining Action Parameters may be specified in any order\: - "asynchronous": Designates that execution will not block (wait). - "require": Designates that this rule must succeed or trigger execution of failsafe. - "wait": Designates that this rule will not execute until all other Actions before this (including "asynchronous" ones) finish executing (in a top-down manner). + The full path to the "rule" is relative to the settings, such that if the controller rule settings are found in "/etc/controller/rules/", then for a directory called "[directory]" and a rule basename of "[basename]", the resulting path would be: "/etc/controller/rules/[directory]/[basename].rule" + It is important to note that for any given "rule", execution within that "rule" may be internally asynchronous (even if the "rule" is synchronous). For example, a service that is often called a daemon will execute in the background. Until that execution succeeds and the daemon goes into the background the representing rule will block.