#define controller_string_actions "actions"
#define controller_string_asynchronous "asynchronous"
#define controller_string_bash "bash"
+ #define controller_string_batch "batch"
#define controller_string_capability "capability"
#define controller_string_create "create"
#define controller_string_command "command"
#define controller_string_consider "consider"
#define controller_string_control "control"
+ #define controller_string_deadline "deadline"
#define controller_string_default "default"
#define controller_string_define "define"
#define controller_string_entry "entry"
#define controller_string_environment "environment"
#define controller_string_fail "fail"
#define controller_string_failsafe "failsafe"
+ #define controller_string_fifo "fifo"
#define controller_string_group "group"
#define controller_string_groups "groups"
#define controller_string_how "how"
+ #define controller_string_idle "idle"
#define controller_string_item "item"
#define controller_string_kill "kill"
#define controller_string_main "main"
#define controller_string_nice "nice"
#define controller_string_no "no"
#define controller_string_optional "optional"
+ #define controller_string_other "other"
#define controller_string_parameter "parameter"
#define controller_string_path "path"
#define controller_string_pid "pid"
#define controller_string_require "require"
#define controller_string_required "required"
#define controller_string_restart "restart"
+ #define controller_string_round_robin "round_robin"
#define controller_string_rule "rule"
#define controller_string_rules "rules"
#define controller_string_scheduler "scheduler"
#define controller_string_actions_length 7
#define controller_string_asynchronous_length 12
#define controller_string_bash_length 4
+ #define controller_string_batch_length 5
#define controller_string_capability_length 10
#define controller_string_create_length 6
#define controller_string_command_length 7
#define controller_string_consider_length 8
#define controller_string_control_length 7
+ #define controller_string_deadline_length 8
#define controller_string_define_length 6
#define controller_string_default_length 7
#define controller_string_entry_length 5
#define controller_string_environment_length 11
#define controller_string_fail_length 4
#define controller_string_failsafe_length 8
+ #define controller_string_fifo_length 4
#define controller_string_group_length 5
#define controller_string_how_length 3
+ #define controller_string_idle_length 4
#define controller_string_item_length 4
#define controller_string_kill_length 4
#define controller_string_main_length 4
#define controller_string_nice_length 4
#define controller_string_no_length 2
#define controller_string_optional_length 8
+ #define controller_string_other_length 5
#define controller_string_parameter_length 9
#define controller_string_path_length 4
#define controller_string_pid_length 3
#define controller_string_require_length 7
#define controller_string_required_length 8
#define controller_string_restart_length 7
+ #define controller_string_round_robin_length 11
#define controller_string_rule_length 4
#define controller_string_rules_length 5
#define controller_string_scheduler_length 9
#define controller_rule_option_wait 0x8
// bitwise codes representing properties on controller_rule_t that have been found in the rule file.
- #define controller_rule_has_group 0x1
- #define controller_rule_has_nice 0x2
- #define controller_rule_has_user 0x4
+ #define controller_rule_has_group 0x1
+ #define controller_rule_has_nice 0x2
+ #define controller_rule_has_scheduler 0x4
+ #define controller_rule_has_user 0x8
typedef struct {
f_status_t status;
f_string_dynamic_t name;
f_string_dynamic_t control;
f_string_dynamic_t path;
- f_string_dynamic_t scheduler;
f_string_dynamic_t script;
f_string_maps_t define;
f_capability_t capability;
f_int32s_t groups;
+ fl_execute_scheduler_t scheduler;
controller_rule_items_t items;
} controller_rule_t;
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
- f_string_dynamic_t_initialize, \
f_string_maps_t_initialize, \
f_string_maps_t_initialize, \
f_string_dynamics_t_initialize, \
f_string_dynamics_t_initialize, \
f_capability_t_initialize, \
f_int32s_t_initialize, \
+ fl_execute_scheduler_t_initialize, \
controller_rule_items_initialize, \
}
fl_string_dynamic_delete(&rule.name); \
fl_string_dynamic_delete(&rule.control); \
fl_string_dynamic_delete(&rule.path); \
- fl_string_dynamic_delete(&rule.scheduler); \
fl_string_dynamic_delete(&rule.script); \
f_macro_string_maps_t_delete_simple(rule.define) \
f_macro_string_maps_t_delete_simple(rule.parameter) \
as.capability = rule->capability;
}
- if (rule->scheduler.used) {
- // @todo: as.scheduler =
+ if (rule->has & controller_rule_has_scheduler) {
+ as.scheduler = &rule->scheduler;
}
if (rule->control.used) {
rule->name.used = 0;
rule->control.used = 0;
rule->path.used = 0;
- rule->scheduler.used = 0;
+ rule->scheduler.policy = 0;
+ rule->scheduler.priority = 0;
rule->script.used = 0;
rule->define.used = 0;
continue;
}
- if (type == controller_rule_setting_type_control || type == controller_rule_setting_type_name || type == controller_rule_setting_type_path || type == controller_rule_setting_type_scheduler || type == controller_rule_setting_type_script) {
+ if (type == controller_rule_setting_type_control || type == controller_rule_setting_type_name || type == controller_rule_setting_type_path || type == controller_rule_setting_type_script) {
if (type == controller_rule_setting_type_control) {
setting_value = &rule->control;
}
else if (type == controller_rule_setting_type_path) {
setting_value = &rule->path;
}
- else if (type == controller_rule_setting_type_scheduler) {
- setting_value = &rule->scheduler;
- }
else if (type == controller_rule_setting_type_script) {
setting_value = &rule->script;
}
continue;
}
}
- else if (type == controller_rule_setting_type_scheduler) {
- // @todo
+
+ continue;
+ }
+
+
+ if (type == controller_rule_setting_type_scheduler) {
+
+ if (cache->content_actions.array[i].used < 1 || cache->content_actions.array[i].used > 2 || rule->has & controller_rule_has_scheduler) {
+
+ 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%sRule setting requires either one or two Content.%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]);
+
+ controller_rule_error_print(data.error, *cache, F_false);
+ }
+
+ if (F_status_is_error_not(status_return)) {
+ status_return = F_status_set_error(F_valid_not);
+ }
+
+ continue;
}
+ if (fl_string_dynamic_partial_compare_string(controller_string_batch, cache->buffer_item, controller_string_batch_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_BATCH;
+ rule->scheduler.priority = 0;
+ }
+ else if (fl_string_dynamic_partial_compare_string(controller_string_deadline, cache->buffer_item, controller_string_deadline_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_DEADLINE;
+ rule->scheduler.priority = 49;
+ }
+ else if (fl_string_dynamic_partial_compare_string(controller_string_fifo, cache->buffer_item, controller_string_fifo_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_FIFO;
+ rule->scheduler.priority = 49;
+ }
+ else if (fl_string_dynamic_partial_compare_string(controller_string_idle, cache->buffer_item, controller_string_idle_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_IDLE;
+ rule->scheduler.priority = 0;
+ }
+ else if (fl_string_dynamic_partial_compare_string(controller_string_other, cache->buffer_item, controller_string_other_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_OTHER;
+ rule->scheduler.priority = 0;
+ }
+ else if (fl_string_dynamic_partial_compare_string(controller_string_round_robin, cache->buffer_item, controller_string_round_robin_length, cache->content_actions.array[i].array[0]) == F_equal_to) {
+ rule->scheduler.policy = SCHED_RR;
+ rule->scheduler.priority = 49;
+ }
+ else {
+ 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%sRule setting has an unknown scheduler '", 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_partial(data.error.to.stream, cache->buffer_item, cache->content_actions.array[i].array[0]);
+ fprintf(data.error.to.stream, "%s%s'.%s%c", data.error.notable.after->string, data.error.context.before->string, data.error.context.after->string, f_string_eol_s[0]);
+
+ controller_rule_error_print(data.error, *cache, F_false);
+ }
+
+ if (F_status_is_error_not(status_return)) {
+ status_return = F_status_set_error(F_valid_not);
+ }
+
+ continue;
+ }
+
+ if (cache->content_actions.array[i].used > 1) {
+ const bool zero_only = rule->scheduler.policy == SCHED_BATCH || rule->scheduler.policy == SCHED_IDLE || rule->scheduler.policy == SCHED_OTHER;
+
+ f_number_signed_t number = 0;
+
+ status = fl_conversion_string_to_number_signed(cache->buffer_item.string, &number, cache->content_actions.array[i].array[1]);
+
+ if (F_status_is_error(status) || (zero_only && number) || (!zero_only && (number < 1 || number > 99))) {
+ status = F_status_set_fine(status);
+
+ if ((zero_only && number) || (!zero_only && (number < 1 || number > 99)) || status == F_data_not || status == F_number || status == F_number_overflow) {
+
+ 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%sRule setting has an invalid number '", 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_partial(data.error.to.stream, cache->buffer_item, cache->content_actions.array[i].array[1]);
+
+ if (zero_only) {
+ fprintf(data.error.to.stream, "%s%s', only ", data.error.notable.after->string, data.error.context.before->string);
+ fprintf(data.error.to.stream, "%s%s0%s", data.error.context.after->string, data.error.notable.before->string, data.error.notable.after->string);
+ fprintf(data.error.to.stream, "%s is", data.error.context.before->string);
+ }
+ else {
+ fprintf(data.error.to.stream, "%s%s', only the whole numbers inclusively between ", data.error.notable.after->string, data.error.context.before->string);
+ fprintf(data.error.to.stream, "%s%s1%s", data.error.context.after->string, data.error.notable.before->string, data.error.notable.after->string);
+ fprintf(data.error.to.stream, "%s and ", data.error.context.before->string);
+ fprintf(data.error.to.stream, "%s%s99%s", data.error.context.after->string, data.error.notable.before->string, data.error.notable.after->string);
+ fprintf(data.error.to.stream, "%s are", data.error.context.before->string);
+ }
+
+ fprintf(data.error.to.stream, " allowed for the designated scheduler.%s%c", data.error.context.after->string, f_string_eol_s[0]);
+
+ controller_rule_error_print(data.error, *cache, F_false);
+ }
+
+ if (F_status_is_error_not(status_return)) {
+ status_return = F_status_set_error(F_valid_not);
+ }
+ }
+ else {
+ fll_error_print(data.error, status, "fl_conversion_string_to_number_signed", F_true);
+ status = F_status_set_error(status);
+ }
+
+ continue;
+ }
+
+ rule->scheduler.priority = number;
+ }
+
+ rule->has |= controller_rule_has_scheduler;
+
continue;
}
fprintf(data.error.to.stream, "%s%sRule setting has an invalid number '", 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_partial(data.error.to.stream, cache->buffer_item, cache->content_actions.array[i].array[0]);
- fprintf(data.error.to.stream, "%s", data.error.notable.after->string);
- fprintf(data.error.to.stream, "%s', only the whole numbers inclusively between ", data.error.context.before->string);
+ fprintf(data.error.to.stream, "%s%s', only the whole numbers inclusively between ", data.error.notable.after->string, data.error.context.before->string);
fprintf(data.error.to.stream, "%s%s-20%s", data.error.context.after->string, data.error.notable.before->string, data.error.notable.after->string);
fprintf(data.error.to.stream, "%s and ", data.error.context.before->string);
fprintf(data.error.to.stream, "%s%s19%s", data.error.context.after->string, data.error.notable.before->string, data.error.notable.after->string);
fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_control, data.context.set.important.after->string, rule->control.used ? rule->control.string : f_string_empty_s, f_string_eol_s[0]);
fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_path, data.context.set.important.after->string, rule->path.used ? rule->path.string : f_string_empty_s, f_string_eol_s[0]);
- fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_scheduler, data.context.set.important.after->string, rule->scheduler.used ? rule->scheduler.string : f_string_empty_s, f_string_eol_s[0]);
+
+
+ fprintf(data.output.stream, " %s%s%s", data.context.set.important.before->string, controller_string_scheduler, data.context.set.important.after->string);
+ if (rule->has & controller_rule_has_scheduler) {
+ f_string_t policy = "";
+
+ if (rule->scheduler.policy == SCHED_BATCH) {
+ policy = controller_string_batch;
+ }
+ else if (rule->scheduler.policy == SCHED_DEADLINE) {
+ policy = controller_string_deadline;
+ }
+ else if (rule->scheduler.policy == SCHED_FIFO) {
+ policy = controller_string_fifo;
+ }
+ else if (rule->scheduler.policy == SCHED_IDLE) {
+ policy = controller_string_idle;
+ }
+ else if (rule->scheduler.policy == SCHED_OTHER) {
+ policy = controller_string_other;
+ }
+ else if (rule->scheduler.policy == SCHED_RR) {
+ policy = controller_string_round_robin;
+ }
+
+ fprintf(data.output.stream, " %s %i", policy, rule->scheduler.priority);
+ }
+ fprintf(data.output.stream, "%c", f_string_eol_s[0]);
+
fprintf(data.output.stream, " %s%s%s %s%c", data.context.set.important.before->string, controller_string_script, data.context.set.important.after->string, rule->script.used ? rule->script.string : f_string_empty_s, f_string_eol_s[0]);
fprintf(data.output.stream, " %s%s%s", data.context.set.important.before->string, controller_string_nice, data.context.set.important.after->string);