From c2bbe37359a0289cde100201132ede94870e9c39 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 8 Jan 2022 21:48:52 -0600 Subject: [PATCH] Cleanup: Simplify structure using more basic file names and using separate print files. These are private files and are not intended to be exposed. This allows for the names to be more generic. Break out the print functions into their own separate files. This will also make the code more multi-lingual friendly in the respect that much of the code that might need to be swapped out exists in a single file. This is still very far from multi-lingual friendly with many print code still not in the isolated print functions file. --- level_3/controller/c/controller.c | 501 -- level_3/controller/c/controller.h | 342 -- level_3/controller/c/private-common.c | 127 - level_3/controller/c/private-common.h | 476 -- level_3/controller/c/private-control.c | 102 - level_3/controller/c/private-control.h | 80 - level_3/controller/c/private-control_print.c | 12 - level_3/controller/c/private-control_print.h | 19 - level_3/controller/c/private-controller.c | 789 --- level_3/controller/c/private-controller.h | 420 -- level_3/controller/c/private-controller_print.c | 68 - level_3/controller/c/private-controller_print.h | 83 - level_3/controller/c/private-entry.c | 2279 ------- level_3/controller/c/private-entry.h | 229 - level_3/controller/c/private-entry_print.c | 196 - level_3/controller/c/private-entry_print.h | 216 - level_3/controller/c/private-lock.c | 117 - level_3/controller/c/private-lock.h | 192 - level_3/controller/c/private-lock_print.c | 71 - level_3/controller/c/private-lock_print.h | 80 - level_3/controller/c/private-process.c | 189 - level_3/controller/c/private-process.h | 146 - level_3/controller/c/private-rule.c | 6207 -------------------- level_3/controller/c/private-rule.h | 794 --- level_3/controller/c/private-rule_print.c | 363 -- level_3/controller/c/private-rule_print.h | 248 - level_3/controller/c/private-task.c | 11 - level_3/controller/c/private-task.h | 19 - level_3/controller/c/private-task_print.c | 12 - level_3/controller/c/private-task_print.h | 19 - level_3/controller/c/private-thread.c | 358 -- level_3/controller/c/private-thread.h | 126 - level_3/controller/c/private-thread_control.c | 64 - level_3/controller/c/private-thread_control.h | 50 - level_3/controller/c/private-thread_entry.c | 259 - level_3/controller/c/private-thread_entry.h | 56 - level_3/controller/c/private-thread_process.c | 372 -- level_3/controller/c/private-thread_process.h | 98 - level_3/controller/c/private-thread_rule.c | 25 - level_3/controller/c/private-thread_rule.h | 38 - level_3/controller/c/private-thread_signal.c | 125 - level_3/controller/c/private-thread_signal.h | 102 - .../fss_basic_list_read/c/fss_basic_list_read.c | 3 +- level_3/fss_basic_list_read/c/private-print.c | 119 + level_3/fss_basic_list_read/c/private-print.h | 107 + ...rivate-fss_basic_list_read.c => private-read.c} | 111 +- ...rivate-fss_basic_list_read.h => private-read.h} | 94 +- level_3/fss_basic_list_read/data/build/settings | 2 +- .../fss_basic_list_write/c/fss_basic_list_write.c | 2 +- ...vate-fss_basic_list_write.c => private-write.c} | 2 +- ...vate-fss_basic_list_write.h => private-write.h} | 6 +- level_3/fss_basic_list_write/data/build/settings | 2 +- level_3/fss_basic_read/c/fss_basic_read.c | 3 +- level_3/fss_basic_read/c/private-print.c | 116 + level_3/fss_basic_read/c/private-print.h | 79 + .../c/{private-fss_basic_read.c => private-read.c} | 108 +- .../c/{private-fss_basic_read.h => private-read.h} | 66 +- level_3/fss_basic_read/data/build/settings | 2 +- level_3/fss_basic_write/c/fss_basic_write.c | 2 +- .../{private-fss_basic_write.c => private-write.c} | 2 +- .../{private-fss_basic_write.h => private-write.h} | 6 +- level_3/fss_basic_write/data/build/settings | 2 +- .../c/fss_embedded_list_read.c | 3 +- level_3/fss_embedded_list_read/c/private-print.c | 56 + level_3/fss_embedded_list_read/c/private-print.h | 51 + ...ate-fss_embedded_list_read.c => private-read.c} | 48 +- ...ate-fss_embedded_list_read.h => private-read.h} | 38 +- level_3/fss_embedded_list_read/data/build/settings | 2 +- .../c/fss_embedded_list_write.c | 2 +- ...e-fss_embedded_list_write.c => private-write.c} | 2 +- ...e-fss_embedded_list_write.h => private-write.h} | 6 +- .../fss_embedded_list_write/data/build/settings | 2 +- .../c/fss_extended_list_read.c | 3 +- level_3/fss_extended_list_read/c/private-print.c | 129 + level_3/fss_extended_list_read/c/private-print.h | 111 + ...ate-fss_extended_list_read.c => private-read.c} | 121 +- ...ate-fss_extended_list_read.h => private-read.h} | 98 +- level_3/fss_extended_list_read/data/build/settings | 2 +- .../c/fss_extended_list_write.c | 2 +- ...e-fss_extended_list_write.c => private-write.c} | 2 +- ...e-fss_extended_list_write.h => private-write.h} | 6 +- .../fss_extended_list_write/data/build/settings | 2 +- level_3/fss_extended_read/c/fss_extended_read.c | 3 +- level_3/fss_extended_read/c/private-print.c | 210 + level_3/fss_extended_read/c/private-print.h | 107 + ...{private-fss_extended_read.c => private-read.c} | 201 +- ...{private-fss_extended_read.h => private-read.h} | 94 +- level_3/fss_extended_read/data/build/settings | 2 +- level_3/fss_extended_write/c/fss_extended_write.c | 2 +- ...rivate-fss_extended_write.c => private-write.c} | 2 +- ...rivate-fss_extended_write.h => private-write.h} | 6 +- level_3/fss_extended_write/data/build/settings | 2 +- level_3/fss_identify/c/fss_identify.c | 2 +- .../{private-fss_identify.c => private-identify.c} | 26 +- .../{private-fss_identify.h => private-identify.h} | 18 +- level_3/fss_identify/c/private-print.c | 34 + level_3/fss_identify/c/private-print.h | 31 + level_3/fss_identify/data/build/settings | 2 +- level_3/fss_payload_read/c/fss_payload_read.c | 3 +- level_3/fss_payload_read/c/private-print.c | 312 + level_3/fss_payload_read/c/private-print.h | 177 + .../{private-fss_payload_read.c => private-read.c} | 304 +- .../{private-fss_payload_read.h => private-read.h} | 164 +- level_3/fss_payload_read/data/build/settings | 2 +- level_3/fss_payload_write/c/fss_payload_write.c | 2 +- ...private-fss_payload_write.c => private-write.c} | 2 +- ...private-fss_payload_write.h => private-write.h} | 6 +- level_3/fss_payload_write/data/build/settings | 2 +- level_3/iki_read/c/iki_read.c | 2 +- level_3/iki_read/c/private-print.c | 53 + level_3/iki_read/c/private-print.h | 40 + .../c/{private-iki_read.c => private-read.c} | 45 +- .../c/{private-iki_read.h => private-read.h} | 27 +- level_3/iki_read/data/build/settings | 2 +- level_3/iki_write/c/iki_write.c | 2 +- .../c/{private-iki_write.c => private-write.c} | 2 +- .../c/{private-iki_write.h => private-write.h} | 6 +- level_3/iki_write/data/build/settings | 2 +- 118 files changed, 1836 insertions(+), 17661 deletions(-) delete mode 100644 level_3/controller/c/controller.c delete mode 100644 level_3/controller/c/controller.h delete mode 100644 level_3/controller/c/private-common.c delete mode 100644 level_3/controller/c/private-common.h delete mode 100644 level_3/controller/c/private-control.c delete mode 100644 level_3/controller/c/private-control.h delete mode 100644 level_3/controller/c/private-control_print.c delete mode 100644 level_3/controller/c/private-control_print.h delete mode 100644 level_3/controller/c/private-controller.c delete mode 100644 level_3/controller/c/private-controller.h delete mode 100644 level_3/controller/c/private-controller_print.c delete mode 100644 level_3/controller/c/private-controller_print.h delete mode 100644 level_3/controller/c/private-entry.c delete mode 100644 level_3/controller/c/private-entry.h delete mode 100644 level_3/controller/c/private-entry_print.c delete mode 100644 level_3/controller/c/private-entry_print.h delete mode 100644 level_3/controller/c/private-lock.c delete mode 100644 level_3/controller/c/private-lock.h delete mode 100644 level_3/controller/c/private-lock_print.c delete mode 100644 level_3/controller/c/private-lock_print.h delete mode 100644 level_3/controller/c/private-process.c delete mode 100644 level_3/controller/c/private-process.h delete mode 100644 level_3/controller/c/private-rule.c delete mode 100644 level_3/controller/c/private-rule.h delete mode 100644 level_3/controller/c/private-rule_print.c delete mode 100644 level_3/controller/c/private-rule_print.h delete mode 100644 level_3/controller/c/private-task.c delete mode 100644 level_3/controller/c/private-task.h delete mode 100644 level_3/controller/c/private-task_print.c delete mode 100644 level_3/controller/c/private-task_print.h delete mode 100644 level_3/controller/c/private-thread.c delete mode 100644 level_3/controller/c/private-thread.h delete mode 100644 level_3/controller/c/private-thread_control.c delete mode 100644 level_3/controller/c/private-thread_control.h delete mode 100644 level_3/controller/c/private-thread_entry.c delete mode 100644 level_3/controller/c/private-thread_entry.h delete mode 100644 level_3/controller/c/private-thread_process.c delete mode 100644 level_3/controller/c/private-thread_process.h delete mode 100644 level_3/controller/c/private-thread_rule.c delete mode 100644 level_3/controller/c/private-thread_rule.h delete mode 100644 level_3/controller/c/private-thread_signal.c delete mode 100644 level_3/controller/c/private-thread_signal.h create mode 100644 level_3/fss_basic_list_read/c/private-print.c create mode 100644 level_3/fss_basic_list_read/c/private-print.h rename level_3/fss_basic_list_read/c/{private-fss_basic_list_read.c => private-read.c} (86%) rename level_3/fss_basic_list_read/c/{private-fss_basic_list_read.h => private-read.h} (76%) rename level_3/fss_basic_list_write/c/{private-fss_basic_list_write.c => private-write.c} (99%) rename level_3/fss_basic_list_write/c/{private-fss_basic_list_write.h => private-write.h} (96%) create mode 100644 level_3/fss_basic_read/c/private-print.c create mode 100644 level_3/fss_basic_read/c/private-print.h rename level_3/fss_basic_read/c/{private-fss_basic_read.c => private-read.c} (83%) rename level_3/fss_basic_read/c/{private-fss_basic_read.h => private-read.h} (80%) rename level_3/fss_basic_write/c/{private-fss_basic_write.c => private-write.c} (99%) rename level_3/fss_basic_write/c/{private-fss_basic_write.h => private-write.h} (97%) create mode 100644 level_3/fss_embedded_list_read/c/private-print.c create mode 100644 level_3/fss_embedded_list_read/c/private-print.h rename level_3/fss_embedded_list_read/c/{private-fss_embedded_list_read.c => private-read.c} (93%) rename level_3/fss_embedded_list_read/c/{private-fss_embedded_list_read.h => private-read.h} (85%) rename level_3/fss_embedded_list_write/c/{private-fss_embedded_list_write.c => private-write.c} (99%) rename level_3/fss_embedded_list_write/c/{private-fss_embedded_list_write.h => private-write.h} (97%) create mode 100644 level_3/fss_extended_list_read/c/private-print.c create mode 100644 level_3/fss_extended_list_read/c/private-print.h rename level_3/fss_extended_list_read/c/{private-fss_extended_list_read.c => private-read.c} (84%) rename level_3/fss_extended_list_read/c/{private-fss_extended_list_read.h => private-read.h} (75%) rename level_3/fss_extended_list_write/c/{private-fss_extended_list_write.c => private-write.c} (99%) rename level_3/fss_extended_list_write/c/{private-fss_extended_list_write.h => private-write.h} (97%) create mode 100644 level_3/fss_extended_read/c/private-print.c create mode 100644 level_3/fss_extended_read/c/private-print.h rename level_3/fss_extended_read/c/{private-fss_extended_read.c => private-read.c} (75%) rename level_3/fss_extended_read/c/{private-fss_extended_read.h => private-read.h} (77%) rename level_3/fss_extended_write/c/{private-fss_extended_write.c => private-write.c} (99%) rename level_3/fss_extended_write/c/{private-fss_extended_write.h => private-write.h} (96%) rename level_3/fss_identify/c/{private-fss_identify.c => private-identify.c} (79%) rename level_3/fss_identify/c/{private-fss_identify.h => private-identify.h} (82%) create mode 100644 level_3/fss_identify/c/private-print.c create mode 100644 level_3/fss_identify/c/private-print.h create mode 100644 level_3/fss_payload_read/c/private-print.c create mode 100644 level_3/fss_payload_read/c/private-print.h rename level_3/fss_payload_read/c/{private-fss_payload_read.c => private-read.c} (76%) rename level_3/fss_payload_read/c/{private-fss_payload_read.h => private-read.h} (70%) rename level_3/fss_payload_write/c/{private-fss_payload_write.c => private-write.c} (99%) rename level_3/fss_payload_write/c/{private-fss_payload_write.h => private-write.h} (96%) create mode 100644 level_3/iki_read/c/private-print.c create mode 100644 level_3/iki_read/c/private-print.h rename level_3/iki_read/c/{private-iki_read.c => private-read.c} (93%) rename level_3/iki_read/c/{private-iki_read.h => private-read.h} (82%) rename level_3/iki_write/c/{private-iki_write.c => private-write.c} (98%) rename level_3/iki_write/c/{private-iki_write.h => private-write.h} (92%) diff --git a/level_3/controller/c/controller.c b/level_3/controller/c/controller.c deleted file mode 100644 index 6a5414b..0000000 --- a/level_3/controller/c/controller.c +++ /dev/null @@ -1,501 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-control.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-entry.h" -#include "private-lock_print.h" -#include "private-rule.h" -#include "private-thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_print_help_ - f_status_t controller_print_help(controller_main_t * const main) { - - controller_lock_print(main->output.to, 0); - - fll_program_print_help_header(main->output.to, main->context, main->program_name_long, controller_program_version_s); - - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_dark_s, f_console_standard_long_dark_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on dark backgrounds."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_light_s, f_console_standard_long_light_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Output using colors that show up better on light backgrounds."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, "Do not main->output.to in color."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Decrease verbosity beyond normal main->output.to."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_normal_s, f_console_standard_long_normal_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Set verbosity to normal main->output.to."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Increase verbosity beyond normal main->output.to."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, inceasing verbosity beyond normal main->output.to."); - fll_program_print_help_option(main->output.to, main->context, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number."); - - f_print_character(f_string_eol_s[0], main->output.to.stream); - - fll_program_print_help_option(main->output.to, main->context, controller_short_cgroup_s, controller_long_cgroup_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom control group file path, such as '" F_control_group_path_system_prefix_s F_control_group_path_system_default_s "'."); - fll_program_print_help_option(main->output.to, main->context, controller_short_daemon_s, controller_long_daemon_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run in daemon only mode (do not process the entry)."); - fll_program_print_help_option(main->output.to, main->context, controller_short_init_s, controller_long_init_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " The program will run as an init replacement."); - fll_program_print_help_option(main->output.to, main->context, controller_short_interruptible_s, controller_long_interruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Designate that this program can be interrupted by a signal."); - fll_program_print_help_option(main->output.to, main->context, controller_short_pid_s, controller_long_pid_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom pid file path, such as '" controller_path_pid_s CONTROLLER_default_s controller_path_suffix_s "'."); - fll_program_print_help_option(main->output.to, main->context, controller_short_settings_s, controller_long_settings_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Specify a custom settings path, such as '" controller_path_settings_s "'."); - fll_program_print_help_option(main->output.to, main->context, controller_short_simulate_s, controller_long_simulate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Run as a simulation."); - fll_program_print_help_option(main->output.to, main->context, controller_short_uninterruptible_s, controller_long_uninterruptible_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Designate that this program cannot be interrupted by a signal."); - fll_program_print_help_option(main->output.to, main->context, controller_short_validate_s, controller_long_validate_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Validate the settings (entry and rules) without running (does not simulate)."); - - fll_program_print_help_usage(main->output.to, main->context, main->program_name, "entry"); - - fl_print_format(" When both the %[%s%s%] parameter and the", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_simulate_s, main->context.set.notable); - fl_print_format(" %[%s%s%] parameter are specified, then additional information on each would be executed rule is printed but no simulation is performed.%c%c", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_validate_s, main->context.set.notable, f_string_eol_s[0], f_string_eol_s[0]); - - fl_print_format(" The default interrupt behavior is to operate as if the %[%s%s%] parameter is passed.%c%c", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, main->setting_default.used ? controller_long_uninterruptible_s : controller_long_interruptible_s, main->context.set.notable, f_string_eol_s[0], f_string_eol_s[0]); - - fl_print_format(" Specify an empty string for the %[%s%s%] parameter to disable pid file creation for this program.%c%c", main->output.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_pid_s, main->context.set.notable, f_string_eol_s[0], f_string_eol_s[0]); - - controller_unlock_print_flush(main->output.to, 0); - - return F_none; - } -#endif // _di_controller_print_help_ - -#ifndef _di_controller_main_ - f_status_t controller_main(controller_main_t * const main, const f_console_arguments_t *arguments) { - - f_status_t status = F_none; - - { - const f_console_parameters_t parameters = macro_f_console_parameters_t_initialize(main->parameters, controller_total_parameters_d); - - { - f_console_parameter_id_t ids[3] = { controller_parameter_no_color_e, controller_parameter_light_e, controller_parameter_dark_e }; - const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 3); - - status = fll_program_parameter_process(*arguments, parameters, choices, F_true, &main->remaining, &main->context); - - main->output.set = &main->context.set; - main->error.set = &main->context.set; - main->warning.set = &main->context.set; - - if (main->context.set.error.before) { - main->output.context = f_color_set_empty_s; - main->output.notable = main->context.set.notable; - - main->error.context = main->context.set.error; - main->error.notable = main->context.set.notable; - - main->warning.context = main->context.set.warning; - main->warning.notable = main->context.set.notable; - } - else { - f_color_set_t *sets[] = { &main->output.context, &main->output.notable, &main->error.context, &main->error.notable, &main->warning.context, &main->warning.notable, 0 }; - - fll_program_parameter_process_empty(&main->context, sets); - } - - if (F_status_is_error(status)) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process", F_true); - fll_print_terminated(f_string_eol_s, main->error.to.stream); - } - - controller_main_delete(main); - - return F_status_set_error(status); - } - } - - // Identify priority of verbosity related parameters. - { - f_console_parameter_id_t ids[4] = { controller_parameter_verbosity_quiet_e, controller_parameter_verbosity_normal_e, controller_parameter_verbosity_verbose_e, controller_parameter_verbosity_debug_e }; - f_console_parameter_id_t choice = 0; - const f_console_parameter_ids_t choices = macro_f_console_parameter_ids_t_initialize(ids, 4); - - status = f_console_parameter_prioritize_right(parameters, choices, &choice); - - if (F_status_is_error(status)) { - controller_main_delete(main); - - return status; - } - - if (choice == controller_parameter_verbosity_quiet_e) { - main->output.verbosity = f_console_verbosity_quiet_e; - main->error.verbosity = f_console_verbosity_quiet_e; - main->warning.verbosity = f_console_verbosity_quiet_e; - } - else if (choice == controller_parameter_verbosity_normal_e) { - main->output.verbosity = f_console_verbosity_normal_e; - main->error.verbosity = f_console_verbosity_normal_e; - main->warning.verbosity = f_console_verbosity_normal_e; - } - else if (choice == controller_parameter_verbosity_verbose_e) { - main->output.verbosity = f_console_verbosity_verbose_e; - main->error.verbosity = f_console_verbosity_verbose_e; - main->warning.verbosity = f_console_verbosity_verbose_e; - } - else if (choice == controller_parameter_verbosity_debug_e) { - main->output.verbosity = f_console_verbosity_debug_e; - main->error.verbosity = f_console_verbosity_debug_e; - main->warning.verbosity = f_console_verbosity_debug_e; - } - } - - status = F_none; - } - - if (main->parameters[controller_parameter_help_e].result == f_console_result_found_e) { - controller_print_help(main); - - controller_main_delete(main); - - return F_none; - } - - if (main->parameters[controller_parameter_version_e].result == f_console_result_found_e) { - controller_lock_print(main->output.to, 0); - - fll_program_print_version(main->output.to, controller_program_version_s); - - controller_unlock_print_flush(main->output.to, 0); - - controller_main_delete(main); - - return F_none; - } - - controller_setting_t setting = controller_setting_t_initialize; - - struct sockaddr_un address; - setting.control_socket.address = (struct sockaddr *) &address; - setting.control_socket.domain = f_socket_domain_file_d; - setting.control_socket.type = f_socket_type_stream_d; - setting.control_socket.length = sizeof(struct sockaddr_un); - - memset(&address, 0, setting.control_socket.length); - - if (main->remaining.used) { - status = f_string_append_nulless(arguments->argv[main->remaining.array[0]], strnlen(arguments->argv[main->remaining.array[0]], f_console_parameter_size), &setting.name_entry); - } - else { - status = f_string_append_nulless(controller_default_s, controller_default_s_length, &setting.name_entry); - } - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - - controller_main_delete(main); - - return status; - } - - status = f_string_dynamic_terminate_after(&setting.name_entry); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - controller_main_delete(main); - - return status; - } - - if (main->parameters[controller_parameter_init_e].result == f_console_result_found_e) { - main->as_init = F_true; - } - - if (main->as_init) { - setting.mode = controller_setting_mode_service_e; - } - - if (main->parameters[controller_parameter_settings_e].result == f_console_result_found_e) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, 0); - - fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_settings_s, main->context.set.notable); - fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, 0); - } - - status = F_status_set_error(F_parameter); - } - else if (main->parameters[controller_parameter_settings_e].locations.used) { - const f_array_length_t location = main->parameters[controller_parameter_settings_e].values.array[main->parameters[controller_parameter_settings_e].values.used - 1]; - - status = fll_path_canonical(arguments->argv[location], &setting.path_setting); - - if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, arguments->argv[location], "verify", fll_error_file_type_path_e); - } - } - else { - if (main->parameters[controller_parameter_init_e].result == f_console_result_found_e && !main->as_init) { - status = f_string_append(controller_path_settings_init_s, controller_path_settings_init_s_length, &setting.path_setting); - } - else if (main->setting_default.used) { - status = f_string_append(main->setting_default.string, main->setting_default.used, &setting.path_setting); - } - else { - status = f_string_append(controller_path_settings_s, controller_path_settings_s_length, &setting.path_setting); - } - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append", F_true); - } - } - - if (F_status_is_error_not(status)) { - if (main->parameters[controller_parameter_pid_e].result == f_console_result_found_e) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, 0); - - fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_pid_s, main->context.set.notable); - fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, 0); - } - - status = F_status_set_error(F_parameter); - } - else if (main->parameters[controller_parameter_pid_e].locations.used) { - const f_array_length_t location = main->parameters[controller_parameter_pid_e].values.array[main->parameters[controller_parameter_pid_e].values.used - 1]; - - if (strnlen(arguments->argv[location], f_console_parameter_size)) { - status = fll_path_canonical(arguments->argv[location], &setting.path_pid); - - if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, arguments->argv[location], "verify", fll_error_file_type_path_e); - } - } - else { - setting.path_pid.used = 0; - } - } - } - - if (F_status_is_error_not(status) && !setting.path_pid.used && !main->parameters[controller_parameter_pid_e].locations.used) { - if (main->parameters[controller_parameter_init_e].result == f_console_result_found_e) { - status = f_string_append(controller_path_pid_init_s, controller_path_pid_init_s_length, &setting.path_pid); - } - else { - status = f_string_append(main->path_pid.string, main->path_pid.used, &setting.path_pid); - } - - if (F_status_is_error_not(status)) { - status = f_string_append(setting.name_entry.string, setting.name_entry.used, &setting.path_pid); - } - - if (F_status_is_error_not(status)) { - status = f_string_append(controller_path_suffix_s, controller_path_suffix_s_length, &setting.path_pid); - } - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append", F_true); - } - } - - if (F_status_is_error_not(status)) { - if (main->parameters[controller_parameter_cgroup_e].result == f_console_result_found_e) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, 0); - - fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_cgroup_s, main->context.set.notable); - fl_print_format("%[' is specified, but no value is given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, 0); - } - - status = F_status_set_error(F_parameter); - } - else if (main->parameters[controller_parameter_cgroup_e].locations.used) { - const f_array_length_t location = main->parameters[controller_parameter_cgroup_e].values.array[main->parameters[controller_parameter_cgroup_e].values.used - 1]; - - if (strnlen(arguments->argv[location], f_console_parameter_size)) { - status = fll_path_canonical(arguments->argv[location], &setting.path_cgroup); - - if (F_status_is_error(status)) { - fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, arguments->argv[location], "verify", fll_error_file_type_path_e); - } - else { - status = f_string_append_assure(F_path_separator_s, 1, &setting.path_cgroup); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true); - } - else { - status = f_string_dynamic_terminate_after(&setting.path_cgroup); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - } - } - } - else { - if (main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(main->warning.to, 0); - - fl_print_format("%c%[%SThe parameter '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix ? main->warning.prefix : f_string_empty_s, main->warning.context); - fl_print_format("%[%s%s%]", main->warning.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_cgroup_s, main->context.set.notable); - fl_print_format("%[' must be a file directory path but instead is an empty string, falling back to the default.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->warning.to, 0); - } - } - } - } - - if (F_status_is_error_not(status) && main->parameters[controller_parameter_daemon_e].result == f_console_result_found_e) { - if (main->parameters[controller_parameter_validate_e].result == f_console_result_found_e) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, 0); - - fl_print_format("%c%[%SThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[' must not be specified with the parameter '%]", main->error.to.stream, main->error.context, main->error.context); - fl_print_format("%[%s%s%]", main->error.to.stream, main->context.set.notable, f_console_symbol_long_enable_s, controller_long_daemon_s, main->context.set.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, 0); - } - - status = F_status_set_error(F_parameter); - } - } - - // Handle defaults dependent on the "as init" execution state. - if (main->as_init) { - setting.entry.pid = controller_entry_pid_disable_e; - setting.entry.show = controller_entry_show_init_e; - - if (main->parameters[controller_parameter_interruptible_e].result == f_console_result_found_e) { - setting.interruptible = F_true; - } - else { - setting.interruptible = F_false; - } - } - else { - if (main->parameters[controller_parameter_uninterruptible_e].result == f_console_result_found_e) { - setting.interruptible = F_false; - } - else { - setting.interruptible = F_true; - } - } - - if (F_status_is_error_not(status)) { - f_signal_set_fill(&main->signal.set); - - status = f_thread_signal_mask(SIG_BLOCK, &main->signal.set, 0); - - if (F_status_is_error_not(status)) { - status = f_signal_open(&main->signal); - } - - // If there is an error opening a signal descriptor, then do not handle signals. - if (F_status_is_error(status)) { - f_signal_mask(SIG_UNBLOCK, &main->signal.set, 0); - f_signal_close(&main->signal); - } - - // A control file path is required. - if (!setting.path_cgroup.used) { - status = f_string_append_nulless(F_control_group_path_system_prefix_s, F_control_group_path_system_prefix_s_length, &setting.path_cgroup); - - if (F_status_is_error_not(status)) { - status = f_string_append_nulless(F_control_group_path_system_default_s, F_control_group_path_system_default_s_length, &setting.path_cgroup); - } - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_nulless", F_true); - } - else { - status = f_string_append_assure(F_path_separator_s, 1, &setting.path_cgroup); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_append_assure", F_true); - } - else { - status = f_string_dynamic_terminate_after(&setting.path_cgroup); - - if (F_status_is_error(status)) { - fll_error_print(main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - } - } - } - } - - if (F_status_is_error_not(status)) { - status = controller_thread_main(main, &setting); - } - - // Ensure a newline is always put at the end of the program execution, unless in quiet mode. - if (F_status_is_error(status) && main->output.verbosity != f_console_verbosity_quiet_e) { - if (F_status_set_fine(status) == F_interrupt) { - fflush(main->output.to.stream); - } - - fll_print_terminated(f_string_eol_s, main->output.to.stream); - } - - if (status != F_child && setting.pid_created) { - const f_status_t status_delete = controller_file_pid_delete(main->pid, setting.path_pid); - - if (F_status_is_error(status_delete) && main->warning.verbosity == f_console_verbosity_debug_e) { - if (F_status_set_fine(status_delete) == F_number_not) { - controller_lock_print(main->warning.to, 0); - - fl_print_format("%c%[%SThe pid file '%]", main->warning.to.stream, f_string_eol_s[0], main->warning.context, main->warning.prefix ? main->warning.prefix : f_string_empty_s, main->warning.context); - fl_print_format("%[%Q%]", main->warning.to.stream, main->warning.notable, setting.path_pid, main->warning.notable); - fl_print_format("%[' must not be specified with the parameter '%]", main->warning.to.stream, main->warning.context, main->warning.context); - fl_print_format("%[%i%]", main->warning.to.stream, main->warning.notable, main->pid, main->warning.notable); - fl_print_format("%[' doesn't contain the expected number, not deleting file.%]%c", main->warning.to.stream, main->warning.context, main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->warning.to, 0); - } - else if (F_status_set_fine(status_delete) != F_interrupt) { - fll_error_file_print(main->warning, F_status_set_fine(status_delete), "controller_file_pid_delete", F_true, setting.path_pid.string, "delete", fll_error_file_type_file_e); - } - } - } - - if (status != F_child && setting.path_control.used) { - f_socket_disconnect(&setting.control_socket, f_socket_close_read_write_e); - - if (!setting.control_readonly) { - f_file_remove(setting.path_control.string); - } - } - - controller_setting_delete_simple(&setting); - controller_main_delete(main); - - if (status == F_child) { - return status; - } - - return status; - } -#endif // _di_controller_main_ - -#ifndef _di_controller_main_delete_ - f_status_t controller_main_delete(controller_main_t * const main) { - - for (f_array_length_t i = 0; i < controller_total_parameters_d; ++i) { - - macro_f_array_lengths_t_delete_simple(main->parameters[i].locations); - macro_f_array_lengths_t_delete_simple(main->parameters[i].locations_sub); - macro_f_array_lengths_t_delete_simple(main->parameters[i].values); - } // for - - macro_f_array_lengths_t_delete_simple(main->remaining); - macro_f_color_context_t_delete_simple(main->context); - - return F_none; - } -#endif // _di_controller_main_delete_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/controller.h b/level_3/controller/c/controller.h deleted file mode 100644 index a4fcdd0..0000000 --- a/level_3/controller/c/controller.h +++ /dev/null @@ -1,342 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - * - * This is the Controller program. - * - * This program utilizes the Featureless Linux Library. - * This program provides system service management, much like sysvcontroller and controllerng. - * This program can be controlled from user-space via the "control" program. - * This program can be used in an initrd and should be capable of pivot root operations. - * - * @todo Implement "exit" files that are the opposite of "entry" files whereas rules specified within are all called via the "stop" action type. - * This would then allow for switching modes. - * The "exit" would be specified in the "entry", by name and would be found under "exits" directory alongside the "entries" directory. - * - * @todo check the return status of unlocks. - * - * @todo the read/write locks (and unlocks) needs to be more robust in that they need to attempt to keep going even on failure or need to wait until resolvable. - * this is done to help ensure that the controller program always continues onward. - * - * @todo just like with the read/write locks, the out of memory cases need to be handled to keep going instead of bailing. - * likely these will need to be sleeps on the premise that eventually memory will clear itself up. - */ -#ifndef _controller_h - -// include pre-requirements -#define _GNU_SOURCE - -// libc includes -#include -#include -#include -#include -#include -#include -#include - -// fll-0 includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// fll-1 includes -#include -#include -#include -#include -#include -#include - -// fll-2 includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_program_version_ - #define controller_program_version_major_s F_string_ascii_0_s - #define controller_program_version_minor_s F_string_ascii_5_s - #define controller_program_version_micro_s F_string_ascii_8_s - - #ifndef controller_program_version_nano_prefix_s - #define controller_program_version_nano_prefix_s - #endif - - #ifndef controller_program_version_nano_s - #define controller_program_version_nano_s - #endif - - #define controller_program_version_s controller_program_version_major_s F_string_ascii_period_s controller_program_version_minor_s F_string_ascii_period_s controller_program_version_micro_s controller_program_version_nano_prefix_s controller_program_version_nano_s -#endif // _di_controller_program_version_ - -#ifndef _di_controller_program_name_ - #define controller_program_name_s "controller" - #define controller_program_name_long_s "Controller Program" - - #define controller_program_name_init_s "init" - #define controller_program_name_init_long_s "Init Program" -#endif // _di_controller_program_name_ - -#ifndef _di_controller_defines_ - - // the init pid path is a system-specific path and needs to be more easily contolled at compile time. - #if defined(_override_controller_path_pid_init_) && defined(_override_controller_path_pid_init_length_) - #define controller_path_pid_init_s _override_controller_path_pid_init_ - #define controller_path_pid_init_s_length _override_controller_path_pid_init_length_ - #elif defined(_controller_as_init_) - #define controller_path_pid_init_s "/var/run/init/init-" - #define controller_path_pid_init_s_length 19 - #else - #define controller_path_pid_init_s "/var/run/controller/controller-" - #define controller_path_pid_init_s_length 31 - #endif /* defined(_override_controller_path_pid_init_) && defined(_override_controller_path_pid_init_length_) */ - - // the settings path is a system-specific path and needs to be more easily contolled at compile time. - #if defined(_override_controller_path_settings_init_) && defined(_override_controller_path_settings_init_length_) - #define controller_path_settings_init_s _override_controller_path_settings_init_ - #define controller_path_settings_init_s_length _override_controller_path_settings_init_length_ - #elif defined(_controller_as_init_) - #define controller_path_settings_init_s "/etc/init" - #define controller_path_settings_init_s_length 9 - #else - #define controller_path_settings_init_s "/etc/controller" - #define controller_path_settings_init_s_length 15 - #endif /* defined(_override_controller_path_settings_init_) && defined(_override_controller_path_settings_init_length_) */ - - #ifdef _override_controller_default_program_script_ - #define controller_default_program_script_s _override_controller_default_program_script_ - #else - #define controller_default_program_script_s "bash" - #endif // _override_controller_default_program_script_ - - #define controller_path_pid_s "controller/run/controller-" - #define controller_path_settings_s "controller" - #define controller_path_suffix_s ".pid" - - #define controller_path_pid_s_length 26 - #define controller_path_settings_s_length 10 - #define controller_path_suffix_s_length 4 - - #define controller_short_cgroup_s "c" - #define controller_short_daemon_s "d" - #define controller_short_init_s "I" - #define controller_short_interruptible_s "i" - #define controller_short_pid_s "p" - #define controller_short_settings_s "s" - #define controller_short_simulate_s "S" - #define controller_short_uninterruptible_s "U" - #define controller_short_validate_s "v" - - #define controller_long_cgroup_s "cgroup" - #define controller_long_daemon_s "daemon" - #define controller_long_init_s "init" - #define controller_long_interruptible_s "interruptible" - #define controller_long_pid_s "pid" - #define controller_long_settings_s "settings" - #define controller_long_simulate_s "simulate" - #define controller_long_uninterruptible_s "uninterruptible" - #define controller_long_validate_s "validate" - - enum { - controller_parameter_help_e, - controller_parameter_light_e, - controller_parameter_dark_e, - controller_parameter_no_color_e, - controller_parameter_verbosity_quiet_e, - controller_parameter_verbosity_normal_e, - controller_parameter_verbosity_verbose_e, - controller_parameter_verbosity_debug_e, - controller_parameter_version_e, - - controller_parameter_cgroup_e, - controller_parameter_daemon_e, - controller_parameter_init_e, - controller_parameter_interruptible_e, - controller_parameter_pid_e, - controller_parameter_settings_e, - controller_parameter_simulate_e, - controller_parameter_uninterruptible_e, - controller_parameter_validate_e, - }; - - #define controller_console_parameter_t_initialize \ - { \ - f_console_parameter_t_initialize(f_console_standard_short_help_s, f_console_standard_long_help_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(f_console_standard_short_light_s, f_console_standard_long_light_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_dark_s, f_console_standard_long_dark_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_no_color_s, f_console_standard_long_no_color_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_quiet_s, f_console_standard_long_quiet_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_normal_s, f_console_standard_long_normal_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_verbose_s, f_console_standard_long_verbose_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_debug_s, f_console_standard_long_debug_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(f_console_standard_short_version_s, f_console_standard_long_version_s, 0, 0, f_console_type_inverse_e), \ - f_console_parameter_t_initialize(controller_short_cgroup_s, controller_long_cgroup_s, 0, 1, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_daemon_s, controller_long_daemon_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_init_s, controller_long_init_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_interruptible_s, controller_long_interruptible_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_pid_s, controller_long_pid_s, 0, 1, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_settings_s, controller_long_settings_s, 0, 1, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_simulate_s, controller_long_simulate_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_uninterruptible_s, controller_long_uninterruptible_s, 0, 0, f_console_type_normal_e), \ - f_console_parameter_t_initialize(controller_short_validate_s, controller_long_validate_s, 0, 0, f_console_type_normal_e), \ - } - - #define controller_total_parameters_d 18 -#endif // _di_controller_defines_ - -#ifndef _di_controller_main_t_ - typedef struct { - f_console_parameter_t parameters[controller_total_parameters_d]; - - f_array_lengths_t remaining; - bool process_pipe; - bool as_init; - - fl_print_t output; - fl_print_t error; - fl_print_t warning; - - f_signal_t signal; - - pid_t pid; - mode_t umask; - int child; - - f_string_t program_name; - f_string_t program_name_long; - f_string_static_t setting_default; - f_string_static_t path_pid; - - f_color_context_t context; - } controller_main_t; - - #define controller_main_t_initialize \ - { \ - controller_console_parameter_t_initialize, \ - f_array_lengths_t_initialize, \ - F_false, \ - F_false, \ - fl_print_t_initialize, \ - macro_fl_print_t_initialize_error(), \ - macro_fl_print_t_initialize_warning(), \ - f_signal_t_initialize, \ - 0, \ - 0, \ - 0, \ - f_string_t_initialize, \ - f_string_t_initialize, \ - f_string_static_t_initialize, \ - f_string_static_t_initialize, \ - f_color_context_t_initialize, \ - } -#endif // _di_controller_main_t_ - -/** - * Print help. - * - * @param main - * The main program data. - * - * @return - * F_none on success. - */ -#ifndef _di_controller_print_help_ - extern f_status_t controller_print_help(controller_main_t * const main); -#endif // _di_controller_print_help_ - -/** - * Execute main program. - * - * Be sure to call controller_main_delete() after executing this. - * - * If main.signal is non-zero, then this blocks and handles the following signals: - * - F_signal_abort - * - F_signal_broken_pipe - * - F_signal_hangup - * - F_signal_interrupt - * - F_signal_quit - * - F_signal_termination - * - * @param main - * The main program data. - * @param arguments - * The parameters passed to the process. - * - * @return - * F_none on success. - * F_child if this is a child process returning. - * - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * - * Status codes (with error bit) are returned on any problem. - * - * @see controller_main_delete() - */ -#ifndef _di_controller_main_ - extern f_status_t controller_main(controller_main_t * const main, const f_console_arguments_t *arguments); -#endif // _di_controller_main_ - -/** - * Deallocate main. - * - * Be sure to call this after executing controller_main(). - * - * If main.signal is non-zero, then this blocks and handles the following signals: - * - F_signal_abort - * - F_signal_broken_pipe - * - F_signal_hangup - * - F_signal_interrupt - * - F_signal_quit - * - F_signal_termination - * - * @param main - * The main program data. - * - * @return - * F_none on success. - * - * Status codes (with error bit) are returned on any problem. - * - * @see controller_main() - */ -#ifndef _di_controller_main_delete_ - extern f_status_t controller_main_delete(controller_main_t * const main); -#endif // _di_controller_main_delete_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _controller_h diff --git a/level_3/controller/c/private-common.c b/level_3/controller/c/private-common.c deleted file mode 100644 index cbb5d0e..0000000 --- a/level_3/controller/c/private-common.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "controller.h" -#include "private-common.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_string_s_ - const f_string_t controller_action_s = CONTROLLER_action_s; - const f_string_t controller_actions_s = CONTROLLER_actions_s; - const f_string_t controller_affinity_s = CONTROLLER_affinity_s; - const f_string_t controller_as_s = CONTROLLER_as_s; - const f_string_t controller_asynchronous_s = CONTROLLER_asynchronous_s; - const f_string_t controller_bash_s = CONTROLLER_bash_s; - const f_string_t controller_batch_s = CONTROLLER_batch_s; - const f_string_t controller_capability_s = CONTROLLER_capability_s; - const f_string_t controller_cgroup_s = CONTROLLER_cgroup_s; - const f_string_t controller_create_s = CONTROLLER_create_s; - const f_string_t controller_command_s = CONTROLLER_command_s; - const f_string_t controller_consider_s = CONTROLLER_consider_s; - const f_string_t controller_control_s = CONTROLLER_control_s; - const f_string_t controller_control_group_s = CONTROLLER_control_group_s; - const f_string_t controller_control_mode_s = CONTROLLER_control_mode_s; - const f_string_t controller_control_user_s = CONTROLLER_control_user_s; - const f_string_t controller_cpu_s = CONTROLLER_cpu_s; - const f_string_t controller_core_s = CONTROLLER_core_s; - const f_string_t controller_data_s = CONTROLLER_data_s; - const f_string_t controller_deadline_s = CONTROLLER_deadline_s; - const f_string_t controller_default_s = CONTROLLER_default_s; - const f_string_t controller_define_s = CONTROLLER_define_s; - const f_string_t controller_delay_s = CONTROLLER_delay_s; - const f_string_t controller_disable_s = CONTROLLER_disable_s; - const f_string_t controller_entry_s = CONTROLLER_entry_s; - const f_string_t controller_entries_s = CONTROLLER_entries_s; - const f_string_t controller_environment_s = CONTROLLER_environment_s; - const f_string_t controller_execute_s = CONTROLLER_execute_s; - const f_string_t controller_existing_s = CONTROLLER_existing_s; - const f_string_t controller_exit_s = CONTROLLER_exit_s; - const f_string_t controller_exits_s = CONTROLLER_exits_s; - const f_string_t controller_fail_s = CONTROLLER_fail_s; - const f_string_t controller_failsafe_s = CONTROLLER_failsafe_s; - const f_string_t controller_failure_s = CONTROLLER_failure_s; - const f_string_t controller_fifo_s = CONTROLLER_fifo_s; - const f_string_t controller_freeze_s = CONTROLLER_freeze_s; - const f_string_t controller_fsize_s = CONTROLLER_fsize_s; - const f_string_t controller_full_path_s = CONTROLLER_full_path_s; - const f_string_t controller_group_s = CONTROLLER_group_s; - const f_string_t controller_groups_s = CONTROLLER_groups_s; - const f_string_t controller_how_s = CONTROLLER_how_s; - const f_string_t controller_idle_s = CONTROLLER_idle_s; - const f_string_t controller_item_s = CONTROLLER_item_s; - const f_string_t controller_init_s = CONTROLLER_init_s; - const f_string_t controller_kill_s = CONTROLLER_kill_s; - const f_string_t controller_limit_s = CONTROLLER_limit_s; - const f_string_t controller_locks_s = CONTROLLER_locks_s; - const f_string_t controller_main_s = CONTROLLER_main_s; - const f_string_t controller_max_s = CONTROLLER_max_s; - const f_string_t controller_memlock_s = CONTROLLER_memlock_s; - const f_string_t controller_method_s = CONTROLLER_method_s; - const f_string_t controller_mode_s = CONTROLLER_mode_s; - const f_string_t controller_msgqueue_s = CONTROLLER_msgqueue_s; - const f_string_t controller_name_s = CONTROLLER_name_s; - const f_string_t controller_need_s = CONTROLLER_need_s; - const f_string_t controller_new_s = CONTROLLER_new_s; - const f_string_t controller_nice_s = CONTROLLER_nice_s; - const f_string_t controller_no_s = CONTROLLER_no_s; - const f_string_t controller_nofile_s = CONTROLLER_nofile_s; - const f_string_t controller_normal_s = CONTROLLER_normal_s; - const f_string_t controller_nproc_s = CONTROLLER_nproc_s; - const f_string_t controller_on_s = CONTROLLER_on_s; - const f_string_t controller_optional_s = CONTROLLER_optional_s; - const f_string_t controller_other_s = CONTROLLER_other_s; - const f_string_t controller_parameter_s = CONTROLLER_parameter_s; - const f_string_t controller_parameters_s = CONTROLLER_parameters_s; - const f_string_t controller_path_s = CONTROLLER_path_s; - const f_string_t controller_pause_s = CONTROLLER_pause_s; - const f_string_t controller_pid_s = CONTROLLER_pid_s; - const f_string_t controller_pid_file_s = CONTROLLER_pid_file_s; - const f_string_t controller_processor_s = CONTROLLER_processor_s; - const f_string_t controller_program_s = CONTROLLER_program_s; - const f_string_t controller_ready_s = CONTROLLER_ready_s; - const f_string_t controller_reload_s = CONTROLLER_reload_s; - const f_string_t controller_require_s = CONTROLLER_require_s; - const f_string_t controller_required_s = CONTROLLER_required_s; - const f_string_t controller_rerun_s = CONTROLLER_rerun_s; - const f_string_t controller_reset_s = CONTROLLER_reset_s; - const f_string_t controller_restart_s = CONTROLLER_restart_s; - const f_string_t controller_resume_s = CONTROLLER_resume_s; - const f_string_t controller_round_robin_s = CONTROLLER_round_robin_s; - const f_string_t controller_rss_s = CONTROLLER_rss_s; - const f_string_t controller_rtprio_s = CONTROLLER_rtprio_s; - const f_string_t controller_rttime_s = CONTROLLER_rttime_s; - const f_string_t controller_rule_s = CONTROLLER_rule_s; - const f_string_t controller_rules_s = CONTROLLER_rules_s; - const f_string_t controller_same_s = CONTROLLER_same_s; - const f_string_t controller_scheduler_s = CONTROLLER_scheduler_s; - const f_string_t controller_script_s = CONTROLLER_script_s; - const f_string_t controller_service_s = CONTROLLER_service_s; - const f_string_t controller_setting_s = CONTROLLER_setting_s; - const f_string_t controller_session_s = CONTROLLER_session_s; - const f_string_t controller_session_new_s = CONTROLLER_session_new_s; - const f_string_t controller_session_same_s = CONTROLLER_session_same_s; - const f_string_t controller_show_s = CONTROLLER_show_s; - const f_string_t controller_sigpending_s = CONTROLLER_sigpending_s; - const f_string_t controller_stack_s = CONTROLLER_stack_s; - const f_string_t controller_start_s = CONTROLLER_start_s; - const f_string_t controller_stop_s = CONTROLLER_stop_s; - const f_string_t controller_succeed_s = CONTROLLER_succeed_s; - const f_string_t controller_success_s = CONTROLLER_success_s; - const f_string_t controller_synchronous_s = CONTROLLER_synchronous_s; - const f_string_t controller_thaw_s = CONTROLLER_thaw_s; - const f_string_t controller_timeout_s = CONTROLLER_timeout_s; - const f_string_t controller_type_s = CONTROLLER_type_s; - const f_string_t controller_use_s = CONTROLLER_use_s; - const f_string_t controller_user_s = CONTROLLER_user_s; - const f_string_t controller_utility_s = CONTROLLER_utility_s; - const f_string_t controller_value_s = CONTROLLER_value_s; - const f_string_t controller_wait_s = CONTROLLER_wait_s; - const f_string_t controller_want_s = CONTROLLER_want_s; - const f_string_t controller_wish_s = CONTROLLER_wish_s; - const f_string_t controller_with_s = CONTROLLER_with_s; - const f_string_t controller_yes_s = CONTROLLER_yes_s; -#endif // _di_controller_string_s_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-common.h b/level_3/controller/c/private-common.h deleted file mode 100644 index 586ffd0..0000000 --- a/level_3/controller/c/private-common.h +++ /dev/null @@ -1,476 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_common_h -#define _PRIVATE_common_h - -#ifdef __cplusplus -extern "C" { -#endif - -// These are included in the order of their dependencies. -#include "common/private-cache.h" -#include "common/private-execute_set.h" -#include "common/private-lock.h" -#include "common/private-rule.h" -#include "common/private-task.h" -#include "common/private-process.h" -#include "common/private-entry.h" -#include "common/private-setting.h" -#include "common/private-thread.h" -#include "common/private-state.h" -#include "common/private-control.h" - -/** - * All special strings used within this program. - * - * These are generally the names to match, representing some action or setting. - */ -#ifndef _di_controller_string_s_ - #define CONTROLLER_action_s "action" - #define CONTROLLER_actions_s "actions" - #define CONTROLLER_affinity_s "affinity" - #define CONTROLLER_as_s "as" - #define CONTROLLER_asynchronous_s "asynchronous" - #define CONTROLLER_bash_s "bash" - #define CONTROLLER_batch_s "batch" - #define CONTROLLER_capability_s "capability" - #define CONTROLLER_cgroup_s "cgroup" - #define CONTROLLER_create_s "create" - #define CONTROLLER_command_s "command" - #define CONTROLLER_consider_s "consider" - #define CONTROLLER_control_s "control" - #define CONTROLLER_control_group_s "control_group" - #define CONTROLLER_control_mode_s "control_mode" - #define CONTROLLER_control_user_s "control_user" - #define CONTROLLER_cpu_s "cpu" - #define CONTROLLER_core_s "core" - #define CONTROLLER_data_s "data" - #define CONTROLLER_deadline_s "deadline" - #define CONTROLLER_default_s "default" - #define CONTROLLER_define_s "define" - #define CONTROLLER_delay_s "delay" - #define CONTROLLER_disable_s "disable" - #define CONTROLLER_entry_s "entry" - #define CONTROLLER_entries_s "entries" - #define CONTROLLER_environment_s "environment" - #define CONTROLLER_execute_s "execute" - #define CONTROLLER_existing_s "existing" - #define CONTROLLER_exit_s "exit" - #define CONTROLLER_exits_s "exits" - #define CONTROLLER_fail_s "fail" - #define CONTROLLER_failsafe_s "failsafe" - #define CONTROLLER_failure_s "failure" - #define CONTROLLER_fifo_s "fifo" - #define CONTROLLER_freeze_s "freeze" - #define CONTROLLER_fsize_s "fsize" - #define CONTROLLER_full_path_s "full_path" - #define CONTROLLER_group_s "group" - #define CONTROLLER_groups_s "groups" - #define CONTROLLER_how_s "how" - #define CONTROLLER_idle_s "idle" - #define CONTROLLER_item_s "item" - #define CONTROLLER_init_s "init" - #define CONTROLLER_kill_s "kill" - #define CONTROLLER_limit_s "limit" - #define CONTROLLER_locks_s "locks" - #define CONTROLLER_main_s "main" - #define CONTROLLER_max_s "max" - #define CONTROLLER_memlock_s "memlock" - #define CONTROLLER_method_s "method" - #define CONTROLLER_mode_s "mode" - #define CONTROLLER_msgqueue_s "msgqueue" - #define CONTROLLER_name_s "name" - #define CONTROLLER_need_s "need" - #define CONTROLLER_new_s "new" - #define CONTROLLER_nice_s "nice" - #define CONTROLLER_no_s "no" - #define CONTROLLER_nofile_s "nofile" - #define CONTROLLER_normal_s "normal" - #define CONTROLLER_nproc_s "nproc" - #define CONTROLLER_on_s "on" - #define CONTROLLER_optional_s "optional" - #define CONTROLLER_other_s "other" - #define CONTROLLER_parameter_s "parameter" - #define CONTROLLER_parameters_s "parameters" - #define CONTROLLER_path_s "path" - #define CONTROLLER_pause_s "pause" - #define CONTROLLER_pid_s "pid" - #define CONTROLLER_pid_file_s "pid_file" - #define CONTROLLER_processor_s "processor" - #define CONTROLLER_program_s "program" - #define CONTROLLER_ready_s "ready" - #define CONTROLLER_reload_s "reload" - #define CONTROLLER_require_s "require" - #define CONTROLLER_required_s "required" - #define CONTROLLER_rerun_s "rerun" - #define CONTROLLER_reset_s "reset" - #define CONTROLLER_restart_s "restart" - #define CONTROLLER_resume_s "resume" - #define CONTROLLER_round_robin_s "round_robin" - #define CONTROLLER_rss_s "rss" - #define CONTROLLER_rtprio_s "rtprio" - #define CONTROLLER_rttime_s "rttime" - #define CONTROLLER_rule_s "rule" - #define CONTROLLER_rules_s "rules" - #define CONTROLLER_same_s "same" - #define CONTROLLER_scheduler_s "scheduler" - #define CONTROLLER_script_s "script" - #define CONTROLLER_service_s "service" - #define CONTROLLER_session_s "session" - #define CONTROLLER_session_new_s "session_new" - #define CONTROLLER_session_same_s "session_same" - #define CONTROLLER_setting_s "setting" - #define CONTROLLER_sigpending_s "sigpending" - #define CONTROLLER_show_s "show" - #define CONTROLLER_stack_s "stack" - #define CONTROLLER_start_s "start" - #define CONTROLLER_stop_s "stop" - #define CONTROLLER_succeed_s "succeed" - #define CONTROLLER_success_s "success" - #define CONTROLLER_synchronous_s "synchronous" - #define CONTROLLER_thaw_s "thaw" - #define CONTROLLER_timeout_s "timeout" - #define CONTROLLER_type_s "type" - #define CONTROLLER_use_s "use" - #define CONTROLLER_user_s "user" - #define CONTROLLER_utility_s "utility" - #define CONTROLLER_value_s "value" - #define CONTROLLER_wait_s "wait" - #define CONTROLLER_want_s "want" - #define CONTROLLER_wish_s "wish" - #define CONTROLLER_with_s "with" - #define CONTROLLER_yes_s "yes" - - #define controller_action_s_length 6 - #define controller_actions_s_length 7 - #define controller_affinity_s_length 8 - #define controller_as_s_length 2 - #define controller_asynchronous_s_length 12 - #define controller_bash_s_length 4 - #define controller_batch_s_length 5 - #define controller_capability_s_length 10 - #define controller_cgroup_s_length 6 - #define controller_create_s_length 6 - #define controller_command_s_length 7 - #define controller_consider_s_length 8 - #define controller_control_s_length 7 - #define controller_control_group_s_length 13 - #define controller_control_mode_s_length 12 - #define controller_control_user_s_length 12 - #define controller_core_s_length 4 - #define controller_cpu_s_length 3 - #define controller_data_s_length 4 - #define controller_deadline_s_length 8 - #define controller_default_s_length 7 - #define controller_define_s_length 6 - #define controller_delay_s_length 5 - #define controller_disable_s_length 7 - #define controller_entry_s_length 5 - #define controller_entries_s_length 7 - #define controller_environment_s_length 11 - #define controller_existing_s_length 8 - #define controller_execute_s_length 7 - #define controller_exit_s_length 4 - #define controller_exits_s_length 5 - #define controller_fail_s_length 4 - #define controller_failure_s_length 7 - #define controller_failsafe_s_length 8 - #define controller_fifo_s_length 4 - #define controller_freeze_s_length 6 - #define controller_fsize_s_length 5 - #define controller_full_path_s_length 9 - #define controller_group_s_length 5 - #define controller_groups_s_length 6 - #define controller_how_s_length 3 - #define controller_idle_s_length 4 - #define controller_init_s_length 4 - #define controller_item_s_length 4 - #define controller_kill_s_length 4 - #define controller_limit_s_length 5 - #define controller_locks_s_length 5 - #define controller_main_s_length 4 - #define controller_max_s_length 3 - #define controller_memlock_s_length 7 - #define controller_method_s_length 6 - #define controller_mode_s_length 4 - #define controller_msgqueue_s_length 8 - #define controller_name_s_length 4 - #define controller_need_s_length 4 - #define controller_new_s_length 3 - #define controller_nice_s_length 4 - #define controller_no_s_length 2 - #define controller_nofile_s_length 6 - #define controller_normal_s_length 6 - #define controller_nproc_s_length 5 - #define controller_on_s_length 2 - #define controller_optional_s_length 8 - #define controller_other_s_length 5 - #define controller_parameter_s_length 9 - #define controller_parameters_s_length 10 - #define controller_path_s_length 4 - #define controller_pause_s_length 5 - #define controller_pid_s_length 3 - #define controller_pid_file_s_length 8 - #define controller_processor_s_length 9 - #define controller_program_s_length 7 - #define controller_ready_s_length 5 - #define controller_reload_s_length 6 - #define controller_require_s_length 7 - #define controller_required_s_length 8 - #define controller_rerun_s_length 5 - #define controller_reset_s_length 5 - #define controller_restart_s_length 7 - #define controller_resume_s_length 6 - #define controller_round_robin_s_length 11 - #define controller_rss_s_length 3 - #define controller_rtprio_s_length 6 - #define controller_rttime_s_length 6 - #define controller_rule_s_length 4 - #define controller_rules_s_length 5 - #define controller_same_s_length 4 - #define controller_scheduler_s_length 9 - #define controller_script_s_length 6 - #define controller_service_s_length 7 - #define controller_session_s_length 7 - #define controller_session_new_s_length 11 - #define controller_session_same_s_length 12 - #define controller_setting_s_length 7 - #define controller_show_s_length 4 - #define controller_sigpending_s_length 10 - #define controller_stack_s_length 5 - #define controller_start_s_length 5 - #define controller_stop_s_length 4 - #define controller_succeed_s_length 7 - #define controller_success_s_length 7 - #define controller_synchronous_s_length 11 - #define controller_thaw_s_length 4 - #define controller_timeout_s_length 7 - #define controller_type_s_length 4 - #define controller_use_s_length 3 - #define controller_user_s_length 4 - #define controller_utility_s_length 7 - #define controller_value_s_length 5 - #define controller_wait_s_length 4 - #define controller_want_s_length 4 - #define controller_wish_s_length 4 - #define controller_with_s_length 4 - #define controller_yes_s_length 3 - - extern const f_string_t controller_action_s; - extern const f_string_t controller_actions_s; - extern const f_string_t controller_affinity_s; - extern const f_string_t controller_as_s; - extern const f_string_t controller_asynchronous_s; - extern const f_string_t controller_bash_s; - extern const f_string_t controller_batch_s; - extern const f_string_t controller_capability_s; - extern const f_string_t controller_cgroup_s; - extern const f_string_t controller_create_s; - extern const f_string_t controller_command_s; - extern const f_string_t controller_consider_s; - extern const f_string_t controller_control_s; - extern const f_string_t controller_control_group_s; - extern const f_string_t controller_control_mode_s; - extern const f_string_t controller_control_user_s; - extern const f_string_t controller_core_s; - extern const f_string_t controller_cpu_s; - extern const f_string_t controller_data_s; - extern const f_string_t controller_deadline_s; - extern const f_string_t controller_default_s; - extern const f_string_t controller_define_s; - extern const f_string_t controller_delay_s; - extern const f_string_t controller_disable_s; - extern const f_string_t controller_entry_s; - extern const f_string_t controller_entries_s; - extern const f_string_t controller_environment_s; - extern const f_string_t controller_existing_s; - extern const f_string_t controller_execute_s; - extern const f_string_t controller_exit_s; - extern const f_string_t controller_exits_s; - extern const f_string_t controller_fail_s; - extern const f_string_t controller_failsafe_s; - extern const f_string_t controller_failure_s; - extern const f_string_t controller_fifo_s; - extern const f_string_t controller_freeze_s; - extern const f_string_t controller_fsize_s; - extern const f_string_t controller_full_path_s; - extern const f_string_t controller_group_s; - extern const f_string_t controller_groups_s; - extern const f_string_t controller_how_s; - extern const f_string_t controller_idle_s; - extern const f_string_t controller_init_s; - extern const f_string_t controller_item_s; - extern const f_string_t controller_kill_s; - extern const f_string_t controller_limit_s; - extern const f_string_t controller_locks_s; - extern const f_string_t controller_main_s; - extern const f_string_t controller_max_s; - extern const f_string_t controller_memlock_s; - extern const f_string_t controller_method_s; - extern const f_string_t controller_mode_s; - extern const f_string_t controller_msgqueue_s; - extern const f_string_t controller_name_s; - extern const f_string_t controller_need_s; - extern const f_string_t controller_new_s; - extern const f_string_t controller_nice_s; - extern const f_string_t controller_no_s; - extern const f_string_t controller_nofile_s; - extern const f_string_t controller_normal_s; - extern const f_string_t controller_nproc_s; - extern const f_string_t controller_on_s; - extern const f_string_t controller_optional_s; - extern const f_string_t controller_other_s; - extern const f_string_t controller_parameter_s; - extern const f_string_t controller_parameters_s; - extern const f_string_t controller_path_s; - extern const f_string_t controller_pause_s; - extern const f_string_t controller_pid_s; - extern const f_string_t controller_pid_file_s; - extern const f_string_t controller_processor_s; - extern const f_string_t controller_program_s; - extern const f_string_t controller_ready_s; - extern const f_string_t controller_reload_s; - extern const f_string_t controller_require_s; - extern const f_string_t controller_required_s; - extern const f_string_t controller_rerun_s; - extern const f_string_t controller_reset_s; - extern const f_string_t controller_restart_s; - extern const f_string_t controller_resume_s; - extern const f_string_t controller_round_robin_s; - extern const f_string_t controller_rss_s; - extern const f_string_t controller_rtprio_s; - extern const f_string_t controller_rttime_s; - extern const f_string_t controller_rule_s; - extern const f_string_t controller_rules_s; - extern const f_string_t controller_same_s; - extern const f_string_t controller_scheduler_s; - extern const f_string_t controller_script_s; - extern const f_string_t controller_service_s; - extern const f_string_t controller_session_s; - extern const f_string_t controller_session_new_s; - extern const f_string_t controller_session_same_s; - extern const f_string_t controller_setting_s; - extern const f_string_t controller_show_s; - extern const f_string_t controller_sigpending_s; - extern const f_string_t controller_stack_s; - extern const f_string_t controller_start_s; - extern const f_string_t controller_stop_s; - extern const f_string_t controller_succeed_s; - extern const f_string_t controller_success_s; - extern const f_string_t controller_synchronous_s; - extern const f_string_t controller_thaw_s; - extern const f_string_t controller_timeout_s; - extern const f_string_t controller_type_s; - extern const f_string_t controller_use_s; - extern const f_string_t controller_user_s; - extern const f_string_t controller_utility_s; - extern const f_string_t controller_value_s; - extern const f_string_t controller_wait_s; - extern const f_string_t controller_want_s; - extern const f_string_t controller_wish_s; - extern const f_string_t controller_with_s; - extern const f_string_t controller_yes_s; -#endif // _di_controller_string_s_ - -/** - * A set of codes for resource limitations. - * - * This essentally converts the POSIX standard names into a more verbose format. - */ -#ifndef _di_controller_resource_limit_t_ - enum { - controller_resource_limit_type_as_e = RLIMIT_AS, - controller_resource_limit_type_core_e = RLIMIT_CORE, - controller_resource_limit_type_cpu_e = RLIMIT_CPU, - controller_resource_limit_type_data_e = RLIMIT_DATA, - controller_resource_limit_type_fsize_e = RLIMIT_FSIZE, - controller_resource_limit_type_locks_e = RLIMIT_LOCKS, - controller_resource_limit_type_memlock_e = RLIMIT_MEMLOCK, - controller_resource_limit_type_msgqueue_e = RLIMIT_MSGQUEUE, - controller_resource_limit_type_nice_e = RLIMIT_NICE, - controller_resource_limit_type_nofile_e = RLIMIT_NOFILE, - controller_resource_limit_type_nproc_e = RLIMIT_NPROC, - controller_resource_limit_type_rss_e = RLIMIT_RSS, - controller_resource_limit_type_rtprio_e = RLIMIT_RTPRIO, - controller_resource_limit_type_rttime_e = RLIMIT_RTTIME, - controller_resource_limit_type_sigpending_e = RLIMIT_SIGPENDING, - controller_resource_limit_type_stack_e = RLIMIT_STACK, - }; -#endif // _di_controller_resource_limit_t_ - -/** - * Provide common/generic definitions. - * - * The controller_common_allocation_large_d or controller_common_allocation_small_d must be at least 2 for this project. - * - * controller_common_allocation_*: - * - large: An allocation step used for buffers that are anticipated to have large buffers. - * - small: An allocation step used for buffers that are anticipated to have small buffers. - */ -#ifndef _di_controller_common_ - #define controller_common_allocation_large_d 256 - #define controller_common_allocation_small_d 16 -#endif // _di_controller_common_ - -/** - * A set of codes representing different with flags. - */ -#ifndef _di_controller_with_defines_ - #define controller_with_full_path_d 0x1 - #define controller_with_session_new_d 0x2 - #define controller_with_session_same_d 0x4 -#endif // _di_controller_with_defines_ - -/** - * A wrapper used for passing a common set of all data, particularly for sharing between threads. - * - * main: The main program data. - * setting: All loaded settings. - * thread: All thread related data. - */ -#ifndef _di_controller_main_t_ - typedef struct { - controller_main_t *main; - controller_setting_t *setting; - controller_thread_t *thread; - } controller_global_t; - - #define controller_global_t_initialize { 0, 0, 0 } - - #define macro_controller_global_t_initialize(main, setting, thread) { \ - main, \ - setting, \ - thread, \ - } -#endif // _di_controller_main_t_ - -/** - * A wrapper used for passing a set of entry processing and execution related data. - * - * global: All data globally shared. - * setting: The setting data. - */ -#ifndef _di_controller_main_entry_t_ - typedef struct { - controller_global_t *global; - controller_setting_t *setting; - } controller_main_entry_t; - - #define controller_main_entry_t_initialize { 0, 0 } - - #define macro_controller_main_entry_t_initialize(global, setting) { \ - global, \ - setting, \ - } -#endif // _di_controller_main_entry_t_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_common_h diff --git a/level_3/controller/c/private-control.c b/level_3/controller/c/private-control.c deleted file mode 100644 index 5749886..0000000 --- a/level_3/controller/c/private-control.c +++ /dev/null @@ -1,102 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-control.h" -#include "private-controller_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_control_configure_client_ - f_status_t controller_control_configure_client(const controller_global_t *global, f_socket_t * const client) { - - struct timeval time_out; - time_out.tv_sec = 0; - time_out.tv_usec = controller_control_default_socket_timeout_d; - - f_status_t status = f_socket_option_set(client, 1, f_socket_option_time_out_receive_d, (void *) &time_out, sizeof(struct timeval)); - - if (F_status_is_error_not(status)) { - status = f_socket_option_set(client, 1, f_socket_option_time_out_send_d, (void *) &time_out, sizeof(struct timeval)); - } - - if (F_status_is_error(status)) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_option_set", F_true); - } - - return status; - } -#endif // _di_controller_control_configure_client_ - -#ifndef _di_controller_control_configure_server_ - f_status_t controller_control_configure_server(const controller_global_t *global, f_socket_t * const server) { - - struct linger value = { 1, 1 }; - - f_status_t status = f_socket_option_set(server, controller_control_default_socket_linger_d, f_socket_option_linger_d, (void *) &value, sizeof(struct linger)); - - if (F_status_is_error(status)) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_option_set", F_true); - } - - return status; - } -#endif // _di_controller_control_configure_server_ - -#ifndef _di_controller_control_accept_ - f_status_t controller_control_accept(const controller_global_t *global, f_socket_t * const server, controller_packet_t * const packet) { - - f_socket_t client = f_socket_t_initialize; - - f_status_t status = f_socket_accept(&client, server->id); - - if (F_status_is_error(status)) { - f_socket_disconnect(&client, f_socket_close_read_write_e); - - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_accept", F_true); - - return status; - } - - controller_control_configure_client(global, &client); - - char buffer[controller_control_default_socket_buffer_d + 1]; - size_t length = 0; - - memset(buffer, 0, controller_control_default_socket_buffer_d + 1); - packet->payload.used = 0; - - // Pre-process the packet header. - client.size_read = controller_control_default_socket_header_d; - status = f_socket_read(&client, f_socket_flag_peek_d, buffer, &length); - - if (F_status_is_error(status)) { - f_socket_disconnect(&client, f_socket_close_read_write_e); - - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_read", F_true); - - return status; - } - - client.size_read = controller_control_default_socket_buffer_d; - - // Get all remaining data. - //while (???) { // until done, based on expected length that should be described in the packet header. - //message_length = recv(&client, buffer, input_size, receive_flags); - - //} // while - - // process the data. - - // send any responses. - // sent = send(&client, packet, output_size, send_flags); - - f_socket_disconnect(&client, f_socket_close_read_write_e); - - return F_none; - } -#endif // _di_controller_control_accept_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-control.h b/level_3/controller/c/private-control.h deleted file mode 100644 index 46987b6..0000000 --- a/level_3/controller/c/private-control.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_control_h -#define _PRIVATE_control_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Configure client socket settings. - * - * @param global - * The global data. - * @param client - * The client socket structure. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_socket_option_set(). - * - * @see f_socket_option_set() - */ -#ifndef _di_controller_control_configure_client_ - extern f_status_t controller_control_configure_client(const controller_global_t *global, f_socket_t * const client) F_attribute_visibility_internal_d; -#endif // _di_controller_control_configure_client_ - -/** - * Configure server socket settings. - * - * @param global - * The global data. - * @param server - * The server socket structure. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_socket_option_set(). - * - * @see f_socket_option_set() - */ -#ifndef _di_controller_control_configure_server_ - extern f_status_t controller_control_configure_server(const controller_global_t *global, f_socket_t * const server) F_attribute_visibility_internal_d; -#endif // _di_controller_control_configure_server_ - -/** - * Accept connections from a control socket server. - * - * Connectons are processed and actions are performed. - * - * @param global - * The global data. - * @param socket - * The socket structure. - * @param packet - * The control packet data structure. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_socket_accept(). - * - * @see f_socket_accept() - */ -#ifndef _di_controller_control_accept_ - extern f_status_t controller_control_accept(const controller_global_t *global, f_socket_t * const server, controller_packet_t * const packet) F_attribute_visibility_internal_d; -#endif // _di_controller_control_accept_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_control_h diff --git a/level_3/controller/c/private-control_print.c b/level_3/controller/c/private-control_print.c deleted file mode 100644 index 354d8e6..0000000 --- a/level_3/controller/c/private-control_print.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-control_print.h" -#include "private-lock_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-control_print.h b/level_3/controller/c/private-control_print.h deleted file mode 100644 index a87f0c5..0000000 --- a/level_3/controller/c/private-control_print.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_control_print_h -#define _PRIVATE_control_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_control_print_h diff --git a/level_3/controller/c/private-controller.c b/level_3/controller/c/private-controller.c deleted file mode 100644 index 34d8588..0000000 --- a/level_3/controller/c/private-controller.c +++ /dev/null @@ -1,789 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-entry_print.h" -#include "private-lock_print.h" -#include "private-thread_control.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_range_after_number_sign_ - f_string_range_t controller_range_after_number_sign(const f_string_static_t buffer, const f_string_range_t range) { - - f_string_range_t result = range; - - for (; result.start <= result.stop; ++result.start) { - - if (!buffer.string[result.start]) continue; - - if (buffer.string[result.start] == '-' || buffer.string[result.start] == '+') { - ++result.start; - } - - break; - } // while - - return result; - } -#endif // _di_controller_range_after_number_sign_ - -#ifndef _di_controller_string_dynamic_rip_nulless_terminated_ - f_status_t controller_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 f_string_dynamic_terminate_after(destination); - } -#endif // _di_controller_string_dynamic_rip_nulless_terminated_ - -#ifndef _di_controller_string_dynamic_append_terminated_ - f_status_t controller_dynamic_append_terminated(const f_string_static_t source, f_string_dynamic_t *destination) { - - f_status_t status = f_string_dynamic_append_nulless(source, destination); - if (F_status_is_error(status)) return status; - - return f_string_dynamic_terminate_after(destination); - } -#endif // _di_controller_string_dynamic_append_terminated_ - -#ifndef _di_controller_string_dynamic_partial_append_terminated_ - f_status_t controller_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 = f_string_dynamic_partial_append(source, range, destination); - if (F_status_is_error(status)) return status; - - return f_string_dynamic_terminate_after(destination); - } -#endif // _di_controller_string_dynamic_partial_append_terminated_ - -#ifndef _di_controller_file_load_ - f_status_t controller_file_load(const controller_global_t global, const bool required, const f_string_t path_prefix, const f_string_static_t path_name, const f_string_t path_suffix, const f_array_length_t path_prefix_length, const f_array_length_t path_suffix_length, controller_cache_t * const cache) { - - f_status_t status = F_none; - f_file_t file = f_file_t_initialize; - - cache->action.name_file.used = 0; - cache->buffer_file.used = 0; - - macro_f_time_spec_t_clear(cache->timestamp); - - status = f_string_append(path_prefix, path_prefix_length, &cache->action.name_file); - - if (F_status_is_error_not(status)) { - status = f_string_append(f_path_separator_s, F_path_separator_s_length, &cache->action.name_file); - } - - if (F_status_is_error_not(status)) { - status = f_string_append(path_name.string, path_name.used, &cache->action.name_file); - } - - if (F_status_is_error_not(status)) { - status = f_string_append(F_path_extension_separator_s, F_path_extension_separator_s_length, &cache->action.name_file); - } - - if (F_status_is_error_not(status)) { - status = f_string_append(path_suffix, path_suffix_length, &cache->action.name_file); - } - - if (F_status_is_error(status)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_append", F_true); - } - - return status; - } - - status = f_string_dynamic_terminate_after(&cache->action.name_file); - - if (F_status_is_error(status)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - - return status; - } - - const f_array_length_t path_length = global.setting->path_setting.used ? global.setting->path_setting.used + F_path_separator_s_length + cache->action.name_file.used : cache->action.name_file.used; - char path[path_length + 1]; - - if (global.setting->path_setting.used) { - memcpy(path, global.setting->path_setting.string, global.setting->path_setting.used); - memcpy(path + global.setting->path_setting.used + F_path_separator_s_length, cache->action.name_file.string, cache->action.name_file.used); - - path[global.setting->path_setting.used] = f_path_separator_s[0]; - } - - path[path_length] = 0; - - status = f_file_stream_open(path, 0, &file); - - if (F_status_is_error(status)) { - if (!required && F_status_set_fine(status) == F_file_found_not) { - f_file_stream_close(F_true, &file); - - return F_file_found_not; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error_file(global.thread, global.main->error, F_status_set_fine(status), "f_file_stream_open", F_true, path, "open", fll_error_file_type_file_e); - } - } - else { - status = f_file_stream_read(file, &cache->buffer_file); - - if (F_status_is_error(status)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error_file(global.thread, global.main->error, F_status_set_fine(status), "f_file_stream_read", F_true, path, "read", fll_error_file_type_file_e); - } - } - } - - f_file_stream_close(F_true, &file); - - if (F_status_is_error_not(status)) { - struct stat stat_file; - - status = f_file_stat(path, F_true, &stat_file); - - if (F_status_is_error(status)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error_file(global.thread, global.main->error, F_status_set_fine(status), "f_file_stat", F_true, path, "stat", fll_error_file_type_file_e); - } - } - else { - cache->timestamp.seconds = stat_file.st_ctim.tv_sec; - cache->timestamp.nanoseconds = stat_file.st_ctim.tv_nsec; - } - } - - if (F_status_is_error(status)) return status; - - return F_none; - } -#endif // _di_controller_file_load_ - -#ifndef _di_controller_file_pid_create_ - f_status_t controller_file_pid_create(const pid_t pid, const f_string_static_t path) { - - f_status_t status = F_none; - - // the file exists, do not attempt to overwrite. - if (f_file_exists(path.string) == F_true) { - return F_status_set_error(F_file_found); - } - - { - f_string_dynamic_t path_directory = f_string_dynamic_t_initialize; - - status = f_file_name_directory(path.string, path.used, &path_directory); - - if (F_status_is_error_not(status)) { - status = f_directory_exists(path_directory.string); - } - - macro_f_string_dynamic_t_delete_simple(path_directory) - - if (F_status_is_error(status)) return status; - - // the directory does not exist so do not bother attempting to create a pid file. - if (status == F_false) { - return F_status_set_error(F_directory_not); - } - } - - f_file_t file = f_file_t_initialize; - - file.flag = F_file_flag_write_only_d; - - status = f_file_stream_open(path.string, f_file_open_mode_truncate_s, &file); - if (F_status_is_error(status)) return status; - - fll_print_format("%i%c", file.stream, pid, f_string_eol_s[0]); - - f_file_stream_close(F_true, &file); - - if (F_status_is_error(status)) return status; - - return F_none; - } -#endif // _di_controller_file_pid_create_ - -#ifndef _di_controller_file_pid_delete_ - f_status_t controller_file_pid_delete(const pid_t pid, const f_string_static_t path) { - - // only delete if the file exists and there is no error while checking. - if (f_file_exists(path.string) != F_true) { - return F_none; - } - - f_status_t status = F_none; - f_file_t pid_file = f_file_t_initialize; - - status = f_file_stream_open(path.string, f_file_open_mode_read_s, &pid_file); - if (F_status_is_error(status)) return status; - - f_string_dynamic_t pid_buffer = f_string_dynamic_t_initialize; - - status = f_file_stream_read(pid_file, &pid_buffer); - - if (F_status_is_error_not(status)) { - status = f_file_stream_close(F_true, &pid_file); - } - - if (F_status_is_error_not(status)) { - f_number_unsigned_t number = 0; - f_string_range_t range = macro_f_string_range_t_initialize(pid_buffer.used); - - for (; range.start < pid_buffer.used; ++range.start) { - if (!isspace(pid_buffer.string[range.start])) break; - } // for - - for (; range.stop > 0; --range.stop) { - if (!isspace(pid_buffer.string[range.stop])) break; - } // for - - status = fl_conversion_string_to_decimal_unsigned(pid_buffer.string, range, &number); - - if (F_status_is_error_not(status) && number == pid) { - status = f_file_remove(path.string); - } - else { - status = F_status_set_error(F_number_not); - } - } - - macro_f_string_dynamic_t_delete_simple(pid_buffer); - - return status; - } -#endif // _di_controller_file_pid_delete_ - -#ifndef _di_controller_file_pid_read_ - f_status_t controller_file_pid_read(const f_string_static_t path, pid_t * const pid) { - - *pid = 0; - - f_status_t status = f_file_exists(path.string); - if (F_status_is_error(status)) return status; - - if (status != F_true) { - return F_data_not; - } - - f_file_t pid_file = f_file_t_initialize; - - status = f_file_stream_open(path.string, f_file_open_mode_read_s, &pid_file); - if (F_status_is_error(status)) return status; - - f_string_dynamic_t pid_buffer = f_string_dynamic_t_initialize; - - status = f_file_stream_read(pid_file, &pid_buffer); - - if (F_status_is_error_not(status)) { - status = f_file_stream_close(F_true, &pid_file); - } - - if (F_status_is_error_not(status)) { - f_number_unsigned_t number = 0; - f_string_range_t range = macro_f_string_range_t_initialize(pid_buffer.used); - - for (; range.start < pid_buffer.used; ++range.start) { - if (!isspace(pid_buffer.string[range.start])) break; - } // for - - for (; range.stop > 0; --range.stop) { - if (!isspace(pid_buffer.string[range.stop])) break; - } // for - - status = fl_conversion_string_to_decimal_unsigned(pid_buffer.string, range, &number); - - if (F_status_is_error_not(status)) { - *pid = (pid_t) number; - } - } - - macro_f_string_dynamic_t_delete_simple(pid_buffer); - - return status; - } -#endif // _di_controller_file_pid_read_ - -#ifndef _di_controller_get_id_user_ - f_status_t controller_get_id_user(const f_string_static_t buffer, const f_string_range_t range, controller_cache_t * const cache, uid_t * const id) { - - f_number_unsigned_t number = 0; - - f_status_t status = fl_conversion_string_to_number_unsigned(buffer.string, range, &number); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_number) { - cache->action.generic.used = 0; - - status = controller_dynamic_rip_nulless_terminated(buffer, range, &cache->action.generic); - if (F_status_is_error(status)) return status; - - status = f_account_id_user_by_name(cache->action.generic.string, id); - if (F_status_is_error(status)) return status; - - if (status == F_exist_not) { - return F_status_set_error(F_exist_not); - } - - return F_none; - } - - return status; - } - else if (number > F_type_size_32_unsigned_d) { - return F_status_set_error(F_number_too_large); - } - - return status; - } -#endif // _di_controller_get_id_user_ - -#ifndef _di_controller_get_id_group_ - f_status_t controller_get_id_group(const f_string_static_t buffer, const f_string_range_t range, controller_cache_t * const cache, gid_t * const id) { - - f_number_unsigned_t number = 0; - - f_status_t status = fl_conversion_string_to_number_unsigned(buffer.string, range, &number); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_number) { - cache->action.generic.used = 0; - - status = controller_dynamic_rip_nulless_terminated(buffer, range, &cache->action.generic); - if (F_status_is_error(status)) return status; - - status = f_account_id_group_by_name(cache->action.generic.string, id); - if (F_status_is_error(status)) return status; - - if (status == F_exist_not) { - return F_status_set_error(F_exist_not); - } - - return F_none; - } - - return status; - } - else if (number > F_type_size_32_unsigned_d) { - return F_status_set_error(F_number_too_large); - } - - return status; - } -#endif // _di_controller_get_id_group_ - -#ifndef _di_controller_perform_ready_ - f_status_t controller_perform_ready(const controller_global_t *global, controller_cache_t * const cache, const bool is_entry) { - - if (!is_entry) { - return F_none; - } - - f_status_t status = F_none; - - if (global->setting->entry.pid != controller_entry_pid_disable_e && !global->setting->path_pid.used) { - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_additional_e) { - status = controller_file_pid_create(global->main->pid, global->setting->path_pid); - } - - // Report pid file error but because this could be an "init" program, consider the pid file as optional and continue on. - if (F_status_is_error(status)) { - - // Always return immediately on memory errors. - if (F_status_set_fine(status) == F_memory_not) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - controller_print_error_file(0, global->main->error, F_status_set_fine(status), "controller_file_pid_create", F_true, global->setting->path_pid.string, "create", fll_error_file_type_file_e); - - flockfile(global->main->error.to.stream); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - - return status; - } - - if (global->main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->warning.to, global->thread); - - if (F_status_set_fine(status) == F_read_only) { - fl_print_format("%c%[%SThe pid file '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->warning.to.stream, global->main->warning.notable, global->setting->path_pid, global->main->warning.notable); - fl_print_format("%[' could not be written because the destination is read only.%]%c", global->main->warning.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - } - else { - controller_print_error_file(0, global->main->warning, F_status_set_fine(status), "controller_file_pid_create", F_true, global->setting->path_pid.string, "create", fll_error_file_type_file_e); - } - - controller_entry_print_error_cache(is_entry, global->main->warning, cache->action); - - controller_unlock_print_flush(global->main->warning.to, global->thread); - } - - status = F_none; - } - else { - global->setting->pid_created = F_true; - - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cPID file '", global->main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_pid, global->main->context.set.notable); - - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - fl_print_format("' created.%c", global->main->output.to.stream, f_string_eol_s[0]); - } - else { - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - } - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - } - - if (global->setting->path_control.used) { - if (global->setting->control_readonly) { - if (f_file_exists(global->setting->path_control.string) != F_true) { - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%[%SControl socket '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - fl_print_format("' .%c", global->main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[' cannot be found while read only mode is enabled and so the Control socket is unavailable.%]%c", global->main->output.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - - return status; - } - } - else { - status = f_socket_create(&global->setting->control_socket); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_create", F_true); - - return status; - } - - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%[%SControl socket '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - fl_print_format("%[' could not be created, code %]", global->main->output.to.stream, global->main->warning.context, global->main->warning.context); - fl_print_format("%[%ui%]", global->main->output.to.stream, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable); - fl_print_format("%[.%]%c", global->main->output.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - else { - status = f_file_remove(global->setting->path_control.string); - - if (F_status_set_fine(status) == F_memory_not) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_file_remove", F_true); - - return status; - } - - global->setting->control_socket.name = global->setting->path_control.string; - - status = f_socket_bind_file(global->setting->control_socket); - - if (F_status_is_error(status)) { - f_socket_disconnect(&global->setting->control_socket, f_socket_close_fast_e); - - if (F_status_set_fine(status) == F_memory_not) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_bind_file", F_true); - - return status; - } - - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%[%SControl socket '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - fl_print_format("%[' could not be bound, code %]", global->main->output.to.stream, global->main->warning.context, global->main->warning.context); - fl_print_format("%[%ui%]", global->main->output.to.stream, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable); - fl_print_format("%[.%]%c", global->main->output.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - else { - status = f_file_role_change(global->setting->path_control.string, global->setting->control_user, global->setting->control_group, F_true); - - if (F_status_is_error(status)) { - f_socket_disconnect(&global->setting->control_socket, f_socket_close_fast_e); - - if (F_status_set_fine(status) == F_memory_not) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_file_role_change", F_true); - - return status; - } - - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%[%SControl socket '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - fl_print_format("%[' failed to set file roles, code %]", global->main->output.to.stream, global->main->warning.context, global->main->warning.context); - fl_print_format("%[%ui%]", global->main->output.to.stream, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable); - fl_print_format("%[.%]%c", global->main->output.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - else { - status = f_file_mode_set(global->setting->path_control.string, global->setting->control_mode); - - if (F_status_is_error(status)) { - f_socket_disconnect(&global->setting->control_socket, f_socket_close_fast_e); - - if (F_status_set_fine(status) == F_memory_not) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_file_role_change", F_true); - - return status; - } - - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%[%SControl socket '%]", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - fl_print_format("%[' failed to set file mode, code %]", global->main->output.to.stream, global->main->warning.context, global->main->warning.context); - fl_print_format("%[%ui%]", global->main->output.to.stream, global->main->context.set.notable, F_status_set_fine(status), global->main->context.set.notable); - fl_print_format("%[.%]%c", global->main->output.to.stream, global->main->warning.context, global->main->warning.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - else { - if (global->main->output.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cControl socket '", global->main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.notable, global->setting->path_control, global->main->context.set.notable); - - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - fl_print_format("' created.%c", global->main->output.to.stream, f_string_eol_s[0]); - } - else { - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - } - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - - status = f_thread_create(0, &global->thread->id_listen, &controller_thread_control_listen, (void *) global); - - if (status == F_child) { - return status; - } - - if (F_status_is_error_not(status)) { - status = f_thread_create(0, &global->thread->id_control, &controller_thread_control, (void *) global); - - if (status == F_child) { - return status; - } - } - - if (F_status_is_error(status)) { - if (global->thread->id_listen) { - f_thread_cancel(global->thread->id_listen); - f_thread_join(global->thread->id_listen, 0); - - global->thread->id_listen = 0; - } - - global->thread->id_control = 0; - - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - } - } - } - } - } - - // Don't fail if unable to create socket file. - status = F_none; - } - } - - return status; - } -#endif // _di_controller_perform_ready_ - -#ifndef _di_controller_status_simplify_error_ - f_status_t controller_status_simplify_error(const f_status_t status) { - - if (status == F_memory_not) { - return F_status_set_error(F_memory); - } - - if (status == F_file_open_max || status == F_space_not || status == F_busy) { - return F_status_set_error(F_resource); - } - - if (status == F_access_denied || status == F_filesystem_quota_block || status == F_prohibited || status == F_input_output) { - return F_status_set_error(F_access); - } - - if (status == F_complete_not_utf || status == F_complete_not_utf_block || status == F_complete_not_utf_eof || status == F_complete_not_utf_eol || status == F_complete_not_utf_eos || status == F_complete_not_utf_stop) { - return F_status_set_error(F_encoding); - } - - if (status == F_number || status == F_number_negative || status == F_number_positive || status == F_number_overflow) { - return F_status_set_error(F_number); - } - - if (status == F_parameter || status == F_found_not || status == F_interrupt || status == F_supported_not || status == F_critical) { - return F_status_set_error(status); - } - - if (status == F_valid_not) { - return F_status_set_error(F_valid_not); - } - - return F_status_set_error(F_failure); - } -#endif // _di_controller_status_simplify_error_ - -#ifndef _di_controller_time_ - void controller_time(const time_t seconds, const long nanoseconds, struct timespec *time) { - - struct timeval now; - - gettimeofday(&now, 0); - - time->tv_sec = now.tv_sec + seconds; - time->tv_nsec = (now.tv_usec * 1000) + nanoseconds; - - // If tv_nsec is 1 second or greater, then increment seconds. - if (time->tv_nsec >= 1000000000) { - ++(time->tv_sec); - - time->tv_nsec -= 1000000000; - } - } -#endif // _di_controller_time_ - -#ifndef _di_controller_time_milliseconds_ - struct timespec controller_time_milliseconds(const f_number_unsigned_t milliseconds) { - - struct timespec time; - time.tv_sec = milliseconds > 1000 ? milliseconds / 1000 : 0; - time.tv_nsec = (time.tv_sec ? milliseconds - time.tv_sec : milliseconds) * 1000; - - return time; - } -#endif // _di_controller_time_milliseconds_ - -#ifndef _di_controller_time_seconds_ - struct timespec controller_time_seconds(const f_number_unsigned_t seconds) { - - struct timespec time; - time.tv_sec = seconds; - time.tv_nsec = 0; - - return time; - } -#endif // _di_controller_time_seconds_ - -#ifndef _di_controller_time_sleep_nanoseconds_ - int controller_time_sleep_nanoseconds(controller_main_t * const main, controller_setting_t * const setting, struct timespec time) { - - // When sleep is a second or more, instead wait for terminating signals if interruptible. - if (setting->interruptible && time.tv_sec) { - siginfo_t information; - f_signal_t signal = f_signal_t_initialize; - - memset(&information, 0, sizeof(siginfo_t)); - - f_signal_set_empty(&signal.set); - f_signal_set_add(F_signal_abort, &signal.set); - f_signal_set_add(F_signal_interrupt, &signal.set); - f_signal_set_add(F_signal_quit, &signal.set); - f_signal_set_add(F_signal_termination, &signal.set); - - if (F_status_is_error(f_signal_wait_until(&signal.set, &time, &information))) { - return -1; - } - - return 0; - } - - return nanosleep(&time, 0); - } -#endif // _di_controller_time_sleep_nanoseconds_ - -#ifndef _di_controller_validate_define_name_ - f_status_t controller_validate_environment_name(const f_string_static_t name) { - - if (!name.used) return F_none; - - f_status_t status = F_none; - - if (name.string[0] != '_') { - status = f_utf_is_alpha(name.string, name.used); - - if (F_status_is_error(status)) return status; - if (status == F_false) return F_false; - } - - for (f_array_length_t i = macro_f_utf_byte_width(name.string[0]); i < name.used; i += macro_f_utf_byte_width(name.string[i])) { - - if (name.string[i] == '_') continue; - - status = f_utf_is_alpha_digit(name.string, name.used); - - if (F_status_is_error(status)) return status; - if (status == F_false) return F_false; - } // for - - return F_true; - } -#endif // _di_controller_validate_define_name_ - -#ifndef _di_controller_validate_has_graph_ - f_status_t controller_validate_has_graph(const f_string_static_t name) { - - if (!name.used) return F_none; - - f_status_t status = F_none; - - for (f_array_length_t i = 0; i < name.used; i += macro_f_utf_byte_width(name.string[i])) { - - status = f_utf_is_graph(name.string, name.used); - - if (F_status_is_error(status)) return status; - if (status == F_true) return F_true; - } // for - - return F_false; - } -#endif // _di_controller_validate_has_graph_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-controller.h b/level_3/controller/c/private-controller.h deleted file mode 100644 index a0fd07b..0000000 --- a/level_3/controller/c/private-controller.h +++ /dev/null @@ -1,420 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_controller_h -#define _PRIVATE_controller_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Given a string whose range represents a number, seek past the first positive or negative sign. - * - * This will stop at the first non-NULL, non-'+' and non-'-' characters. - * - * Only the first '+' or '-' are processed. - * - * @param buffer - * The string referenced by the range. - * @param range - * The range within the buffer to process. - * - * @return - * The string range. - * The start range will be past the stop range on overflow or on any failure. - */ -#ifndef _di_controller_range_after_number_sign_ - extern f_string_range_t controller_range_after_number_sign(const f_string_static_t buffer, const f_string_range_t range) F_attribute_visibility_internal_d; -#endif // _di_controller_range_after_number_sign_ - -/** - * Rip a string from the 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: f_string_dynamic_terminate_after(). - * Errors (with error bit) from: fl_string_dynamic_rip_nulless(). - * - * @see f_string_dynamic_terminate_after() - * @see fl_string_dynamic_rip_nulless() - */ -#ifndef _di_controller_string_dynamic_rip_nulless_terminated_ - extern f_status_t controller_dynamic_rip_nulless_terminated(const f_string_static_t source, const f_string_range_t range, f_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // _di_controller_string_dynamic_rip_nulless_terminated_ - -/** - * Append a string 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: f_string_dynamic_append_nulless(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see f_string_dynamic_append_nulless() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_string_dynamic_append_terminated_ - extern f_status_t controller_dynamic_append_terminated(const f_string_static_t from, f_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // _di_controller_string_dynamic_append_terminated_ - -/** - * Append given range from within a string and then add a NULL after the end of the string. - * - * @param from - * The string to copy from. - * @param range - * The range within the from string to copy. - * @param destination - * The string to copy to. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see f_string_dynamic_append() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_string_dynamic_partial_append_terminated_ - extern f_status_t controller_dynamic_partial_append_terminated(const f_string_static_t from, const f_string_range_t range, f_string_dynamic_t *destination) F_attribute_visibility_internal_d; -#endif // _di_controller_string_dynamic_partial_append_terminated_ - -/** - * Load a file from the controller settings directory. - * - * @param global - * The global data. - * @param required - * If TRUE, the file is required to exist and will throw an error if not found. - * If FALSE, the file is not required to exist and will return without error if not found. - * @param path_prefix - * The path prefix, such as 'entries' from '/etc/controller/entries/default.entry'. - * @param path_name - * The path name, such as 'default' from '/etc/controller/entries/default.entry'. - * @param path_suffix - * The path suffix, such as 'entry' from '/etc/controller/entries/default.entry'. - * @param path_prefix_length - * The length of the prefix path. - * @param path_suffix_length - * The length of the suffix path. - * @param cache - * The following within the cache is updated: - * - name_file: The partial path of the file is inserted. - * - buffer_file: The contents of the file is inserted. - * - timestamp: This is updated to reflect the last changed timestamp. - * - * @return - * F_none on success. - * F_file_found_not if required is FALSE and the file is not found. - * - * Errors (with error bit) from: f_file_stat(). - * Errors (with error bit) from: f_file_stream_open(). - * Errors (with error bit) from: f_file_stream_read(). - * Errors (with error bit) from: f_string_append(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see f_file_stat() - * @see f_file_stream_open() - * @see f_file_stream_read() - * @see f_string_append() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_file_load_ - extern f_status_t controller_file_load(const controller_global_t global, const bool required, const f_string_t path_prefix, const f_string_static_t path_name, const f_string_t path_suffix, const f_array_length_t path_prefix_length, const f_array_length_t path_suffix_length, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_file_load_ - -/** - * Create the pid file, if possible. - * - * @param pid - * The PID (process id). - * @param path - * The file path to the pid file to create. - * - * @return - * F_none on success. - * F_access_denied if pid file is not created due to access denied errors. - * F_directory_not if pid file is not created due to a parent directory is unavailable or invalid. - * - * Errors (with error bit) from: f_directory_exists(). - * Errors (with error bit) from: f_file_name_directory(). - * Errors (with error bit) from: f_file_stream_open(). - * - * @see f_directory_exists() - * @see f_file_name_directory() - * @see f_file_stream_open() - */ -#ifndef _di_controller_file_pid_create_ - f_status_t controller_file_pid_create(const pid_t pid, const f_string_static_t path) F_attribute_visibility_internal_d; -#endif // _di_controller_file_pid_create_ - -/** - * Delete the pid file, if exists and is valid. - * - * This is meant to be called on exit and avoids checking status codes, returning void. - * - * @param pid - * The PID (process id). - * @param path - * The file path to the pid file to create. - * - * @return - * F_none on success. - * - * F_number_not (with error bit) if the number from the pid file doesn't match the expected pid. - * - * Errors (with error bit) from: f_file_stream_close(). - * Errors (with error bit) from: f_file_stream_open(). - * Errors (with error bit) from: f_file_stream_read(). - * Errors (with error bit) from: fl_conversion_string_to_decimal_unsigned() - */ -#ifndef _di_controller_file_pid_delete_ - f_status_t controller_file_pid_delete(const pid_t pid, const f_string_static_t path) F_attribute_visibility_internal_d; -#endif // _di_controller_file_pid_delete_ - -/** - * Read the PID from a PID file. - * - * @param path - * The file path to the pid file to create. - * @param pid - * The PID to be read. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_file_stream_close(). - * Errors (with error bit) from: f_file_stream_open(). - * Errors (with error bit) from: f_file_stream_read(). - * Errors (with error bit) from: fl_conversion_string_to_decimal_unsigned() - */ -#ifndef _di_controller_file_pid_read_ - f_status_t controller_file_pid_read(const f_string_static_t path, pid_t * const pid) F_attribute_visibility_internal_d; -#endif // _di_controller_file_pid_read_ - -/** - * Convert the string from a string representation of an ID or a user name into the numeric representation of that ID or user name. - * - * @param buffer - * A string containing user name or ID. - * @param range - * The range within the buffer specifically containing the name or ID. - * @param cache - * The cache. - * @param id - * The determined user ID. - * - * @return - * F_none on success. - * F_exist_not (with error bit) if failed to match the name to an ID. - * F_number_too_large (with error bit) if the given ID is too large. - * - * Errors (with error bit) from: f_account_id_user_by_name(). - * Errors (with error bit) from: fl_conversion_string_to_number_unsigned(). - * - * @see f_account_id_user_by_name() - * @see fl_conversion_string_to_number_unsigned() - */ -#ifndef _di_controller_get_id_user_ - f_status_t controller_get_id_user(const f_string_static_t buffer, const f_string_range_t range, controller_cache_t * const cache, uid_t * const id) F_attribute_visibility_internal_d; -#endif // _di_controller_get_id_user_ - -/** - * Convert the string from a string representation of an ID or a group name into the numeric representation of that ID or group name. - * - * @param buffer - * A string containing group name or ID. - * @param range - * The range within the buffer specifically containing the name or ID. - * @param cache - * The cache. - * @param id - * The determined group ID. - * - * @return - * F_none on success. - * F_exist_not (with error bit) if failed to match the name to an ID. - * F_number_too_large (with error bit) if the given ID is too large. - * - * Errors (with error bit) from: f_account_id_group_by_name(). - * Errors (with error bit) from: fl_conversion_string_to_number_unsigned(). - * - * @see f_account_id_group_by_name() - * @see fl_conversion_string_to_number_unsigned() - */ -#ifndef _di_controller_get_id_group_ - f_status_t controller_get_id_group(const f_string_static_t buffer, const f_string_range_t range, controller_cache_t * const cache, gid_t * const id) F_attribute_visibility_internal_d; -#endif // _di_controller_get_id_group_ - -/** - * Perform all activities requiring the state to be "ready". - * - * This prints messages on errors. - * - * This does not do any locking or unlocking for the setting data, be sure to lock appropriately before and after calling this. - * - * @param global - * The global data. - * @param cache - * The cache. - * @param is_entry - * If TRUE, then this operate as an entry. - * If FALSE, then this operate as an exit. - * - * @return - * F_none on success. - * - * Errors from controller_file_pid_create() are not returned, unless it is a memory error. - * - * @see controller_file_pid_create() - */ -#ifndef _di_controller_perform_ready_ - extern f_status_t controller_perform_ready(const controller_global_t *global, controller_cache_t * const cache, const bool is_entry) F_attribute_visibility_internal_d; -#endif // _di_controller_perform_ready_ - -/** - * Given a wide range of status codes (that are errors), simplify them down to a small subset. - * - * @param status - * The status code (without the error bit set) to simplify. - * - * @return - * A subset of status codes with error bit. - */ -#ifndef _di_controller_status_simplify_error_ - extern f_status_t controller_status_simplify_error(const f_status_t status) F_attribute_visibility_internal_d; -#endif // _di_controller_status_simplify_error_ - -/** - * Get the current time, plus the given offset. - * - * @todo this is basic enough that there needs to be an f_time class with this function f_time_now(), f_time_future(), f_time_past(). - * "struct timespec" -> f_time_nano_t, "struct timeval" -> f_time_micro_t. - * - * @param seconds - * The seconds to add to current time. - * @param nanoseconds - * The nanoseconds to add to current time. - * @param time - * The resulting current time. - */ -#ifndef _di_controller_time_ - void controller_time(const time_t seconds, const long nanoseconds, struct timespec *time) F_attribute_visibility_internal_d; -#endif // _di_controller_time_ - -/** - * Convert milliseconds to nanoseconds. - * - * @param milliseconds - * The number of milliseconds. - * - * @return - * A time structure suitable for passing to nanosleep() and similar functions. - * - * @see nanosleep() - */ -#ifndef _di_controller_time_milliseconds_ - extern struct timespec controller_time_milliseconds(const f_number_unsigned_t milliseconds) F_attribute_visibility_internal_d; -#endif // _di_controller_time_milliseconds_ - -/** - * Convert seconds to nanoseconds. - * - * @param seconds - * The number of seconds. - * - * @return - * A time structure suitable for passing to nanosleep() and similar functions. - * - * @see nanosleep() - */ -#ifndef _di_controller_time_seconds_ - extern struct timespec controller_time_seconds(const f_number_unsigned_t seconds) F_attribute_visibility_internal_d; -#endif // _di_controller_time_seconds_ - -/** - * Sleep for a given number of nanoseconds. - * - * @param main - * The main program data. - * @param setting - * The settings. - * @param time - * The number of nanoseconds to sleep. - * - * @return - * The result of nanosleep(). - * - * @see nanosleep() - */ -#ifndef _di_controller_time_sleep_nanoseconds_ - extern int controller_time_sleep_nanoseconds(controller_main_t * const main, controller_setting_t * const setting, struct timespec time) F_attribute_visibility_internal_d; -#endif // _di_controller_time_sleep_nanoseconds_ - -/** - * Validate that the given string is a valid environment variable name. - * - * A valid environment variable name must begin with an alpha-character or an underscore. - * Every character after that may be alphanumeric or underscore. - * All other characters, including Unicode characters, are invalid. - * - * @param name - * The string to validate. - * - * @return - * F_true on valid. - * F_false on invalid. - * F_none if there is no string to validate (used = 0). - * - * Errors (with error bit) from: f_utf_is_alpha(). - * Errors (with error bit) from: f_utf_is_alpha_digit(). - * - * @see f_utf_is_alpha() - * @see f_utf_is_alpha_digit() - */ -#ifndef _di_controller_validate_define_name_ - extern f_status_t controller_validate_environment_name(const f_string_static_t name) F_attribute_visibility_internal_d; -#endif // _di_controller_validate_define_name_ - -/** - * Validate that the given string has at least one graph character. - * - * @param name - * The string to validate. - * - * @return - * F_true on valid. - * F_false on invalid. - * F_none if there is no string to validate (used = 0). - * - * Errors (with error bit) from: f_utf_is_graph(). - * - * @see f_utf_is_graph() - */ -#ifndef _di_controller_validate_has_graph_ - extern f_status_t controller_validate_has_graph(const f_string_static_t name) F_attribute_visibility_internal_d; -#endif // _di_controller_validate_has_graph_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_controller_h diff --git a/level_3/controller/c/private-controller_print.c b/level_3/controller/c/private-controller_print.c deleted file mode 100644 index f4191bb..0000000 --- a/level_3/controller/c/private-controller_print.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller_print.h" -#include "private-lock_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_print_error_ - void controller_print_error(controller_thread_t * const thread, const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - if (thread) { - f_thread_mutex_lock(&thread->lock.print); - } - - fll_error_print(print, status, function, fallback); - - if (thread) { - f_thread_mutex_unlock(&thread->lock.print); - } - } -#endif // _di_controller_print_error_ - -#ifndef _di_controller_print_error_file_ - void controller_print_error_file(controller_thread_t * const thread, const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - if (thread) { - f_thread_mutex_lock(&thread->lock.print); - } - - fll_error_file_print(print, status, function, fallback, name, operation, type); - - if (thread) { - f_thread_mutex_unlock(&thread->lock.print); - } - } -#endif // _di_controller_print_error_file_ - -#ifndef _di_controller_print_signal_received_ - void controller_print_signal_received(controller_main_t * const main, const f_status_t signal) { - - if (main->warning.verbosity != f_console_verbosity_verbose_e) return; - - // Must flush and reset color because the interrupt may have interrupted the middle of a print function. - fflush(main->warning.to.stream); - - flockfile(main->warning.to.stream); - - fl_print_format("%]%c%c%[Received signal code %]", main->warning.to.stream, main->context.set.reset, f_string_eol_s[0], f_string_eol_s[0], main->context.set.warning, main->context.set.warning); - fl_print_format("%[%i%]", main->warning.to.stream, main->context.set.notable, signal, main->context.set.notable); - fl_print_format("%[.%]%c", main->warning.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s[0]); - - funlockfile(main->warning.to.stream); - } -#endif // _di_controller_print_signal_received_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-controller_print.h b/level_3/controller/c/private-controller_print.h deleted file mode 100644 index bbfd80e..0000000 --- a/level_3/controller/c/private-controller_print.h +++ /dev/null @@ -1,83 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_controller_print_h -#define _PRIVATE_controller_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Print the error, locking the print mutex during the print. - * - * @param thread - * (optional) The thread data. - * Set to NULL to disable locking on the thread (this should be done only if the lock is already in place). - * @param print - * Designates how printing is to be performed. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param function - * The name of the function where the error happened. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * - * @see fll_error_print() - */ -#ifndef _di_controller_print_error_ - extern void controller_print_error(controller_thread_t * const thread, const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback) F_attribute_visibility_internal_d; -#endif // _di_controller_print_error_ - -/** - * Print the file error, locking the print mutex during the print. - * - * @param thread - * (optional) The thread data. - * Set to NULL to disable locking on the thread (this should be done only if the lock is already in place). - * @param print - * Designates how printing is to be performed. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param function - * The name of the function where the error happened. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * @param name - * The name of the file or directory. - * @param operation - * The operation that fails, such as 'create' or 'access'. - * @param type - * A valid file type code from the fll_error_file_type enum. - * - * @see fll_error_file_print() - */ -#ifndef _di_controller_print_error_file_ - extern void controller_print_error_file(controller_thread_t * const thread, const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_print_error_file_ - -/** - * Print a message about a process signal being recieved, such as an interrupt signal. - * - * @param main - * The main program data. - * @param signal - * The signal received. - */ -#ifndef _di_controller_print_signal_received_ - extern void controller_print_signal_received(controller_main_t * const main, const f_status_t signal) F_attribute_visibility_internal_d; -#endif // _di_controller_print_signal_received_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_controller_print_h diff --git a/level_3/controller/c/private-entry.c b/level_3/controller/c/private-entry.c deleted file mode 100644 index b7ce5c3..0000000 --- a/level_3/controller/c/private-entry.c +++ /dev/null @@ -1,2279 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-entry.h" -#include "private-entry_print.h" -#include "private-lock.h" -#include "private-lock_print.h" -#include "private-rule.h" -#include "private-thread.h" -#include "private-thread_process.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_entry_action_type_is_rule_ - f_status_t controller_entry_action_type_is_rule(uint8_t type) { - - switch (type) { - case controller_entry_action_type_freeze_e: - case controller_entry_action_type_kill_e: - case controller_entry_action_type_pause_e: - case controller_entry_action_type_reload_e: - case controller_entry_action_type_restart_e: - case controller_entry_action_type_resume_e: - case controller_entry_action_type_start_e: - case controller_entry_action_type_stop_e: - case controller_entry_action_type_thaw_e: - return F_true; - } - - return F_false; - } -#endif // _di_controller_entry_action_type_is_rule_ - -#ifndef _di_controller_entry_action_type_name_ - f_string_static_t controller_entry_action_type_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_entry_action_type_consider_e: - buffer.string = controller_consider_s; - buffer.used = controller_consider_s_length; - break; - - case controller_entry_action_type_execute_e: - buffer.string = controller_execute_s; - buffer.used = controller_execute_s_length; - break; - - case controller_entry_action_type_failsafe_e: - buffer.string = controller_failsafe_s; - buffer.used = controller_failsafe_s_length; - break; - - case controller_entry_action_type_freeze_e: - buffer.string = controller_freeze_s; - buffer.used = controller_freeze_s_length; - break; - - case controller_entry_action_type_item_e: - buffer.string = controller_item_s; - buffer.used = controller_item_s_length; - break; - - case controller_entry_action_type_kill_e: - buffer.string = controller_kill_s; - buffer.used = controller_kill_s_length; - break; - - case controller_entry_action_type_pause_e: - buffer.string = controller_pause_s; - buffer.used = controller_pause_s_length; - break; - - case controller_entry_action_type_ready_e: - buffer.string = controller_ready_s; - buffer.used = controller_ready_s_length; - break; - - case controller_entry_action_type_reload_e: - buffer.string = controller_reload_s; - buffer.used = controller_reload_s_length; - break; - - case controller_entry_action_type_restart_e: - buffer.string = controller_restart_s; - buffer.used = controller_restart_s_length; - break; - - case controller_entry_action_type_resume_e: - buffer.string = controller_resume_s; - buffer.used = controller_resume_s_length; - break; - - case controller_entry_action_type_start_e: - buffer.string = controller_start_s; - buffer.used = controller_start_s_length; - break; - - case controller_entry_action_type_stop_e: - buffer.string = controller_stop_s; - buffer.used = controller_stop_s_length; - break; - - case controller_entry_action_type_thaw_e: - buffer.string = controller_thaw_s; - buffer.used = controller_thaw_s_length; - break; - - case controller_entry_action_type_timeout_e: - buffer.string = controller_timeout_s; - buffer.used = controller_timeout_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_entry_action_type_name_ - -#ifndef _di_controller_entry_action_type_to_rule_action_type_ - uint8_t controller_entry_action_type_to_rule_action_type(uint8_t type) { - - switch (type) { - case controller_entry_action_type_freeze_e: - return controller_rule_action_type_freeze_e; - - case controller_entry_action_type_kill_e: - return controller_rule_action_type_kill_e; - - case controller_entry_action_type_pause_e: - return controller_rule_action_type_pause_e; - - case controller_entry_action_type_reload_e: - return controller_rule_action_type_reload_e; - - case controller_entry_action_type_restart_e: - return controller_rule_action_type_restart_e; - - case controller_entry_action_type_resume_e: - return controller_rule_action_type_resume_e; - - case controller_entry_action_type_start_e: - return controller_rule_action_type_start_e; - - case controller_entry_action_type_stop_e: - return controller_rule_action_type_stop_e; - - case controller_entry_action_type_thaw_e: - return controller_rule_action_type_thaw_e; - } - - return 0; - } -#endif // _di_controller_entry_action_type_to_rule_action_type_ - -#ifndef _di_controller_entry_actions_read_ - f_status_t controller_entry_actions_read(const controller_global_t global, const bool is_entry, const f_string_range_t content_range, controller_cache_t * const cache, controller_entry_actions_t *actions) { - - f_status_t status = F_none; - f_status_t status_action = F_none; - - actions->used = 0; - - cache->object_actions.used = cache->object_actions.size; - - while (cache->object_actions.used) { - - cache->object_actions.array[--cache->object_actions.used].start = 1; - cache->object_actions.array[cache->object_actions.used].stop = 0; - } // while - - cache->content_actions.used = cache->content_actions.size; - - while (cache->content_actions.used) { - cache->content_actions.array[--cache->content_actions.used].used = 0; - } // while - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_entry, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - f_string_range_t range = content_range; - - status = fll_fss_extended_read(cache->buffer_file, state, &range, &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0); - } - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread); - - return status; - } - - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread); - - return status; - } - - cache->delimits.used = 0; - - status = controller_entry_actions_increase_by(cache->object_actions.used, actions); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_actions_increase_by", F_true, global.thread); - - return status; - } - - controller_entry_action_t *action = 0; - - f_array_length_t allocate = 0; - f_array_length_t at_least = 0; - f_array_length_t at_most = 0; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < cache->object_actions.used; ++i) { - - cache->action.line_action = 0; - cache->action.name_action.used = 0; - - action = &actions->array[actions->used]; - action->type = 0; - action->code = 0; - action->line = 0; - action->number = 0; - action->status = F_known_not; - action->parameters.used = 0; - - status = f_fss_count_lines(cache->buffer_file, cache->object_actions.array[i].start, &cache->action.line_action); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread); - break; - } - - action->line = ++cache->action.line_action; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread); - break; - } - - if (fl_string_dynamic_compare_string(controller_consider_s, cache->action.name_action, controller_consider_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_consider_e; - } - else if (fl_string_dynamic_compare_string(controller_execute_s, cache->action.name_action, controller_execute_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_execute_e; - } - else if (fl_string_dynamic_compare_string(controller_failsafe_s, cache->action.name_action, controller_failsafe_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_failsafe_e; - } - else if (fl_string_dynamic_compare_string(controller_freeze_s, cache->action.name_action, controller_freeze_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_freeze_e; - } - else if (fl_string_dynamic_compare_string(controller_item_s, cache->action.name_action, controller_item_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_item_e; - } - else if (fl_string_dynamic_compare_string(controller_kill_s, cache->action.name_action, controller_kill_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_kill_e; - } - else if (fl_string_dynamic_compare_string(controller_pause_s, cache->action.name_action, controller_pause_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_pause_e; - } - else if (fl_string_dynamic_compare_string(controller_ready_s, cache->action.name_action, controller_ready_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_ready_e; - } - else if (fl_string_dynamic_compare_string(controller_reload_s, cache->action.name_action, controller_reload_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_reload_e; - } - else if (fl_string_dynamic_compare_string(controller_restart_s, cache->action.name_action, controller_restart_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_restart_e; - } - else if (fl_string_dynamic_compare_string(controller_resume_s, cache->action.name_action, controller_resume_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_resume_e; - } - else if (fl_string_dynamic_compare_string(controller_start_s, cache->action.name_action, controller_start_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_start_e; - } - else if (fl_string_dynamic_compare_string(controller_stop_s, cache->action.name_action, controller_stop_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_stop_e; - } - else if (fl_string_dynamic_compare_string(controller_thaw_s, cache->action.name_action, controller_thaw_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_thaw_e; - } - else if (fl_string_dynamic_compare_string(controller_timeout_s, cache->action.name_action, controller_timeout_s_length) == F_equal_to) { - actions->array[actions->used].type = controller_entry_action_type_timeout_e; - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SUnknown %s item action '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context); - fl_print_format("%[%S%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->warning, cache->action); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - continue; - } - - if (action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(action->type)) { - allocate = cache->content_actions.array[i].used; - at_least = 2; - at_most = allocate; - } - else if (action->type == controller_entry_action_type_execute_e) { - allocate = cache->content_actions.array[i].used; - at_least = 1; - at_most = allocate; - } - else if (action->type == controller_entry_action_type_failsafe_e || action->type == controller_entry_action_type_item_e) { - allocate = 1; - at_least = 1; - at_most = 1; - } - else if (action->type == controller_entry_action_type_timeout_e) { - allocate = 2; - at_least = 2; - at_most = 2; - } - else if (action->type == controller_entry_action_type_ready_e) { - allocate = 1; - at_least = 0; - at_most = 1; - } - - if (cache->content_actions.array[i].used < at_least || cache->content_actions.array[i].used > at_most) { - action->status = F_status_set_error(F_parameter); - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - f_thread_mutex_lock(&global.thread->lock.print); - - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable); - fl_print_format("%[' requires ", global.main->error.to.stream, global.main->error.context); - - if (at_least == at_most) { - f_print_terminated("exactly ", global.main->error.to.stream); - } - - fl_print_format("%]%[%un%]", global.main->error.to.stream, global.main->error.context, global.main->error.notable, at_least, global.main->error.notable); - - if (action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(action->type)) { - fl_print_format("%[ or more parameters.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - else { - if (at_least == at_most) { - fl_print_format("%[ parameters.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - else { - fl_print_format("%[ to %]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%un%]", global.main->error.to.stream, global.main->error.notable, at_most, global.main->error.notable); - fl_print_format("%[ parameters.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - } - - funlockfile(global.main->error.to.stream); - - f_thread_mutex_unlock(&global.thread->lock.print); - } - } - else { - action->status = F_none; - } - - if (F_status_is_error(action->status)) { - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - - continue; - } - - if (allocate) { - status = f_string_dynamics_increase_by(allocate, &action->parameters); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase_by", F_true, global.thread); - - action->status = status; - - if (F_status_is_error_not(status_action)) { - status_action = status; - } - - break; - } - - for (j = 0; j < allocate && j < cache->content_actions.array[i].used; ++j) { - - action->parameters.array[j].used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_file, cache->content_actions.array[i].array[j], &action->parameters.array[j]); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread); - - action->status = status; - - if (F_status_is_error_not(status_action)) { - status_action = status; - } - - break; - } - - ++action->parameters.used; - } // for - - if (F_status_is_error_not(action->status)) { - if (action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(action->type)) { - if (action->parameters.array[0].used) { - - // Force the path to be canonical (removing all '../' parts). - status = fll_path_canonical(action->parameters.array[0].string, &cache->buffer_path); - - if (F_status_is_error(status)) { - // @todo instead call: fll_error_file_print(). - // fll_error_file_print(main->error, F_status_set_fine(status), "fll_path_canonical", F_true, arguments->argv[location], "verify", fll_error_file_type_path_e); - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_path_canonical", F_true, global.thread); - - action->status = status; - - if (F_status_set_fine(status) == F_memory_not) { - status_action = status; - break; - } - - if (F_status_is_error_not(status_action)) { - status_action = status; - } - } - } - else { - action->status = F_status_set_error(F_parameter); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - fll_print_format("%c%[%SThe %s item action must not have an empty string for a path (the first parameter).%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context, f_string_eol_s[0]); - } - } - - if (action->parameters.array[1].used) { - cache->buffer_path.used = 0; - - status = f_file_name_base(action->parameters.array[1].string, action->parameters.array[1].used, &cache->buffer_path); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_file_name_base", F_true, global.thread); - - if (F_status_set_fine(status) == F_memory_not) { - status_action = status; - break; - } - - action->status = status; - - if (F_status_is_error_not(status_action)) { - status_action = status; - } - } - else { - if (fl_string_dynamic_compare(action->parameters.array[1], cache->buffer_path) == F_equal_to_not) { - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - status = f_string_dynamic_terminate_after(&cache->buffer_path); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread); - - action->status = status; - - if (F_status_set_fine(status) == F_memory_not) { - status_action = status; - } - - break; - } - - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action second parameter '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[1], global.main->error.notable); - fl_print_format("%[' must be a base path name, such as '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_path, global.main->error.notable); - fl_print_format("%['.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - - action->status = F_status_set_error(F_parameter); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - } - } - } - else { - action->status = F_status_set_error(F_parameter); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - fll_print_format("%c%[%SThe %s item action must not have an empty string for a rule name (the second parameter).%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context, f_string_eol_s[0]); - } - } - - for (j = 2; j < action->parameters.used; ++j) { - - if (fl_string_dynamic_compare_string(controller_asynchronous_s, action->parameters.array[j], controller_asynchronous_s_length) == F_equal_to) { - action->code |= controller_entry_rule_code_asynchronous_d; - } - else if (fl_string_dynamic_compare_string(controller_require_s, action->parameters.array[j], controller_require_s_length) == F_equal_to) { - action->code |= controller_entry_rule_code_require_d; - } - else if (fl_string_dynamic_compare_string(controller_wait_s, action->parameters.array[j], controller_wait_s_length) == F_equal_to) { - action->code |= controller_entry_rule_code_wait_d; - } - else { - if (action->status == F_none) { - action->status = F_status_set_error(F_supported_not); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action third parameter (and beyond) must be one of '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_asynchronous_s, global.main->error.notable); - fl_print_format("%[', '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_require_s, global.main->error.notable); - fl_print_format("%[', or '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_wait_s, global.main->error.notable); - fl_print_format("%[' but instead has '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[j], global.main->error.notable); - fl_print_format("%['.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - } - } // for - } - else if (action->type == controller_entry_action_type_failsafe_e || action->type == controller_entry_action_type_item_e) { - if (fl_string_dynamic_compare_string(controller_main_s, action->parameters.array[0], controller_main_s_length) == F_equal_to) { - action->status = F_status_set_error(F_supported_not); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action may not specify the reserved item '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_main_s, global.main->error.notable); - fl_print_format("%['.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - } - } - else if (action->type == controller_entry_action_type_timeout_e) { - - if (fl_string_dynamic_compare_string(controller_kill_s, action->parameters.array[0], controller_kill_s_length) == F_equal_to) { - action->code = controller_entry_timeout_code_kill_d; - } - else if (fl_string_dynamic_compare_string(controller_start_s, action->parameters.array[0], controller_start_s_length) == F_equal_to) { - action->code = controller_entry_timeout_code_start_d; - } - else if (fl_string_dynamic_compare_string(controller_stop_s, action->parameters.array[0], controller_stop_s_length) == F_equal_to) { - action->code = controller_entry_timeout_code_stop_d; - } - else { - action->status = F_status_set_error(F_supported_not); - - if (F_status_is_error_not(status_action)) { - status_action = action->status; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action must have one of '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_kill_s, global.main->error.notable); - fl_print_format("%[', '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_start_s, global.main->error.notable); - fl_print_format("%[', or '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_stop_s, global.main->error.notable); - fl_print_format("%[' but instead has '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[0], global.main->error.notable); - fl_print_format("%['.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - } - - if (action->status == F_none) { - const f_string_range_t range = macro_f_string_range_t_initialize(action->parameters.array[1].used); - - status = fl_conversion_string_to_number_unsigned(action->parameters.array[1].string, range, &action->number); - - if (F_status_is_error(status) || status == F_data_not) { - action->number = 0; - - if (status == F_data_not) { - action->status = F_status_set_error(F_number); - } - else { - action->status = controller_status_simplify_error(F_status_set_fine(status)); - } - - if (F_status_set_fine(status) == F_memory_not) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, global.thread); - - status_action = status; - break; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action parameter '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[1], global.main->error.notable); - fl_print_format("%[' is not a valid supported number.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - } - } - } - else if (action->type == controller_entry_action_type_ready_e) { - if (action->parameters.used) { - if (fl_string_dynamic_compare_string(controller_wait_s, action->parameters.array[0], controller_wait_s_length) == F_equal_to) { - action->code |= controller_entry_rule_code_wait_d; - } - else { - action->status = F_status_set_error(F_supported_not); - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - flockfile(global.main->error.to.stream); - - fl_print_format("%c%[%SThe %s item action may only have '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_wait_s, global.main->error.notable); - fl_print_format("%[' but instead has '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[0], global.main->error.notable); - fl_print_format("%['.%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - funlockfile(global.main->error.to.stream); - } - } - } - } - } - } - - ++actions->used; - } // for - - if (F_status_is_error(status_action)) { - return status_action; - } - - return status; - } -#endif // _di_controller_entry_actions_read_ - -#ifndef _di_controller_entry_preprocess_ - f_status_t controller_entry_preprocess(const controller_global_t global, const bool is_entry, controller_cache_t * const cache) { - - f_status_t status = F_none; - f_status_t status2 = F_none; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_array_length_t at_i = 0; - f_array_length_t at_j = 1; - - controller_entry_t *entry = is_entry ? &global.setting->entry : &global.setting->exit; - controller_entry_actions_t *actions = 0; - - uint8_t error_has = F_false; - - // This effectively sets the read for an entry and resets the ready for an exit. - // @todo should there be a ready_exit instead? - // @todo the global.setting->ready in this function may need mutex lock protection. - // @todo disconnect the socket file if applicable. - global.setting->ready = controller_setting_ready_no_e; - - cache->ats.used = 0; - - cache->action.line_action = 0; - cache->action.line_item = 0; - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - macro_f_array_lengths_t_increase_by(status, cache->ats, controller_common_allocation_small_d) - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, global.thread); - - 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; - - cache->action.line_item = entry->items.array[0].line; - cache->action.name_item.used = 0; - - status = controller_dynamic_append_terminated(entry->items.array[0].name, &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread); - - return status; - } - - while (controller_thread_is_enabled(is_entry, global.thread)) { - - actions = &entry->items.array[cache->ats.array[at_i]].actions; - - for (; cache->ats.array[at_j] < actions->used && controller_thread_is_enabled(is_entry, global.thread); ++cache->ats.array[at_j]) { - - cache->action.line_action = actions->array[cache->ats.array[at_j]].line; - cache->action.name_action.used = 0; - - status2 = controller_dynamic_append_terminated(controller_entry_action_type_name(actions->array[cache->ats.array[at_j]].type), &cache->action.name_action); - - if (F_status_is_error(status2)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread); - - return status2; - } - - if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_ready_e) { - - if (global.setting->ready == controller_setting_ready_wait_e) { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SMultiple '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context); - fl_print_format("%[%s%]", global.main->warning.to.stream, global.main->warning.notable, controller_ready_s, global.main->warning.notable); - fl_print_format("%[' %s item actions detected; only the first will be used.%]%c", global.main->warning.to.stream, global.main->warning.context, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->warning, cache->action); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - } - else { - global.setting->ready = controller_setting_ready_wait_e; - } - } - else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_item_e) { - error_has = F_false; - - // "main" is not allowed to be used for an "item" and "setting" is not an executable "item". - if (fl_string_dynamic_compare_string(controller_main_s, actions->array[cache->ats.array[at_j]].parameters.array[0], controller_main_s_length) == F_equal_to) { - continue; - } - else if (fl_string_dynamic_compare_string(controller_setting_s, actions->array[cache->ats.array[at_j]].parameters.array[0], controller_setting_s_length) == F_equal_to) { - continue; - } - - // Walk though each items and check to see if the item actually exists. - for (i = 1; i < entry->items.used && controller_thread_is_enabled(is_entry, global.thread); ++i) { - - if (fl_string_dynamic_compare(entry->items.array[i].name, actions->array[cache->ats.array[at_j]].parameters.array[0]) == F_equal_to) { - - // Check to see if "i" is already in the stack (to prevent recursion) (skipping main). - for (j = 2; j < cache->ats.used; j += 2) { - - if (cache->ats.array[j] == i) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe %s item named '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, is_entry ? controller_entry_s : controller_exit_s, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, entry->items.array[i].name, global.main->error.notable); - fl_print_format("%[' cannot be executed because recursion is not allowed.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->error, cache->action); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status)) { - status = F_status_set_error(F_recurse); - } - - error_has = F_true; - break; - } - } // for - - if (error_has) break; - - macro_f_array_lengths_t_increase_by(status2, cache->ats, controller_common_allocation_small_d) - - if (F_status_is_error(status2)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "macro_f_array_lengths_t_increase_by", F_true, global.thread); - - return status2; - } - - // Save the value so to avoid string comparison during normal operation. - actions->array[cache->ats.array[at_j]].number = i; - - // Continue into the requested item. - at_i = cache->ats.used; - at_j = cache->ats.used + 1; - - cache->ats.array[at_i] = i; - cache->ats.array[at_j] = 0; - cache->ats.used += 2; - - cache->action.name_action.used = 0; - cache->action.line_action = 0; - - cache->action.name_item.used = 0; - cache->action.line_item = entry->items.array[i].line; - - status2 = controller_dynamic_append_terminated(entry->items.array[i].name, &cache->action.name_item); - - if (F_status_is_error(status2)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread); - - return status2; - } - - break; - } - } // for - - if (error_has || i >= entry->items.used) { - if (i >= entry->items.used) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe %s item named '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, is_entry ? controller_entry_s : controller_exit_s, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, actions->array[cache->ats.array[at_j]].parameters.array[0], global.main->error.notable); - fl_print_format("%[' does not exist.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->error, cache->action); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status)) { - status = F_status_set_error(F_valid_not); - } - } - } - else { - break; - } - } - } // for - - cache->action.line_action = 0; - cache->action.name_action.used = 0; - - // End of actions found, so drop to previous loop in stack. - if (cache->ats.array[at_j] == actions->used) { - - // All actions for "main" are processed so there is nothing left to do. - if (at_i == 0) break; - - at_i -= 2; - at_j -= 2; - - cache->ats.used -= 2; - ++cache->ats.array[at_j]; - - cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line; - cache->action.name_item.used = 0; - - status2 = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item); - - if (F_status_is_error(status2)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status2), "controller_dynamic_append_terminated", F_true, global.thread); - - return status2; - } - } - } // while - - if (!controller_thread_is_enabled(is_entry, global.thread)) { - return F_status_set_error(F_interrupt); - } - - // If ready was never found in the entry, then default to always ready. - if (global.setting->ready == controller_setting_ready_no_e) { - global.setting->ready = controller_setting_ready_yes_e; - } - - return status; - } -#endif // _di_controller_entry_preprocess_ - -#ifndef _di_controller_entry_process_ - f_status_t controller_entry_process(const controller_global_t *global, controller_cache_t * const cache, const bool failsafe, const bool is_entry) { - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - f_array_length_t at_i = 0; - f_array_length_t at_j = 1; - - uint8_t options_force = 0; - uint8_t options_process = 0; - - controller_entry_t *entry = is_entry ? &global->setting->entry : &global->setting->exit; - controller_entry_action_t *entry_action = 0; - controller_entry_actions_t *entry_actions = 0; - controller_process_t *process = 0; - - // an empty stack is used here because each rule here is the first rule run in the rule's scope. - const f_array_lengths_t stack = f_array_lengths_t_initialize; - - cache->ats.used = 0; - cache->stack.used = 0; - - cache->action.line_action = 0; - cache->action.line_item = 0; - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - macro_f_array_lengths_t_increase_by(status, cache->ats, controller_common_allocation_small_d) - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, global->thread); - - 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] = failsafe ? global->setting->failsafe_item_id : 0; - cache->ats.array[1] = 0; - cache->ats.used = 2; - - cache->action.line_item = entry->items.array[cache->ats.array[0]].line; - cache->action.name_item.used = 0; - - status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[0]].name, &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread); - - return status; - } - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cProcessing %s%s item '", global->main->output.to.stream, f_string_eol_s[0], failsafe ? "failsafe " : "", is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%Q%]'.%c", global->main->output.to.stream, global->main->context.set.notable, cache->action.name_item, global->main->context.set.notable, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - - // The pre-process determines if ready is explicitly specified within the entry file and if it is not start as ready. - if (global->setting->ready == controller_setting_ready_yes_e) { - status = controller_perform_ready(global, cache, is_entry); - if (F_status_is_error(status)) return status; - } - - while (controller_thread_is_enabled(is_entry, global->thread)) { - - entry_actions = &entry->items.array[cache->ats.array[at_i]].actions; - - for (; cache->ats.array[at_j] < entry_actions->used && controller_thread_is_enabled(is_entry, global->thread); ++cache->ats.array[at_j]) { - - entry_action = &entry_actions->array[cache->ats.array[at_j]]; - - cache->action.line_action = entry_action->line; - cache->action.name_action.used = 0; - - status = controller_dynamic_append_terminated(controller_entry_action_type_name(entry_action->type), &cache->action.name_action); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread); - - return status; - } - - if (F_status_is_error(entry_action->status)) { - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cThe %s item action '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.title, cache->action.name_action, global->main->context.set.title); - - if (entry_action->parameters.used) { - fl_print_format(" %[", global->main->output.to.stream, global->main->context.set.notable); - - controller_entry_action_parameters_print(global->main->output.to.stream, *entry_action); - - fl_print_format("%]", global->main->output.to.stream, global->main->context.set.notable); - } - - fl_print_format("' is %[%s%] and is in a ", global->main->output.to.stream, global->main->context.set.notable, entry_action->code & controller_entry_rule_code_require_d ? "required" : "optional", global->main->context.set.notable); - - fl_print_format("%[failed%] state, skipping.%c", global->main->output.to.stream, global->main->context.set.notable, global->main->context.set.notable, global->main->context.set.notable, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - else { - if ((entry_action->code & controller_entry_rule_code_require_d) && global->main->error.verbosity != f_console_verbosity_quiet_e || !(entry_action->code & controller_entry_rule_code_require_d) && (global->main->warning.verbosity == f_console_verbosity_verbose_e || global->main->warning.verbosity == f_console_verbosity_debug_e)) { - fl_print_t *output = 0; - - if (entry_action->code & controller_entry_rule_code_require_d) { - output = &global->main->error; - } - else { - output = &global->main->warning; - } - - controller_lock_print(output->to, global->thread); - - fl_print_format("%c%[%SThe %s item action '%]", output->to.stream, f_string_eol_s[0], output->context, output->prefix ? output->prefix : f_string_empty_s, is_entry ? controller_entry_s : controller_exit_s, output->context); - fl_print_format("%[%Q%]", output->to.stream, output->notable, cache->action.name_action, output->notable); - - - if (entry_action->parameters.used) { - fl_print_format(" %[", output->to.stream, global->main->context.set.notable); - - controller_entry_action_parameters_print(output->to.stream, *entry_action); - - fl_print_format("%]", output->to.stream, global->main->context.set.notable); - } - - if (entry_action->code & controller_entry_rule_code_require_d) { - fl_print_format("%[' is%] %[required%]", output->to.stream, output->context, output->context, output->notable, output->notable); - } - else { - fl_print_format("%[' is%] %[optional%]", output->to.stream, output->context, output->context, output->notable, output->notable); - } - - fl_print_format(" %[and is in a%] %[failed%]", output->to.stream, output->context, output->context, output->notable, output->notable); - - if (entry_action->code & controller_entry_rule_code_require_d) { - fl_print_format(" %[state, aborting.%]%c", output->to.stream, output->context, output->context, f_string_eol_s[0]); - } - else { - fl_print_format(" %[state, skipping.%]%c", output->to.stream, output->context, output->context, f_string_eol_s[0]); - } - - controller_entry_print_error_cache(is_entry, *output, cache->action); - - controller_unlock_print_flush(output->to, global->thread); - } - - if (controller_entry_action_type_is_rule(entry_action->type) && entry_action->code & controller_entry_rule_code_require_d) { - return F_status_is_error(F_require); - } - } - - continue; - } - - if (entry_action->type == controller_entry_action_type_ready_e) { - if ((entry_action->code & controller_entry_rule_code_wait_d) || global->setting->ready == controller_setting_ready_wait_e) { - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e || entry->show == controller_entry_show_init_e) { - if (global->main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cWaiting before processing %s item action '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%s%]", global->main->output.to.stream, global->main->context.set.title, controller_ready_s, global->main->context.set.title); - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - status = controller_rule_wait_all(*global, is_entry, F_false, process); - if (F_status_is_error(status)) return status; - } - } - - if (global->setting->ready == controller_setting_ready_yes_e) { - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e) { - if (global->main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cIgnoring %s item action '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%s%]", global->main->output.to.stream, global->main->context.set.title, controller_ready_s, global->main->context.set.title); - fl_print_format("', state already is ready.%c", global->main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - } - else { - if (!failsafe && (global->main->error.verbosity == f_console_verbosity_verbose_e || entry->show == controller_entry_show_init_e) && global->main->parameters[controller_parameter_simulate_e].result == f_console_result_none_e) { - fl_print_format("%cState is now '%[%s%]'.%c", global->main->output.to.stream, f_string_eol_s[0], global->main->context.set.notable, controller_ready_s, global->main->context.set.notable, f_string_eol_s[0]); - } - - status = controller_perform_ready(global, cache, is_entry); - if (F_status_is_error(status)) return status; - } - } - else if (entry_action->type == controller_entry_action_type_item_e) { - if (entry_action->number == 0 || entry_action->number >= entry->items.used || failsafe && entry_action->number == global->setting->failsafe_item_id) { - - // This should not happen if the pre-process is working as intended, but in case it doesn't, return a critical error to prevent infinite recursion and similar errors. - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - fl_print_format("%c%[Invalid %s item index '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, is_entry ? controller_entry_s : controller_exit_s, global->main->error.context); - fl_print_format("%[%un%]", global->main->error.to.stream, global->main->error.notable, entry_action->number, global->main->error.notable); - fl_print_format("%[' detected.%]%c", global->main->error.to.stream, global->main->error.context, global->main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - - return F_status_is_error(F_critical); - } - - macro_f_array_lengths_t_increase_by(status, cache->ats, controller_common_allocation_small_d) - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, global->thread); - - return status; - } - - // continue into the requested item. - cache->ats.array[cache->ats.used] = entry_action->number; - cache->ats.array[cache->ats.used + 1] = 0; - - at_i = cache->ats.used; - at_j = cache->ats.used + 1; - - cache->ats.used += 2; - - cache->action.name_action.used = 0; - cache->action.line_action = 0; - - cache->action.name_item.used = 0; - cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line; - - status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread); - - return status; - } - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e) { - if (global->main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cProcessing %s item '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.title, cache->action.name_item, global->main->context.set.title); - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - - // Exit inner loop to force restarting and start processing the requested item. - break; - } - else if (entry_action->type == controller_entry_action_type_consider_e || controller_entry_action_type_is_rule(entry_action->type)) { - status_lock = controller_lock_write(is_entry, global->thread, &global->thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global->main->error, F_status_set_fine(status_lock), F_false, global->thread); - - break; - } - - status = controller_rules_increase(&global->setting->rules); - - f_thread_unlock(&global->thread->lock.rule); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_rules_increase", F_true, global->thread); - - return status; - } - - const f_array_length_t id_rule_length = entry_action->parameters.array[0].used + entry_action->parameters.array[1].used + 1; - char id_rule_name[id_rule_length + 1]; - const f_string_static_t alias_rule = macro_f_string_static_t_initialize(id_rule_name, id_rule_length); - - memcpy(id_rule_name, entry_action->parameters.array[0].string, entry_action->parameters.array[0].used); - memcpy(id_rule_name + entry_action->parameters.array[0].used + 1, entry_action->parameters.array[1].string, entry_action->parameters.array[1].used); - - id_rule_name[entry_action->parameters.array[0].used] = f_path_separator_s[0]; - id_rule_name[id_rule_length] = 0; - - status_lock = controller_lock_read(is_entry, global->thread, &global->thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global->main->error, F_status_set_fine(status_lock), F_true, global->thread); - - break; - } - - status = controller_rule_find(alias_rule, global->setting->rules, 0); - - f_thread_unlock(&global->thread->lock.rule); - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e || (entry->show == controller_entry_show_init_e && entry_action->type != controller_entry_action_type_consider_e)) { - if (global->main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%s %s item rule ", global->main->output.to.stream, f_string_eol_s[0], entry_action->type == controller_entry_action_type_consider_e ? "Considering" : "Processing", is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("'%[%Q%]'", global->main->output.to.stream, global->main->context.set.title, alias_rule, global->main->context.set.title); - - if (entry->show == controller_entry_show_init_e && global->main->parameters[controller_parameter_simulate_e].result == f_console_result_none_e) { - fl_print_format(" [%[%s%]]", global->main->output.to.stream, global->main->context.set.notable, entry_action->code == controller_entry_rule_code_asynchronous_d ? controller_asynchronous_s : controller_synchronous_s, global->main->context.set.notable); - - if (entry_action->code == controller_entry_rule_code_wait_d) { - fl_print_format(" [%[%s%]]", global->main->output.to.stream, global->main->context.set.notable, controller_wait_s, global->main->context.set.notable); - } - - if (entry_action->code == controller_entry_rule_code_require_d) { - fl_print_format(" [%[%s%]]", global->main->output.to.stream, global->main->context.set.notable, controller_required_s, global->main->context.set.notable); - } - } - - fl_print_format(".%c", global->main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - - if (!controller_thread_is_enabled(is_entry, global->thread)) break; - - // The rule is not yet loaded, ensure that it is loaded. - if (status != F_true) { - - // Rule execution will re-use the existing cache, so save the current cache. - const f_array_length_t cache_line_action = cache->action.line_action; - const f_array_length_t cache_line_item = cache->action.line_item; - - const f_array_length_t cache_name_action_used = cache->action.name_action.used; - const f_array_length_t cache_name_item_used = cache->action.name_item.used; - const f_array_length_t cache_name_file_used = cache->action.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->action.name_action.string, cache->action.name_action.used); - memcpy(cache_name_item, cache->action.name_item.string, cache->action.name_item.used); - memcpy(cache_name_file, cache->action.name_file.string, cache->action.name_file.used); - - status_lock = controller_lock_write(is_entry, global->thread, &global->thread->lock.rule); - - if (F_status_is_fine(status_lock)) { - status = controller_rule_read(*global, is_entry, alias_rule, cache, entry, &global->setting->rules.array[global->setting->rules.used]); - } - - // Restore cache. - memcpy(cache->action.name_action.string, cache_name_action, cache_name_action_used); - memcpy(cache->action.name_item.string, cache_name_item, cache_name_item_used); - memcpy(cache->action.name_file.string, cache_name_file, cache_name_file_used); - - cache->action.name_action.string[cache_name_action_used] = 0; - cache->action.name_item.string[cache_name_item_used] = 0; - cache->action.name_file.string[cache_name_file_used] = 0; - - cache->action.name_action.used = cache_name_action_used; - cache->action.name_item.used = cache_name_item_used; - cache->action.name_file.used = cache_name_file_used; - - cache->action.line_action = cache_line_action; - cache->action.line_item = cache_line_item; - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global->main->error, F_status_set_fine(status_lock), F_false, global->thread); - break; - } - - if (F_status_set_fine(status) == F_interrupt || !controller_thread_is_enabled(is_entry, global->thread)) { - f_thread_unlock(&global->thread->lock.rule); - - break; - } - - if (F_status_is_error(status)) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - - // Designate the action as failed. - entry_action->status = F_status_set_error(F_failure); - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_none_e) { - f_thread_unlock(&global->thread->lock.rule); - - if (entry_action->code & controller_entry_rule_code_require_d) { - return F_status_set_error(F_require); - } - - ++cache->ats.array[at_j]; - break; - } - } - else { - ++global->setting->rules.used; - } - - f_thread_unlock(&global->thread->lock.rule); - } - - if (F_status_is_error_not(status)) { - options_force = 0; - options_process = 0; - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - options_process |= controller_process_option_simulate_d; - } - - if (entry_action->code & controller_entry_rule_code_require_d) { - options_process |= controller_process_option_require_d; - } - - if (entry_action->code & controller_entry_rule_code_wait_d) { - options_process |= controller_process_option_wait_d; - } - - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_found_e) { - options_process |= controller_process_option_validate_d; - } - - if (entry_action->code & controller_entry_rule_code_asynchronous_d) { - if (global->main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - options_force |= controller_process_option_asynchronous_d; - } - - options_process |= controller_process_option_asynchronous_d; - } - - status = controller_rule_process_begin(*global, options_force, alias_rule, controller_entry_action_type_to_rule_action_type(entry_action->type), options_process, is_entry ? controller_process_type_entry_e : controller_process_type_exit_e, stack, *cache); - - if (F_status_set_fine(status) == F_memory_not || status == F_child || F_status_set_fine(status) == F_interrupt) { - break; - } - - if (F_status_is_error(status) && global->main->parameters[controller_parameter_simulate_e].result == f_console_result_none_e && (entry_action->code & controller_entry_rule_code_require_d)) { - return F_status_set_error(F_require); - } - } - } - else if (entry_action->type == controller_entry_action_type_execute_e) { - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global->main->error.verbosity == f_console_verbosity_verbose_e || global->main->error.verbosity == f_console_verbosity_debug_e || entry->show == controller_entry_show_init_e) { - if (global->main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%c%s is executing '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - - for (f_array_length_t k = 0; k < entry_action->parameters.used; ++k) { - - fl_print_format("%[%Q%]", global->main->output.to.stream, global->main->context.set.title, entry_action->parameters.array[k], global->main->context.set.title); - - if (k + 1 < entry_action->parameters.used) { - f_print_character(f_string_space_s[0], global->main->output.to.stream); - } - } // for - - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - } - - if (global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - return F_execute; - } - - controller_thread_process_cancel(*global, is_entry, is_entry ? controller_thread_cancel_execute_e : controller_thread_cancel_exit_execute_e, process); - - int result = 0; - int option = FL_execute_parameter_option_path_d; - - if (entry->session == controller_entry_session_new_e) { - option |= FL_execute_parameter_option_session_d; - } - - status = fll_execute_into(0, entry_action->parameters, option, 0, (void *) &result); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_file_found_not) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - fl_print_format("%c%[%SExecution failed, unable to find program or script '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, global->main->error.context); - fl_print_format("%[%Q%]", global->main->error.to.stream, global->main->error.notable, entry_action->parameters.array[0], global->main->error.notable); - fl_print_format("%['.%]%c", global->main->error.to.stream, global->main->error.context, global->main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - } - else { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "fll_execute_into", F_true, global->thread); - } - - return F_status_set_error(F_execute); - } - else if (result != 0) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - fl_print_format("%c%[%SExecution failed with return value of '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, global->main->error.context); - fl_print_format("%[%i%]", global->main->error.to.stream, global->main->error.notable, result, global->main->error.notable); - fl_print_format("$['.%]%c", global->main->error.to.stream, global->main->error.context, global->main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - - return F_status_set_error(F_execute); - } - - return F_execute; - } - else if (entry_action->type == controller_entry_action_type_timeout_e) { - const f_string_t suffix = " MegaTime (milliseconds)"; - - if (entry_action->code == controller_entry_timeout_code_kill_d) { - entry->timeout_kill = entry_action->number; - - controller_entry_preprocess_print_simulate_setting_value(*global, is_entry, controller_timeout_s, controller_kill_s, entry->items.array[global->setting->failsafe_item_id].name, suffix); - } - else if (entry_action->code == controller_entry_timeout_code_start_d) { - entry->timeout_start = entry_action->number; - - controller_entry_preprocess_print_simulate_setting_value(*global, is_entry, controller_timeout_s, controller_start_s, entry->items.array[global->setting->failsafe_item_id].name, suffix); - } - else if (entry_action->code == controller_entry_timeout_code_stop_d) { - entry->timeout_stop = entry_action->number; - - controller_entry_preprocess_print_simulate_setting_value(*global, is_entry, controller_timeout_s, controller_stop_s, entry->items.array[global->setting->failsafe_item_id].name, suffix); - } - } - else if (entry_action->type == controller_entry_action_type_failsafe_e) { - - if (failsafe) { - if (global->main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global->main->warning.to, global->thread); - - fl_print_format("%c%[%SFailsafe may not be specified when running in failsafe, ignoring.%]%c", global->main->warning.to.stream, f_string_eol_s[0], global->main->warning.context, global->main->warning.prefix, global->main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global->main->warning, cache->action); - - controller_unlock_print_flush(global->main->warning.to, global->thread); - } - } - else { - if (entry_action->number == 0 || entry_action->number >= entry->items.used) { - - // This should not happen if the pre-process is working as designed, but in case it doesn't, return a critical error to prevent infinite recursion and similar errors. - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global->main->error.to, global->thread); - - fl_print_format("%c%[%SInvalid %s item index '%]", global->main->error.to.stream, f_string_eol_s[0], global->main->error.context, global->main->error.prefix ? global->main->error.prefix : f_string_empty_s, is_entry ? controller_entry_s : controller_exit_s, global->main->error.context); - fl_print_format("%[%un%]", global->main->error.to.stream, global->main->error.notable, entry_action->number, global->main->error.notable); - fl_print_format("%[' detected.%]%c", global->main->error.to.stream, global->main->error.context, global->main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global->main->error, cache->action); - - controller_unlock_print_flush(global->main->error.to, global->thread); - } - - return F_status_is_error(F_critical); - } - else { - global->setting->failsafe_enabled = F_true; - global->setting->failsafe_item_id = entry_action->number; - - controller_entry_preprocess_print_simulate_setting_value(*global, is_entry, controller_failsafe_s, 0, entry->items.array[global->setting->failsafe_item_id].name, 0); - } - } - } - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt) break; - - cache->action.line_action = 0; - cache->action.name_action.used = 0; - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not || F_status_set_fine(status) == F_require) { - break; - } - } - - // End of actions found, so drop to previous loop in stack. - if (cache->ats.array[at_j] == entry_actions->used) { - - // All actions for "main" are processed so there is nothing left to do. - if (at_i == 0) break; - - at_i -= 2; - at_j -= 2; - - cache->ats.used -= 2; - ++cache->ats.array[at_j]; - - cache->action.line_item = entry->items.array[cache->ats.array[at_i]].line; - cache->action.name_item.used = 0; - - status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[at_i]].name, &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread); - - break; - } - } - } // while - - if (!controller_thread_is_enabled(is_entry, global->thread)) { - return F_status_set_error(F_interrupt); - } - - if (status == F_child) { - return status; - } - - if (F_status_is_error(status_lock)) { - return status_lock; - } - - // Check to see if any required processes failed, but do not do this if already operating in failsafe. - if (F_status_is_error_not(status) && !failsafe && global->main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - const f_status_t status_wait = controller_rule_wait_all(*global, is_entry, F_true, 0); - - if (F_status_is_error(status_wait)) { - return status_wait; - } - - if (status_wait == F_require) { - return F_status_set_error(F_require); - } - } - - if ((global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e && global->main->error.verbosity != f_console_verbosity_quiet_e) || global->main->error.verbosity == f_console_verbosity_verbose_e) { - controller_lock_print(global->main->output.to, global->thread); - - fl_print_format("%cDone processing %s item '", global->main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - fl_print_format("%[%s%]", global->main->output.to.stream, global->main->context.set.title, controller_main_s, global->main->context.set.title); - fl_print_format("'.%c", global->main->output.to.stream, f_string_eol_s[0]); - - // failsafe should not print the extra newline because the failure exit from controller_main should handle this. - if (!failsafe) { - f_print_terminated(f_string_eol_s, global->main->output.to.stream); - } - - controller_unlock_print_flush(global->main->output.to, global->thread); - } - - return status; - } -#endif // _di_controller_entry_process_ - -#ifndef _di_controller_entry_read_ - f_status_t controller_entry_read(const controller_global_t global, const bool is_entry, controller_cache_t * const cache) { - - f_status_t status = F_none; - - controller_entry_t *entry = is_entry ? &global.setting->entry : &global.setting->exit; - - entry->status = F_known_not; - entry->items.used = 0; - - if (global.main->as_init) { - entry->session = controller_entry_session_new_e; - } - else { - entry->session = controller_entry_session_same_e; - } - - cache->action.line_action = 0; - cache->action.line_item = 0; - - macro_f_time_spec_t_clear(cache->timestamp); - - cache->comments.used = 0; - cache->delimits.used = 0; - - cache->content_action.used = 0; - - { - f_array_length_t i = 0; - - for (; i < cache->content_actions.used; ++i) { - cache->content_actions.array[i].used = 0; - } // for - - for (i = 0; i < cache->content_items.used; ++i) { - cache->content_items.array[i].used = 0; - } // for - } - - cache->content_actions.used = 0; - cache->content_items.used = 0; - - cache->object_actions.used = 0; - cache->object_items.used = 0; - - cache->buffer_file.used = 0; - cache->buffer_path.used = 0; - - cache->action.name_file.used = 0; - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - if (is_entry) { - status = controller_file_load(global, F_true, controller_entries_s, global.setting->name_entry, controller_entry_s, controller_entries_s_length, controller_entry_s_length, cache); - } - else { - status = controller_file_load(global, F_false, controller_exits_s, global.setting->name_entry, controller_exit_s, controller_exits_s_length, controller_exit_s_length, cache); - - if (status == F_file_found_not) { - return F_file_found_not; - } - } - - if (F_status_is_error_not(status)) { - if (cache->buffer_file.used) { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_entry, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - f_string_range_t range = macro_f_string_range_t_initialize(cache->buffer_file.used); - - status = fll_fss_basic_list_read(cache->buffer_file, state, &range, &cache->object_items, &cache->content_items, &cache->delimits, 0, &cache->comments); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true); - } - else { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread); - } - } - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fll_print_format("%c%[%SThe %s file is empty.%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : is_entry ? controller_entry_s : controller_exit_s, global.main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_data_not); - } - } - - if (F_status_is_error_not(status) && cache->object_items.used) { - status = controller_entry_items_increase_by(cache->object_items.used, &entry->items); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_items_increase_by", F_true, global.thread); - } - else { - - // 0x1 = main found, 0x2 = found existing. - uint8_t code = 0; - - f_string_range_t *range = 0; - - f_array_length_t at = 0; - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < cache->object_items.used && controller_thread_is_enabled(is_entry, global.thread); ++i) { - - if (code & 0x2) { - code -= 0x2; - } - - at = 0; - range = 0; - - cache->action.line_action = 0; - cache->action.line_item = 0; - - cache->comments.used = 0; - cache->delimits.used = 0; - - cache->content_action.used = 0; - cache->content_actions.used = 0; - - cache->object_actions.used = 0; - - cache->buffer_path.used = 0; - - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - status = controller_entry_items_increase_by(controller_common_allocation_small_d, &entry->items); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_items_increase_by", F_true, global.thread); - break; - } - - status = controller_dynamic_partial_append_terminated(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_partial_append_terminated", F_true, global.thread); - break; - } - - status = f_fss_count_lines(cache->buffer_file, cache->object_items.array[i].start, &cache->action.line_item); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread); - break; - } - - ++cache->action.line_item; - - for (j = (code & 0x1) ? 1 : 0; j < entry->items.used; ++j) { - - if (fl_string_dynamic_compare(entry->items.array[j].name, cache->action.name_item) == F_equal_to) { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SIgnoring duplicate %s item '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_file, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->warning, cache->action); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - code |= 0x2; - break; - } - } // for - - if (code & 0x2) continue; - - range = &cache->content_items.array[i].array[0]; - - if (fl_string_dynamic_compare_string(controller_main_s, cache->action.name_item, controller_main_s_length) == F_equal_to) { - code |= 0x1; - - at = 0; - - if (!entry->items.used) { - entry->items.used = 1; - } - } - else if (fl_string_dynamic_compare_string(controller_setting_s, cache->action.name_item, controller_setting_s_length) == F_equal_to) { - status = controller_entry_settings_read(global, is_entry, *range, cache); - - continue; - } - else if (entry->items.used) { - at = entry->items.used++; - } - else { - - // skip position 0, which is reserved for "main". - entry->items.array[0].name.used = 0; - - at = 1; - entry->items.used = 2; - } - - entry->items.array[at].line = cache->action.line_item; - - status = controller_dynamic_append_terminated(cache->action.name_item, &entry->items.array[at].name); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true); - - break; - } - - status = controller_entry_actions_read(global, is_entry, *range, cache, &entry->items.array[at].actions); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) != F_interrupt) { - controller_lock_print(global.main->error.to, global.thread); - - controller_entry_print_error_cache(is_entry, global.main->error, cache->action); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_set_fine(status) == F_memory_not) { - break; - } - } - } // for - - if (is_entry && F_status_set_fine(status) == F_interrupt) { - return status; - } - - if (F_status_is_error_not(status)) { - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - if (!(code & 0x1)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe required %s item '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_main_s, global.main->error.notable); - fl_print_format("%[' was not found.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_found_not); - } - - if (F_status_is_error_not(status)) { - controller_entry_action_t *action = 0; - - f_array_length_t k = 0; - - // 0x1 = missing or not, 0x2 = one or more missing. - uint8_t missing = 0; - - for (i = 0; i < entry->items.used; ++i) { - - for (j = 0; j < entry->items.array[i].actions.used; ++j) { - - if (!controller_thread_is_enabled(is_entry, global.thread)) { - return F_status_set_error(F_interrupt); - } - - action = &entry->items.array[i].actions.array[j]; - - // only process actions that don't already have an error. - if (F_status_is_error(action->status)) continue; - - if (action->type == controller_entry_action_type_failsafe_e || action->type == controller_entry_action_type_item_e) { - missing |= 0x1; - - for (k = 0; k < entry->items.used; ++k) { - - if (fl_string_dynamic_compare(action->parameters.array[0], entry->items.array[k].name) == F_equal_to) { - if (missing & 0x1) { - missing -= 0x1; - } - - break; - } - } // for - - if (missing & 0x1) { - missing |= 0x2; - - cache->action.line_action = action->line; - cache->action.line_item = entry->items.array[i].line; - - status = controller_dynamic_append_terminated(entry->items.array[i].name, &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true); - - break; - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe required %s item '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, action->parameters.array[0], global.main->error.notable); - fl_print_format("%[' does not exist.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->error, cache->action); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - action->number = 0; - action->status = controller_status_simplify_error(F_found_not); - - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - } - else { - action->number = k; - } - } - } // for - } // for - } - } - } - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) != F_interrupt) { - controller_entry_print_error_cache(is_entry, global.main->error, cache->action); - } - - entry->status = controller_status_simplify_error(F_status_set_fine(status)); - } - else { - entry->status = F_none; - } - - return entry->status; - } -#endif // _di_controller_entry_read_ - -#ifndef _di_controller_entry_settings_read_ - f_status_t controller_entry_settings_read(const controller_global_t global, const bool is_entry, const f_string_range_t content_range, controller_cache_t * const cache) { - - f_status_t status = F_none; - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_entry, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - f_string_range_t range = content_range; - - status = fll_fss_extended_read(cache->buffer_file, state, &range, &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0); - } - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread); - - return status; - } - - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread); - - return status; - } - - cache->delimits.used = 0; - - f_array_length_t i = 0; - f_array_length_t j = 0; - f_array_length_t line = 0; - - controller_entry_t *entry = is_entry ? &global.setting->entry : &global.setting->exit; - - for (; i < cache->object_actions.used; ++i) { - - status = f_fss_count_lines(cache->buffer_file, cache->object_actions.array[i].start, &cache->action.line_action); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread); - - break; - } - - line = ++cache->action.line_action; - cache->action.name_action.used = 0; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_actions.array[i], &cache->action.name_action); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread); - - break; - } - - if (is_entry && fl_string_dynamic_compare_string(controller_control_s, cache->action.name_action, controller_control_s_length) == F_equal_to) { - if (cache->content_actions.array[i].used != 1) { - controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1); - - continue; - } - - cache->action.generic.used = 0; - global.setting->path_control.used = 0; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->content_actions.array[i].array[0], &global.setting->path_control); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - - if (f_path_is_relative(global.setting->path_control.string, global.setting->path_control.used) == F_true) { - - // Use the PID file path for creating a relative path to the control socket. - status = f_file_name_directory(global.setting->path_pid.string, global.setting->path_pid.used, &cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_file_name_directory", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - - status = f_string_append(f_path_separator_s, 1, &cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - - status = f_string_dynamic_append(global.setting->path_control, &cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - } - else { - status = f_string_dynamic_append(global.setting->path_control, &cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - } - - status = f_string_dynamic_terminate_after(&cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread); - - global.setting->path_control.used = 0; - - break; - } - - status = fll_path_canonical(cache->action.generic.string, &global.setting->path_control); - - if (F_status_is_error(status)) { - controller_entry_print_error_file(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_path_canonical", F_true, cache->action.generic.string, "analyze", fll_error_file_type_path_e, global.thread); - - global.setting->path_control.used = 0; - - continue; - } - } - else if (is_entry && fl_string_dynamic_compare_string(controller_control_group_s, cache->action.name_action, controller_control_group_s_length) == F_equal_to) { - gid_t number = 0; - - status = controller_get_id_group(cache->buffer_file, cache->content_actions.array[i].array[0], cache, &number); - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_exist_not) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid group", cache->content_actions.array[i].array[0], ", because no group was found by that name", global.thread, cache); - } - else if (status == F_number_too_large) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid group", cache->content_actions.array[i].array[0], ", because the given ID is too large", global.thread, cache); - } - else if (status == F_number) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid group", cache->content_actions.array[i].array[0], ", because the given ID is not a valid supported number", global.thread, cache); - } - else { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_get_id_group", F_true, global.thread); - } - - continue; - } - - global.setting->control_group = number; - } - else if (is_entry && fl_string_dynamic_compare_string(controller_control_mode_s, cache->action.name_action, controller_control_mode_s_length) == F_equal_to) { - mode_t mode = 0; - uint8_t replace = 0; - f_file_mode_t mode_file = f_file_mode_t_initialize; - - cache->action.generic.used = 0; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->content_actions.array[i].array[0], &cache->action.generic); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread); - - break; - } - - status = f_file_mode_from_string(cache->action.generic.string, global.main->umask, &mode_file, &replace); - - if (F_status_is_error(status)) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an unsupported mode", cache->content_actions.array[i].array[0], ", because the format is unknown or contains invalid data", global.thread, cache); - - continue; - } - - status = f_file_mode_to_mode(mode_file, &mode); - - if (F_status_is_error(status)) { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_file_mode_to_mode", F_true, global.thread); - - continue; - } - - global.setting->control_mode = mode; - } - else if (is_entry && fl_string_dynamic_compare_string(controller_control_user_s, cache->action.name_action, controller_control_user_s_length) == F_equal_to) { - uid_t number = 0; - - status = controller_get_id_user(cache->buffer_file, cache->content_actions.array[i].array[0], cache, &number); - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_exist_not) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because no user was found by that name", global.thread, cache); - } - else if (status == F_number_too_large) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because the given ID is too large", global.thread, cache); - } - else if (status == F_number) { - controller_entry_setting_read_print_error_with_range(is_entry, global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because the given ID is not a valid supported number", global.thread, cache); - } - else { - controller_entry_print_error(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_get_id_user", F_true, global.thread); - } - - continue; - } - - global.setting->control_user = number; - } - else if (is_entry && fl_string_dynamic_compare_string(controller_mode_s, cache->action.name_action, controller_mode_s_length) == F_equal_to) { - if (cache->content_actions.array[i].used != 1) { - controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1); - - continue; - } - - if (fl_string_dynamic_partial_compare_string(controller_service_s, cache->buffer_file, controller_service_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - global.setting->mode = controller_setting_mode_service_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_program_s, cache->buffer_file, controller_program_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - global.setting->mode = controller_setting_mode_program_e; - } - else { - controller_entry_settings_read_print_setting_unknown_action_value(global, is_entry, *cache, i); - - continue; - } - } - else if (fl_string_dynamic_compare_string(controller_pid_s, cache->action.name_action, controller_pid_s_length) == F_equal_to) { - if (cache->content_actions.array[i].used != 1) { - controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1); - - continue; - } - - if (fl_string_dynamic_partial_compare_string(controller_disable_s, cache->buffer_file, controller_disable_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->pid = controller_entry_pid_disable_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_ready_s, cache->buffer_file, controller_ready_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->pid = controller_entry_pid_ready_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_require_s, cache->buffer_file, controller_require_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->pid = controller_entry_pid_require_e; - } - else { - controller_entry_settings_read_print_setting_unknown_action_value(global, is_entry, *cache, i); - - continue; - } - } - else if (fl_string_dynamic_compare_string(controller_session_s, cache->action.name_action, controller_session_s_length) == F_equal_to) { - if (cache->content_actions.array[i].used != 1) { - controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1); - - continue; - } - - if (fl_string_dynamic_partial_compare_string(controller_new_s, cache->buffer_file, controller_new_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->session = controller_entry_session_new_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_same_s, cache->buffer_file, controller_same_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->session = controller_entry_session_same_e; - } - else { - controller_entry_settings_read_print_setting_unknown_action_value(global, is_entry, *cache, i); - - continue; - } - } - else if (fl_string_dynamic_compare_string(controller_show_s, cache->action.name_action, controller_show_s_length) == F_equal_to) { - if (cache->content_actions.array[i].used != 1) { - controller_entry_settings_read_print_setting_requires_exactly(global, is_entry, *cache, 1); - - continue; - } - - if (fl_string_dynamic_partial_compare_string(controller_normal_s, cache->buffer_file, controller_normal_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->show = controller_entry_show_normal_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_init_s, cache->buffer_file, controller_init_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - entry->show = controller_entry_show_init_e; - } - else { - controller_entry_settings_read_print_setting_unknown_action_value(global, is_entry, *cache, i); - - continue; - } - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_entry_settings_read_print_setting_unknown_action(global, is_entry, *cache); - } - - continue; - } - } // for - - return status; - } -#endif // _di_controller_entry_settings_read_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-entry.h b/level_3/controller/c/private-entry.h deleted file mode 100644 index f457ba5..0000000 --- a/level_3/controller/c/private-entry.h +++ /dev/null @@ -1,229 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_entry_h -#define _PRIVATE_entry_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Determine if the type code represents a Rule type. - * - * @param type - * The type code to compare against. - * - * @return - * TRUE if Rule type. - * FALSE otherwise. - */ -#ifndef _di_controller_entry_action_type_is_rule_ - extern f_status_t controller_entry_action_type_is_rule(uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_action_type_is_rule_ - -/** - * Get a string representing the entry action type. - * - * @param type - * The entry action type code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_entry_action_type_name_ - extern f_string_static_t controller_entry_action_type_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_action_type_name_ - -/** - * Convert the Entry Action type to Rule Action type. - * - * @param type - * The Entry Action type. - * - * @return - * TRUE if Rule type. - * FALSE otherwise. - */ -#ifndef _di_controller_entry_action_type_to_rule_action_type_ - extern uint8_t controller_entry_action_type_to_rule_action_type(uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_action_type_to_rule_action_type_ - -/** - * Read the entry list, extracting all items and values. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param content_range - * The range in the list buffer representing the content. - * @param cache - * A structure for containing and caching relevant data. - * @param actions - * The processed actions. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: controller_entry_actions_increase_by(). - * Errors (with error bit) from: f_fss_count_lines(). - * Errors (with error bit) from: fl_fss_apply_delimit(). - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: fl_string_dynamic_rip_nulless(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * Errors (with error bit) from: f_string_dynamics_increase_by(). - * Errors (with error bit) from: fll_fss_extended_read(). - * - * @see controller_entry_actions_increase_by() - * @see f_fss_count_lines() - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamic_terminate_after() - * @see f_string_dynamics_increase_by() - * @see fl_fss_apply_delimit() - * @see fl_string_dynamic_rip_nulless() - * @see fll_fss_extended_read() - */ -#ifndef _di_controller_entry_actions_read_ - extern f_status_t controller_entry_actions_read(const controller_global_t global, const bool is_entry, const f_string_range_t content_range, controller_cache_t * const cache, controller_entry_actions_t *actions) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_actions_read_ - -/** - * Pre-process all items for the loaded entry. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this operate as an entry. - * If FALSE, then this operate as an exit. - * @param cache - * The main/global cache to use. - * - * @return - * F_none on success. - * F_recurse (with error bit) on a recursion error. - * F_valid_not (with error bit) on invalid entry item, entry item action, or entry item action value. - * - * Errors (with error bit) from: macro_f_array_lengths_t_increase_by(). - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * This will detect and report all errors, but only the first error is returned. - * Memory related errors return immediately. - - * @see macro_f_array_lengths_t_increase_by() - * @see f_string_dynamic_append() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_entry_preprocess_ - extern f_status_t controller_entry_preprocess(const controller_global_t global, const bool is_entry, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_preprocess_ - -/** - * Process (execute) all Items for the loaded Entry or Exit. - * - * @param global - * The global data. - * @param cache - * The main/global cache to use. - * @param failsafe - * If TRUE, operate in failsafe mode (starts at designated failsafe Item). - * If FALSE, operate in normal mode (starts at "main" Item). - * @param is_entry - * If TRUE, then this operate as an entry. - * If FALSE, then this operate as an exit. - * - * @return - * F_none on success. - * F_execute on success and program exiting (scripts may result in this) or when execute would have been executed but is instead simulated. - * - * F_require (with error bit) if a required Item failed. - * F_critical (with error bit) on any critical error. - * F_execute (with error bit) if the "execute" Item Action failed. - * - * Errors (with error bit) from: macro_f_array_lengths_t_increase_by(). - * Errors (with error bit) from: controller_perform_ready(). - * Errors (with error bit) from: controller_dynamic_append_terminated(). - * - * @see macro_f_array_lengths_t_increase_by() - * @see controller_perform_ready() - * @see controller_dynamic_append_terminated() - */ -#ifndef _di_controller_entry_process_ - extern f_status_t controller_entry_process(const controller_global_t *global, controller_cache_t * const cache, const bool failsafe, const bool is_entry) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_process_ - -/** - * Read the entry, extracting all lists. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param cache - * The cache for the specific thread. - * This should be the cache global.thread->asynchronouss.array[global.id].cache. - * - * @return - * F_none on success. - * F_file_found_not on file not found for a an exit file (is_entry is FALSE). - * - * Errors (with error bit) from: controller_entry_actions_read(). - * Errors (with error bit) from: controller_entry_items_increase_by(). - * Errors (with error bit) from: controller_file_load(). - * Errors (with error bit) from: controller_status_simplify_error(). - * Errors (with error bit) from: controller_dynamic_append_terminated(). - * Errors (with error bit) from: controller_dynamic_partial_append_terminated(). - * Errors (with error bit) from: f_fss_count_lines(). - * Errors (with error bit) from: fl_fss_apply_delimit(). - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: f_string_dynamic_terminate(). - * Errors (with error bit) from: fll_fss_basic_list_read(). - * - * @see controller_entry_actions_read() - * @see controller_entry_items_increase_by() - * @see controller_file_load() - * @see controller_status_simplify_error() - * @see controller_dynamic_append_terminated() - * @see controller_dynamic_partial_append_terminated() - * @see f_fss_count_lines() - * @see fl_fss_apply_delimit() - * @see f_string_dynamic_append() - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamic_terminate() - * @see fll_fss_basic_list_read() - */ -#ifndef _di_controller_entry_read_ - extern f_status_t controller_entry_read(const controller_global_t global, const bool is_entry, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_read_ - -/** - * Read the entry settings, loading all settings. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param content_range - * The range in the list buffer representing the content. - * @param cache - * A structure for containing and caching relevant data. - */ -#ifndef _di_controller_entry_settings_read_ - extern f_status_t controller_entry_settings_read(const controller_global_t global, const bool is_entry, const f_string_range_t content_range, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_settings_read_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_entry_h diff --git a/level_3/controller/c/private-entry_print.c b/level_3/controller/c/private-entry_print.c deleted file mode 100644 index c628e10..0000000 --- a/level_3/controller/c/private-entry_print.c +++ /dev/null @@ -1,196 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-entry_print.h" -#include "private-lock_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_entry_action_parameters_print_ - void controller_entry_action_parameters_print(FILE * const stream, const controller_entry_action_t action) { - - for (f_array_length_t index = 0; ;) { - - f_print_dynamic_safely(action.parameters.array[index], stream); - - ++index; - - if (index == action.parameters.used) break; - - f_print_terminated(f_string_space_s, stream); - } // for - } -#endif // _di_controller_entry_action_parameters_print_ - -#ifndef _di_controller_entry_preprocess_print_simulate_setting_value_ - void controller_entry_preprocess_print_simulate_setting_value(const controller_global_t global, const bool is_entry, const f_string_t name, const f_string_t name_sub, const f_string_static_t value, const f_string_t suffix) { - - if (global.main->error.verbosity != f_console_verbosity_debug_e && !(global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - return; - } - - controller_lock_print(global.main->output.to, global.thread); - - fl_print_format("%cProcessing %s item action '", global.main->output.to.stream, f_string_eol_s[0], is_entry ? controller_entry_s : controller_exit_s); - - fl_print_format("%[%S%]' setting ", global.main->output.to.stream, global.main->context.set.title, name, global.main->context.set.title); - - if (name_sub) { - fl_print_format("'%[%S%]'", global.main->output.to.stream, global.main->context.set.notable, name_sub, global.main->context.set.notable); - } - else { - fl_print_format("value", global.main->output.to.stream); - } - - fl_print_format(" to '%[%Q%]", global.main->output.to.stream, global.main->context.set.important, value, global.main->context.set.important); - - fl_print_format("'%S.%c", global.main->output.to.stream, suffix, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->output.to, global.thread); - } -#endif // _di_controller_entry_preprocess_print_simulate_setting_value_ - -#ifndef _di_controller_entry_print_error_ - void controller_entry_print_error(const bool is_entry, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - f_thread_mutex_lock(&thread->lock.print); - - fll_error_print(print, status, function, fallback); - - flockfile(print.to.stream); - - controller_entry_print_error_cache(is_entry, print, cache); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_entry_print_error_ - -#ifndef _di_controller_entry_print_error_cache_ - void controller_entry_print_error_cache(const bool is_entry, const fl_print_t output, const controller_cache_action_t cache) { - - fl_print_format("%c%[%SWhile processing ", output.to.stream, f_string_eol_s[0], output.context, output.prefix); - - if (cache.name_action.used) { - fl_print_format("action '%]", output.to.stream, output.context); - fl_print_format("%[%Q%]", output.to.stream, output.notable, cache.name_action, output.notable); - fl_print_format("%[' on line%] ", output.to.stream, output.context, output.context); - fl_print_format("%[%un%]", output.to.stream, output.notable, cache.line_action, output.notable); - fl_print_format("%[ for ", output.to.stream, output.context); - } - - if (cache.name_item.used) { - fl_print_format("%s item '%]", output.to.stream, is_entry ? controller_entry_s : controller_exit_s, output.context); - fl_print_format("%[%Q%]", output.to.stream, output.notable, cache.name_item, output.notable); - fl_print_format("%[' on line%] ", output.to.stream, output.context, output.context); - fl_print_format("%[%un%]", output.to.stream, output.notable, cache.line_item, output.notable); - fl_print_format("%[ for ", output.to.stream, output.context); - } - - if (cache.name_file.used) { - fl_print_format("%s file '%]", output.to.stream, is_entry ? controller_entry_s : controller_exit_s, output.context); - fl_print_format("%[%Q%]%['", output.to.stream, output.notable, cache.name_file, output.notable, output.context); - } - - fl_print_format(".%]%c", output.to.stream, output.context, f_string_eol_s[0]); - } -#endif // _di_controller_entry_print_error_cache_ - -#ifndef _di_controller_entry_print_error_file_ - void controller_entry_print_error_file(const bool is_entry, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type, controller_thread_t *thread) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_file_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - f_thread_mutex_lock(&thread->lock.print); - - fll_error_file_print(print, status, function, fallback, name, operation, type); - - flockfile(print.to.stream); - - controller_entry_print_error_cache(is_entry, print, cache); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_entry_print_error_file_ - -#ifndef _di_controller_entry_setting_read_print_error_with_range_ - void controller_entry_setting_read_print_error_with_range(const bool is_entry, const fl_print_t print, const f_string_t before, const f_string_range_t range, const f_string_t after, controller_thread_t * const thread, controller_cache_t * const cache) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - controller_lock_print(print.to, thread); - - fl_print_format("%c%[%S%s setting%S '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, is_entry ? "Entry" : "Exit", before, print.context); - fl_print_format("%[%/Q%]", print.to.stream, print.notable, cache->buffer_file, range, print.notable); - fl_print_format("%['%S.%]%c", print.to.stream, print.context, after, print.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, print, cache->action); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_entry_setting_read_print_error_with_range_ - -#ifndef _di_controller_entry_settings_read_print_setting_requires_exactly_ - void controller_entry_settings_read_print_setting_requires_exactly(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_number_unsigned_t total) { - - if (global.main->error.verbosity == f_console_verbosity_quiet_e) return; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe %s item setting '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache.action.name_action, global.main->error.notable); - fl_print_format("%[' requires exactly %]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%un%]", global.main->error.to.stream, global.main->error.notable, total, global.main->error.notable); - fl_print_format("%[' %s.%]%c", global.main->error.to.stream, global.main->error.context, total > 1 ? controller_parameters_s : controller_parameter_s, global.main->error.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->error, cache.action); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } -#endif // _di_controller_entry_settings_read_print_setting_requires_exactly_ - -#ifndef _di_controller_entry_settings_read_print_setting_unknown_action_ - void controller_entry_settings_read_print_setting_unknown_action(const controller_global_t global, const bool is_entry, const controller_cache_t cache) { - - if (global.main->warning.verbosity != f_console_verbosity_debug_e) return; - - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SUnknown %s item setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.action.name_action, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->warning, cache.action); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } -#endif // _di_controller_entry_settings_read_print_setting_unknown_action_ - -#ifndef _di_controller_entry_settings_read_print_setting_unknown_action_value_ - void controller_entry_settings_read_print_setting_unknown_action_value(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_array_length_t index) { - - if (global.main->warning.verbosity != f_console_verbosity_debug_e) return; - - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SThe %s item setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.action.name_action, global.main->warning.notable); - fl_print_format("%[' has an unknown value '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, is_entry ? controller_entry_s : controller_exit_s, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache.content_actions.array[index].array[0], global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_entry_print_error_cache(is_entry, global.main->warning, cache.action); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } -#endif // _di_controller_entry_settings_read_print_setting_unknown_action_value_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-entry_print.h b/level_3/controller/c/private-entry_print.h deleted file mode 100644 index 180a9a2..0000000 --- a/level_3/controller/c/private-entry_print.h +++ /dev/null @@ -1,216 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_entry_print_h -#define _PRIVATE_entry_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Print all parameters for some action, separated by a space. - * - * @param stream - * The file stream to print to. - * @param action - * The entry action whose parameters will be printed. - */ -#ifndef _di_controller_entry_action_parameters_print_ - extern void controller_entry_action_parameters_print(FILE * const stream, const controller_entry_action_t action) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_action_parameters_print_ - -/** - * Print message regarding the population of a setting when in simulation or verbose mode. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this operate as an entry. - * If FALSE, then this operate as an exit. - * @param name - * The Object name of the setting being populated. - * @param name_sub - * (optional) A sub-name associated with the setting being populated. - * Set to NULL to disable. - * @param value - * The value being set. - * @param suffix - * An additional message to append at the end (before the final period). - */ -#ifndef _di_controller_entry_preprocess_print_simulate_setting_value_ - extern void controller_entry_preprocess_print_simulate_setting_value(const controller_global_t global, const bool is_entry, const f_string_t name, const f_string_t name_sub, const f_string_static_t value, const f_string_t suffix) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_preprocess_print_simulate_setting_value_ - -/** - * Print the entry related error, locking the print mutex during the print. - * - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param print - * Designates how printing is to be performed. - * @param cache - * The action cache. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param function - * The name of the function where the error happened. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * @param thread - * The thread data. - * - * @see fll_error_print() - * @see controller_entry_print_error_cache() - */ -#ifndef _di_controller_entry_print_error_ - extern void controller_entry_print_error(const bool is_entry, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_print_error_ - -/** - * Print additional error/warning information in addition to existing error that is found within the cache. - * - * This is explicitly intended to be used in addition to the error message. - * - * This neither locks the thread nor does it check to see if output is enabled or disabled. - * - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param output - * Designates how printing is to be performed. - * @param cache - * The action cache. - * - * @see controller_entry_actions_read() - * @see controller_entry_read() - */ -#ifndef _di_controller_entry_print_error_cache_ - extern void controller_entry_print_error_cache(const bool is_entry, const fl_print_t output, const controller_cache_action_t cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_print_error_cache_ - -/** - * Print the entry related file error, locking the print mutex during the print. - * - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param print - * Designates how printing is to be performed. - * @param cache - * The action cache. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param function - * The name of the function where the error happened. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * @param name - * The name of the file or directory. - * @param operation - * The operation that fails, such as 'create' or 'access'. - * @param type - * A valid file type code from the fll_error_file_type enum. - * @param thread - * The thread data. - * - * @see fll_error_file_print() - * @see controller_entry_print_error_cache() - */ -#ifndef _di_controller_entry_print_error_file_ - extern void controller_entry_print_error_file(const bool is_entry, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, const f_string_t name, const f_string_t operation, const uint8_t type, controller_thread_t *thread) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_print_error_file_ - -/** - * Print a message about an entry setting problem, with additional messages about the value. - * - * This is intended to be explicitly called by controller_entry_settings_read(). - * This is intended only to be used for simple messages. - * - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param print - * The error or warning output structure. - * @param before - * The string to add to the message being printed (before the value). - * @param range - * The range within the cache item buffer representing the value. - * @param after - * The string to add to the message being printed (after the value). - * @param thread - * The thread data. - * @param cache - * A structure for containing and caching relevant data. - * - * @see controller_entry_settings_read() - */ -#ifndef _di_controller_entry_setting_read_print_error_with_range_ - extern void controller_entry_setting_read_print_error_with_range(const bool is_entry, const fl_print_t print, const f_string_t before, const f_string_range_t range, const f_string_t after, controller_thread_t * const thread, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_setting_read_print_error_with_range_ - -/** - * Print a message for when an entry setting action has the incorrect number of parameters. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param cache - * A structure for containing and caching relevant data. - * @param total - * The expected number of arguments. - */ -#ifndef _di_controller_entry_settings_read_print_setting_requires_exactly_ - extern void controller_entry_settings_read_print_setting_requires_exactly(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_number_unsigned_t total) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_settings_read_print_setting_requires_exactly_ - -/** - * Print a message for when an entry setting action is unknown. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param cache - * A structure for containing and caching relevant data. - */ -#ifndef _di_controller_entry_settings_read_print_setting_unknown_action_ - extern void controller_entry_settings_read_print_setting_unknown_action(const controller_global_t global, const bool is_entry, const controller_cache_t cache) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_settings_read_print_setting_unknown_action_ - -/** - * Print a message for when an entry setting action has an unknown value. - * - * @param global - * The global data. - * @param is_entry - * If TRUE, then this loads as an entry. - * If FALSE, then this loads as an exit. - * @param cache - * A structure for containing and caching relevant data. - * @param total - * The expected number of arguments. - * @param index - * The location in the content actions array representing the action value. - */ -#ifndef _di_controller_entry_settings_read_print_setting_unknown_action_value_ - extern void controller_entry_settings_read_print_setting_unknown_action_value(const controller_global_t global, const bool is_entry, const controller_cache_t cache, const f_array_length_t index) F_attribute_visibility_internal_d; -#endif // _di_controller_entry_settings_read_print_setting_unknown_action_value_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_entry_print_h diff --git a/level_3/controller/c/private-lock.c b/level_3/controller/c/private-lock.c deleted file mode 100644 index a18fd98..0000000 --- a/level_3/controller/c/private-lock.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-lock.h" -#include "private-thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_lock_create_ - f_status_t controller_lock_create(controller_lock_t *lock) { - - f_status_t status = f_thread_mutex_create(0, &lock->print); - if (F_status_is_error(status)) return status; - - status = f_thread_mutex_create(0, &lock->alert); - if (F_status_is_error(status)) return status; - - status = f_thread_lock_create(0, &lock->process); - if (F_status_is_error(status)) return status; - - status = f_thread_lock_create(0, &lock->rule); - if (F_status_is_error(status)) return status; - - status = f_thread_condition_create(0, &lock->alert_condition); - if (F_status_is_error(status)) return status; - - return F_none; - } -#endif // _di_controller_lock_create_ - -#ifndef _di_controller_lock_read_ - f_status_t controller_lock_read(const bool is_normal, controller_thread_t * const thread, f_thread_lock_t *lock) { - - struct timespec time; - - f_status_t status = F_none; - - for (;;) { - - controller_time(controller_thread_lock_read_timeout_seconds_d, controller_thread_lock_read_timeout_nanoseconds_d, &time); - - status = f_thread_lock_read_timed(&time, lock); - - if (status == F_time) { - if (!controller_thread_is_enabled(is_normal, thread)) { - return F_status_set_error(F_interrupt); - } - } - else { - break; - } - } // for - - return status; - } -#endif // _di_controller_lock_read_ - -#ifndef _di_controller_lock_read_process_ - f_status_t controller_lock_read_process(controller_process_t * const process, controller_thread_t * const thread, f_thread_lock_t *lock) { - - return controller_lock_read_process_type(process->type, thread, lock); - } -#endif // _di_controller_lock_read_process_ - -#ifndef _di_controller_lock_read_process_type_ - f_status_t controller_lock_read_process_type(const uint8_t type, controller_thread_t * const thread, f_thread_lock_t *lock) { - - return controller_lock_read(type != controller_process_type_exit_e, thread, lock); - } -#endif // _di_controller_lock_read_process_type_ - -#ifndef _di_controller_lock_write_ - f_status_t controller_lock_write(const bool is_normal, controller_thread_t * const thread, f_thread_lock_t *lock) { - - struct timespec time; - - f_status_t status = F_none; - - for (;;) { - - controller_time(controller_thread_lock_write_timeout_seconds_d, controller_thread_lock_write_timeout_nanoseconds_d, &time); - - status = f_thread_lock_write_timed(&time, lock); - - if (status == F_time) { - if (!controller_thread_is_enabled(is_normal, thread)) { - return F_status_set_error(F_interrupt); - } - } - else { - break; - } - } // for - - return status; - } -#endif // _di_controller_lock_write_ - -#ifndef _di_controller_lock_write_process_ - f_status_t controller_lock_write_process(controller_process_t * const process, controller_thread_t * const thread, f_thread_lock_t *lock) { - - return controller_lock_write_process_type(process->type, thread, lock); - } -#endif // _di_controller_lock_write_process_ - -#ifndef _di_controller_lock_write_process_type_ - f_status_t controller_lock_write_process_type(const uint8_t type, controller_thread_t * const thread, f_thread_lock_t *lock) { - - return controller_lock_write(type != controller_process_type_exit_e, thread, lock); - } -#endif // _di_controller_lock_write_process_type_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-lock.h b/level_3/controller/c/private-lock.h deleted file mode 100644 index 5c78ddf..0000000 --- a/level_3/controller/c/private-lock.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_lock_h -#define _PRIVATE_lock_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Perform the initial, required, allocation for the lock. - * - * @param lock - * The lock to allocate. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_thread_lock_delete(). - * Errors (with error bit) from: f_thread_mutex_delete(). - * - * @see f_thread_lock_delete() - * @see f_thread_mutex_delete() - */ -#ifndef _di_controller_lock_create_ - extern f_status_t controller_lock_create(controller_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_create_ - -/** - * Wait to get a read lock. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a read lock on. - * - * @return - * F_none on success. - * F_status if main thread is disabled and write lock was never achieved. - * - * F_interrupt (with error bit set) on (exit) signal received, lock will not be set when this is returned. - * - * Status from: f_thread_lock_read_timed(). - * - * Errors (with error bit) from: f_thread_lock_read_timed(). - * - * @see f_thread_lock_read_timed() - */ -#ifndef _di_controller_lock_read_ - extern f_status_t controller_lock_read(const bool is_normal, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_read_ - -/** - * Wait to get a read lock for some process. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param process - * The process to use when checking if thread is enabled. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a read lock on. - * - * @return - * - * Status from: controller_lock_read(). - * - * Errors (with error bit) from: controller_lock_read(). - * - * @see controller_lock_read() - */ -#ifndef _di_controller_lock_read_process_ - extern f_status_t controller_lock_read_process(controller_process_t * const process, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_read_process_ - -/** - * Wait to get a read lock for some process type. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param type - * The process type to use when checking if thread is enabled. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a read lock on. - * - * @return - * - * Status from: controller_lock_read(). - * - * Errors (with error bit) from: controller_lock_read(). - * - * @see controller_lock_read() - */ -#ifndef _di_controller_lock_read_process_type_ - extern f_status_t controller_lock_read_process_type(const uint8_t type, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_read_process_type_ - -/** - * Wait to get a write lock. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a write lock on. - * - * @return - * F_none on success. - * F_status if main thread is disabled and write lock was never achieved. - * - * F_interrupt (with error bit set) on (exit) signal received, lock will not be set when this is returned. - * - * Status from: f_thread_lock_write_timed(). - * - * Errors (with error bit) from: f_thread_lock_write_timed(). - * - * @see f_thread_lock_write_timed() - */ -#ifndef _di_controller_lock_write_ - extern f_status_t controller_lock_write(const bool is_normal, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_write_ - -/** - * Wait to get a write lock for some process. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param process - * The process to use when checking if thread is enabled. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a write lock on. - * - * @return - * - * Status from: controller_lock_write_process_type(). - * - * Errors (with error bit) from: controller_lock_write_process_type(). - * - * @see controller_lock_write_process_type() - */ -#ifndef _di_controller_lock_write_process_ - extern f_status_t controller_lock_write_process(controller_process_t * const process, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_write_process_ - -/** - * Wait to get a write lock for some process type. - * - * Given a r/w lock, periodically check to see if main thread is disabled while waiting. - * - * @param type - * The process type to use when checking if thread is enabled. - * @param thread - * The thread data used to determine if the main thread is disabled or not. - * @param lock - * The r/w lock to obtain a write lock on. - * - * @return - * - * Status from: controller_lock_write(). - * - * Errors (with error bit) from: controller_lock_write(). - * - * @see controller_lock_write() - */ -#ifndef _di_controller_lock_write_process_type_ - extern f_status_t controller_lock_write_process_type(const uint8_t type, controller_thread_t * const thread, f_thread_lock_t *lock) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_write_process_type_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_lock_h diff --git a/level_3/controller/c/private-lock_print.c b/level_3/controller/c/private-lock_print.c deleted file mode 100644 index 2e1d0fa..0000000 --- a/level_3/controller/c/private-lock_print.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-lock_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_lock_print_error_critical_ - void controller_lock_print_error_critical(const fl_print_t print, const f_status_t status, const bool read, controller_thread_t *thread) { - - // A signal is not an error. - if (status == F_interrupt) return; - - if (print.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(print.to, thread); - - fl_print_format("%c%[%SThe pid file '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix ? print.prefix : f_string_empty_s, print.context); - fl_print_format("%['Critical failure while attempting to establish '%]", print.to.stream, print.context, print.context); - fl_print_format("%[%s lock%]", print.to.stream, print.notable, read ? "read" : "write", print.notable); - - if (status != F_failure) { - fl_print_format(" %['due to%] ", print.to.stream, print.context, print.context); - - if (status == F_parameter) { - fl_print_format("%[Invalid Parameter%]", print.to.stream, print.notable, print.notable); - } - else if (status == F_deadlock) { - fl_print_format("%[Deadlock%]", print.to.stream, print.notable, print.notable); - } - else if (status == F_resource_not) { - fl_print_format("%[Too Many Locks%]", print.to.stream, print.notable, print.notable); - } - else { - fl_print_format("%[Unknown Error%]", print.to.stream, print.notable, print.notable); - } - } - - fl_print_format("%['.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); - - controller_unlock_print_flush(print.to, thread); - } - } -#endif // _di_controller_lock_print_error_critical_ - -#ifndef _di_controller_lock_print_ - void controller_lock_print(const f_file_t to, controller_thread_t * const thread) { - - if (thread) { - f_thread_mutex_lock(&thread->lock.print); - } - - flockfile(to.stream); - } -#endif // _di_controller_lock_print_ - -#ifndef _di_controller_unlock_print_flush_ - void controller_unlock_print_flush(const f_file_t to, controller_thread_t * const thread) { - - fflush(to.stream); - funlockfile(to.stream); - - if (thread) { - f_thread_mutex_unlock(&thread->lock.print); - } - } -#endif // _di_controller_unlock_print_flush_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-lock_print.h b/level_3/controller/c/private-lock_print.h deleted file mode 100644 index 0f60359..0000000 --- a/level_3/controller/c/private-lock_print.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_lock_print_h -#define _PRIVATE_lock_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Print a r/w lock related error message, locking the print mutex during the print. - * - * This will ignore F_interrupt and not print any messages, if passed. - * - * @param print - * Designates how printing is to be performed. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param read - * If TRUE, then this is for a read lock. - * If FALSE, then this is for a write lock. - * @param thread - * The thread data. - */ -#ifndef _di_controller_lock_print_error_critical_ - extern void controller_lock_print_error_critical(const fl_print_t print, const f_status_t status, const bool read, controller_thread_t *thread) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_print_error_critical_ - -/** - * Lock the mutex and the stream. - * - * This is implemented as a compliment to controller_unlock_print_flush() for consistency reasons. - * - * @param to - * The file stream to lock. - * @param thread - * The thread containing the print mutex to lock. - * - * @see flockfile() - * - * @see f_thread_mutex_unlock() - */ -#ifndef _di_controller_lock_print_ - extern void controller_lock_print(const f_file_t to, controller_thread_t * const thread) F_attribute_visibility_internal_d; -#endif // _di_controller_lock_print_ - -/** - * Flush the stream buffer and then unlock the mutex. - * - * This unlocks both the stream and the mutex locks. - * - * Weird behavior was observed when piping data from this program. - * The behavior appears related to how this handles locks in addition to the file streams own locking mechanisms. - * - * As a work-around, this performs a flush immediately before unlocking the print mutex. - * - * @param to - * The file stream to unlock and flush. - * @param thread - * The thread containing the print mutex to unlock. - * - * @see funlockfile() - * - * @see f_thread_mutex_unlock() - */ -#ifndef _di_controller_unlock_print_flush_ - void controller_unlock_print_flush(const f_file_t to, controller_thread_t * const thread) F_attribute_visibility_internal_d; -#endif // _di_controller_unlock_print_flush_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_lock_print_h diff --git a/level_3/controller/c/private-process.c b/level_3/controller/c/private-process.c deleted file mode 100644 index 08a9830..0000000 --- a/level_3/controller/c/private-process.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-lock.h" -#include "private-lock_print.h" -#include "private-process.h" -#include "private-rule.h" -#include "private-thread.h" -#include "private-thread_process.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_process_find_ - f_status_t controller_process_find(const f_array_length_t action, const f_string_static_t alias, const controller_processs_t processs, f_array_length_t *at) { - - if (!alias.used) return F_none; - if (!processs.used) return F_false; - - for (f_array_length_t i = 0; i < processs.used; ++i) { - - if (processs.array[i] && processs.array[i]->action == action && fl_string_dynamic_compare(alias, processs.array[i]->rule.alias) == F_equal_to) { - if (at) *at = i; - - return F_true; - } - } // for - - return F_false; - } -#endif // _di_controller_process_find_ - -#ifndef _di_controller_process_prepare_ - f_status_t controller_process_prepare(const controller_global_t global, const bool is_normal, const uint8_t action, const f_string_static_t alias, f_array_length_t *id) { - - f_status_t status = F_none; - - if (controller_process_find(action, alias, global.thread->processs, id) == F_false) { - f_thread_unlock(&global.thread->lock.process); - - status = controller_lock_write(is_normal, global.thread, &global.thread->lock.process); - - if (F_status_is_error(status)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_false, global.thread); - } - else { - status = controller_processs_increase(&global.thread->processs); - } - - if (F_status_is_error_not(status) && global.thread->processs.array[global.thread->processs.used]) { - - controller_process_t *process = global.thread->processs.array[global.thread->processs.used]; - - status = controller_lock_write(is_normal, global.thread, &process->lock); - - if (F_status_is_error(status)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_false, global.thread); - } - else { - process->action = action; - process->rule.alias.used = 0; - - status = f_string_dynamic_append(alias, &process->rule.alias); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate_after(&process->rule.alias); - - if (F_status_is_error_not(status)) { - process->id = global.thread->processs.used++; - status = F_none; - - if (id) { - *id = process->id; - } - } - } - - f_thread_unlock(&process->lock); - } - } - - f_thread_unlock(&global.thread->lock.process); - - // The read lock must be restored on return. - const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process); - - if (F_status_is_error(status_lock)) { - return F_status_set_error(F_lock); - } - } - else { - status = F_found; - } - - return status; - } -#endif // _di_controller_process_prepare_ - -#ifndef _di_controller_process_prepare_process_type_ - f_status_t controller_process_prepare_process_type(const controller_global_t global, const uint8_t type, const uint8_t action, const f_string_static_t alias, f_array_length_t *id) { - - return controller_process_prepare(global, type != controller_process_type_exit_e, action, alias, id); - } -#endif // _di_controller_process_prepare_process_type_ - -#ifndef _di_controller_process_wait_ - f_status_t controller_process_wait(const controller_global_t global, controller_process_t * const process) { - - if (!controller_thread_is_enabled_process(process, global.thread)) { - return F_status_set_error(F_interrupt); - } - - struct timespec time; - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - uint8_t count = 0; - - do { - f_thread_mutex_lock(&process->wait_lock); - - if (count < controller_thread_wait_timeout_1_before_d) { - controller_time(controller_thread_wait_timeout_1_seconds_d, controller_thread_wait_timeout_1_nanoseconds_d, &time); - } - else if (count < controller_thread_wait_timeout_2_before_d) { - controller_time(controller_thread_wait_timeout_2_seconds_d, controller_thread_wait_timeout_2_nanoseconds_d, &time); - } - else if (count < controller_thread_wait_timeout_3_before_d) { - controller_time(controller_thread_wait_timeout_3_seconds_d, controller_thread_wait_timeout_3_nanoseconds_d, &time); - } - else { - controller_time(controller_thread_wait_timeout_4_seconds_d, controller_thread_wait_timeout_4_nanoseconds_d, &time); - } - - status = f_thread_condition_wait_timed(&time, &process->wait, &process->wait_lock); - - f_thread_mutex_unlock(&process->wait_lock); - - if (!controller_thread_is_enabled_process(process, global.thread)) { - return F_status_set_error(F_interrupt); - } - - if (F_status_is_error(status)) break; - - status_lock = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - break; - } - - if (!controller_rule_status_is_available(process->action, process->rule) && !(process->state == controller_process_state_active_e || process->state == controller_process_state_busy_e)) { - f_thread_unlock(&process->lock); - - return F_none; - } - - if (status != F_time) { - - // move up the wait timer after a trigger was received. - if (count < controller_thread_wait_timeout_2_before_d) { - count = 0; - } - else if (count < controller_thread_wait_timeout_3_before_d) { - count = controller_thread_wait_timeout_1_before_d; - } - else { - count = controller_thread_wait_timeout_2_before_d; - } - } - - f_thread_unlock(&process->lock); - - if (count < controller_thread_wait_timeout_3_before_d) { - ++count; - } - - } while (status == F_time && controller_thread_is_enabled_process(process, global.thread)); - - return status; - } -#endif // _di_controller_process_wait_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-process.h b/level_3/controller/c/private-process.h deleted file mode 100644 index c818851..0000000 --- a/level_3/controller/c/private-process.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_process_h -#define _PRIVATE_process_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Prepare the process. - * - * The process is initialized with the process id, the rule alias, and the rule action type. - * These are the necessary parts for uniquely identifying the process. - * - * If a process by the given Rule alias and Rule Action already exists, then nothing is done. - * - * This requires that a global.thread->lock.process lock be set on process->lock before being called. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param action - * The Rule Action to use. - * @param alias - * The Rule alias to use. - * @param id - * (optional) The process ID when found or created. - * Set to NULL to not use. - * - * @return - * F_none on success. - * F_found on success, but nothing was done because an existing process was found. - * - * F_lock (with error bit) if failed to re-establish read lock on global.thread->lock.process while returning. - * - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * Errors (with error bit) from: controller_lock_read(). - * Errors (with error bit) from: controller_lock_write(). - * - * @see f_string_dynamic_append() - * @see f_string_dynamic_terminate_after() - * @see controller_lock_read() - * @see controller_lock_write() - */ -#ifndef _di_controller_process_prepare_ - extern f_status_t controller_process_prepare(const controller_global_t global, const bool is_normal, const uint8_t action, const f_string_static_t alias, f_array_length_t *id) F_attribute_visibility_internal_d; -#endif // _di_controller_process_prepare_ - -/** - * Prepare the process for some process type. - * - * The process is initialized with the process id, the rule alias, and the rule action type. - * These are the necessary parts for uniquely identifying the process. - * - * If a process by the given Rule alias and Rule Action already exists, then nothing is done. - * - * This requires that a global.thread->lock.process lock be set on process->lock before being called. - * - * @param global - * The global data. - * @param type - * The process type to use when checking if thread is enabled. - * @param action - * The Rule Action to use. - * @param alias - * The Rule alias to use. - * @param id - * (optional) The process ID when found or created. - * Set to NULL to not use. - * - * @return - * Success from: controller_process_prepare() - * - * Errors (with error bit) from: controller_process_prepare(). - * - * @see controller_process_prepare() - */ -#ifndef _di_controller_process_prepare_process_type_ - extern f_status_t controller_process_prepare_process_type(const controller_global_t global, const uint8_t type, const uint8_t action, const f_string_static_t alias, f_array_length_t *id) F_attribute_visibility_internal_d; -#endif // _di_controller_process_prepare_process_type_ - -/** - * Find an existing process, for the given Rule Action. - * - * Do not confuse this with a process in the context of a PID. - * This is a stucture for the current processing of some rule. - * - * This does not do any locking or unlocking for the processs data, be sure to lock appropriately before and after calling this. - * - * @param action - * The Rule Action to find. - * @param alias - * The Rule alias to find. - * @param processs - * The array of processes to. - * @param at - * The location within processs the id was found. - * (optional) Set to NULL to disable. - * - * @return - * F_none if not given a valid id to search. - * F_false if there is no process found. - * F_true if there is a process found (address is stored in "at"). - */ -#ifndef _di_controller_process_find_ - f_status_t controller_process_find(const f_array_length_t action, const f_string_static_t alias, const controller_processs_t processs, f_array_length_t *at) F_attribute_visibility_internal_d; -#endif // _di_controller_process_find_ - -/*** - * Safely wait for a process, periodically checking to see if process completed or check if exiting. - * - * @param global - * The global data. - * @param process - * The process to wait on. - * - * @return - * F_none on success. - * - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * - * Success from: f_thread_condition_wait_timed(). - * - * Errors (with error bit) from: f_thread_condition_wait_timed(). - * - * @see f_thread_condition_wait_timed() - */ -#ifndef _di_controller_process_wait_ - extern f_status_t controller_process_wait(const controller_global_t global, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_process_wait_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_process_h diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c deleted file mode 100644 index 19caf0e..0000000 --- a/level_3/controller/c/private-rule.c +++ /dev/null @@ -1,6207 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-lock.h" -#include "private-lock_print.h" -#include "private-process.h" -#include "private-rule.h" -#include "private-rule_print.h" -#include "private-thread.h" -#include "private-thread_process.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_rule_action_method_name_ - f_string_static_t controller_rule_action_method_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_rule_action_method_extended_e: - buffer.string = controller_rule_action_method_string_extended_s; - buffer.used = controller_rule_action_method_string_extended_s_length; - break; - - case controller_rule_action_method_extended_list_e: - buffer.string = controller_rule_action_method_string_extended_list_s; - buffer.used = controller_rule_action_method_string_extended_list_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_rule_action_method_name_ - -#ifndef _di_controller_rule_find_ - f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_array_length_t *at) { - - if (!alias.used) return F_none; - if (!rules.used) return F_false; - - for (f_array_length_t i = 0; i < rules.used; ++i) { - - if (fl_string_dynamic_compare(alias, rules.array[i].alias) == F_equal_to) { - if (at) *at = i; - - return F_true; - } - } // for - - return F_false; - } -#endif // _di_controller_rule_find_ - -#ifndef _di_controller_rule_parameters_read_ - f_status_t controller_rule_parameters_read(const controller_global_t global, 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 = f_string_dynamics_increase(controller_common_allocation_small_d, parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - - return status; - } - - parameters->array[parameters->used].used = 0; - - status = f_string_dynamic_partial_append_nulless(buffer, *object, ¶meters->array[0]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true); - - return status; - } - - status = f_string_dynamic_terminate_after(¶meters->array[0]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - return status; - } - - ++parameters->used; - } - - if (content && content->used) { - - for (f_array_length_t i = 0; i < content->used; ++i) { - - if (content->array[i].start > content->array[i].start) continue; - - status = f_string_dynamics_increase(controller_common_allocation_small_d, parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - - return status; - } - - parameters->array[parameters->used].used = 0; - - status = f_string_dynamic_partial_append_nulless(buffer, content->array[i], ¶meters->array[parameters->used]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true); - - return status; - } - - status = f_string_dynamic_terminate_after(¶meters->array[parameters->used]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - return status; - } - - ++parameters->used; - } // for - } - - return F_none; - } -#endif // _di_controller_rule_parameters_read_ - -#ifndef _di_controller_rule_action_type_to_action_execute_type_ - uint8_t controller_rule_action_type_to_action_execute_type(const uint8_t type) { - - if (type == controller_rule_action_type_freeze_e) { - return controller_rule_action_type_execute_freeze_e; - } - - if (type == controller_rule_action_type_kill_e) { - return controller_rule_action_type_execute_kill_e; - } - - if (type == controller_rule_action_type_pause_e) { - return controller_rule_action_type_execute_pause_e; - } - - if (type == controller_rule_action_type_reload_e) { - return controller_rule_action_type_execute_reload_e; - } - - if (type == controller_rule_action_type_restart_e) { - return controller_rule_action_type_execute_restart_e; - } - - if (type == controller_rule_action_type_resume_e) { - return controller_rule_action_type_execute_resume_e; - } - - if (type == controller_rule_action_type_start_e) { - return controller_rule_action_type_execute_start_e; - } - - if (type == controller_rule_action_type_stop_e) { - return controller_rule_action_type_execute_stop_e; - } - - if (type == controller_rule_action_type_thaw_e) { - return controller_rule_action_type_execute_thaw_e; - } - - return controller_rule_action_type_execute__enum_size_e; - } -#endif // _di_controller_rule_action_type_to_action_execute_type_ - -#ifndef _di_controller_rule_action_type_name_ - f_string_static_t controller_rule_action_type_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_rule_action_type_freeze_e: - buffer.string = controller_freeze_s; - buffer.used = controller_freeze_s_length; - break; - - case controller_rule_action_type_group_e: - buffer.string = controller_group_s; - buffer.used = controller_group_s_length; - break; - - case controller_rule_action_type_kill_e: - buffer.string = controller_kill_s; - buffer.used = controller_kill_s_length; - break; - - case controller_rule_action_type_pause_e: - buffer.string = controller_pause_s; - buffer.used = controller_pause_s_length; - break; - - case controller_rule_action_type_pid_file_e: - buffer.string = controller_pid_file_s; - buffer.used = controller_pid_file_s_length; - break; - - case controller_rule_action_type_rerun_e: - buffer.string = controller_rerun_s; - buffer.used = controller_rerun_s_length; - break; - - case controller_rule_action_type_reload_e: - buffer.string = controller_reload_s; - buffer.used = controller_reload_s_length; - break; - - case controller_rule_action_type_restart_e: - buffer.string = controller_restart_s; - buffer.used = controller_restart_s_length; - break; - - case controller_rule_action_type_resume_e: - buffer.string = controller_resume_s; - buffer.used = controller_resume_s_length; - break; - - case controller_rule_action_type_start_e: - buffer.string = controller_start_s; - buffer.used = controller_start_s_length; - break; - - case controller_rule_action_type_stop_e: - buffer.string = controller_stop_s; - buffer.used = controller_stop_s_length; - break; - - case controller_rule_action_type_thaw_e: - buffer.string = controller_thaw_s; - buffer.used = controller_thaw_s_length; - break; - - case controller_rule_action_type_user_e: - buffer.string = controller_user_s; - buffer.used = controller_user_s_length; - break; - - case controller_rule_action_type_with_e: - buffer.string = controller_with_s; - buffer.used = controller_with_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_rule_action_type_name_ - -#ifndef _di_controller_rule_action_type_execute_name_ - f_string_static_t controller_rule_action_type_execute_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_rule_action_type_execute_freeze_e: - buffer.string = controller_freeze_s; - buffer.used = controller_freeze_s_length; - break; - - case controller_rule_action_type_execute_kill_e: - buffer.string = controller_kill_s; - buffer.used = controller_kill_s_length; - break; - - case controller_rule_action_type_execute_pause_e: - buffer.string = controller_pause_s; - buffer.used = controller_pause_s_length; - break; - - case controller_rule_action_type_execute_reload_e: - buffer.string = controller_reload_s; - buffer.used = controller_reload_s_length; - break; - - case controller_rule_action_type_execute_restart_e: - buffer.string = controller_restart_s; - buffer.used = controller_restart_s_length; - break; - - case controller_rule_action_type_execute_resume_e: - buffer.string = controller_resume_s; - buffer.used = controller_resume_s_length; - break; - - case controller_rule_action_type_execute_start_e: - buffer.string = controller_start_s; - buffer.used = controller_start_s_length; - break; - - case controller_rule_action_type_execute_stop_e: - buffer.string = controller_stop_s; - buffer.used = controller_stop_s_length; - break; - - case controller_rule_action_type_execute_thaw_e: - buffer.string = controller_thaw_s; - buffer.used = controller_thaw_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_rule_action_type_execute_name_ - -#ifndef _di_controller_rule_action_read_ - f_status_t controller_rule_action_read(const controller_global_t global, const bool is_normal, const uint8_t type, const uint8_t method, controller_cache_t * const cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) { - - f_status_t status = F_none; - - if (method == controller_rule_action_method_extended_list_e) { - cache->comments.used = 0; - cache->delimits.used = 0; - cache->content_action.used = 0; - cache->content_actions.used = 0; - cache->object_actions.used = 0; - - if (actions->size) { - actions->array[actions->used].parameters.used = 0; - } - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - - status = fl_fss_extended_list_content_read(cache->buffer_item, state, range, &cache->content_action, &cache->delimits, &cache->comments); - } - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true); - } - else if (status == F_fss_found_content) { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); - } - else { - - // "script" and "utility" types use the entire content and can be directly passed through. - if (item->type == controller_rule_item_type_script_e || item->type == controller_rule_item_type_utility_e) { - actions->array[actions->used].parameters.used = 0; - - status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - } - else { - actions->array[actions->used].type = type; - actions->array[actions->used].line = cache->action.line_action; - actions->array[actions->used].parameters.used = 0; - actions->array[actions->used].status = F_known_not; - - status = f_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)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true); - } - - status = f_string_dynamic_terminate_after(&actions->array[actions->used].parameters.array[0]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - else { - actions->array[actions->used++].parameters.used = 1; - } - } - - return status; - } - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - - cache->delimits.used = 0; - - // 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, state, &cache->content_action.array[0], &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0); - } - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fll_fss_extended_read", F_true); - } - else { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); - } - else { - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < cache->object_actions.used; ++i) { - status = controller_rule_actions_increase_by(controller_common_allocation_small_d, actions); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->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)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true); - - break; - } - - actions->array[actions->used].type = type; - actions->array[actions->used].line += ++item->line; - actions->array[actions->used].parameters.used = 0; - actions->array[actions->used].status = F_known_not; - - status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - - actions->array[actions->used].status = controller_status_simplify_error(F_status_set_fine(status)); - - break; - } - - status = controller_rule_parameters_read(global, 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_error(F_status_set_fine(status)); - } // for - - range->start = cache->content_action.array[0].start; - } - } - } - } - else { - status = F_data_not; - } - } - else { - cache->content_action.used = 0; - cache->delimits.used = 0; - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - - status = fl_fss_extended_content_read(cache->buffer_item, state, range, &cache->content_action, 0, &cache->delimits); - } - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fll_fss_extended_content_read", F_true); - } - else if (status == F_fss_found_content) { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); - } - else if (type == controller_rule_action_type_pid_file_e) { - item->pid_file.used = 0; - - status = fl_string_dynamic_rip(cache->buffer_item, cache->content_action.array[0], &item->pid_file); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_string_dynamic_rip", F_true); - } - else { - status = f_string_dynamic_terminate_after(&item->pid_file); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - } - } - else if (type == controller_rule_action_type_rerun_e) { - uint8_t type_rerun = 0; - - if (cache->content_action.used) { - if (fl_string_dynamic_partial_compare_string(controller_freeze_s, cache->buffer_item, controller_freeze_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_freeze_e; - } - if (fl_string_dynamic_partial_compare_string(controller_kill_s, cache->buffer_item, controller_kill_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_kill_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_pause_s, cache->buffer_item, controller_pause_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_pause_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_reload_s, cache->buffer_item, controller_reload_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_reload_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_restart_s, cache->buffer_item, controller_restart_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_restart_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_resume_s, cache->buffer_item, controller_resume_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_resume_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_start_s, cache->buffer_item, controller_start_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_start_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_stop_s, cache->buffer_item, controller_stop_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_stop_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_thaw_s, cache->buffer_item, controller_thaw_s_length, cache->content_action.array[0]) == F_equal_to) { - type_rerun = controller_rule_action_type_execute_thaw_e; - } - } - - if (!type_rerun) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_rerun_s, global.main->error.notable); - fl_print_format("%[' has '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_action.array[0], global.main->error.notable); - fl_print_format("%[' as the first value, only the following are allowed: '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_freeze_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_kill_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_pause_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_reload_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_restart_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_resume_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', '%]", global.main->error.to.stream, global.main->error.notable, controller_start_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[', or '%]", global.main->error.to.stream, global.main->error.notable, controller_stop_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_thaw_s, global.main->error.notable, global.main->error.context); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return F_status_set_error(F_valid_not); - } - - controller_rule_rerun_item_t *rerun_item = 0; - - if (cache->content_action.used > 1) { - if (fl_string_dynamic_partial_compare_string(controller_failure_s, cache->buffer_item, controller_failure_s_length, cache->content_action.array[1]) == F_equal_to) { - rerun_item = &item->reruns[type_rerun].failure; - item->reruns[type_rerun].is |= controller_rule_rerun_is_failure_d; - } - else if (fl_string_dynamic_partial_compare_string(controller_success_s, cache->buffer_item, controller_success_s_length, cache->content_action.array[1]) == F_equal_to) { - rerun_item = &item->reruns[type_rerun].success; - item->reruns[type_rerun].is |= controller_rule_rerun_is_success_d; - } - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_rerun_s, global.main->error.notable); - fl_print_format("%[' has '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_action.array[1], global.main->error.notable); - fl_print_format("%[' as the second value, only the following are allowed: '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]%[' or '%]", global.main->error.to.stream, global.main->error.notable, controller_stop_s, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_thaw_s, global.main->error.notable, global.main->error.context); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return F_status_set_error(F_valid_not); - } - - for (f_array_length_t i = 2; i < cache->content_action.used; ++i) { - - if (fl_string_dynamic_partial_compare_string(controller_delay_s, cache->buffer_item, controller_delay_s_length, cache->content_action.array[i]) == F_equal_to) { - status = controller_rule_action_read_rerun_number(global, controller_delay_s, cache, &i, &rerun_item->delay); - } - else if (fl_string_dynamic_partial_compare_string(controller_max_s, cache->buffer_item, controller_max_s_length, cache->content_action.array[i]) == F_equal_to) { - status = controller_rule_action_read_rerun_number(global, controller_max_s, cache, &i, &rerun_item->max); - } - else if (fl_string_dynamic_partial_compare_string(controller_reset_s, cache->buffer_item, controller_reset_s_length, cache->content_action.array[i]) == F_equal_to) { - item->reruns[type_rerun].is |= rerun_item == &item->reruns[type_rerun].failure ? controller_rule_rerun_is_failure_reset_d : controller_rule_rerun_is_success_reset_d; - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_rerun_s, global.main->error.notable); - fl_print_format("%[' has an unknown value '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_action.array[i], global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return F_status_set_error(F_valid_not); - } - } // for - } - else if (type == controller_rule_action_type_with_e) { - - for (f_array_length_t i = 0; i < cache->content_action.used; ++i) { - - if (fl_string_dynamic_partial_compare_string(controller_full_path_s, cache->buffer_item, controller_full_path_s_length, cache->content_action.array[i]) == F_equal_to) { - item->with |= controller_with_full_path_d; - } - else if (fl_string_dynamic_partial_compare_string(controller_session_new_s, cache->buffer_item, controller_session_new_s_length, cache->content_action.array[i]) == F_equal_to) { - item->with |= controller_with_session_new_d; - - // "session_new" and "session_same" are mutually exclusive. - if (item->with & controller_with_session_same_d) { - item->with -= controller_with_session_same_d; - } - } - else if (fl_string_dynamic_partial_compare_string(controller_session_same_s, cache->buffer_item, controller_session_same_s_length, cache->content_action.array[i]) == F_equal_to) { - item->with |= controller_with_session_same_d; - - // "session_new" and "session_same" are mutually exclusive. - if (item->with & controller_with_session_new_d) { - item->with -= controller_with_session_new_d; - } - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SUnknown value '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_action.array[i], global.main->error.notable); - fl_print_format("%[' for rule item action '%]%[%s%]", global.main->error.to.stream, global.main->error.context, global.main->error.context, global.main->error.notable, controller_with_s, global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_valid_not); - break; - } - } // for - } - else if (item->type == controller_rule_item_type_script_e || item->type == controller_rule_item_type_utility_e) { - status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - } - else { - - // "script" types use the entire content as a single string piped to the script, so merge all arguments together. - actions->array[actions->used].type = type; - actions->array[actions->used].line = cache->action.line_action; - actions->array[actions->used].parameters.used = 0; - actions->array[actions->used].status = F_known_not; - - for (f_array_length_t i = 0; i < cache->content_action.used; ++i) { - - status = f_string_dynamic_partial_mash_nulless(f_string_space_s, F_string_space_s_length, cache->buffer_item, cache->content_action.array[i], &actions->array[actions->used].parameters.array[0]); - if (F_status_is_error(status)) break; - } // for - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_mash_nulless", F_true); - } - else { - status = f_string_dynamic_terminate_after(&actions->array[actions->used].parameters.array[0]); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - else { - actions->array[actions->used++].parameters.used = 1; - } - } - } - } - else { - status = f_fss_count_lines(cache->buffer_item, range->start, &actions->array[actions->used].line); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true); - } - else { - actions->array[actions->used].type = type; - 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(global, cache->buffer_item, 0, &cache->content_action, &actions->array[actions->used].parameters); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_rule_parameters_read", F_true); - - actions->array[actions->used++].status = controller_status_simplify_error(F_status_set_fine(status)); - } - else { - actions->array[actions->used++].status = status; - } - } - } - } - else { - status = F_data_not; - } - } - - if (F_status_is_error_not(status) && status == F_data_not) { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SAction is empty, nothing to do.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, cache->action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - } - - return status; - } -#endif // _di_controller_rule_action_read_ - -#ifndef _di_controller_rule_action_read_rerun_number_ - f_status_t controller_rule_action_read_rerun_number(const controller_global_t global, const f_string_t name, controller_cache_t * const cache, f_array_length_t * const index, f_number_unsigned_t * const number) { - - f_status_t status = F_none; - f_number_unsigned_t parsed = 0; - - if (*index + 1 == cache->content_action.used) { - status = F_status_set_error(F_valid_not); - } - else { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, cache->content_action.array[++(*index)], &parsed); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_action.array[*index]), &parsed); - } - - if (status == F_data_not) { - status = F_status_set_error(F_valid_not); - } - } - - if (F_status_is_error(status)) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - status = F_status_set_fine(status); - - if (status != F_valid_not && status != F_number && status != F_number_decimal && status != F_number_overflow && status != F_number_underflow && status != F_number_negative) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - } - else { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_rerun_s, global.main->error.notable); - fl_print_format("%[' requires a positive whole number or 0 for the '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%S%]", global.main->error.to.stream, global.main->error.notable, name, global.main->error.notable); - fl_print_format("%[' value", global.main->error.to.stream, global.main->error.context, global.main->error.context); - - if (*index + 1 == cache->content_action.used) { - fl_print_format(", but none were given.%]%c", global.main->error.to.stream, global.main->error.context, f_string_eol_s[0]); - } - else { - fl_print_format(", but '%]%[%/Q%]", global.main->error.to.stream, global.main->error.context, global.main->error.notable, cache->buffer_item, cache->content_action.array[*index], global.main->error.notable); - - if (status == F_number || status == F_number_decimal) { - fl_print_format("%[' was given.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - else if (status == F_number_overflow) { - fl_print_format("%[' is too large.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - else { - fl_print_format("%[' is negative.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - } - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - } - - return status; - } - - *number = parsed; - - return F_none; - } -#endif // _di_controller_rule_action_read_rerun_number_ - -#ifndef _di_controller_rule_copy_ - f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t *destination) { - - f_status_t status = F_none; - - // Delete the third party structures. - macro_f_control_group_t_delete_simple(destination->cgroup) - f_capability_delete(&destination->capability); - - for (f_array_length_t i = 0; i < controller_rule_action_type__enum_size_e; ++i) { - destination->status[i] = source.status[i]; - } // for - - destination->timeout_kill = source.timeout_kill; - destination->timeout_start = source.timeout_start; - destination->timeout_stop = source.timeout_stop; - - destination->has = source.has; - destination->nice = source.nice; - destination->user = source.user; - destination->group = source.group; - - destination->timestamp.seconds = source.timestamp.seconds; - destination->timestamp.nanoseconds = source.timestamp.nanoseconds; - - destination->alias.used = 0; - destination->name.used = 0; - destination->path.used = 0; - destination->script.used = 0; - - destination->define.used = 0; - destination->parameter.used = 0; - destination->environment.used = 0; - - destination->affinity.used = 0; - destination->groups.used = 0; - destination->limits.used = 0; - destination->scheduler.policy = source.scheduler.policy; - destination->scheduler.priority = source.scheduler.priority; - - for (f_array_length_t i = 0; i < destination->ons.size; ++i) { - - destination->ons.array[i].action = 0; - destination->ons.array[i].need.used = 0; - destination->ons.array[i].want.used = 0; - destination->ons.array[i].wish.used = 0; - } // for - - destination->ons.used = 0; - destination->items.used = 0; - - if (source.alias.used) { - status = f_string_dynamic_append(source.alias, &destination->alias); - if (F_status_is_error(status)) return status; - } - - if (source.name.used) { - status = f_string_dynamic_append(source.name, &destination->name); - if (F_status_is_error(status)) return status; - } - - if (source.path.used) { - status = f_string_dynamic_append(source.path, &destination->path); - if (F_status_is_error(status)) return status; - } - - if (source.script.used) { - status = f_string_dynamic_append(source.script, &destination->script); - if (F_status_is_error(status)) return status; - } - - if (source.define.used) { - status = f_string_maps_append(source.define, &destination->define); - if (F_status_is_error(status)) return status; - } - - if (source.parameter.used) { - status = f_string_maps_append(source.parameter, &destination->parameter); - if (F_status_is_error(status)) return status; - } - - if (source.environment.used) { - status = f_string_dynamics_append(source.environment, &destination->environment); - if (F_status_is_error(status)) return status; - } - - if (source.ons.used) { - if (destination->ons.used < source.ons.used) { - status = controller_rule_ons_resize(source.ons.used, &destination->ons); - if (F_status_is_error(status)) return status; - } - - for (f_array_length_t i = 0; i < source.ons.used; ++i) { - - destination->ons.array[i].action = source.ons.array[i].action; - - if (source.ons.array[i].need.used) { - destination->ons.array[i].need.used = 0; - - status = f_string_dynamics_append(source.ons.array[i].need, &destination->ons.array[i].need); - if (F_status_is_error(status)) return status; - } - - if (source.ons.array[i].want.used) { - destination->ons.array[i].want.used = 0; - - status = f_string_dynamics_append(source.ons.array[i].want, &destination->ons.array[i].want); - if (F_status_is_error(status)) return status; - } - - if (source.ons.array[i].wish.used) { - destination->ons.array[i].wish.used = 0; - - status = f_string_dynamics_append(source.ons.array[i].wish, &destination->ons.array[i].wish); - if (F_status_is_error(status)) return status; - } - } // for - - destination->ons.used = source.ons.used; - } - - if (source.affinity.used) { - status = f_type_int32s_append(source.affinity, &destination->affinity); - if (F_status_is_error(status)) return status; - } - - if (source.capability) { - status = f_capability_copy(source.capability, &destination->capability); - if (F_status_is_error(status)) return status; - } - - status = f_control_group_copy(source.cgroup, &destination->cgroup); - if (F_status_is_error(status)) return status; - - if (source.groups.used) { - status = f_type_int32s_append(source.groups, &destination->groups); - if (F_status_is_error(status)) return status; - } - - if (source.limits.used) { - status = f_limit_sets_copy(source.limits, &destination->limits); - if (F_status_is_error(status)) return status; - } - - if (source.items.used) { - controller_rule_item_t *item_source = 0; - controller_rule_item_t *item_destination = 0; - - controller_rule_action_t *action_source = 0; - controller_rule_action_t *action_destination = 0; - - if (source.items.used > destination->items.size) { - status = controller_rule_items_increase_by(source.items.used - destination->items.size, &destination->items); - if (F_status_is_error(status)) return status; - } - - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < source.items.used; ++i) { - - item_source = &source.items.array[i]; - item_destination = &destination->items.array[i]; - - if (item_source->actions.used > item_destination->actions.size) { - status = controller_rule_actions_increase_by(item_source->actions.used - item_destination->actions.size, &item_destination->actions); - if (F_status_is_error(status)) return status; - } - - item_destination->type = item_source->type; - item_destination->with = item_source->with; - item_destination->line = item_source->line; - item_destination->pid_file.used = 0; - - status = f_string_dynamic_append(item_source->pid_file, &item_destination->pid_file); - if (F_status_is_error(status)) return status; - - status = f_string_dynamic_terminate_after(&item_destination->pid_file); - if (F_status_is_error(status)) return status; - - for (j = 0; j < controller_rule_action_type_execute__enum_size_e; ++j) { - item_destination->reruns[j].is = item_source->reruns[j].is; - item_destination->reruns[j].failure.count = item_source->reruns[j].failure.count; - item_destination->reruns[j].failure.delay = item_source->reruns[j].failure.delay; - item_destination->reruns[j].failure.max = item_source->reruns[j].failure.max; - item_destination->reruns[j].success.count = item_source->reruns[j].success.count; - item_destination->reruns[j].success.delay = item_source->reruns[j].success.delay; - item_destination->reruns[j].success.max = item_source->reruns[j].success.max; - } // for - - for (j = 0; j < item_source->actions.used; ++j) { - - action_source = &item_source->actions.array[j]; - action_destination = &item_destination->actions.array[j]; - - action_destination->type = action_source->type; - action_destination->line = action_source->line; - action_destination->status = action_source->status; - - action_destination->parameters.used = 0; - - status = f_string_dynamics_append(action_source->parameters, &action_destination->parameters); - if (F_status_is_error(status)) return status; - } // for - - item_destination->actions.used = item_source->actions.used; - } // for - - destination->items.used = source.items.used; - } - - return status; - } -#endif // _di_controller_rule_copy_ - -#ifndef _di_controller_rule_execute_ - f_status_t controller_rule_execute(const controller_global_t global, const uint8_t action, const uint8_t options, controller_process_t * const process) { - - f_status_t status = F_none; - f_status_t success = F_false; - - f_array_length_t i = 0; - f_array_length_t j = 0; - f_array_length_t k = 0; - - // Child processes should receive all signals and handle the signals as they see fit. - f_signal_how_t signals = f_signal_how_t_initialize; - f_signal_set_empty(&signals.block); - f_signal_set_fill(&signals.block_not); - - f_string_maps_t environment = f_string_maps_t_initialize; - - const f_string_dynamics_t arguments_none = f_string_dynamics_t_initialize; - - controller_execute_set_t execute_set = macro_controller_execute_set_t_initialize(0, 0, process->rule.has & controller_rule_has_environment_d ? &environment : 0, &signals, 0, fl_execute_as_t_initialize); - - if (process->rule.affinity.used) { - execute_set.as.affinity = &process->rule.affinity; - } - - if (process->rule.capability) { - execute_set.as.capability = process->rule.capability; - } - - if (process->rule.has & controller_rule_has_cgroup_d) { - execute_set.as.control_group = &process->rule.cgroup; - - // Make sure all required cgroup directories exist. - if (controller_rule_status_is_available(action, process->rule)) { - status = fll_control_group_prepare(process->rule.cgroup); - - if (F_status_is_error(status)) { - controller_print_error_file(global.thread, global.main->error, F_status_set_fine(status), "fll_control_group_prepare", F_true, process->rule.cgroup.path.string, "prepare control groups for", fll_error_file_type_directory_e); - - return status; - } - } - } - - if (process->rule.has & controller_rule_has_group_d) { - execute_set.as.id_group = &process->rule.group; - - if (process->rule.groups.used) { - execute_set.as.id_groups = &process->rule.groups; - } - } - - if (process->rule.limits.used) { - execute_set.as.limits = &process->rule.limits; - } - - if (process->rule.has & controller_rule_has_scheduler_d) { - execute_set.as.scheduler = &process->rule.scheduler; - } - - if (process->rule.has & controller_rule_has_nice_d) { - execute_set.as.nice = &process->rule.nice; - } - - if (process->rule.has & controller_rule_has_user_d) { - execute_set.as.id_user = &process->rule.user; - } - - status = fl_environment_load_names(process->rule.environment, &environment); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_environment_load_names", F_true); - - return status; - } - - for (i = 0; i < process->rule.items.used && controller_thread_is_enabled_process(process, global.thread); ++i) { - - if (process->rule.items.array[i].type == controller_rule_item_type_setting_e) continue; - - for (j = 0; j < process->rule.items.array[i].actions.used; ++j) { - - if (!controller_thread_is_enabled_process(process, global.thread)) { - status = F_status_set_error(F_interrupt); - - break; - } - - if (process->rule.items.array[i].actions.array[j].type != action) continue; - - execute_set.parameter.data = 0; - execute_set.parameter.option = FL_execute_parameter_option_threadsafe_d | FL_execute_parameter_option_return_d; - - if (process->rule.items.array[i].with & controller_with_full_path_d) { - execute_set.parameter.option |= FL_execute_parameter_option_path_d; - } - - if (process->rule.items.array[i].with & controller_with_session_new_d) { - execute_set.parameter.option |= FL_execute_parameter_option_session_d; - } - - if (process->rule.items.array[i].type == controller_rule_item_type_command_e) { - for (;;) { - - status = controller_rule_execute_foreground(process->rule.items.array[i].type, 0, process->rule.items.array[i].actions.array[j].parameters, options, &execute_set, process); - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - - if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { - continue; - } - - break; - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - - if (F_status_is_error(status)) { - process->rule.items.array[i].actions.array[j].status = F_status_set_error(F_failure); - - if (!(options & controller_process_option_simulate_d)) break; - - success = F_status_set_error(F_failure); - } - else if (success == F_false || success == F_ignore) { - success = F_true; - } - } - else if (process->rule.items.array[i].type == controller_rule_item_type_script_e) { - execute_set.parameter.data = &process->rule.items.array[i].actions.array[j].parameters.array[0]; - - for (;;) { - - status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.script.used ? process->rule.script.string : controller_default_program_script_s, arguments_none, options, &execute_set, process); - - if (status == F_child || F_status_set_fine(status) == F_lock) break; - if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - - if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { - continue; - } - - break; - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - - if (F_status_is_error(status)) { - process->rule.items.array[i].actions.array[j].status = F_status_set_error(F_failure); - - if (!(options & controller_process_option_simulate_d)) break; - - success = F_status_set_error(F_failure); - } - else if (success == F_false || success == F_ignore) { - success = F_true; - } - } - else if (process->rule.items.array[i].type == controller_rule_item_type_service_e) { - if (process->rule.items.array[i].pid_file.used) { - for (;;) { - - status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, 0, process->rule.items.array[i].actions.array[j].parameters, options, process->rule.items.array[i].with, &execute_set, process); - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - - if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { - continue; - } - - break; - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - - if (F_status_is_error(status)) { - process->rule.items.array[i].actions.array[j].status = F_status_set_error(F_failure); - - if (!(options & controller_process_option_simulate_d)) break; - - success = F_status_set_error(F_failure); - } - else if (success == F_false || success == F_ignore) { - success = F_true; - } - } - else { - success = F_status_set_error(F_failure); - - // @todo make this more specific. - controller_rule_action_print_error_missing_pid(global.main->error, process->rule.alias.string); - } - } - else if (process->rule.items.array[i].type == controller_rule_item_type_utility_e) { - if (process->rule.items.array[i].pid_file.used) { - execute_set.parameter.data = &process->rule.items.array[i].actions.array[j].parameters.array[0]; - - for (;;) { - - status = controller_rule_execute_pid_with(process->rule.items.array[i].pid_file, process->rule.items.array[i].type, process->rule.script.used ? process->rule.script.string : controller_default_program_script_s, arguments_none, options, process->rule.items.array[i].with, &execute_set, process); - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - if (F_status_is_error(status) && F_status_set_fine(status) != F_failure) break; - - if (controller_rule_execute_rerun(controller_rule_action_type_to_action_execute_type(action), process, &process->rule.items.array[i]) > 0) { - continue; - } - - break; - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) break; - - if (F_status_is_error(status)) { - process->rule.items.array[i].actions.array[j].status = F_status_set_error(F_failure); - - if (!(options & controller_process_option_simulate_d)) break; - - success = F_status_set_error(F_failure); - } - else if (success == F_false || success == F_ignore) { - success = F_true; - } - } - else { - success = F_status_set_error(F_failure); - - // @todo make this more specific. - controller_rule_action_print_error_missing_pid(global.main->error, process->rule.alias.string); - } - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SAction type is unknown, ignoring.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - if (success == F_false) { - success = F_ignore; - } - - continue; - } - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_is_error(status) && !(options & controller_process_option_simulate_d)) { - break; - } - } // for - - macro_f_string_maps_t_delete_simple(environment); - - // Lock failed, attempt to re-establish lock before returning. - if (F_status_set_fine(status) == F_lock) { - status = controller_lock_read(process, global.thread, &process->lock); - - if (F_status_is_error(status)) { - return F_status_set_error(F_lock); - } - - success = F_false; - } - - if (!controller_thread_is_enabled_process(process, global.thread)) { - return F_status_set_error(F_interrupt); - } - - if (status == F_child || F_status_is_error(status)) { - return status; - } - - if (success == F_false || success == F_failure) { - return F_status_set_error(F_failure); - } - - if (success == F_ignore) { - return F_ignore; - } - - return F_none; - } -#endif // _di_controller_rule_execute_ - -#ifndef _di_controller_rule_execute_foreground_ - f_status_t controller_rule_execute_foreground(const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, controller_execute_set_t * const execute_set, controller_process_t * const process) { - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - f_string_dynamics_t arguments_none = f_string_dynamics_t_initialize; - - controller_main_t * const main = (controller_main_t *) process->main_data; - controller_thread_t * const thread = (controller_thread_t *) process->main_thread; - - f_execute_result_t result = f_execute_result_t_initialize; - - status = controller_pids_increase(&process->childs); - - if (F_status_is_error(status)) { - controller_print_error(thread, main->error, F_status_set_fine(status), "controller_pids_increase", F_true); - - return status; - } - - pid_t *child = 0; - f_string_dynamic_t *child_pid_file = 0; - - { - f_array_length_t i = 0; - - while (i < process->childs.used && process->childs.array[i]) { - ++i; - } // while - - child = &process->childs.array[i]; - - if (i == process->childs.used) { - ++process->childs.used; - } - } - - if (options & controller_process_option_simulate_d) { - if (main->output.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->output.to, thread); - - fl_print_format("%cSimulating execution of '%[", main->output.to.stream, f_string_eol_s[0], main->context.set.title); - - if (program) { - f_print_safely_terminated(program, main->output.to.stream); - } - else { - f_print_dynamic_safely(arguments.array[0], main->output.to.stream); - } - - fl_print_format("%]' with the arguments: '%[", main->output.to.stream, main->context.set.title, main->context.set.important); - - for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) { - - if (program && i || !program && i > 1) { - f_print_terminated(f_string_space_s, main->output.to.stream); - } - - f_print_dynamic_safely(arguments.array[i], main->output.to.stream); - } // for - - fl_print_format("%]' from '", main->output.to.stream, main->context.set.important); - fl_print_format("%[%Q%]'.%c", main->output.to.stream, main->context.set.notable, process->rule.name, main->context.set.notable, f_string_eol_s[0]); - - controller_unlock_print_flush(main->output.to, thread); - } - - // Sleep for less than a second to better show simulation of synchronous vs asynchronous. - { - const struct timespec delay = controller_time_milliseconds(controller_thread_simulation_timeout_d); - - if (controller_time_sleep_nanoseconds(main, (controller_setting_t *) process->main_setting, delay) == -1) { - status = F_status_set_error(F_interrupt); - } - } - - if (F_status_set_fine(status) != F_interrupt) { - const f_string_static_t simulated_program = macro_f_string_static_t_initialize(f_string_empty_s, 0); - const f_string_statics_t simulated_arguments = f_string_statics_t_initialize; - fl_execute_parameter_t simulated_parameter = macro_fl_execute_parameter_t_initialize(execute_set->parameter.option, execute_set->parameter.wait, process->rule.has & controller_rule_has_environment_d ? execute_set->parameter.environment : 0, execute_set->parameter.signals, &simulated_program); - - status = fll_execute_program(controller_default_program_script_s, simulated_arguments, &simulated_parameter, &execute_set->as, (void *) &result); - } - } - else { - status = fll_execute_program(program, arguments, &execute_set->parameter, &execute_set->as, (void *) &result); - } - - if (status == F_parent) { - const pid_t id_child = result.pid; - result.status = 0; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread); - - if (F_status_set_fine(status_lock) != F_interrupt) { - status = controller_lock_read_process(process, thread, &process->lock); - - if (status == F_none) { - return status_lock; - } - } - - return F_status_set_error(F_lock); - } - - // Assign the child process id to allow for the cancel process to send appropriate termination signals to the child process. - *child = id_child; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread); - } - - if (F_status_set_fine(status_lock) != F_interrupt) { - - // Have the parent wait for the child process to finish. - waitpid(id_child, &result.status, 0); - } - - if (F_status_set_fine(status_lock) == F_interrupt || !controller_thread_is_enabled_process(process, thread)) { - if (status_lock == F_none) { - return F_status_set_error(F_interrupt); - } - - return F_status_set_error(F_lock); - } - - if (status_lock == F_none) { - f_thread_unlock(&process->lock); - } - - status_lock = controller_lock_write_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread); - - if (F_status_set_fine(status_lock) != F_interrupt) { - status = controller_lock_read_process(process, thread, &process->lock); - - if (status == F_none) { - return status_lock; - } - } - - return F_status_set_error(F_lock); - } - - process->result = result.status; - - // Remove the pid now that waidpid() has returned. - *child = 0; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread); - - return F_status_set_error(F_lock); - } - - if (WIFEXITED(result.status) ? WEXITSTATUS(result.status) : 0) { - status = F_status_set_error(F_failure); - } - else { - status = F_none; - } - } - else { - main->child = result.status; - - if (!controller_thread_is_enabled_process(process, thread)) { - return F_status_set_error(F_interrupt); - } - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_user) { - status = F_child; - } - else { - status = F_status_set_error(status); - } - } - - if (status == F_child || F_status_set_fine(status) == F_interrupt) { - return status; - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if ((WIFEXITED(process->result) && WEXITSTATUS(process->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) { - controller_rule_item_print_error_execute(type == controller_rule_item_type_script_e, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process); - } - else { - controller_print_error(thread, main->error, F_status_set_fine(status), "fll_execute_program", F_true); - } - - status = F_status_set_error(status); - } - - return status; - } -#endif // _di_controller_rule_execute_foreground_ - -#ifndef _di_controller_rule_execute_pid_with_ - f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, const uint8_t with, controller_execute_set_t * const execute_set, controller_process_t * const process) { - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - controller_main_t * const main = (controller_main_t *) process->main_data; - controller_thread_t * const thread = (controller_thread_t *) process->main_thread; - - f_execute_result_t result = f_execute_result_t_initialize; - - status = controller_pids_increase(&process->childs); - - if (F_status_is_error(status)) { - controller_print_error(thread, main->error, F_status_set_fine(status), "controller_pids_increase", F_true); - - return status; - } - - status = f_string_dynamics_increase(controller_common_allocation_small_d, &process->path_pids); - - if (F_status_is_error(status)) { - controller_print_error(thread, main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true); - - return status; - } - - pid_t *child = 0; - f_string_dynamic_t *child_pid_file = 0; - - { - f_array_length_t i = 0; - - while (i < process->childs.used && process->childs.array[i]) { - ++i; - } // while - - child = &process->childs.array[i]; - - if (i == process->childs.used) { - ++process->childs.used; - } - - for (i = 0; i < process->path_pids.used && process->path_pids.array[i].used; ++i) { - // Do nothing. - } // for - - child_pid_file = &process->path_pids.array[i]; - - if (i == process->path_pids.used) { - ++process->path_pids.used; - } - } - - status = f_file_exists(pid_file.string); - - if (F_status_is_error(status)) { - controller_print_error_file(thread, main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file_e); - - return status; - } - - if (status == F_true) { - controller_print_error_file(thread, main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file_e); - - return F_status_set_error(F_file_found); - } - - status = controller_dynamic_append_terminated(pid_file, child_pid_file); - - if (F_status_is_error(status)) { - controller_print_error(thread, main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true); - - return status; - } - - if (options & controller_process_option_simulate_d) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, thread); - - fl_print_format("%cSimulating execution of '%[", main->error.to.stream, f_string_eol_s[0], main->context.set.title); - - if (program) { - f_print_safely_terminated(program, main->error.to.stream); - } - else { - f_print_dynamic_safely(arguments.array[0], main->error.to.stream); - } - - fl_print_format("%]' with the arguments: '%[", main->error.to.stream, main->context.set.title, main->context.set.important); - - for (f_array_length_t i = program ? 0 : 1; i < arguments.used; ++i) { - - if (program && i || !program && i > 1) { - f_print_terminated(f_string_space_s, main->error.to.stream); - } - - f_print_dynamic_safely(arguments.array[i], main->error.to.stream); - } // for - - fl_print_format("%]' from '", main->error.to.stream, main->context.set.important); - fl_print_format("%[%Q%]'.%c", main->error.to.stream, main->context.set.notable, process->rule.name, main->context.set.notable, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, thread); - } - - // Sleep for less than a second to better show simulation of synchronous vs asynchronous. - { - const struct timespec delay = controller_time_milliseconds(controller_thread_simulation_timeout_d); - - if (controller_time_sleep_nanoseconds(main, (controller_setting_t *) process->main_setting, delay) == -1) { - status = F_status_set_error(F_interrupt); - } - } - - if (F_status_set_fine(status) != F_interrupt) { - const f_string_static_t simulated_program = macro_f_string_static_t_initialize(f_string_empty_s, 0); - const f_string_statics_t simulated_arguments = f_string_statics_t_initialize; - fl_execute_parameter_t simulated_parameter = macro_fl_execute_parameter_t_initialize(execute_set->parameter.option, execute_set->parameter.wait, process->rule.has & controller_rule_has_environment_d ? execute_set->parameter.environment : 0, execute_set->parameter.signals, &simulated_program); - - status = fll_execute_program(controller_default_program_script_s, simulated_arguments, &simulated_parameter, &execute_set->as, (void *) &result); - } - } - else { - status = fll_execute_program(program, arguments, &execute_set->parameter, &execute_set->as, (void *) &result); - } - - if (status == F_parent) { - const pid_t id_child = result.pid; - result.status = 0; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread); - - if (F_status_set_fine(status_lock) != F_interrupt) { - status = controller_lock_read_process(process, thread, &process->lock); - - if (status == F_none) { - return status_lock; - } - } - - return F_status_set_error(F_lock); - } - - // Assign the child process id to allow for the cancel process to send appropriate termination signals to the child process. - *child = id_child; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread); - } - - if (F_status_set_fine(status_lock) != F_interrupt) { - - // The child process should perform the change into background, therefore it is safe to wait for the child to exit (another process is spawned). - waitpid(id_child, &result.status, 0); - } - - if (!controller_thread_is_enabled_process(process, thread)) { - if (status_lock == F_none) { - return F_status_set_error(F_interrupt); - } - - return F_status_set_error(F_lock); - } - - if (status_lock == F_none) { - f_thread_unlock(&process->lock); - } - - status_lock = controller_lock_write_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread); - - if (F_status_set_fine(status_lock) != F_interrupt) { - status = controller_lock_read_process(process, thread, &process->lock); - - if (status == F_none) { - return status_lock; - } - } - - return F_status_set_error(F_lock); - } - - process->result = result.status; - - // Remove the pid now that waidpid() has returned. - *child = 0; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread); - - return F_status_set_error(F_lock); - } - - if (WIFEXITED(result.status) ? WEXITSTATUS(result.status) : 0) { - status = F_status_set_error(F_failure); - } - else { - status = F_none; - } - } - else { - main->child = result.status; - - if (!controller_thread_is_enabled_process(process, thread)) { - return F_status_set_error(F_interrupt); - } - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_child || status == F_capability || status == F_group || status == F_nice || status == F_user) { - status = F_child; - } - else { - status = F_status_set_error(status); - } - } - - if (status == F_child || F_status_set_fine(status) == F_interrupt) { - return status; - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if ((WIFEXITED(process->result) && WEXITSTATUS(process->result)) || status == F_control_group || status == F_failure || status == F_limit || status == F_processor || status == F_schedule) { - controller_rule_item_print_error_execute(type == controller_rule_item_type_utility_e, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process); - } - else { - controller_print_error(thread, main->error, F_status_set_fine(status), "fll_execute_program", F_true); - } - - return F_status_set_error(status); - } - - return status; - } -#endif // _di_controller_rule_execute_pid_with_ - -#ifndef _di_controller_rule_execute_rerun_ - int8_t controller_rule_execute_rerun(const uint8_t action, controller_process_t * const process, controller_rule_item_t * const item) { - - const int result = WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0; - - if (item->reruns[action].is & (result ? controller_rule_rerun_is_failure_d : controller_rule_rerun_is_success_d)) { - controller_main_t * const main = (controller_main_t *) process->main_data; - controller_thread_t * const thread = (controller_thread_t *) process->main_thread; - controller_rule_rerun_item_t *rerun_item = result ? &item->reruns[action].failure : &item->reruns[action].success; - - if (!controller_thread_is_enabled_process(process, thread)) return -2; - - if (!rerun_item->max || rerun_item->count < rerun_item->max) { - if (main->error.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(main->output.to, thread); - - fl_print_format("%cRe-running '", main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%q%]", main->output.to.stream, main->context.set.title, process->rule.alias, main->context.set.title); - f_print_terminated("' '", main->output.to.stream); - fl_print_format("%[%q%]", main->output.to.stream, main->context.set.notable, controller_rule_action_type_execute_name(action), main->context.set.notable); - f_print_terminated("' with a ", main->output.to.stream); - fl_print_format("%[%s%]", main->output.to.stream, main->context.set.notable, controller_delay_s, main->context.set.notable); - f_print_terminated(" of ", main->output.to.stream); - fl_print_format("%[%ul%] MegaTime", main->output.to.stream, main->context.set.notable, rerun_item->delay, main->context.set.notable); - - if (rerun_item->max) { - f_print_terminated(" for ", main->output.to.stream); - fl_print_format("%[%ul%]", main->output.to.stream, main->context.set.notable, rerun_item->count, main->context.set.notable); - f_print_terminated(" of ", main->output.to.stream); - fl_print_format("%[%s%] ", main->output.to.stream, main->context.set.notable, controller_max_s, main->context.set.notable); - fl_print_format("%[%ul%]", main->output.to.stream, main->context.set.notable, rerun_item->max, main->context.set.notable); - fl_print_format(".%c", main->output.to.stream, f_string_eol_s[0]); - } - else { - fl_print_format(" with no %[%s%].%c", main->output.to.stream, main->context.set.notable, controller_max_s, main->context.set.notable, f_string_eol_s[0]); - } - - controller_unlock_print_flush(main->output.to, thread); - } - - if (rerun_item->delay) { - const struct timespec delay = controller_time_milliseconds(rerun_item->delay); - - if (controller_time_sleep_nanoseconds(main, (controller_setting_t *) process->main_setting, delay) == -1) { - return -1; - } - - if (!controller_thread_is_enabled_process(process, thread)) return -2; - } - - if (item->reruns[action].is & (result ? controller_rule_rerun_is_failure_reset_d : controller_rule_rerun_is_success_reset_d)) { - if (result) { - item->reruns[action].success.count = 0; - } - else { - item->reruns[action].failure.count = 0; - } - } - - if (rerun_item->max) { - ++rerun_item->count; - } - - return F_true; - } - } - - return F_false; - } -#endif // _di_controller_rule_execute_rerun_ - -#ifndef _di_controller_rule_id_construct_ - f_status_t controller_rule_id_construct(const controller_global_t global, const f_string_static_t source, const f_string_range_t directory, const f_string_range_t basename, f_string_dynamic_t * const alias) { - - f_status_t status = F_none; - - alias->used = 0; - - status = f_string_dynamic_partial_append_nulless(source, directory, alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true); - - return status; - } - - status = f_string_append(f_path_separator_s, F_path_separator_s_length, alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_append", F_true); - - return status; - } - - status = f_string_dynamic_partial_append_nulless(source, basename, alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true); - - return status; - } - - status = f_string_dynamic_terminate_after(alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - - return status; - } -#endif // _di_controller_rule_id_construct_ - -#ifndef _di_controller_rule_status_is_available_ - f_status_t controller_rule_status_is_available(const uint8_t action, const controller_rule_t rule) { - - return F_status_is_error_not(rule.status[0]) && rule.status[action] == F_known_not; - } -#endif // _di_controller_rule_status_is_available_ - -#ifndef _di_controller_rule_status_is_error_ - f_status_t controller_rule_status_is_error(const uint8_t action, const controller_rule_t rule) { - - return F_status_is_error(rule.status[0]) || F_status_is_error(rule.status[action]); - } -#endif // _di_controller_rule_status_is_error_ - -#ifndef _di_controller_rule_item_read_ - f_status_t controller_rule_item_read(const controller_global_t global, const bool is_normal, controller_cache_t * const cache, controller_rule_item_t * const item) { - - f_status_t status = F_none; - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - f_string_range_t range = macro_f_string_range_t_initialize(cache->buffer_item.used); - f_array_length_t last = 0; - - uint8_t type = 0; - uint8_t method = 0; - bool multiple = F_false; - - 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, state, &range, &cache->range_action, &cache->delimits); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true); - - break; - } - - if (status == F_fss_found_object) { - multiple = F_true; - } - else { - range.start = last; - multiple = F_false; - cache->delimits.used = 0; - - // The current line is not an Extended List object, so the next possibility is a Basic List (and Extended List, both use the same Object structure). - status = fl_fss_extended_object_read(cache->buffer_item, state, &range, &cache->range_action, 0, &cache->delimits); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_extended_object_read", F_true); - - break; - } - - // Nothing of importance here, so continue onto the next line. - // @todo present an error if this line is anything but whitespace. - if (status != F_fss_found_object) continue; - } - - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->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->action.line_action); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true); - - break; - } - - cache->action.line_action += ++item->line; - cache->action.name_action.used = 0; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->range_action, &cache->action.name_action); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true); - - break; - } - - if (fl_string_dynamic_compare_string(controller_freeze_s, cache->action.name_action, controller_freeze_s_length) == F_equal_to) { - type = controller_rule_action_type_freeze_e; - } - else if (fl_string_dynamic_compare_string(controller_group_s, cache->action.name_action, controller_group_s_length) == F_equal_to) { - type = controller_rule_action_type_group_e; - } - else if (fl_string_dynamic_compare_string(controller_kill_s, cache->action.name_action, controller_kill_s_length) == F_equal_to) { - type = controller_rule_action_type_kill_e; - } - else if (fl_string_dynamic_compare_string(controller_pause_s, cache->action.name_action, controller_pause_s_length) == F_equal_to) { - type = controller_rule_action_type_pause_e; - } - else if (fl_string_dynamic_compare_string(controller_pid_file_s, cache->action.name_action, controller_pid_file_s_length) == F_equal_to) { - type = controller_rule_action_type_pid_file_e; - } - else if (fl_string_dynamic_compare_string(controller_reload_s, cache->action.name_action, controller_reload_s_length) == F_equal_to) { - type = controller_rule_action_type_reload_e; - } - else if (fl_string_dynamic_compare_string(controller_rerun_s, cache->action.name_action, controller_rerun_s_length) == F_equal_to) { - type = controller_rule_action_type_rerun_e; - } - else if (fl_string_dynamic_compare_string(controller_restart_s, cache->action.name_action, controller_restart_s_length) == F_equal_to) { - type = controller_rule_action_type_restart_e; - } - else if (fl_string_dynamic_compare_string(controller_resume_s, cache->action.name_action, controller_resume_s_length) == F_equal_to) { - type = controller_rule_action_type_resume_e; - } - else if (fl_string_dynamic_compare_string(controller_start_s, cache->action.name_action, controller_start_s_length) == F_equal_to) { - type = controller_rule_action_type_start_e; - } - else if (fl_string_dynamic_compare_string(controller_stop_s, cache->action.name_action, controller_stop_s_length) == F_equal_to) { - type = controller_rule_action_type_stop_e; - } - else if (fl_string_dynamic_compare_string(controller_thaw_s, cache->action.name_action, controller_thaw_s_length) == F_equal_to) { - type = controller_rule_action_type_thaw_e; - } - else if (fl_string_dynamic_compare_string(controller_user_s, cache->action.name_action, controller_user_s_length) == F_equal_to) { - type = controller_rule_action_type_user_e; - } - else if (fl_string_dynamic_compare_string(controller_with_s, cache->action.name_action, controller_with_s_length) == F_equal_to) { - type = controller_rule_action_type_with_e; - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SUnknown rule item action '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_action, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, cache->action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - continue; - } - - if (multiple) { - if (type == controller_rule_action_type_group_e || type == controller_rule_action_type_pid_file_e || type == controller_rule_action_type_user_e) { - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SFSS Extended List is not allowed for the rule item action '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_supported_not); - break; - } - - method = controller_rule_action_method_extended_list_e; - } - else { - method = controller_rule_action_method_extended_e; - } - - status = controller_rule_actions_increase_by(controller_common_allocation_small_d, &item->actions); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true); - - break; - } - - status = controller_rule_action_read(global, is_normal, type, method, cache, item, &item->actions, &range); - if (F_status_is_error(status)) break; - } // for - - return status; - } -#endif // _di_controller_rule_item_read_ - -#ifndef _di_controller_rule_item_type_name_ - f_string_static_t controller_rule_item_type_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_rule_item_type_command_e: - buffer.string = controller_command_s; - buffer.used = controller_command_s_length; - break; - - case controller_rule_item_type_script_e: - buffer.string = controller_script_s; - buffer.used = controller_script_s_length; - break; - - case controller_rule_item_type_service_e: - buffer.string = controller_service_s; - buffer.used = controller_service_s_length; - break; - - case controller_rule_item_type_setting_e: - buffer.string = controller_setting_s; - buffer.used = controller_setting_s_length; - break; - - case controller_rule_item_type_utility_e: - buffer.string = controller_utility_s; - buffer.used = controller_utility_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_rule_item_type_name_ - -#ifndef _di_controller_rule_items_increase_by_ - f_status_t controller_rule_items_increase_by(const f_array_length_t amount, controller_rule_items_t * const items) { - - if (items->used + amount > items->size) { - if (items->used + amount > F_array_length_t_size_d) { - return F_status_set_error(F_array_too_large); - } - - const f_status_t status = f_memory_resize(items->size, items->used + amount, sizeof(controller_rule_item_t), (void **) & items->array); - - if (F_status_is_error_not(status)) { - items->size = items->used + amount; - } - - return status; - } - - return F_data_not; - } -#endif // _di_controller_rule_items_increase_by_ - -#ifndef _di_controller_rule_setting_limit_type_name_ - f_string_static_t controller_rule_setting_limit_type_name(const uint8_t type) { - - f_string_static_t buffer = f_string_static_t_initialize; - - switch (type) { - case controller_resource_limit_type_as_e: - buffer.string = controller_as_s; - buffer.used = controller_as_s_length; - break; - - case controller_resource_limit_type_core_e: - buffer.string = controller_core_s; - buffer.used = controller_core_s_length; - break; - - case controller_resource_limit_type_cpu_e: - buffer.string = controller_cpu_s; - buffer.used = controller_cpu_s_length; - break; - - case controller_resource_limit_type_data_e: - buffer.string = controller_data_s; - buffer.used = controller_data_s_length; - break; - - case controller_resource_limit_type_fsize_e: - buffer.string = controller_fsize_s; - buffer.used = controller_fsize_s_length; - break; - - case controller_resource_limit_type_locks_e: - buffer.string = controller_locks_s; - buffer.used = controller_locks_s_length; - break; - - case controller_resource_limit_type_memlock_e: - buffer.string = controller_memlock_s; - buffer.used = controller_memlock_s_length; - break; - - case controller_resource_limit_type_msgqueue_e: - buffer.string = controller_msgqueue_s; - buffer.used = controller_msgqueue_s_length; - break; - - case controller_resource_limit_type_nice_e: - buffer.string = controller_nice_s; - buffer.used = controller_nice_s_length; - break; - - case controller_resource_limit_type_nofile_e: - buffer.string = controller_nofile_s; - buffer.used = controller_nofile_s_length; - break; - - case controller_resource_limit_type_nproc_e: - buffer.string = controller_nproc_s; - buffer.used = controller_nproc_s_length; - break; - - case controller_resource_limit_type_rss_e: - buffer.string = controller_rss_s; - buffer.used = controller_rss_s_length; - break; - - case controller_resource_limit_type_rtprio_e: - buffer.string = controller_rtprio_s; - buffer.used = controller_rtprio_s_length; - break; - - case controller_resource_limit_type_rttime_e: - buffer.string = controller_rttime_s; - buffer.used = controller_rttime_s_length; - break; - - case controller_resource_limit_type_sigpending_e: - buffer.string = controller_sigpending_s; - buffer.used = controller_sigpending_s_length; - break; - - case controller_resource_limit_type_stack_e: - buffer.string = controller_stack_s; - buffer.used = controller_stack_s_length; - break; - } - - buffer.size = buffer.used; - - return buffer; - } -#endif // _di_controller_rule_setting_limit_type_name_ - -#ifndef _di_controller_rule_process_ - f_status_t controller_rule_process(const controller_global_t global, controller_process_t * const process) { - - switch (process->action) { - case controller_rule_action_type_freeze_e: - case controller_rule_action_type_kill_e: - case controller_rule_action_type_pause_e: - case controller_rule_action_type_reload_e: - case controller_rule_action_type_restart_e: - case controller_rule_action_type_resume_e: - case controller_rule_action_type_start_e: - case controller_rule_action_type_stop_e: - case controller_rule_action_type_thaw_e: - break; - - default: - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SUnsupported action type '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%q%]", global.main->error.to.stream, global.main->error.notable, controller_rule_action_type_name(process->action), global.main->error.notable); - fl_print_format("%[' while attempting to execute rule.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return F_status_set_error(F_parameter); - } - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - process->cache.action.name_action.used = 0; - process->cache.action.name_item.used = 0; - process->cache.action.name_file.used = 0; - - status = f_string_append(controller_rules_s, controller_rules_s_length, &process->cache.action.name_file); - - if (F_status_is_error_not(status)) { - status = f_string_append(f_path_separator_s, F_path_separator_s_length, &process->cache.action.name_file); - } - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true); - - return status; - } - - status = f_string_dynamic_append(process->rule.alias, &process->cache.action.name_file); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_true); - - return status; - } - - status = f_string_append(F_path_extension_separator_s, F_path_extension_separator_s_length, &process->cache.action.name_file); - - if (F_status_is_error_not(status)) { - status = f_string_append(controller_rule_s, controller_rule_s_length, &process->cache.action.name_file); - } - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true); - - return status; - } - - status = f_string_dynamic_terminate_after(&process->cache.action.name_file); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_true); - - return status; - } - - if ((process->options & controller_process_option_simulate_d) && (process->options & controller_process_option_validate_d)) { - controller_rule_validate(global, process->rule, process->action, process->options, &process->cache); - } - - f_array_length_t i = 0; - - { - f_array_length_t j = 0; - f_array_length_t k = 0; - f_array_length_t id_rule = 0; - f_array_length_t id_dependency = 0; - - bool found = F_false; - - controller_process_t *dependency = 0; - - uint8_t options_process = 0; - - const f_string_t strings[3] = { - "needed", - "wanted", - "wished for", - }; - - f_string_dynamics_t empty = f_string_dynamics_t_initialize; - f_string_dynamics_t *dynamics[3] = { &empty, &empty, &empty }; - - if (process->action) { - - for (i = 0; i < process->rule.ons.used; ++i) { - - if (process->rule.ons.array[i].action == process->action) { - dynamics[0] = &process->rule.ons.array[i].need; - dynamics[1] = &process->rule.ons.array[i].want; - dynamics[2] = &process->rule.ons.array[i].wish; - - break; - } - } // for - } - - // i==0 is need, i==1 is want, i==2 is wish. - // loop through all dependencies: wait for depedency, execute dependency, fail due to missing required dependency, or skip unrequired missing dependencies. - for (i = 0; i < 3 && controller_thread_is_enabled_process(process, global.thread); ++i) { - - for (j = 0; j < dynamics[i]->used && controller_thread_is_enabled_process(process, global.thread); ++j) { - - id_dependency = 0; - dependency = 0; - found = F_false; - - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.process); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - } - else { - status = controller_process_prepare_process_type(global, process->type, process->action, dynamics[i]->array[j], &id_dependency); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_lock) { - if (!controller_thread_is_enabled_process_type(process->type, global.thread)) { - return F_status_set_error(F_interrupt); - } - } - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_rule_not_loaded(global.main->error, dynamics[i]->array[j].string); - controller_rule_print_error_cache(global.main->error, process->cache.action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return status; - } - - status = F_true; - } - - if (status == F_true) { - found = F_true; - - dependency = global.thread->processs.array[id_dependency]; - - status_lock = controller_lock_read_process(process, global.thread, &dependency->active); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - status = F_false; - dependency = 0; - - f_thread_unlock(&global.thread->lock.process); - } - else { - f_thread_unlock(&global.thread->lock.process); - - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - status = F_false; - } - else { - status = controller_rule_find(dynamics[i]->array[j], global.setting->rules, &id_rule); - - f_thread_unlock(&global.thread->lock.rule); - } - } - } - else { - f_thread_unlock(&global.thread->lock.process); - } - - if (status != F_true) { - found = F_false; - id_rule = 0; - - if (i == 0) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], dynamics[i]->array[j].string, "was not found"); - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - status = F_status_set_error(F_found_not); - - if (!(process->options & controller_process_option_simulate_d)) { - if (dependency) { - f_thread_unlock(&dependency->active); - } - - break; - } - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], dynamics[i]->array[j].string, "was not found"); - - controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - } - } - else if (found) { - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - found = F_false; - status = status_lock; - } - } - - if (found) { - - // the dependency may have write locks, which needs to be avoided, so copy the alias from the rule. - char alias_other_buffer[global.setting->rules.array[id_rule].alias.used + 1]; - - memcpy(alias_other_buffer, global.setting->rules.array[id_rule].alias.string, global.setting->rules.array[id_rule].alias.used); - alias_other_buffer[global.setting->rules.array[id_rule].alias.used] = 0; - - const f_string_static_t alias_other = macro_f_string_static_t_initialize(alias_other_buffer, global.setting->rules.array[id_rule].alias.used); - - f_thread_unlock(&global.thread->lock.rule); - - status_lock = controller_lock_read_process(process, global.thread, &dependency->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - status = status_lock; - } - else if (dependency->state == controller_process_state_active_e || dependency->state == controller_process_state_busy_e) { - f_thread_unlock(&dependency->lock); - - status = controller_process_wait(global, dependency); - - if (F_status_is_error(status) && !(process->options & controller_process_option_simulate_d)) break; - - status = dependency->rule.status[process->action]; - } - else { - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - f_thread_unlock(&dependency->lock); - - status = status_lock; - } - else if (controller_rule_status_is_available(process->action, global.setting->rules.array[id_rule])) { - f_thread_unlock(&global.thread->lock.rule); - f_thread_unlock(&dependency->lock); - - options_process = 0; - - if (global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - options_process |= controller_process_option_simulate_d; - } - - if (process->options & controller_process_option_validate_d) { - options_process |= controller_process_option_validate_d; - } - - // Synchronously execute dependency. - status = controller_rule_process_begin(global, 0, alias_other, process->action, options_process, process->type, process->stack, dependency->cache); - - if (status == F_child || F_status_set_fine(status) == F_interrupt) { - f_thread_unlock(&dependency->active); - - break; - } - - if (F_status_is_error(status)) { - if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], alias_other_buffer, "failed during execution"); - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - if (!(dependency->options & controller_process_option_simulate_d) || F_status_set_fine(status) == F_memory_not) { - f_thread_unlock(&dependency->active); - - break; - } - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "failed during execution"); - - controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - } - } - } - else { - status = global.setting->rules.array[id_rule].status[process->action]; - - f_thread_unlock(&global.thread->lock.rule); - f_thread_unlock(&dependency->lock); - } - } - - if (!controller_thread_is_enabled_process(process, global.thread)) { - f_thread_unlock(&dependency->active); - - break; - } - - if (F_status_is_error_not(status_lock)) { - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - } - } - - if (F_status_is_error(status_lock)) { - if (F_status_is_error(status_lock)) { - controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], alias_other_buffer, "due to lock failure"); - } - - status = status_lock; - } - else if (controller_rule_status_is_error(process->action, global.setting->rules.array[id_rule])) { - f_thread_unlock(&global.thread->lock.rule); - - if (i == 0 || i == 1) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], alias_other_buffer, "is in a failed state"); - - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - status = F_status_set_error(F_found_not); - - if (!(dependency->options & controller_process_option_simulate_d)) { - f_thread_unlock(&dependency->active); - - break; - } - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "is in a failed state"); - - controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - } - } - else { - f_thread_unlock(&global.thread->lock.rule); - } - } - - if (dependency) { - f_thread_unlock(&dependency->active); - } - } // for - - if (status == F_child || F_status_set_fine(status) == F_interrupt) break; - - if (F_status_is_error(status) && !(process->options & controller_process_option_simulate_d)) break; - } // for - } - - if (status == F_child || F_status_set_fine(status) == F_interrupt) { - return status; - } - - if (!controller_thread_is_enabled_process(process, global.thread)) { - return F_status_set_error(F_interrupt); - } - - if ((process->options & controller_process_option_wait_d) && F_status_is_error_not(status) && (process->options & controller_process_option_validate_d)) { - status_lock = controller_rule_wait_all_process_type(global, process->type, F_false, process); - - if (F_status_set_fine(status_lock) == F_interrupt) { - return status_lock; - } - } - - if (!(process->options & controller_process_option_validate_d) && F_status_is_error_not(status)) { - - // find at least one of the requested action when the rule is required. - if (process->options & controller_process_option_require_d) { - bool missing = F_true; - - f_array_length_t j = 0; - - for (i = 0; i < process->rule.items.used; ++i) { - - for (j = 0; j < process->rule.items.array[i].actions.used; ++j) { - - if (process->rule.items.array[i].actions.array[j].type == process->action) { - missing = F_false; - break; - } - } // for - } // for - - if (missing) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - if (process->rule.items.used) { - fl_print_format("%c%[%SThe rule '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, process->rule.name, global.main->error.notable); - fl_print_format("%[' has no '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%q%]", global.main->error.to.stream, global.main->error.notable, controller_rule_action_type_name(process->action), global.main->error.notable); - fl_print_format("%[' action to execute.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - else { - fl_print_format("%c%[%SThe rule '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, process->rule.name, global.main->error.notable); - fl_print_format("%[ has no known '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s %s%]", global.main->error.to.stream, global.main->error.notable, controller_rule_s, controller_type_s, global.main->error.notable); - fl_print_format("%[' (such as '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_command_s, global.main->error.notable); - fl_print_format("%[', '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_service_s, global.main->error.notable); - fl_print_format("%[', '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_script_s, global.main->error.notable); - fl_print_format("%[', or '%]", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[%s%]", global.main->error.to.stream, global.main->error.notable, controller_utility_s, global.main->error.notable); - fl_print_format("%[') to execute.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - } - - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_parameter); - } - } - - if (F_status_is_error_not(status)) { - status = controller_rule_execute(global, process->action, process->options, process); - - if (status == F_child || F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock) { - return status; - } - - if (F_status_is_error(status)) { - controller_rule_item_print_error(global.thread, global.main->error, process->cache.action, F_true, F_status_set_fine(status)); - } - } - } - - f_array_length_t id_rule = 0; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - if (F_status_set_fine(status) != F_interrupt) { - status = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error_not(status)) { - return status_lock; - } - } - - return F_status_set_error(F_lock); - } - - if (F_status_is_error(status)) { - process->rule.status[process->action] = controller_status_simplify_error(F_status_set_fine(status)); - } - else { - process->rule.status[process->action] = status; - } - - status_lock = controller_lock_write_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&process->lock); - - status = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error_not(status)) { - return status_lock; - } - - return F_status_set_error(F_lock); - } - - // Update the global rule status, which is stored separately from the rule status for this process. - if (controller_rule_find(process->rule.alias, global.setting->rules, &id_rule) == F_true) { - controller_rule_t *rule = &global.setting->rules.array[id_rule]; - - rule->status[process->action] = process->rule.status[process->action]; - - f_array_length_t j = 0; - - controller_rule_item_t *rule_item = 0; - controller_rule_action_t *rule_action = 0; - - // @todo implement a "version" counter and detect if the rule version is different before attempting update. - // Copy all rule item action statuses from the rule process to the rule. - for (i = 0; i < rule->items.used; ++i) { - - rule_item = &rule->items.array[i]; - - for (j = 0; j < rule_item->actions.used; ++j) { - rule_item->actions.array[j].status = process->rule.items.array[i].actions.array[j].status; - } // for - } // for - } - - f_thread_unlock(&global.thread->lock.rule); - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - return F_status_set_error(F_lock); - } - - return process->rule.status[process->action]; - } -#endif // _di_controller_rule_process_ - -#ifndef _di_controller_rule_process_begin_ - f_status_t controller_rule_process_begin(const controller_global_t global, const uint8_t options_force, const f_string_static_t alias_rule, const uint8_t action, const uint8_t options, const uint8_t type, const f_array_lengths_t stack, const controller_cache_t cache) { - - if (!controller_thread_is_enabled_process_type(type, global.thread)) { - return F_status_set_error(F_interrupt); - } - - f_status_t status = F_none; - f_status_t status_lock = F_none; - - controller_process_t *process = 0; - - status = controller_lock_read_process_type(type, global.thread, &global.thread->lock.process); - - if (F_status_is_error(status)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_true, global.thread); - - return status; - } - - { - f_array_length_t at = 0; - - status = controller_process_prepare(global, type != controller_process_type_exit_e, action, alias_rule, &at); - - if (F_status_is_error(status)) { - f_thread_unlock(&global.thread->lock.process); - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_rule_not_loaded(global.main->error, alias_rule.string); - controller_rule_print_error_cache(global.main->error, cache.action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - return status; - } - - process = global.thread->processs.array[at]; - - status = controller_lock_read_process_type(type, global.thread, &process->active); - - if (F_status_is_error(status)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_true, global.thread); - controller_rule_item_print_error(global.thread, global.main->error, cache.action, F_false, F_status_set_fine(status)); - - f_thread_unlock(&global.thread->lock.process); - - return status; - } - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&process->active); - f_thread_unlock(&global.thread->lock.process); - - return status_lock; - } - - // once a write lock on the process is achieved, it is safe to unlock the global process read lock. - f_thread_unlock(&global.thread->lock.process); - - // if the process is already running, then there is nothing to do. - if (process->state == controller_process_state_active_e || process->state == controller_process_state_busy_e) { - f_thread_unlock(&process->lock); - f_thread_unlock(&process->active); - - return F_busy; - } - - // the thread is done, so close the thread. - if (process->state == controller_process_state_done_e) { - controller_thread_join(&process->id_thread); - - f_thread_mutex_lock(&process->wait_lock); - f_thread_condition_signal_all(&process->wait); - f_thread_mutex_unlock(&process->wait_lock); - } - - process->id = at; - } - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&process->active); - - return status_lock; - } - - process->state = controller_process_state_active_e; - process->action = action; - process->options = options; - process->type = type; - - macro_f_time_spec_t_clear(process->cache.timestamp) - macro_f_string_range_t_clear(process->cache.range_action) - - process->cache.ats.used = 0; - process->cache.stack.used = 0; - process->cache.comments.used = 0; - process->cache.delimits.used = 0; - process->cache.content_action.used = 0; - process->cache.content_actions.used = 0; - process->cache.content_items.used = 0; - process->cache.object_actions.used = 0; - process->cache.object_items.used = 0; - process->cache.buffer_file.used = 0; - process->cache.buffer_item.used = 0; - process->cache.buffer_path.used = 0; - process->cache.action.line_action = cache.action.line_action; - process->cache.action.line_item = cache.action.line_item; - process->cache.action.name_action.used = 0; - process->cache.action.name_file.used = 0; - process->cache.action.name_item.used = 0; - process->cache.action.generic.used = 0; - - process->stack.used = 0; - - process->main_data = (void *) global.main; - process->main_setting = (void *) global.setting; - process->main_thread = (void *) global.thread; - - if (F_status_is_error_not(status) && stack.used) { - if (process->stack.size < stack.used) { - status = f_type_array_lengths_resize(stack.used, &process->stack); - } - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_type_array_lengths_resize", F_true); - } - else { - for (f_array_length_t i = 0; i < stack.used; ++i) { - process->stack.array[i] = stack.array[i]; - } // for - - process->stack.used = stack.used; - } - } - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_append(cache.action.name_action, &process->cache.action.name_action); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_append(cache.action.name_file, &process->cache.action.name_file); - } - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_append(cache.action.name_item, &process->cache.action.name_item); - } - else { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_append", F_true); - } - } - - f_thread_unlock(&process->lock); - - if (F_status_is_error_not(status)) { - if (process->action && (options_force & controller_process_option_asynchronous_d)) { - if (process->type == controller_process_type_exit_e) { - status = f_thread_create(0, &process->id_thread, controller_thread_process_other, (void *) process); - } - else { - status = f_thread_create(0, &process->id_thread, controller_thread_process_normal, (void *) process); - } - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - } - else { - status = controller_rule_process_do(options_force, process); - - if (status == F_child || F_status_set_fine(status) == F_interrupt) { - f_thread_unlock(&process->active); - - return status; - } - } - } - - if (!action || F_status_is_error(status) && (process->state == controller_process_state_active_e || process->state == controller_process_state_busy_e)) { - { - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&process->active); - - return status_lock; - } - } - - if (!action || (options_force & controller_process_option_asynchronous_d)) { - process->state = controller_process_state_done_e; - } - else { - process->state = controller_process_state_idle_e; - } - - f_thread_mutex_lock(&process->wait_lock); - f_thread_condition_signal_all(&process->wait); - f_thread_mutex_unlock(&process->wait_lock); - - f_thread_unlock(&process->lock); - } - - f_thread_unlock(&process->active); - - if (F_status_is_error(status)) { - return status; - } - - return F_none; - } -#endif // _di_controller_rule_process_begin_ - -#ifndef _di_controller_rule_process_do_ - f_status_t controller_rule_process_do(const uint8_t options_force, controller_process_t * const process) { - - f_status_t status_lock = F_none; - - controller_global_t global = macro_controller_global_t_initialize((controller_main_t *) process->main_data, (controller_setting_t *) process->main_setting, (controller_thread_t *) process->main_thread); - - // The process and active locks shall be held for the duration of this processing (aside from switching between read to/from write). - if (options_force & controller_process_option_asynchronous_d) { - status_lock = controller_lock_read_process(process, global.thread, &process->active); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - return status_lock; - } - } - - status_lock = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - f_status_t status = F_none; - - f_array_length_t id_rule = 0; - - const f_array_length_t used_original_stack = process->stack.used; - - status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - f_thread_unlock(&process->lock); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - if (controller_rule_find(process->rule.alias, global.setting->rules, &id_rule) == F_true) { - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&global.thread->lock.rule); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - controller_rule_delete_simple(&process->rule); - - status = controller_rule_copy(global.setting->rules.array[id_rule], &process->rule); - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - f_thread_unlock(&global.thread->lock.rule); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - f_thread_unlock(&global.thread->lock.rule); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_rule_copy", F_true); - } - else if (!process->action) { - - // This is a "consider" Action, so do not actually execute the rule. - f_thread_unlock(&process->lock); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return F_process_not; - } - else { - for (f_array_length_t i = 0; i < process->stack.used && controller_thread_is_enabled_process(process, global.thread); ++i) { - - if (process->stack.array[i] == id_rule) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe rule '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, process->rule.alias, global.main->error.notable); - fl_print_format("%[' is already on the execution dependency stack, this recursion is prohibited.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, process->cache.action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - // Never continue on circular recursion errors even in simulate mode. - status = F_status_set_error(F_recurse); - - break; - } - } // for - - if (!controller_thread_is_enabled_process(process, global.thread)) { - f_thread_unlock(&process->lock); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return F_status_set_error(F_interrupt); - } - - if (F_status_is_error_not(status)) { - status = f_type_array_lengths_increase(controller_common_allocation_small_d, &process->stack); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_type_array_lengths_increase", F_true); - } - else { - f_thread_unlock(&process->lock); - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - process->stack.array[process->stack.used++] = id_rule; - - f_thread_unlock(&process->lock); - - status_lock = controller_lock_read_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - } - } - } - - if (F_status_is_error_not(status)) { - status = controller_rule_process(global, process); - } - } - else { - f_thread_unlock(&global.thread->lock.rule); - - status = F_status_set_error(F_found_not); - - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_item_print_error_rule_not_loaded(global.main->error, process->rule.alias.string); - controller_rule_print_error_cache(global.main->error, process->cache.action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - } - - if (status == F_child) { - f_thread_unlock(&process->lock); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status; - } - - status_lock = controller_lock_write_process(process, global.thread, &global.thread->lock.rule); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - if (F_status_set_fine(status) != F_lock) { - f_thread_unlock(&process->lock); - } - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - if (F_status_set_fine(status) == F_lock) { - if (controller_rule_find(process->rule.alias, global.setting->rules, &id_rule) == F_true) { - global.setting->rules.array[id_rule].status[process->action] = status; - } - } - - f_thread_unlock(&global.thread->lock.rule); - - if (F_status_set_fine(status) != F_lock) { - f_thread_unlock(&process->lock); - } - - if (F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_lock && !controller_thread_is_enabled_process(process, global.thread)) { - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return F_status_set_error(F_interrupt); - } - - status_lock = controller_lock_write_process(process, global.thread, &process->lock); - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - return status_lock; - } - - if (options_force & controller_process_option_asynchronous_d) { - process->state = controller_process_state_done_e; - } - else { - process->state = controller_process_state_idle_e; - } - - process->stack.used = used_original_stack; - - // inform all things waiting that the process has finished running. - f_thread_mutex_lock(&process->wait_lock); - f_thread_condition_signal_all(&process->wait); - f_thread_mutex_unlock(&process->wait_lock); - - f_thread_unlock(&process->lock); - - if (options_force & controller_process_option_asynchronous_d) { - f_thread_unlock(&process->active); - } - - if (controller_thread_is_enabled_process(process, global.thread)) { - return status; - } - - return F_status_set_error(F_interrupt); - } -#endif // _di_controller_rule_process_do_ - -#ifndef _di_controller_rule_read_ - f_status_t controller_rule_read(const controller_global_t global, const bool is_normal, const f_string_static_t alias, controller_cache_t * const cache, controller_entry_t * const entry, controller_rule_t * const rule) { - - f_status_t status = F_none; - - bool for_item = F_true; - - for (f_array_length_t i = 0; i < controller_rule_action_type__enum_size_e; ++i) { - rule->status[i] = F_known_not; - } // for - - rule->timeout_kill = entry->timeout_kill ? entry->timeout_kill : 0; - rule->timeout_start = entry->timeout_start ? entry->timeout_start : 0; - rule->timeout_stop = entry->timeout_stop ? entry->timeout_stop : 0; - - rule->has = 0; - rule->group = 0; - rule->user = 0; - rule->nice = 0; - - macro_f_time_spec_t_clear(rule->timestamp); - - rule->alias.used = 0; - rule->name.used = 0; - rule->path.used = 0; - rule->script.used = 0; - - rule->define.used = 0; - rule->parameter.used = 0; - rule->environment.used = 0; - - rule->affinity.used = 0; - - if (rule->capability) { - f_capability_delete(&rule->capability); - rule->capability = 0; - } - - for (f_array_length_t i = 0; i < rule->cgroup.groups.size; ++i) { - rule->cgroup.groups.array[i].used = 0; - } // for - - rule->cgroup.as_new = F_false; - rule->cgroup.path.used = 0; - rule->cgroup.groups.used = 0; - - macro_f_control_group_t_clear(rule->cgroup); - - rule->groups.used = 0; - rule->limits.used = 0; - - rule->scheduler.policy = 0; - rule->scheduler.priority = 0; - - for (f_array_length_t i = 0; i < rule->ons.size; ++i) { - rule->ons.array[i].need.used = 0; - rule->ons.array[i].want.used = 0; - rule->ons.array[i].wish.used = 0; - } // for - - rule->ons.used = 0; - rule->items.used = 0; - - cache->action.line_item = 0; - cache->action.line_action = 0; - - cache->range_action.start = 1; - cache->range_action.stop = 0; - - cache->comments.used = 0; - cache->delimits.used = 0; - - cache->buffer_file.used = 0; - cache->buffer_item.used = 0; - cache->buffer_path.used = 0; - - for (f_array_length_t i = 0; i < cache->content_items.used; ++i) { - cache->content_items.array[i].used = 0; - } // for - - cache->content_items.used = 0; - cache->object_items.used = 0; - - cache->action.name_action.used = 0; - cache->action.name_file.used = 0; - cache->action.name_item.used = 0; - - status = f_string_dynamic_append_nulless(alias, &rule->alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true); - } - else { - status = f_string_dynamic_terminate_after(&rule->alias); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - } - else { - status = controller_file_load(global, F_true, controller_rules_s, rule->alias, controller_rule_s, controller_rules_s_length, controller_rule_s_length, cache); - } - } - - if (F_status_is_error_not(status)) { - rule->timestamp = cache->timestamp; - - if (cache->buffer_file.used) { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - f_string_range_t range = macro_f_string_range_t_initialize(cache->buffer_file.used); - - status = fll_fss_basic_list_read(cache->buffer_file, state, &range, &cache->object_items, &cache->content_items, &cache->delimits, 0, &cache->comments); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true); - } - else { - status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true); - } - } - } - } - - if (F_status_is_error_not(status) && cache->object_items.used) { - status = controller_rule_items_increase_by(cache->object_items.used, &rule->items); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true); - } - else { - f_array_length_t i = 0; - f_array_length_t j = 0; - - for (; i < cache->object_items.used; ++i) { - - cache->action.line_item = 0; - cache->action.line_action = 0; - - cache->range_action.start = 1; - cache->range_action.stop = 0; - - cache->comments.used = 0; - cache->delimits.used = 0; - - cache->content_action.used = 0; - - for (j = 0; j < cache->content_actions.used; ++j) { - cache->content_actions.array[j].used = 0; - } // for - - cache->content_actions.used = 0; - cache->object_actions.used = 0; - - cache->buffer_item.used = 0; - cache->buffer_path.used = 0; - - cache->action.name_action.used = 0; - cache->action.name_item.used = 0; - - for_item = F_true; - - status = f_fss_count_lines(cache->buffer_file, cache->object_items.array[i].start, &cache->action.line_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true); - - break; - } - - rule->items.array[rule->items.used].line = ++cache->action.line_item; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_file, cache->object_items.array[i], &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true); - - break; - } - - if (fl_string_dynamic_compare_string(controller_setting_s, cache->action.name_item, controller_setting_s_length) == F_equal_to) { - rule->items.array[rule->items.used].type = 0; - } - else if (fl_string_dynamic_compare_string(controller_command_s, cache->action.name_item, controller_command_s_length) == F_equal_to) { - rule->items.array[rule->items.used].type = controller_rule_item_type_command_e; - } - else if (fl_string_dynamic_compare_string(controller_script_s, cache->action.name_item, controller_script_s_length) == F_equal_to) { - rule->items.array[rule->items.used].type = controller_rule_item_type_script_e; - } - else if (fl_string_dynamic_compare_string(controller_service_s, cache->action.name_item, controller_service_s_length) == F_equal_to) { - rule->items.array[rule->items.used].type = controller_rule_item_type_service_e; - } - else if (fl_string_dynamic_compare_string(controller_utility_s, cache->action.name_item, controller_utility_s_length) == F_equal_to) { - rule->items.array[rule->items.used].type = controller_rule_item_type_utility_e; - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SUnknown rule item '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_item, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, cache->action, F_true); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - continue; - } - - status = f_string_dynamic_partial_append(cache->buffer_file, cache->content_items.array[i].array[0], &cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append", F_true); - - break; - } - - status = f_string_dynamic_terminate_after(&cache->buffer_item); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true); - - break; - } - - if (rule->items.array[rule->items.used].type) { - - // Initialize the item with settings. - rule->items.array[rule->items.used].with = 0; - - if (entry->session == controller_entry_session_new_e) { - rule->items.array[rule->items.used].with |= controller_with_session_new_d; - } - else { - rule->items.array[rule->items.used].with |= controller_with_session_same_d; - } - - status = controller_rule_item_read(global, is_normal, cache, &rule->items.array[rule->items.used]); - if (F_status_is_error(status)) break; - - ++rule->items.used; - } - else { - for_item = F_false; - - status = controller_rule_setting_read(global, is_normal, *global.setting, cache, rule); - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - break; - } - } - } - } // for - } - } - - if (F_status_is_error(status)) { - controller_rule_item_print_error(global.thread, global.main->error, cache->action, for_item, F_status_set_fine(status)); - - rule->status[0] = controller_status_simplify_error(F_status_set_fine(status)); - - return rule->status[0]; - } - - return F_none; - } -#endif // _di_controller_rule_read_ - -#ifndef _di_controller_rule_setting_read_ - f_status_t controller_rule_setting_read(const controller_global_t global, const bool is_normal, const controller_setting_t setting, controller_cache_t * const cache, controller_rule_t * const rule) { - - f_status_t status = F_none; - f_status_t status_return = F_none; - - f_string_range_t range = macro_f_string_range_t_initialize(cache->buffer_item.used); - f_string_range_t range2 = f_string_range_t_initialize; - - { - controller_state_interrupt_t custom = macro_controller_state_interrupt_t_initialize(is_normal, global.thread); - f_state_t state = macro_f_state_t_initialize(controller_common_allocation_large_d, controller_common_allocation_small_d, 0, &controller_thread_signal_state_fss, 0, (void *) &custom, 0); - - status = fll_fss_extended_read(cache->buffer_item, state, &range, &cache->object_actions, &cache->content_actions, 0, 0, &cache->delimits, 0); - } - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, F_false); - - return status; - } - - f_array_length_t path_original_length = 0; - f_string_dynamic_t *setting_value = 0; - f_string_dynamics_t *setting_values = 0; - f_string_maps_t *setting_maps = 0; - - f_array_length_t i = 0; - f_array_length_t j = 0; - uint8_t type = 0; - uint8_t action = 0; - bool empty_disallow = F_true; - - // Save the current name item and line number to restore on return. - const f_array_length_t line_item = cache->action.line_item; - const f_array_length_t length_name_item = cache->action.name_item.used; - - char name_item[length_name_item]; - name_item[length_name_item] = 0; - - memcpy(name_item, cache->action.name_item.string, length_name_item); - - for (; i < cache->content_actions.used; ++i, type = 0) { - - // The name_action is used to store all setting values for a single setting. - cache->action.name_action.used = 0; - - // The name_item is used to store the setting name. - cache->action.name_item.used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->object_actions.array[i], &cache->action.name_item); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - } - else { - status = f_string_dynamic_terminate_after(&cache->action.name_item); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - empty_disallow = F_true; - - if (fl_string_dynamic_compare_string(controller_affinity_s, cache->action.name_item, controller_affinity_s_length) == F_equal_to) { - type = controller_rule_setting_type_affinity_e; - } - else if (fl_string_dynamic_compare_string(controller_capability_s, cache->action.name_item, controller_capability_s_length) == F_equal_to) { - type = controller_rule_setting_type_capability_e; - } - else if (fl_string_dynamic_compare_string(controller_cgroup_s, cache->action.name_item, controller_cgroup_s_length) == F_equal_to) { - type = controller_rule_setting_type_cgroup_e; - } - else if (fl_string_dynamic_compare_string(controller_define_s, cache->action.name_item, controller_define_s_length) == F_equal_to) { - type = controller_rule_setting_type_define_e; - } - else if (fl_string_dynamic_compare_string(controller_environment_s, cache->action.name_item, controller_environment_s_length) == F_equal_to) { - type = controller_rule_setting_type_environment_e; - empty_disallow = F_false; - } - else if (fl_string_dynamic_compare_string(controller_group_s, cache->action.name_item, controller_group_s_length) == F_equal_to) { - type = controller_rule_setting_type_group_e; - } - else if (fl_string_dynamic_compare_string(controller_limit_s, cache->action.name_item, controller_limit_s_length) == F_equal_to) { - type = controller_rule_setting_type_limit_e; - } - else if (fl_string_dynamic_compare_string(controller_name_s, cache->action.name_item, controller_name_s_length) == F_equal_to) { - type = controller_rule_setting_type_name_e; - } - else if (fl_string_dynamic_compare_string(controller_nice_s, cache->action.name_item, controller_nice_s_length) == F_equal_to) { - type = controller_rule_setting_type_nice_e; - } - else if (fl_string_dynamic_compare_string(controller_on_s, cache->action.name_item, controller_on_s_length) == F_equal_to) { - type = controller_rule_setting_type_on_e; - } - else if (fl_string_dynamic_compare_string(controller_parameter_s, cache->action.name_item, controller_parameter_s_length) == F_equal_to) { - type = controller_rule_setting_type_parameter_e; - } - else if (fl_string_dynamic_compare_string(controller_path_s, cache->action.name_item, controller_path_s_length) == F_equal_to) { - type = controller_rule_setting_type_path_e; - } - else if (fl_string_dynamic_compare_string(controller_scheduler_s, cache->action.name_item, controller_scheduler_s_length) == F_equal_to) { - type = controller_rule_setting_type_scheduler_e; - } - else if (fl_string_dynamic_compare_string(controller_script_s, cache->action.name_item, controller_script_s_length) == F_equal_to) { - type = controller_rule_setting_type_script_e; - } - else if (fl_string_dynamic_compare_string(controller_timeout_s, cache->action.name_item, controller_timeout_s_length) == F_equal_to) { - type = controller_rule_setting_type_timeout_e; - } - else if (fl_string_dynamic_compare_string(controller_user_s, cache->action.name_item, controller_user_s_length) == F_equal_to) { - type = controller_rule_setting_type_user_e; - } - else { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SUnknown rule setting '%]", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context); - fl_print_format("%[%Q%]", global.main->warning.to.stream, global.main->warning.notable, cache->action.name_item, global.main->warning.notable); - fl_print_format("%['.%]%c", global.main->warning.to.stream, global.main->warning.context, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, cache->action, F_false); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - continue; - } - - if (cache->content_actions.array[i].used) { - range2.start = cache->content_actions.array[i].array[0].start; - range2.stop = cache->content_actions.array[i].array[cache->content_actions.array[i].used - 1].stop; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, range2, &cache->action.name_action); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - } - else { - status = f_string_dynamic_terminate_after(&cache->action.name_action); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - continue; - } - } - else { - if (empty_disallow) { - if (global.main->warning.verbosity == f_console_verbosity_debug_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->warning.to, global.thread); - - fl_print_format("%c%[%SEmpty rule setting.%]%c", global.main->warning.to.stream, f_string_eol_s[0], global.main->warning.context, global.main->warning.prefix, global.main->warning.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->warning, cache->action, F_false); - - controller_unlock_print_flush(global.main->warning.to, global.thread); - } - - continue; - } - } - - if (type == controller_rule_setting_type_affinity_e) { - // @todo use sched_getaffinity() to get the available cpus and do not add an invalid cpu to the affinity array. - - if (!cache->content_actions.array[i].used) { - controller_rule_setting_read_print_error(global.main->error, "requires one or more Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - rule->affinity.used = 0; - - f_number_signed_t number = 0; - - for (j = 0; j < cache->content_actions.array[i].used; ++j, number = 0) { - - // @todo this needs to be in a function such as f_int32s_increase(). - if (rule->affinity.used + 1 > rule->affinity.size) { - f_array_length_t size = rule->affinity.used + controller_common_allocation_small_d; - - if (size > F_array_length_t_size_d) { - if (rule->affinity.used + 1 > F_array_length_t_size_d) { - status = F_status_set_error(F_array_too_large); - } - else { - size = F_array_length_t_size_d; - } - } - - if (F_status_is_error_not(status)) { - macro_f_int32s_t_resize(status, rule->affinity, size); - } - } - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "macro_f_int32s_t_resize", F_true, F_false); - break; - } - - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, cache->content_actions.array[i].array[j], &number); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_actions.array[i].array[j]), &number); - - // Restore error on parameter problem. - if (F_status_set_fine(status) == F_parameter) { - status = F_status_set_error(F_number_positive); - } - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_data_not || status == F_number || status == F_number_overflow || status == F_number_underflow || status == F_number_negative || status == F_number_decimal) { - if (status == F_number_underflow) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[j], ", the number is too small for this system", i, line_item, global.thread, cache); - } - else if (status == F_number_overflow || status == F_number_positive) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[j], ", the number is too large for this system", i, line_item, global.thread, cache); - } - else { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid number", cache->content_actions.array[i].array[j], ", only whole numbers are allowed for an affinity value", i, line_item, global.thread, cache); - } - - status = F_status_set_error(F_valid_not); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - else { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false); - - status = F_status_set_error(status); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - - continue; - } - - rule->affinity.array[rule->affinity.used++] = number; - } // for - - controller_rule_setting_read_print_values(global, controller_affinity_s, i, cache); - - continue; - } - - if (type == controller_rule_setting_type_define_e || type == controller_rule_setting_type_parameter_e) { - if (cache->content_actions.array[i].used != 2) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly two Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - if (type == controller_rule_setting_type_define_e) { - setting_maps = &rule->define; - } - else if (type == controller_rule_setting_type_parameter_e) { - setting_maps = &rule->parameter; - } - - status = f_string_maps_increase(controller_common_allocation_small_d, setting_maps); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_maps_increase", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - setting_maps->array[setting_maps->used].name.used = 0; - setting_maps->array[setting_maps->used].value.used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &setting_maps->array[setting_maps->used].name); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[1], &setting_maps->array[setting_maps->used].value); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - } - else { - status = f_string_dynamic_terminate_after(&setting_maps->array[setting_maps->used].value); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - controller_rule_setting_read_print_value(global, type == controller_rule_setting_type_define_e ? controller_define_s : controller_parameter_s, 0, setting_maps->array[setting_maps->used].name, 0); - - ++setting_maps->used; - - continue; - } - - if (type == controller_rule_setting_type_cgroup_e) { - if (cache->content_actions.array[i].used < 2 || rule->has & controller_rule_has_cgroup_d) { - controller_rule_setting_read_print_error(global.main->error, "requires two or more Content", i, line_item, global.thread, cache); - - 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_existing_s, cache->buffer_item, controller_existing_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - rule->cgroup.as_new = F_false; - } - else if (fl_string_dynamic_partial_compare_string(controller_new_s, cache->buffer_item, controller_new_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - rule->cgroup.as_new = F_true; - } - else { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unknown option", cache->content_actions.array[i].array[0], "", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - rule->cgroup.path.used = 0; - - status = f_string_dynamic_append(global.setting->path_cgroup, &rule->cgroup.path); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_false); - } - else { - rule->cgroup.groups.used = 0; - - for (j = 1; j < cache->content_actions.array[i].used; ++j) { - - status = f_string_dynamics_increase(controller_common_allocation_small_d, &rule->cgroup.groups); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false); - break; - } - - rule->cgroup.groups.array[rule->cgroup.groups.used].used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[j], &rule->cgroup.groups.array[rule->cgroup.groups.used]); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - break; - } - - ++rule->cgroup.groups.used; - } // for - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - rule->cgroup.path.used = 0; - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - rule->has |= controller_rule_has_cgroup_d; - - controller_rule_setting_read_print_values(global, controller_cgroup_s, i, cache); - - continue; - } - - if (type == controller_rule_setting_type_limit_e) { - if (cache->content_actions.array[i].used != 3) { - controller_rule_setting_read_print_error(global.main->error, "requires three Content", i, line_item, global.thread, cache); - - 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_as_s, cache->buffer_item, controller_as_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_as_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_core_s, cache->buffer_item, controller_core_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_core_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_cpu_s, cache->buffer_item, controller_cpu_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_cpu_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_data_s, cache->buffer_item, controller_data_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_data_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_fsize_s, cache->buffer_item, controller_fsize_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_fsize_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_locks_s, cache->buffer_item, controller_locks_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_locks_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_memlock_s, cache->buffer_item, controller_memlock_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_memlock_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_msgqueue_s, cache->buffer_item, controller_msgqueue_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_msgqueue_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_nice_s, cache->buffer_item, controller_nice_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_nice_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_nofile_s, cache->buffer_item, controller_nofile_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_nofile_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_nproc_s, cache->buffer_item, controller_nproc_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_nproc_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_rss_s, cache->buffer_item, controller_rss_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_rss_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_rtprio_s, cache->buffer_item, controller_rtprio_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_rtprio_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_rttime_s, cache->buffer_item, controller_rttime_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_rttime_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_sigpending_s, cache->buffer_item, controller_sigpending_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_sigpending_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_stack_s, cache->buffer_item, controller_stack_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - type = controller_resource_limit_type_stack_e; - } - else { - if (global.main->error.verbosity == f_console_verbosity_debug_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SUnknown resource limit type '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, cache->action.name_action, global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_true); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - for (j = 0; j < rule->limits.used; ++j) { - - if (type == rule->limits.array[j].type) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe resource limit type is already specified%]%c", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - status = F_status_set_error(F_valid_not); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - } // for - - if (F_status_is_error(status)) continue; - - macro_f_limit_sets_t_increase(status, controller_common_allocation_small_d, rule->limits); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_limit_sets_increase", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - f_number_signed_t number = 0; - - for (j = 1; j < 3; ++j, number = 0) { - - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, cache->content_actions.array[i].array[j], &number); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_actions.array[i].array[j]), &number); - - // Restore error on parameter problem. - if (F_status_set_fine(status) == F_parameter) { - status = F_status_set_error(F_number_positive); - } - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_data_not || status == F_number || status == F_number_overflow || status == F_number_underflow || status == F_number_negative || status == F_number_positive || status == F_number_decimal) { - if (status == F_number_underflow) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[j], ", the number is too small for this system", i, line_item, global.thread, cache); - } - else if (status == F_number_overflow) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[j], ", the number is too large for this system", i, line_item, global.thread, cache); - } - else { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[j], ", only whole numbers are allowed for a resource limit value", i, line_item, global.thread, cache); - } - - status = F_status_set_error(F_valid_not); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - else { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false); - - status = F_status_set_error(status); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - - break; - } - - if (j == 1) { - rule->limits.array[rule->limits.used].value.rlim_cur = number; - } - else { - rule->limits.array[rule->limits.used].value.rlim_max = number; - } - } // for - - if (F_status_is_error(status)) continue; - - rule->limits.array[rule->limits.used++].type = type; - - controller_rule_setting_read_print_values(global, controller_limit_s, i, cache); - - continue; - } - - if (type == controller_rule_setting_type_name_e || type == controller_rule_setting_type_path_e || type == controller_rule_setting_type_script_e) { - - if (type == controller_rule_setting_type_name_e) { - setting_value = &rule->name; - } - else if (type == controller_rule_setting_type_path_e) { - setting_value = &rule->path; - } - else if (type == controller_rule_setting_type_script_e) { - setting_value = &rule->script; - } - - if (setting_value->used || cache->content_actions.array[i].used != 1) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - if (type == controller_rule_setting_type_name_e || type == controller_rule_setting_type_script_e) { - status = controller_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; - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - status = controller_validate_has_graph(*setting_value); - - if (status == F_false || F_status_set_fine(status) == F_complete_not_utf) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - } - - if (status == F_false) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting has an invalid name '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, *setting_value, global.main->error.notable); - fl_print_format("%[', there must be at least 1 graph character.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - else { - - // this function should only return F_complete_not_utf on error. - controller_rule_print_error(global.thread, global.main->error, cache->action, F_complete_not_utf, "controller_validate_has_graph", F_true, F_false); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - } - - setting_value->used = 0; - - continue; - } - - controller_rule_setting_read_print_value(global, type == controller_rule_setting_type_name_e ? controller_name_s : controller_script_s, 0, *setting_value, 0); - } - else if (type == controller_rule_setting_type_path_e) { - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], setting_value); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - } - else { - status = f_string_dynamic_terminate_after(setting_value); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - setting_value->used = 0; - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - controller_rule_setting_read_print_value(global, controller_path_s, 0, *setting_value, 0); - } - - continue; - } - - if (type == controller_rule_setting_type_scheduler_e) { - - if (cache->content_actions.array[i].used < 1 || cache->content_actions.array[i].used > 2 || rule->has & controller_rule_has_scheduler_d) { - controller_rule_setting_read_print_error(global.main->error, "requires either one or two Content", i, line_item, global.thread, cache); - - 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_batch_s, cache->buffer_item, controller_batch_s_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_deadline_s, cache->buffer_item, controller_deadline_s_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_fifo_s, cache->buffer_item, controller_fifo_s_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_idle_s, cache->buffer_item, controller_idle_s_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_other_s, cache->buffer_item, controller_other_s_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_round_robin_s, cache->buffer_item, controller_round_robin_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - rule->scheduler.policy = SCHED_RR; - rule->scheduler.priority = 49; - } - else { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unknown scheduler", cache->content_actions.array[i].array[0], "", i, line_item, global.thread, cache); - - 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, cache->content_actions.array[i].array[1], &number); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_actions.array[i].array[1]), &number); - - // Restore error on parameter problem. - if (F_status_set_fine(status) == F_parameter) { - status = F_status_set_error(F_number_positive); - } - } - - 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 || status == F_number_negative || status == F_number_positive) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting has an invalid number '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable); - - if (zero_only) { - fl_print_format("%[', only%] ", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[0%]%[ is", global.main->error.to.stream, global.main->error.notable, global.main->error.notable, global.main->error.context); - } - else { - fl_print_format("%[', only the whole numbers inclusively between%] ", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[1%] %[and%] ", global.main->error.to.stream, global.main->error.notable, global.main->error.notable, global.main->error.context, global.main->error.context); - fl_print_format("%[99%] %[are", global.main->error.to.stream, global.main->error.notable, global.main->error.notable, global.main->error.context); - } - - fl_print_format(" allowed for the designated scheduler.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - else { - controller_rule_print_error(global.thread, global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false); - status = F_status_set_error(status); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - - continue; - } - - rule->scheduler.priority = number; - } - - rule->has |= controller_rule_has_scheduler_d; - - controller_rule_setting_read_print_values(global, controller_scheduler_s, i, cache); - - continue; - } - - if (type == controller_rule_setting_type_timeout_e) { - if (cache->content_actions.array[i].used != 2) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly two Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - uint8_t timeout_code = 0; - - if (fl_string_dynamic_partial_compare_string(controller_kill_s, cache->buffer_item, controller_kill_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - timeout_code = controller_rule_timeout_code_kill_d; - } - else if (fl_string_dynamic_partial_compare_string(controller_start_s, cache->buffer_item, controller_start_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - timeout_code = controller_rule_timeout_code_start_d; - } - else if (fl_string_dynamic_partial_compare_string(controller_stop_s, cache->buffer_item, controller_stop_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - timeout_code = controller_rule_timeout_code_stop_d; - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting's first value has '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable); - fl_print_format("%[' but only supports %s, %s, and %s.%]%c", global.main->error.to.stream, global.main->error.context, controller_kill_s, controller_start_s, controller_stop_s, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - f_number_unsigned_t number = 0; - - status = fl_conversion_string_to_number_unsigned(cache->buffer_item.string, cache->content_actions.array[i].array[1], &number); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_unsigned(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_actions.array[i].array[1]), &number); - - // Restore error on parameter problem. - if (F_status_set_fine(status) == F_parameter) { - status = F_status_set_error(F_number_positive); - } - } - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_number_overflow) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an unsupported number", cache->content_actions.array[i].array[1], ", the number is too large for this system", i, line_item, global.thread, cache); - } - else if (status == F_data_not || status == F_number || status == F_number_underflow || status == F_number_negative || status == F_number_positive || status == F_number_decimal) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid number", cache->content_actions.array[i].array[1], ", only positive whole numbers are allowed", i, line_item, global.thread, cache); - } - else { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_print_error(global.thread, global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - else { - if (timeout_code == controller_rule_timeout_code_kill_d) { - rule->timeout_kill = number; - } - else if (timeout_code == controller_rule_timeout_code_start_d) { - rule->timeout_start = number; - } - else { - rule->timeout_stop = number; - } - - if (global.main->error.verbosity == f_console_verbosity_debug_e || (global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - f_string_t name_sub = controller_stop_s; - - if (timeout_code == controller_rule_timeout_code_kill_d) { - name_sub = controller_kill_s; - } - else if (timeout_code == controller_rule_timeout_code_start_d) { - name_sub = controller_start_s; - } - - cache->action.generic.used = 0; - - status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->content_actions.array[i].array[1], &cache->action.generic); - - if (F_status_is_error(status)) { - controller_print_error(global.thread, global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true); - - break; - } - - controller_rule_setting_read_print_value(global, controller_timeout_s, name_sub, cache->action.generic, 0); - } - } - - continue; - } - - if (type == controller_rule_setting_type_capability_e || type == controller_rule_setting_type_nice_e || type == controller_rule_setting_type_user_e) { - if (cache->content_actions.array[i].used != 1 || type == controller_rule_setting_type_capability_e && rule->capability || type == controller_rule_setting_type_group_e && (rule->has & controller_rule_has_group_d) || type == controller_rule_setting_type_nice_e && (rule->has & controller_rule_has_nice_d) || type == controller_rule_setting_type_user_e && (rule->has & controller_rule_has_user_d)) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - if (type == controller_rule_setting_type_capability_e) { - cache->action.generic.used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &cache->action.generic); - - if (F_status_is_error(status)) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - - status = f_string_dynamic_terminate_after(&cache->action.generic); - - if (F_status_is_error(status)) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - - status = f_capability_from_text(cache->action.generic.string, &rule->capability); - - if (F_status_is_error(status) && F_status_set_fine(status) != F_supported_not) { - if (F_status_set_fine(status) == F_memory_not) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_capability_from_text", F_true, F_false); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - status_return = status; - break; - } - - controller_rule_setting_read_print_error(global.main->error, "failed to process the capabilities", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - controller_rule_setting_read_print_value(global, controller_capability_s, 0, cache->action.generic, 0); - } - else if (type == controller_rule_setting_type_nice_e) { - f_number_signed_t number = 0; - - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, cache->content_actions.array[i].array[0], &number); - - if (F_status_set_fine(status) == F_number_positive) { - status = fl_conversion_string_to_number_signed(cache->buffer_item.string, controller_range_after_number_sign(cache->buffer_item, cache->content_actions.array[i].array[0]), &number); - - // Restore error on parameter problem. - if (F_status_set_fine(status) == F_parameter) { - status = F_status_set_error(F_number_positive); - } - } - - if (F_status_is_error(status) || number < -20 || number > 19) { - status = F_status_set_fine(status); - - if (number < -20 || number > 19 || status == F_data_not || status == F_number || status == F_number_overflow || status == F_number_underflow || status == F_number_decimal) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting has an invalid number '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[0], global.main->error.notable); - fl_print_format("%[', only the whole numbers inclusively between%] ", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[-20%]", global.main->error.to.stream, global.main->error.notable, global.main->error.notable); - fl_print_format(" %[and%] ", global.main->error.to.stream, global.main->error.context, global.main->error.context); - fl_print_format("%[19%]", global.main->error.to.stream, global.main->error.notable, global.main->error.notable); - fl_print_format(" %[are allowed.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - else { - controller_rule_print_error(global.thread, global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false); - status = F_status_set_error(status); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - } - else { - rule->nice = number; - rule->has |= controller_rule_has_nice_d; - - if (global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e || global.main->error.verbosity == f_console_verbosity_verbose_e) { - cache->action.generic.used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &cache->action.generic); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate_after(&cache->action.generic); - } - - if (F_status_is_error(status)) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), cache->action.generic.used ? "f_string_dynamic_partial_append_nulless" : "f_string_dynamic_terminate_after", F_true, F_false); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - - if (F_status_is_error_not(status)) { - controller_rule_setting_read_print_value(global, controller_nice_s, 0, cache->action.generic, 0); - } - } - } - } - else if (type == controller_rule_setting_type_user_e) { - uid_t number = 0; - - status = controller_get_id_user(cache->buffer_item, cache->content_actions.array[i].array[0], cache, &number); - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_exist_not) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because no user was found by that name", i, line_item, global.thread, cache); - } - else if (status == F_number_too_large) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because the given ID is too large", i, line_item, global.thread, cache); - } - else if (status == F_number) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid user", cache->content_actions.array[i].array[0], ", because the given ID is not a valid supported number", i, line_item, global.thread, cache); - } - else { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_print_error(global.thread, global.main->error, cache->action, status, "controller_get_id_user", F_true, F_false); - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(status); - } - } - else { - rule->user = number; - rule->has |= controller_rule_has_user_d; - - if (global.main->error.verbosity == f_console_verbosity_debug_e || (global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - cache->action.generic.used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[0], &cache->action.generic); - - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate_after(&cache->action.generic); - } - - controller_rule_setting_read_print_value(global, controller_user_s, 0, cache->action.generic, 0); - } - } - } - - continue; - } - - if (type == controller_rule_setting_type_group_e) { - if (!cache->content_actions.array[i].used) { - controller_rule_setting_read_print_error(global.main->error, "requires one or more Content", i, line_item, global.thread, cache); - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - gid_t number = 0; - - rule->groups.used = 0; - - for (j = 0; j < cache->content_actions.array[i].used; ++j) { - - macro_f_int32s_t_increase_by(status, rule->groups, controller_common_allocation_small_d) - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - status = controller_get_id_group(cache->buffer_item, cache->content_actions.array[i].array[j], cache, &number); - - if (F_status_is_error(status)) { - status = F_status_set_fine(status); - - if (status == F_exist_not) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid group", cache->content_actions.array[i].array[j], ", because no group was found by that name", i, line_item, global.thread, cache); - } - else if (status == F_number_too_large) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid group", cache->content_actions.array[i].array[j], ", because the given ID is too large", i, line_item, global.thread, cache); - } - else if (status == F_number) { - controller_rule_setting_read_print_error_with_range(global.main->error, " has an invalid group", cache->content_actions.array[i].array[j], ", because the given ID is not a valid supported number", i, line_item, global.thread, cache); - } - else { - - // get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_print_error(global.thread, global.main->error, cache->action, status, "f_account_id_group_by_name", F_true, F_false); - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(status); - } - } - else { - if (rule->has & controller_rule_has_group_d) { - rule->groups.array[rule->groups.used++] = number; - } - else { - rule->group = number; - rule->has |= controller_rule_has_group_d; - } - } - } // for - - controller_rule_setting_read_print_values(global, controller_group_s, i, cache); - - continue; - } - - if (type == controller_rule_setting_type_environment_e) { - setting_values = &rule->environment; - - for (j = 0; j < cache->content_actions.array[i].used; ++j) { - - status = f_string_dynamics_increase(controller_common_allocation_small_d, setting_values); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - setting_values->array[setting_values->used].used = 0; - - status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[j], &setting_values->array[setting_values->used]); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false); - } - else { - status = f_string_dynamic_terminate_after(&setting_values->array[setting_values->used]); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - setting_values->array[setting_values->used].used = 0; - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - status = controller_validate_environment_name(setting_values->array[setting_values->used]); - - if (status == F_false || F_status_set_fine(status) == F_complete_not_utf) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - if (status == F_false) { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting has an invalid environment variable name '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, global.main->error.notable, setting_values->array[setting_values->used], global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - } - else { - - // This function should only return F_complete_not_utf on error. - controller_rule_print_error(global.thread, global.main->error, cache->action, F_complete_not_utf, "controller_validate_environment_name", F_true, F_false); - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - } - - setting_values->array[setting_values->used].used = 0; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - ++setting_values->used; - } // for - - rule->has |= controller_rule_has_environment_d; - - if (cache->content_actions.array[i].used) { - controller_rule_setting_read_print_values(global, controller_environment_s, i, cache); - } - else { - if (global.main->error.verbosity == f_console_verbosity_debug_e || (global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - controller_lock_print(global.main->output.to, global.thread); - - fl_print_format("%cProcessing rule item action '%[%s%]' setting value to an empty set.%c", global.main->output.to.stream, f_string_eol_s[0], global.main->context.set.title, controller_environment_s, global.main->context.set.title, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->output.to, global.thread); - } - } - - continue; - } - - // The "on" Rule Setting. - if (cache->content_actions.array[i].used != 4) { - controller_rule_setting_read_print_error(global.main->error, "requires exactly four Content", i, line_item, global.thread, cache); - - 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_freeze_s, cache->buffer_item, controller_freeze_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_freeze_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_kill_s, cache->buffer_item, controller_kill_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_kill_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_pause_s, cache->buffer_item, controller_pause_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_pause_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_reload_s, cache->buffer_item, controller_reload_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_reload_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_restart_s, cache->buffer_item, controller_restart_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_restart_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_resume_s, cache->buffer_item, controller_resume_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_resume_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_start_s, cache->buffer_item, controller_start_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_start_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_stop_s, cache->buffer_item, controller_stop_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_stop_e; - } - else if (fl_string_dynamic_partial_compare_string(controller_thaw_s, cache->buffer_item, controller_thaw_s_length, cache->content_actions.array[i].array[0]) == F_equal_to) { - action = controller_rule_action_type_thaw_e; - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - f_thread_mutex_lock(&global.thread->lock.print); - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting's second value has '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable); - fl_print_format("%[' but only supports %s, %s, %s, %s, %s", global.main->error.to.stream, global.main->error.context, controller_freeze_s, controller_kill_s, controller_pause_s, controller_reload_s, controller_restart_s); - fl_print_format("%s, %s, %s, and %s.%]%c", global.main->error.to.stream, controller_resume_s, controller_start_s, controller_stop_s, controller_thaw_s, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - for (j = 0; j < rule->ons.used; ++j) { - if (rule->ons.array[j].action == action) break; - } // for - - if (j == rule->ons.used) { - status = controller_rule_ons_increase(&rule->ons); - } - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "controller_rule_ons_increase", F_true, F_false); - } - else { - if (fl_string_dynamic_partial_compare_string(controller_need_s, cache->buffer_item, controller_need_s_length, cache->content_actions.array[i].array[1]) == F_equal_to) { - setting_values = &rule->ons.array[j].need; - } - else if (fl_string_dynamic_partial_compare_string(controller_want_s, cache->buffer_item, controller_want_s_length, cache->content_actions.array[i].array[1]) == F_equal_to) { - setting_values = &rule->ons.array[j].want; - } - else if (fl_string_dynamic_partial_compare_string(controller_wish_s, cache->buffer_item, controller_wish_s_length, cache->content_actions.array[i].array[1]) == F_equal_to) { - setting_values = &rule->ons.array[j].wish; - } - else { - if (global.main->error.verbosity != f_console_verbosity_quiet_e) { - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SRule setting's second value has '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->error.notable); - fl_print_format("%[' but only supports %s, %s, and %s.%]%c", global.main->error.to.stream, global.main->error.context, controller_need_s, controller_want_s, controller_wish_s, global.main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(global.main->error, cache->action, F_false); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - if (F_status_is_error_not(status_return)) { - status_return = F_status_set_error(F_valid_not); - } - - continue; - } - - status = f_string_dynamics_increase_by(controller_common_allocation_small_d, setting_values); - - if (F_status_is_error(status)) { - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase_by", F_true, F_false); - } - } - - if (F_status_is_error(status)) { - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - status = controller_rule_id_construct(global, cache->buffer_item, cache->content_actions.array[i].array[2], cache->content_actions.array[i].array[3], &setting_values->array[setting_values->used]); - - if (F_status_is_error(status)) { - setting_values->array[setting_values->used].used = 0; - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[i].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_rule_item_print_error(global.thread, global.main->error, cache->action, F_false, F_status_set_fine(status)); - - continue; - } - - cache->buffer_path.used = 0; - - 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; - - controller_rule_print_error(global.thread, global.main->error, cache->action, F_status_set_fine(status), "f_file_name_base", F_true, F_false); - - if (F_status_set_fine(status) == F_memory_not) { - status_return = status; - break; - } - - if (F_status_is_error_not(status_return)) { - status_return = status; - } - - continue; - } - - 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 (global.main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(global.main->error.to, global.thread); - - fl_print_format("%c%[%SThe rule item action third parameter '%]", global.main->error.to.stream, f_string_eol_s[0], global.main->error.context, global.main->error.prefix, global.main->error.context); - fl_print_format("%[%/Q%]", global.main->error.to.stream, global.main->error.notable, cache->buffer_item, cache->content_actions.array[i].array[2], global.main->error.notable); - fl_print_format("%[' must be a base path name, such as %un '.%]", global.main->error.to.stream, global.main->error.context, cache->buffer_path.used, global.main->error.context); - fl_print_format("%[%Q%]", global.main->error.to.stream, cache->buffer_path, global.main->error.notable); - fl_print_format("%['.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->error.to, global.thread); - } - - setting_values->array[setting_values->used].used = 0; - - continue; - } - - rule->ons.array[j].action = action; - - ++setting_values->used; - - if (j == rule->ons.used) { - ++rule->ons.used; - } - - if (global.main->error.verbosity == f_console_verbosity_debug_e || (global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - controller_lock_print(global.main->output.to, global.thread); - - fl_print_format("%cProcessing rule item action '%[%S%]', adding ", global.main->output.to.stream, f_string_eol_s[0], global.main->context.set.title, controller_on_s, global.main->context.set.title); - fl_print_format("'%[%/Q%]' of ", global.main->output.to.stream, global.main->context.set.notable, cache->buffer_item, cache->content_actions.array[i].array[1], global.main->context.set.notable); - fl_print_format("'%[%/Q%]/", global.main->output.to.stream, global.main->context.set.important, cache->buffer_item, cache->content_actions.array[i].array[2], global.main->context.set.important); - fl_print_format("%[%/Q%]'.%c", global.main->output.to.stream, global.main->context.set.important, cache->buffer_item, cache->content_actions.array[i].array[3], global.main->context.set.important, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->output.to, global.thread); - } - } // for - - // Restore the current name item and line number, which there should already be enough allocated space for. - memcpy(cache->action.name_item.string, name_item, length_name_item); - - cache->action.name_item.string[length_name_item] = 0; - cache->action.name_item.used = length_name_item; - - cache->action.line_item = line_item; - - return status_return; - } -#endif // _di_controller_rule_setting_read_ - -#ifndef _di_controller_rule_validate_ - void controller_rule_validate(const controller_global_t global, const controller_rule_t rule, const uint8_t action, const uint8_t options, controller_cache_t * const cache) { - - const controller_main_t *main = global.main; - - switch (action) { - case controller_rule_action_type_freeze_e: - case controller_rule_action_type_kill_e: - case controller_rule_action_type_pause_e: - case controller_rule_action_type_reload_e: - case controller_rule_action_type_restart_e: - case controller_rule_action_type_resume_e: - case controller_rule_action_type_start_e: - case controller_rule_action_type_stop_e: - case controller_rule_action_type_thaw_e: - break; - - default: - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, global.thread); - - fl_print_format("%c%[%SUnsupported action type '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%q%]", main->error.to.stream, main->error.notable, controller_rule_action_type_name(action), main->error.notable); - fl_print_format("%[' while attempting to validate rule execution.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(main->error, cache->action, F_true); - - controller_unlock_print_flush(main->error.to, global.thread); - } - - return; - } - - f_array_length_t i = 0; - f_array_length_t j = 0; - - // find at least one of the requested action. - { - bool missing = F_true; - - for (; i < rule.items.used; ++i) { - - for (j = 0; j < rule.items.array[i].actions.used; ++j) { - - if (!action || rule.items.array[i].actions.array[j].type == action) { - missing = F_false; - break; - } - } // for - } // for - - if (missing) { - controller_lock_print(main->output.to, global.thread); - - if (rule.items.used) { - fl_print_format("%cRule '", main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%Q%]' has no '", main->output.to.stream, main->context.set.title, rule.name, main->context.set.title); - fl_print_format("%[%q%]' action to execute and would '", main->output.to.stream, main->context.set.title, controller_rule_action_type_name(action), main->context.set.title); - fl_print_format("%[%s%]' because it is '", main->output.to.stream, main->context.set.important, options & controller_process_option_require_d ? controller_fail_s : controller_succeed_s, main->context.set.important); - fl_print_format("%[%s%]'.%c", main->output.to.stream, main->context.set.important, options & controller_process_option_require_d ? controller_required_s : controller_optional_s, main->context.set.important, f_string_eol_s[0]); - } - else { - fl_print_format("%cRule '", main->output.to.stream, f_string_eol_s[0]); - fl_print_format("%[%Q%]' has no known '", main->output.to.stream, main->context.set.title, rule.name, main->context.set.title); - fl_print_format("%[%s %s%]' (such as ", main->output.to.stream, main->context.set.title, controller_rule_s, controller_type_s, main->context.set.title); - fl_print_format("'%[%s%]', ", main->output.to.stream, main->context.set.title, controller_command_s, main->context.set.title); - fl_print_format("'%[%s%]', ", main->output.to.stream, main->context.set.title, controller_service_s, main->context.set.title); - fl_print_format("'%[%s%]', or ", main->output.to.stream, main->context.set.title, controller_script_s, main->context.set.title); - fl_print_format("'%[%s%]'", main->output.to.stream, main->context.set.title, controller_utility_s, main->context.set.title); - fl_print_format(") and would '%[%s%]' because it is '", main->output.to.stream, main->context.set.important, options & controller_process_option_require_d ? controller_fail_s : controller_succeed_s, main->context.set.important); - fl_print_format("%[%s%]'.%c", main->output.to.stream, main->context.set.important, options & controller_process_option_require_d ? controller_required_s : controller_optional_s, main->context.set.important, f_string_eol_s[0]); - } - - controller_unlock_print_flush(main->output.to, global.thread); - } - } - - controller_lock_print(main->output.to, global.thread); - - fl_print_format("%cRule %[%Q%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.title, rule.alias, main->context.set.title, f_string_eol_s[0]); - - // name. - fl_print_format(" %[%s%] %Q%c", main->output.to.stream, main->context.set.important, controller_name_s, main->context.set.important, rule.name, f_string_eol_s[0]); - - // capability. - fl_print_format(" %[%s%] ", main->output.to.stream, main->context.set.important, controller_capability_s, main->context.set.important); - - if (f_capability_supported()) { - if (rule.capability) { - cache->action.generic.used = 0; - - if (F_status_is_error_not(f_capability_to_text(rule.capability, &cache->action.generic))) { - f_print_dynamic_safely(cache->action.generic, main->output.to.stream); - } - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - } - else { - fl_print_format("%[(unsupported)%]%c", main->output.to.stream, main->context.set.warning, main->context.set.warning, f_string_eol_s[0]); - } - - // control group. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_cgroup_s, main->context.set.important); - - if (rule.has & controller_rule_has_cgroup_d) { - fl_print_format(" %s", main->output.to.stream, rule.cgroup.as_new ? controller_new_s : controller_existing_s); - - for (i = 0; i < rule.cgroup.groups.used; ++i) { - - if (rule.cgroup.groups.array[i].used) { - fl_print_format(" %Q", main->output.to.stream, rule.cgroup.groups.array[i]); - } - } // for - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // how. - fl_print_format(" %[%s%] %s%c", main->output.to.stream, main->context.set.important, controller_how_s, main->context.set.important, options & controller_process_option_asynchronous_d ? controller_asynchronous_s : controller_synchronous_s, f_string_eol_s[0]); - - // nice. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_nice_s, main->context.set.important); - - if (rule.has & controller_rule_has_nice_d) { - fl_print_format(" %i", main->output.to.stream, rule.nice); - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // scheduler. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_scheduler_s, main->context.set.important); - - if (rule.has & controller_rule_has_scheduler_d) { - f_string_t policy = ""; - - if (rule.scheduler.policy == SCHED_BATCH) { - policy = controller_batch_s; - } - else if (rule.scheduler.policy == SCHED_DEADLINE) { - policy = controller_deadline_s; - } - else if (rule.scheduler.policy == SCHED_FIFO) { - policy = controller_fifo_s; - } - else if (rule.scheduler.policy == SCHED_IDLE) { - policy = controller_idle_s; - } - else if (rule.scheduler.policy == SCHED_OTHER) { - policy = controller_other_s; - } - else if (rule.scheduler.policy == SCHED_RR) { - policy = controller_round_robin_s; - } - - fl_print_format(" %s %i", main->output.to.stream, policy, rule.scheduler.priority); - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // script. - fl_print_format(" %[%s%] %Q%c", main->output.to.stream, main->context.set.important, controller_script_s, main->context.set.important, rule.script, f_string_eol_s[0]); - - // user. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_user_s, main->context.set.important); - - if (rule.has & controller_rule_has_user_d) { - fl_print_format(" %i", main->output.to.stream, rule.user); - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // wait. - fl_print_format(" %[%s%] %s%c", main->output.to.stream, main->context.set.important, controller_wait_s, main->context.set.important, options & controller_process_option_wait_d ? controller_yes_s : controller_no_s, f_string_eol_s[0]); - - // affinity. - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_affinity_s, main->context.set.important, f_string_eol_s[0]); - - for (i = 0; i < rule.affinity.used; ++i) { - fl_print_format(" %i%c", main->output.to.stream, rule.affinity.array[i], f_string_eol_s[0]); - } // for - - // define. - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_define_s, main->context.set.important, f_string_eol_s[0]); - - for (i = 0; i < rule.define.used; ++i) { - - if (rule.define.array[i].name.used && rule.define.array[i].value.used) { - fl_print_format(" %Q %[=%] %Q%c", main->output.to.stream, rule.define.array[i].name, main->context.set.important, main->context.set.important, rule.define.array[i].value, f_string_eol_s[0]); - } - } // for - - // environment. - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_environment_s, main->context.set.important, f_string_eol_s[0]); - - for (i = 0; i < rule.environment.used; ++i) { - - if (rule.environment.array[i].used) { - fl_print_format(" %Q%c", main->output.to.stream, rule.environment.array[i], f_string_eol_s[0]); - } - } // for - - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_parameter_s, main->context.set.important, f_string_eol_s[0]); - - // parameter. - for (i = 0; i < rule.parameter.used; ++i) { - - if (rule.parameter.array[i].name.used && rule.parameter.array[i].value.used) { - fl_print_format(" %Q %[=%] %Q%c", main->output.to.stream, rule.parameter.array[i].name, main->context.set.important, main->context.set.important, rule.parameter.array[i].value, f_string_eol_s[0]); - } - } // for - - // group. - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_group_s, main->context.set.important, f_string_eol_s[0]); - - if (rule.has & controller_rule_has_group_d) { - fl_print_format(" %i%c", main->output.to.stream, rule.group, f_string_eol_s[0]); - - for (i = 0; i < rule.groups.used; ++i) { - fl_print_format(" %i%c", main->output.to.stream, rule.groups.array[i], f_string_eol_s[0]); - } // for - } - - // limit. - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_limit_s, main->context.set.important, f_string_eol_s[0]); - - for (i = 0; i < rule.limits.used; ++i) { - fl_print_format(" %Q %[=%] %un %un%c", main->output.to.stream, controller_rule_setting_limit_type_name(rule.limits.array[i].type), main->context.set.important, main->context.set.important, rule.limits.array[i].value.rlim_cur, rule.limits.array[i].value.rlim_max, f_string_eol_s[0]); - } // for - - // on. - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_on_s, main->context.set.important, f_string_eol_s[0]); - - for (i = 0; i < rule.ons.used; ++i) { - - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_action_s, main->context.set.important, f_string_eol_s[0]); - - { - f_string_t action = ""; - - if (rule.ons.array[i].action == controller_rule_action_type_freeze_e) { - action = controller_freeze_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_kill_e) { - action = controller_kill_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_pause_e) { - action = controller_pause_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_reload_e) { - action = controller_reload_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_restart_e) { - action = controller_restart_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_resume_e) { - action = controller_resume_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_start_e) { - action = controller_start_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_stop_e) { - action = controller_stop_s; - } - else if (rule.ons.array[i].action == controller_rule_action_type_thaw_e) { - action = controller_thaw_s; - } - - fl_print_format(" %[%s%] %s%c", main->output.to.stream, main->context.set.important, controller_type_s, main->context.set.important, action, f_string_eol_s[0]); - } - - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_need_s, main->context.set.important, f_string_eol_s[0]); - - for (j = 0; j < rule.ons.array[i].need.used; ++j) { - - if (rule.ons.array[i].need.array[j].used) { - fl_print_format(" %Q%c", main->output.to.stream, rule.ons.array[i].need.array[j], f_string_eol_s[0]); - } - } // for - - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_want_s, main->context.set.important, f_string_eol_s[0]); - - for (j = 0; j < rule.ons.array[i].want.used; ++j) { - - if (rule.ons.array[i].want.array[j].used) { - fl_print_format(" %Q%c", main->output.to.stream, rule.ons.array[i].want.array[j], f_string_eol_s[0]); - } - } // for - - fl_print_format(" }%c %[%s%] {%c", main->output.to.stream, f_string_eol_s[0], main->context.set.important, controller_wish_s, main->context.set.important, f_string_eol_s[0]); - - for (j = 0; j < rule.ons.array[i].wish.used; ++j) { - - if (rule.ons.array[i].wish.array[j].used) { - fl_print_format(" %Q%c", main->output.to.stream, rule.ons.array[i].wish.array[j], f_string_eol_s[0]); - } - } // for - - fl_print_format(" }%c }%c", main->output.to.stream, f_string_eol_s[0], f_string_eol_s[0]); - } // for - - fl_print_format(" }%c", main->output.to.stream, f_string_eol_s[0]); - - // items. - if (rule.items.used) { - controller_rule_action_t *action = 0; - controller_rule_item_t *item = 0; - controller_rule_rerun_item_t *rerun_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]; - - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_item_s, main->context.set.important, f_string_eol_s[0]); - - // type. - fl_print_format(" %[%s%] %Q%c", main->output.to.stream, main->context.set.important, controller_type_s, main->context.set.important, controller_rule_item_type_name(item->type), f_string_eol_s[0]); - - // pid_file. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_pid_file_s, main->context.set.important); - if (item->pid_file.used) { - fl_print_format(" %Q", main->output.to.stream, item->pid_file); - } - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // with. - fl_print_format(" %[%s%]", main->output.to.stream, main->context.set.important, controller_with_s, main->context.set.important); - if (item->with & controller_with_full_path_d) { - fl_print_format(" %s", main->output.to.stream, controller_full_path_s); - } - if (item->with & controller_with_session_new_d) { - fl_print_format(" %s", main->output.to.stream, controller_session_new_s); - } - if (item->with & controller_with_session_same_d) { - fl_print_format(" %s", main->output.to.stream, controller_session_same_s); - } - f_print_terminated(f_string_eol_s, main->output.to.stream); - - // actions. - for (j = 0; j < item->actions.used; ++j) { - - action = &item->actions.array[j]; - - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_action_s, main->context.set.important, f_string_eol_s[0]); - fl_print_format(" %[%s%] %q%c", main->output.to.stream, main->context.set.important, controller_type_s, main->context.set.important, controller_rule_action_type_name(action->type), f_string_eol_s[0]); - - if (item->type == controller_rule_item_type_script_e || item->type == controller_rule_item_type_utility_e) { - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_parameter_s, main->context.set.important, f_string_eol_s[0]); - - parameter = &action->parameters.array[0]; - - if (parameter->used) { - f_print_terminated(" ", main->output.to.stream); - - for (k = 0; k < parameter->used; ++k) { - - if (parameter->string[k] == f_fss_eol_s[0]) { - if (k + 1 < parameter->used) { - f_print_terminated(f_string_eol_s, main->output.to.stream); - f_print_terminated(" ", main->output.to.stream); - } - } - else { - // @fixme change this to handle UTF-8 characters (cannot use f_print_character_safely() as it is not UTF-8 safe as-is). - f_print_character_safely(parameter->string[k], main->output.to.stream); - } - } // for - - f_print_terminated(f_string_eol_s, main->output.to.stream); - } - - fl_print_format(" }%c", main->output.to.stream, f_string_eol_s[0]); - } - else { - for (k = 0; k < action->parameters.used; ++k) { - fl_print_format(" %[%s%] %Q%c", main->output.to.stream, main->context.set.important, controller_parameter_s, main->context.set.important, action->parameters.array[k], f_string_eol_s[0]); - } // for - } - - fl_print_format(" }%c", main->output.to.stream, f_string_eol_s[0]); - } // for - - // rerun. - fl_print_format(" %[%s%] {%c", main->output.to.stream, main->context.set.important, controller_rerun_s, main->context.set.important, f_string_eol_s[0]); - for (j = 0; j < controller_rule_action_type_execute__enum_size_e; ++j) { - - for (k = 0; k < 2; ++k) { - if (!k && (item->reruns[j].is & controller_rule_rerun_is_failure_d)) { - rerun_item = &item->reruns[j].failure; - } - else if (k && (item->reruns[j].is & controller_rule_rerun_is_success_d)) { - rerun_item = &item->reruns[j].success; - } - else { - rerun_item = 0; - continue; - } - - fl_print_format(" %[", main->output.to.stream, main->context.set.important); - switch (j) { - case controller_rule_action_type_execute_freeze_e: - f_print_terminated(controller_freeze_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_kill_e: - f_print_terminated(controller_kill_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_pause_e: - f_print_terminated(controller_pause_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_reload_e: - f_print_terminated(controller_reload_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_restart_e: - f_print_terminated(controller_restart_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_resume_e: - f_print_terminated(controller_resume_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_start_e: - f_print_terminated(controller_start_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_stop_e: - f_print_terminated(controller_stop_s, main->output.to.stream); - break; - - case controller_rule_action_type_execute_thaw_e: - f_print_terminated(controller_thaw_s, main->output.to.stream); - break; - - default: - break; - } - - fl_print_format("%] %s", main->output.to.stream, main->context.set.important, k ? controller_success_s : controller_failure_s); - fl_print_format(" %s %ul %s %ul", main->output.to.stream, controller_delay_s, rerun_item->delay, controller_max_s, rerun_item->max); - - if (!k && (item->reruns[j].is & controller_rule_rerun_is_failure_reset_d) || k && (item->reruns[j].is & controller_rule_rerun_is_success_reset_d)) { - fl_print_format(" %s", main->output.to.stream, controller_reset_s); - } - - f_print_terminated(f_string_eol_s, main->output.to.stream); - } // for - } // for - fl_print_format(" }%c", main->output.to.stream, f_string_eol_s[0]); - - fl_print_format(" }%c", main->output.to.stream, f_string_eol_s[0]); - } // for - } - - fl_print_format("}%c", main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(main->output.to, global.thread); - } -#endif // _di_controller_rule_validate_ - -#ifndef _di_controller_rule_wait_all_ - f_status_t controller_rule_wait_all(const controller_global_t global, const bool is_normal, const bool required, controller_process_t * const caller) { - - f_status_t status_lock = F_none; - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &global.thread->lock.process); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process); - } - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - return status_lock; - } - - if (!global.thread->processs.used) { - f_thread_unlock(&global.thread->lock.process); - - return F_data_not; - } - - f_status_t status = F_none; - - bool required_not_run = F_false; - bool skip = F_false; - - f_array_length_t i = 0; - f_array_length_t j = 0; - - // build a list of what to wait for so that anything new after this point will not be waited for. - const f_array_length_t process_total = global.thread->processs.used; - controller_process_t *process_list[process_total]; - - for (; i < process_total; ++i) { - process_list[i] = global.thread->processs.array[i]; - } // for - - f_thread_unlock(&global.thread->lock.process); - - for (i = 0; i < process_total; ++i) { - - if (caller) { - if (!controller_thread_is_enabled_process(caller, global.thread)) break; - } - else { - if (!controller_thread_is_enabled(is_normal, global.thread)) break; - } - - // re-establish global process read lock to wait for or protect from the cleanup thread while checking the read process. - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &global.thread->lock.process); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process); - } - - if (F_status_is_error(status_lock)) break; - - if (!process_list[i]) { - f_thread_unlock(&global.thread->lock.process); - - continue; - } - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &process_list[i]->active); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &process_list[i]->active); - } - - if (F_status_is_error(status_lock)) { - f_thread_unlock(&global.thread->lock.process); - - break; - } - - // once the active lock is obtained, then the main process read lock can be safely released. - f_thread_unlock(&global.thread->lock.process); - - if (caller) { - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &global.thread->lock.rule); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.rule); - } - - if (F_status_is_error(status_lock)) { - f_thread_unlock(&process_list[i]->active); - - break; - } - - if (fl_string_dynamic_compare(caller->rule.alias, process_list[i]->rule.alias) == F_equal_to) { - f_thread_unlock(&global.thread->lock.rule); - f_thread_unlock(&process_list[i]->active); - - continue; - } - - skip = F_false; - - for (j = 0; j < caller->stack.used; ++j) { - - if (caller) { - if (!controller_thread_is_enabled_process(caller, global.thread)) break; - } - else { - if (!controller_thread_is_enabled(is_normal, global.thread)) break; - } - - if (global.thread->processs.array[caller->stack.array[j]] && fl_string_dynamic_compare(process_list[i]->rule.alias, global.thread->processs.array[caller->stack.array[j]]->rule.alias) == F_equal_to) { - skip = F_true; - } - - if (skip) break; - } // for - - f_thread_unlock(&global.thread->lock.rule); - - if (skip) { - f_thread_unlock(&process_list[i]->active); - - continue; - } - } - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &process_list[i]->lock); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &process_list[i]->lock); - } - - if (F_status_is_error(status_lock)) { - f_thread_unlock(&process_list[i]->active); - - break; - } - - if (required) { - if (!(process_list[i]->options & controller_process_option_require_d)) { - f_thread_unlock(&process_list[i]->lock); - f_thread_unlock(&process_list[i]->active); - - continue; - } - } - - if (!process_list[i]->state || process_list[i]->state == controller_process_state_idle_e || process_list[i]->state == controller_process_state_done_e) { - - if (process_list[i]->state == controller_process_state_done_e) { - f_thread_unlock(&process_list[i]->lock); - - if (caller) { - status_lock = controller_lock_write_process(process_list[i], global.thread, &process_list[i]->lock); - } - else { - status_lock = controller_lock_write(is_normal, global.thread, &process_list[i]->lock); - } - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread); - - f_thread_unlock(&process_list[i]->active); - - return status_lock; - } - - if (process_list[i]->state == controller_process_state_done_e) { - f_thread_unlock(&process_list[i]->active); - - if (f_thread_lock_write_try(&process_list[i]->active) == F_none) { - - controller_thread_join(&process_list[i]->id_thread); - - process_list[i]->state = controller_process_state_idle_e; - - f_thread_unlock(&process_list[i]->active); - - f_thread_mutex_lock(&process_list[i]->wait_lock); - f_thread_condition_signal_all(&process_list[i]->wait); - f_thread_mutex_unlock(&process_list[i]->wait_lock); - } - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &process_list[i]->active); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &process_list[i]->active); - } - - if (F_status_is_error(status_lock)) { - f_thread_unlock(&process_list[i]->lock); - - break; - } - } - - f_thread_unlock(&process_list[i]->lock); - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &process_list[i]->lock); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &process_list[i]->lock); - } - - if (F_status_is_error(status_lock)) break; - } - - if (process_list[i]->options & controller_process_option_require_d) { - if (controller_rule_status_is_error(process_list[i]->action, process_list[i]->rule)) { - status = F_status_set_error(F_require); - - f_thread_unlock(&process_list[i]->lock); - f_thread_unlock(&process_list[i]->active); - - break; - } - else if (controller_rule_status_is_available(process_list[i]->action, process_list[i]->rule)) { - required_not_run = F_true; - } - } - - f_thread_unlock(&process_list[i]->lock); - f_thread_unlock(&process_list[i]->active); - - if (F_status_set_fine(status) == F_require) break; - - continue; - } - - if (!controller_rule_status_is_error(process_list[i]->action, process_list[i]->rule) && (process_list[i]->state == controller_process_state_active_e || process_list[i]->state == controller_process_state_busy_e)) { - f_thread_unlock(&process_list[i]->lock); - - status = controller_process_wait(global, process_list[i]); - - if (F_status_set_fine(status) == F_interrupt) { - f_thread_unlock(&process_list[i]->active); - - break; - } - - if (caller) { - status_lock = controller_lock_read_process(caller, global.thread, &process_list[i]->lock); - } - else { - status_lock = controller_lock_read(is_normal, global.thread, &process_list[i]->lock); - } - - if (F_status_is_error(status_lock)) { - f_thread_unlock(&process_list[i]->active); - - break; - } - - if ((process_list[i]->options & controller_process_option_require_d)) { - f_thread_unlock(&process_list[i]->lock); - - if (controller_rule_status_is_error(process_list[i]->action, process_list[i]->rule)) { - status = F_status_set_error(F_require); - - f_thread_unlock(&process_list[i]->active); - break; - } - } - else { - f_thread_unlock(&process_list[i]->lock); - } - } - else { - f_thread_unlock(&process_list[i]->lock); - } - - f_thread_unlock(&process_list[i]->active); - - if (F_status_set_fine(status) == F_interrupt || F_status_set_fine(status) == F_require) break; - } // for - - if (F_status_is_error(status_lock)) { - controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread); - - return status_lock; - } - - if (caller) { - if (!controller_thread_is_enabled_process(caller, global.thread)) { - return F_status_set_error(F_interrupt); - } - } - else { - if (!controller_thread_is_enabled(is_normal, global.thread)) { - return F_status_set_error(F_interrupt); - } - } - - if (F_status_set_fine(status) == F_require) { - return status; - } - - if (required_not_run) { - return F_require; - } - - return F_none; - } -#endif // _di_controller_rule_wait_all_ - -#ifndef _di_controller_rule_wait_all_process_type_ - f_status_t controller_rule_wait_all_process_type(const controller_global_t global, const uint8_t type, const bool required, controller_process_t * const caller) { - - return controller_rule_wait_all(global, type != controller_process_type_exit_e, required, caller); - } -#endif // _di_controller_rule_wait_all_process_type_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-rule.h b/level_3/controller/c/private-rule.h deleted file mode 100644 index a5f19a9..0000000 --- a/level_3/controller/c/private-rule.h +++ /dev/null @@ -1,794 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_rule_h -#define _PRIVATE_rule_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Get a string representing the rule action method. - * - * @param type - * The rule action type code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_rule_action_method_name_ - extern f_string_static_t controller_rule_action_method_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_method_name_ - -/** - * Find the location of the Rule by the Rule alias. - * - * @param alias - * The Rule alias to find. - * @param rules - * The rules to search through. - * @param at - * The index the rule was found at. - * (optional) Set to NULL to disable. - * - * @return - * F_none on success, but the id.used is 0. - * F_true on success and rule was found, index is updated. - * F_false on success and rule was not found. - */ -#ifndef _di_controller_rule_find_ - extern f_status_t controller_rule_find(const f_string_static_t alias, const controller_rules_t rules, f_array_length_t *at) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_find_ - -/** - * Read the parameters for some rule action. - * - * The object and content ranges are merged together (in that order) as the action parameters. - * - * @param global - * The global data. - * @param buffer - * The buffer containing the content. - * @param object - * (optional) The range representing where the object is found within the buffer. - * Set pointer address to 0 to disable. - * @param content - * (optional) The ranges representing where the content is found within the buffer. - * Set pointer address to 0 to disable. - * @param parameters - * The processed parameters. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_fss_count_lines(). - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: f_string_dynamics_increase(). - * - * @see f_fss_count_lines() - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamics_increase() - */ -#ifndef _di_controller_rule_parameters_read_ - extern f_status_t controller_rule_parameters_read(const controller_global_t global, const f_string_static_t buffer, f_fss_object_t *object, f_fss_content_t *content, f_string_dynamics_t *parameters) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_parameters_read_ - -/** - * Convert the action type to an action execute type. - * - * @param type - * The action type to convert from. - * - * @return - * The converted action type, converted into an action execute type. - * - * The code controller_rule_action_type_execute__enum_size_e is returned for unknown types. - * - */ -#ifndef _di_controller_rule_action_type_to_action_execute_type_ - extern uint8_t controller_rule_action_type_to_action_execute_type(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_type_to_action_execute_type_ - -/** - * Get a string representing the rule action type. - * - * @param type - * The rule action type code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_rule_action_type_name_ - extern f_string_static_t controller_rule_action_type_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_type_name_ - -/** - * Get a string representing the rule action execute type. - * - * @param type - * The rule action type execute code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_rule_action_type_execute_name_ - extern f_string_static_t controller_rule_action_type_execute_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_type_execute_name_ - -/** - * 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 global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @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 - * The processed item. - * @param actions - * The processed actions. - * @param range - * The current positions within the buffer being operated on. - * This is expected to be set to a position immediately after a valid object read. - * - * @return - * F_none on success. - * - * 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_actions_increase_by() - * @see controller_rule_parameters_read() - * @see f_fss_count_lines() - */ -#ifndef _di_controller_rule_action_read_ - extern f_status_t controller_rule_action_read(const controller_global_t global, const bool is_normal, const uint8_t type, const uint8_t method, controller_cache_t * const cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_read_ - -/** - * Copy a rule, allocating new space as necessary. - * - * This does not do any locking or unlocking for the rule data, be sure to lock appropriately before and after calling this. - * - * @param source - * The source rule to copy from. - * @param destination - * The destination rule to copy to. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_capability_copy(). - * Errors (with error bit) from: f_control_group_copy(). - * Errors (with error bit) from: f_limit_sets_copy(). - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_string_dynamics_append(). - * Errors (with error bit) from: f_string_maps_append(). - * Errors (with error bit) from: f_type_int32s_append(). - * - * @see f_capability_copy() - * @see f_control_group_copy() - * @see f_limit_sets_append() - * @see f_string_dynamic_append() - * @see f_string_dynamics_append() - * @see f_string_maps_append() - * @see f_type_int32s_append() - */ -#ifndef _di_controller_rule_copy_ - extern f_status_t controller_rule_copy(const controller_rule_t source, controller_rule_t *destination) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_copy_ - -/** - * Perform an execution of the given rule. - * - * This requires that a read lock be set on process->lock before being called. - * - * @param global - * The global data. - * @param action - * The action to perform based on the action type codes. - * - * Only subset of the action type codes are supported: - * - controller_rule_action_type_kill_e - * - controller_rule_action_type_pause_e - * - controller_rule_action_type_reload_e - * - controller_rule_action_type_restart_e - * - controller_rule_action_type_resume_e - * - controller_rule_action_type_start_e - * - controller_rule_action_type_stop_e - * @param options - * Process options to consider when executing. - * If bit controller_process_option_simulate_d, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). - * @param process - * The process data for processing this rule. - * - * @return - * F_none on success. - * F_child on child process exiting. - * F_ignore if the rule is unknown and nothing can be done. - * - * F_failure (with error bit) if failed to execute. - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_lock (with error bit) if failed to re-establish read lock on process->lock while returning. - * - * On success and the rule is run synchronously, then the individual status for the rule is set to F_complete. - * On success and the rule is run asynchronously, then the individual status for the rule is set to F_busy. - * On failure, the individual status for the rule is set to an appropriate error status. - */ -#ifndef _di_controller_rule_execute_ - extern f_status_t controller_rule_execute(const controller_global_t global, const uint8_t action, const uint8_t options, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_execute_ - -/** - * Perform an execution of the given rule in the foreground. - * - * This requires that a read lock be set on process->lock before being called. - * - * @param type - * The item type code. - * @param program - * The program to use (such as "bash"). - * @param arguments - * The arguments to pass to the program. - * @param options - * Process options to consider when executing. - * If bit controller_process_option_simulate_d, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). - * @param execute_set - * The execute parameter and as settings. - * @param process - * The process data for processing this rule. - * - * @return - * F_none on success. - * F_child on child process exiting. - * - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_lock (with error bit) if failed to re-establish read lock on process->lock while returning. - * - * Errors (with error bit) from: fll_execute_program(). - * - * @see fll_execute_program() - */ -#ifndef _di_controller_rule_execute_foreground_ - extern f_status_t controller_rule_execute_foreground(const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, controller_execute_set_t * const execute_set, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_execute_foreground_ - -/** - * Perform an execution of the given rule in the foreground or background and creating a PID file. - * - * This requires that a read lock be set on process->lock before being called. - * - * When this is synchronous, this will wait for the PID file to be generated before continuing. - * When this is asynchronous, this will continue on adding the rule id and action to the asynchronous list. - * - * @param pid_file - * The path to the PID file. - * @param type - * The item type code. - * @param program - * The program to use (such as "bash"). - * @param arguments - * The arguments to pass to the program. - * @param options - * Process options to consider when executing. - * If bit controller_process_option_simulate_d, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). - * @param with - * The "with" option flags. - * @param execute_set - * The execute parameter and as settings. - * @param process - * The process data for processing this rule. - * - * @return - * F_none on success. - * F_child on child process exiting. - * - * F_file_found (with error bit) if the PID file already exists. - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_lock (with error bit) if failed to re-establish read lock on process->lock while returning. - * - * Errors (with error bit) from: fll_execute_program(). - * - * @see fll_execute_program() - */ -#ifndef _di_controller_rule_execute_pid_with_ - extern f_status_t controller_rule_execute_pid_with(const f_string_dynamic_t pid_file, const uint8_t type, const f_string_t program, const f_string_statics_t arguments, const uint8_t options, const uint8_t with, controller_execute_set_t * const execute_set, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_execute_pid_with_ - -/** - * Determine whether or not an execute rule should be re-run, applying a delay as requested. - * - * @param action - * The action type. - * @param process - * The process data for processing this rule. - * @param item - * The rule item being executed. - * - * @return - * A positive number to designate re-run. - * 0 to designate do not re-run. - * -1 to designate an error from nanosleep(), with errno set to values like: - * - EFAULT: Designates that there was a problem copying information from user space. - * - EINTR: Consider this having returned F_interrupt. - * - EINVAL: Consider this having returned F_status_set_error(F_parameter); - * -2 to designate exit due to signal/disabled thread. - */ -#ifndef _di_controller_rule_execute_rerun_ - extern int8_t controller_rule_execute_rerun(const uint8_t action, controller_process_t * const process, controller_rule_item_t * const item) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_execute_rerun_ - -/** - * Construct an id from two distinct strings found within a single given source. - * - * @param global - * The global 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 alias - * The constructed alias. - * - * @return - * F_none on success. - * - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see f_string_append() - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_rule_id_construct_ - extern f_status_t controller_rule_id_construct(const controller_global_t global, const f_string_static_t source, const f_string_range_t directory, const f_string_range_t basename, f_string_dynamic_t * const alias) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_id_construct_ - -/** - * Check to see if the given Rule has status F_known_not for the given Rule Action. - * - * The global Rule status is checked for error and any errors on the global Rule status will result in F_false. - * - * @param action - * The Rule Action type. - * @param rule - * The Rule. - * - * @return - * F_true on available (status is F_known_not). - * F_false on unavailable. - */ -#ifndef _di_controller_rule_status_is_available_ - extern f_status_t controller_rule_status_is_available(const uint8_t action, const controller_rule_t rule) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_status_is_available_ - -/** - * Check to see if the given Rule has status is designated as an error for the given Rule Action. - * - * The global Rule status is checked for error and any errors on the global Rule status will result in F_true. - * - * @param action - * The Rule Action type. - * @param rule - * The Rule. - * - * @return - * F_true if status represents an error. - * F_false if status does not represent an error. - */ -#ifndef _di_controller_rule_status_is_error_ - extern f_status_t controller_rule_status_is_error(const uint8_t action, const controller_rule_t rule) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_status_is_error_ - -/** - * 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. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param cache - * A structure for containing and caching relevant data. - * @param item - * The processed item. - * - * @return - * F_none on success. - * F_valid_not (with error bit) on invalid data. - * - * Errors (with error bit) from: f_fss_count_lines(). - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: f_string_dynamic_terminate_after(). - * - * @see controller_rule_action_read() - * @see f_fss_count_lines() - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamic_terminate_after() - */ -#ifndef _di_controller_rule_item_read_ - extern f_status_t controller_rule_item_read(const controller_global_t global, const bool is_normal, controller_cache_t * const cache, controller_rule_item_t * const item) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_read_ - -/** - * Get a string representing the rule item type. - * - * @param type - * The rule item type code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_rule_item_type_name_ - extern f_string_static_t controller_rule_item_type_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_type_name_ - -/** - * Increase the size of the rule items array by the specified amount, but only if necessary. - * - * This only increases size if the current used plus amount is greater than the currently allocated size. - * - * @param amount - * A positive number representing how much to increase the size by. - * @param items - * The items to resize. - * - * @return - * F_none on success. - * F_array_too_large (with error bit) if the resulting new size is bigger than the max array length. - * - * Errors (with error bit) from: f_memory_resize(). - * - * @see f_memory_resize() - */ -#ifndef _di_controller_rule_items_increase_by_ - extern f_status_t controller_rule_items_increase_by(const f_array_length_t amount, controller_rule_items_t * const items) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_items_increase_by_ - -/** - * Get a string representing the rule setting limit type. - * - * @param type - * The rule setting limit type code. - * - * @return - * The string with used > 0 on success. - * The string with used == 0 if no match was found. - */ -#ifndef _di_controller_rule_setting_limit_type_name_ - extern f_string_static_t controller_rule_setting_limit_type_name(const uint8_t type) F_attribute_visibility_internal_d; -#endif // di_controller_rule_setting_limit_type_name_ - -/** - * Process and execute the given rule. - * - * Any dependent rules are processed and executed as per "need", "want", and "wish" rule settings. - * All dependent rules must be already loaded, this function will not load any rules. - * - * This requires that a read lock be set on process->lock before being called. - * - * This function is recursively called for each "need", "want", and "wish", and has a max recursion length of the max size of the f_array_lengths_t array. - * - * The rule status will be updated by this function. - * - * @param global - * The global data. - * @param process - * The process data for processing this rule. - * - * @return - * F_none on success. - * F_child on child process exiting. - * F_failure on execution failure. - * - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_lock (with error bit) if failed to re-establish read lock on process->lock while returning. - * - * Errors (with error bit) from: controller_lock_read(). - * Errors (with error bit) from: controller_lock_write(). - */ -#ifndef _di_controller_rule_process_ - extern f_status_t controller_rule_process(const controller_global_t global, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_process_ - -/** - * Synchronously or asynchronously begin processing some rule. - * - * @param global - * The global data. - * @param options_force - * Force the given process options, only supporting a subset of process options. - * - * If controller_process_option_asynchronous_d, then asynchronously execute. - * If not controller_process_option_asynchronous_d, then synchronously execute. - * @param alias_rule - * The alias of the rule, such as "boot/init". - * @param action - * The action to perform based on the action type codes. - * @param options - * The process options to pass to the process. - * @param type - * The process type, such as controller_process_type_entry_e. - * @param stack - * A stack representing the processes already running in this rule process dependency tree. - * This is used to prevent circular dependencies. - * @param cache - * A structure for containing and caching relevant data. - * - * @return - * F_none on success. - * F_busy on success and the process was found to already be running (nothing to do). - * - * F_found_not (with error bit) if unable to for a process for the given rule id. - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_recurse (with error bit) on recursion error (the process is already on the process stack). - * - * Status from: controller_rule_process(). - * - * Errors (with error bit) from: controller_rule_process(). - * Errors (with error bit) from: f_string_dynamic_append(). - * Errors (with error bit) from: f_thread_create(). - * - * @see controller_rule_process() - * @see f_string_dynamic_append() - * @see f_thread_create() - */ -#ifndef _di_controller_rule_process_begin_ - extern f_status_t controller_rule_process_begin(const controller_global_t global, const uint8_t options_force, const f_string_static_t alias_rule, const uint8_t action, const uint8_t options, const uint8_t type, const f_array_lengths_t stack, const controller_cache_t cache) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_process_begin_ - -/** - * Helper for calling controller_rule_process(). - * - * This does all the preparation work that needs to be synchronously performed within the same thread. - * This will copy the rule by the alias to the process structure. - * - * @param options_force - * Force the given process options, only supporting a subset of process options. - * - * If controller_process_option_asynchronous_d, then asynchronously execute. - * If not controller_process_option_asynchronous_d, then synchronously execute. - * @param process - * The process data. - * - * @return - * F_none on success. - * F_found on the process was found to already be running (nothing to do). - * F_process_not if the process was not executed because it is a "consider" Action. - * - * F_found_not (with error bit) if unable to for a process for the given rule id. - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * - * Status from: controller_rule_process(). - * - * Errors (with error bit) from: controller_rule_copy(). - * Errors (with error bit) from: controller_rule_process(). - * - * @see controller_rule_copy() - * @see controller_rule_process() - * @see controller_rule_process_begin() - */ -#ifndef _di_controller_rule_process_do_ - extern f_status_t controller_rule_process_do(const uint8_t options_force, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_process_do_ - -/** - * Read the rule file, extracting all valid items. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param alias - * The string identifying the rule. - * This is constructed from the path parts to the file without the file extension and without the settings directory prefix. - * "/etc/controller/rules/example/my.rule" would have a rule id of "example/my". - * @param cache - * A structure for containing and caching relevant data. - * @param entry - * The entry containing the rule being read. - * @param rule - * The processed rule. - * The rule status will be updated by this function. - * - * @return - * F_none on success. - * - * Simplified status (with error bit) from controller_status_simplify_error() on failure. - * - * @see controller_rule_items_increase_by(). - * @see controller_rule_item_read(). - * @see f_fss_count_lines(). - * @see fl_fss_apply_delimit(). - * @see f_string_dynamic_partial_append(). - * @see f_string_dynamic_partial_append_nulless(). - * @see f_string_dynamic_terminate_after(). - * @see fll_fss_basic_list_read(). - */ -#ifndef _di_controller_rule_read_ - extern f_status_t controller_rule_read(const controller_global_t global, const bool is_normal, const f_string_static_t alias, controller_cache_t * const cache, controller_entry_t * const entry, controller_rule_t * const rule) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_read_ - -/** - * Process a number from a rule file, incrementing index as necessary. - * - * This prints error messages as necessary. - * - * This is intended to be called by controller_rule_action_read(). - * - * @param global - * The global data. - * @param name - * The name representing the value whose number is being processed. - * @param cache - * A structure for containing and caching relevant data. - * @param index - * The position within the content action array for some rule to process. - * @param number - * The processed number will be saved here. - * - * @return - * F_none on success. - * - * F_valid_not (with error bit) on failure due to invalid value. - * - * Errors (with error bit) from: fl_conversion_string_to_number_signed(). - * - * @see controller_rule_action_read() - * @see fl_conversion_string_to_number_signed() - */ -#ifndef _di_controller_rule_action_read_rerun_number_ - extern f_status_t controller_rule_action_read_rerun_number(const controller_global_t global, const f_string_t name, controller_cache_t * const cache, f_array_length_t * const index, f_number_unsigned_t * const number) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_read_rerun_number_ - -/** - * Read the content within the buffer, extracting all valid settings. - * - * This will perform additional FSS read functions as appropriate. - * - * Errors from this are not considered fatal, but the first error code encountered is returned. - * Memory failure errors are always immediately returned. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param setting - * The controller settings data. - * @param cache - * A structure for containing and caching relevant data. - * @param rule - * The processed rule. - * - * @return - * F_none on success. - * - * F_valid_not (with error bit) on success but there were one or more invalid settings encountered. - * - * Errors (with error bit) from: f_string_dynamic_partial_append_nulless(). - * Errors (with error bit) from: fl_string_dynamic_rip_nulless(). - * Errors (with error bit) from: f_string_dynamics_increase(). - * Errors (with error bit) from: f_string_maps_increase(). - * Errors (with error bit) from: fll_fss_extended_read(). - * Errors (with error bit) from: fll_path_canonical(). - * - * @see f_string_dynamic_partial_append_nulless() - * @see f_string_dynamics_increase() - * @see f_string_maps_increase() - * @see fl_string_dynamic_rip_nulless() - * @see fll_fss_extended_read() - * @see fll_path_canonical() - */ -#ifndef _di_controller_rule_setting_read_ - extern f_status_t controller_rule_setting_read(const controller_global_t global, const bool is_normal, const controller_setting_t setting, controller_cache_t * const cache, controller_rule_t * const rule) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_setting_read_ - -/** - * Perform a simulated execution of the given rule. - * - * This simply prints information about the rule. - * - * This automatically sets the rule's status to F_complete. - * - * @param global - * The global data. - * @param rule - * The rule to process. - * @param action - * The action to perform based on the action type codes. - * @param options - * A number using bits to represent specific boolean options. - * If no bits set, then operate normally in a synchronous manner. - * If bit controller_process_option_simulate_d, then the rule execution is in simulation mode (printing a message that the rule would be executed but does not execute the rule). - * If bit controller_process_option_asynchronous_d, then run asynchronously. - * @param cache - * A structure for containing and caching relevant data. - */ -#ifndef _di_controller_rule_validate_ - extern void controller_rule_validate(const controller_global_t global, const controller_rule_t rule, const uint8_t action, const uint8_t options, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_validate_ - -/** - * Wait until all currently running Rule processes are complete. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * This is ignored when caller is not NULL. - * @param required - * If TRUE, then only process required rules and if a required rule has failed, return. - * If FALSE, process all waits, returning normally (required rules still result in failure). - * @param caller - * The process representing the caller so that the process never waits on itself. - * (optional) set to 0 when calling from a thread that is not running/executing any process. - * Failure to set this to the process on a thread running/executing a process will likely result in a deadlock. - * - * @return - * F_none on success. - * F_data_not on success and nothing to do. - * F_require on success, but a required rule has not been run yet. - * - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - * F_require (with error bit set) if a required process is in failed status when required is TRUE. - */ -#ifndef _di_controller_rule_wait_all_ - extern f_status_t controller_rule_wait_all(const controller_global_t global, const bool is_normal, const bool required, controller_process_t * const caller) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_wait_all_ - -/** - * Wait until all currently running Rule processes are complete for some process type. - * - * @param global - * The global data. - * @param type - * The process type to use when checking if thread is enabled. - * @param required - * If TRUE, then only process required rules and if a required rule has failed, return. - * If FALSE, process all waits, returning normally. - * @param caller - * The process representing the caller so that the process never waits on itself. - * (optional) set to 0 when calling from a thread that is not running/executing any process. - * Failure to set this to the process on a thread running/executing a process will likely result in a deadlock. - * - * @return - * Success from controller_rule_wait_all(). - * - * Errors (with error bit) from: controller_rule_wait_all(). - * - * @see controller_rule_wait_all() - */ -#ifndef _di_controller_rule_wait_all_process_type_ - extern f_status_t controller_rule_wait_all_process_type(const controller_global_t global, const uint8_t type, const bool required, controller_process_t * const caller) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_wait_all_process_type_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_rule_h diff --git a/level_3/controller/c/private-rule_print.c b/level_3/controller/c/private-rule_print.c deleted file mode 100644 index 5d491ef..0000000 --- a/level_3/controller/c/private-rule_print.c +++ /dev/null @@ -1,363 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-rule_print.h" -#include "private-lock_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_rule_print_error_ - void controller_rule_print_error(controller_thread_t * const thread, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, const bool item) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - f_thread_mutex_lock(&thread->lock.print); - - fll_error_print(print, status, function, fallback); - - flockfile(print.to.stream); - - controller_rule_print_error_cache(print, cache, item); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_rule_print_error_ - -#ifndef _di_controller_rule_print_error_cache_ - void controller_rule_print_error_cache(const fl_print_t print, const controller_cache_action_t cache, const bool item) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - fl_print_format("%c%[%SWhile processing ", print.to.stream, f_string_eol_s[0], print.context, print.prefix); - - if (cache.name_action.used) { - fl_print_format("%s '%]", print.to.stream, item ? controller_action_s : controller_value_s, print.context); - fl_print_format("%[%Q%]", print.to.stream, print.notable, cache.name_action, print.notable); - fl_print_format("%[' on line%] ", print.to.stream, print.context, print.context); - fl_print_format("%[%un%]", print.to.stream, print.notable, cache.line_action, print.notable); - fl_print_format("%[ for ", print.to.stream, print.context); - } - - if (cache.name_item.used) { - fl_print_format("rule %s '%]", print.to.stream, item ? controller_item_s : controller_setting_s, print.context); - fl_print_format("%[%Q%]", print.to.stream, print.notable, cache.name_item, print.notable); - fl_print_format("%[' on line%] ", print.to.stream, print.context, print.context); - fl_print_format("%[%un%]", print.to.stream, print.notable, cache.line_item, print.notable); - fl_print_format("%[ for ", print.to.stream, print.context); - } - - if (cache.name_file.used) { - fl_print_format("rule file '%]%[%Q%]%['", print.to.stream, print.context, print.notable, cache.name_file, print.notable, print.context); - } - - fl_print_format(".%]%c", print.to.stream, print.context, f_string_eol_s[0]); - } -#endif // _di_controller_rule_print_error_cache_ - -#ifndef _di_controller_rule_item_print_error_ - void controller_rule_item_print_error(controller_thread_t * const thread, const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - if (status == F_interrupt) return; - - // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_lock_print(). - f_thread_mutex_lock(&thread->lock.print); - - controller_rule_print_error_cache(print, cache, item); - - flockfile(print.to.stream); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_rule_item_print_error_ - -#ifndef _di_controller_rule_item_print_error_execute_ - void controller_rule_item_print_error_execute(const bool script_is, const f_string_t name, const f_status_t status, controller_process_t * const process) { - - if (((controller_main_t *) process->main_data)->error.verbosity != f_console_verbosity_quiet_e) { - fl_print_t * const print = &((controller_main_t *) process->main_data)->error; - - controller_lock_print(print->to, (controller_thread_t *) process->main_thread); - - fl_print_format("%c%[%SThe %s '%]", print->to.stream, f_string_eol_s[0], print->context, print->prefix, script_is ? controller_script_s : controller_program_s, print->context); - fl_print_format("%[%S%]", print->to.stream, print->notable, name, print->notable); - - if (status == F_control_group || status == F_limit || status == F_processor || status == F_schedule) { - fl_print_format("%[' failed due to a failure to setup the '%]%[", print->to.stream, print->context, print->context, print->notable); - - if (status == F_control_group) { - f_print_terminated(controller_cgroup_s, print->to.stream); - } - else if (status == F_limit) { - f_print_terminated(controller_limit_s, print->to.stream); - } - else if (status == F_processor) { - f_print_terminated(controller_processor_s, print->to.stream); - } - else if (status == F_schedule) { - f_print_terminated(controller_scheduler_s, print->to.stream); - } - - fl_print_format("%]%['.%]%c", print->to.stream, print->notable, print->context, print->context, f_string_eol_s[0]); - } - else if (WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0) { - const uint8_t code = WIFEXITED(process->result) ? WEXITSTATUS(process->result) : 0; - - if (code == F_execute_access) { - fl_print_format("%[' access denied.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_bad) { - fl_print_format("%[' cannot execute, unsupported format.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_buffer) { - fl_print_format("%[' invalid memory access in arguments buffer.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_busy) { - fl_print_format("%[' required resources are unavailable, too busy.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_capability) { - fl_print_format("%[' failed to setup capabilities.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_control_group) { - fl_print_format("%[' failed to setup control group.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_child) { - fl_print_format("%[' failed to setup child process.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_directory_not) { - fl_print_format("%[' invalid path, part of the path is not a valid directory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_failure) { - fl_print_format("%[' failed during execution.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_file_found_not) { - fl_print_format("%[' could not be executed, unable to find file.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_file_type_directory) { - fl_print_format("%[' ELF interpreter is a directory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_fork_not) { - fl_print_format("%[' fork failure.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_format_not) { - fl_print_format("%[' could not be executed because the program has an invalid ELF header.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_group) { - fl_print_format("%[' failed to setup group.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_input_output) { - fl_print_format("%[' I/O failure.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_limit) { - fl_print_format("%[' failed to setup resource limits.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_loop) { - fl_print_format("%[' max recursion reached.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_memory_not) { - fl_print_format("%[' out of memory.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_name_not) { - fl_print_format("%[' file name or path is too long.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_nice) { - fl_print_format("%[' failed to setup niceness.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_parameter) { - fl_print_format("%[' invalid parameter.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_pipe) { - fl_print_format("%[' pipe failed.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_processor) { - fl_print_format("%[' failed to setup processor affinity.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_prohibited) { - fl_print_format("%[' access prohibited.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_resource_not) { - fl_print_format("%[' resource limit reached.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_schedule) { - fl_print_format("%[' failed to setup scheduler.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_terminal) { - fl_print_format("%[' failed while processing the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_terminal_known_not) { - fl_print_format("%[' cannot process terminal, unknown terminal control command.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_terminal_not) { - fl_print_format("%[' cannot process terminal, not a known terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_terminal_prohibited) { - fl_print_format("%[' insufficient permissions to process the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_terminal_valid_not) { - fl_print_format("%[' invalid parameter while processing the terminal.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_too_large) { - fl_print_format("%[' too many arguments or arguments are too large.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_user) { - fl_print_format("%[' failed to setup user.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else if (code == F_execute_valid_not) { - fl_print_format("%[' unknown ELF interpreter format.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - else { - fl_print_format("%[' failed with the execute error code %]", print->to.stream, print->context, print->context); - fl_print_format("%[%i%]", print->to.stream, print->notable, code, print->notable); - fl_print_format("%[.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - } - else { - fl_print_format("%[' failed.%]%c", print->to.stream, print->context, print->context, f_string_eol_s[0]); - } - - controller_unlock_print_flush(print->to, (controller_thread_t *) process->main_thread); - } - } -#endif // _di_controller_rule_item_print_error_execute_ - -#ifndef _di_controller_rule_action_print_error_missing_pid_ - void controller_rule_action_print_error_missing_pid(const fl_print_t print, const f_string_t alias) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - fl_print_format("%c%[%SThe rule '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, print.context); - fl_print_format("%[%S%]", print.to.stream, print.notable, alias, print.notable); - fl_print_format("%[' is not designating a pid file.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); - } -#endif // _di_controller_rule_action_print_error_missing_pid_ - -#ifndef _di_controller_rule_item_print_error_need_want_wish_ - void controller_rule_item_print_error_need_want_wish(const fl_print_t print, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - fl_print_format("%c%[%SThe %s rule '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, need_want_wish, print.context); - fl_print_format("%[%S%]", print.to.stream, print.notable, value, print.notable); - fl_print_format("%[' %S.%]%c", print.to.stream, print.context, why, print.context, f_string_eol_s[0]); - } -#endif // _di_controller_rule_item_print_error_need_want_wish_ - -#ifndef _di_controller_rule_item_print_error_rule_not_loaded_ - void controller_rule_item_print_error_rule_not_loaded(const fl_print_t print, const f_string_t alias) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - fl_print_format("%c%[%SThe rule '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, print.context); - fl_print_format("%[%S%]", print.to.stream, print.notable, alias, print.notable); - fl_print_format("%[' is no longer loaded.%]%c", print.to.stream, print.context, print.context, f_string_eol_s[0]); - } -#endif // _di_controller_rule_item_print_error_rule_not_loaded_ - -#ifndef _di_controller_rule_setting_read_print_error_ - void controller_rule_setting_read_print_error(const fl_print_t print, const f_string_t message, const f_array_length_t index, const f_array_length_t line_item, controller_thread_t * const thread, controller_cache_t * const cache) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[index].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(print.to, thread); - - fl_print_format("%c%[%SRule setting %S.%]%c", print.to.stream, f_string_eol_s[0], print.context, print.prefix, message, print.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(print, cache->action, F_false); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_rule_setting_read_print_error_ - -#ifndef _di_controller_rule_setting_read_print_error_with_range_ - void controller_rule_setting_read_print_error_with_range(const fl_print_t print, const f_string_t before, const f_string_range_t range, const f_string_t after, const f_array_length_t index, const f_array_length_t line_item, controller_thread_t * const thread, controller_cache_t * const cache) { - - if (print.verbosity == f_console_verbosity_quiet_e) return; - - // Get the current line number within the settings item. - cache->action.line_item = line_item; - f_fss_count_lines(cache->buffer_item, cache->object_actions.array[index].start, &cache->action.line_item); - - cache->action.line_action = ++cache->action.line_item; - - controller_lock_print(print.to, thread); - - fl_print_format("%c%[%SRule setting%S '%]", print.to.stream, f_string_eol_s[0], print.context, print.prefix, before, print.context); - fl_print_format("%[%/Q%]", print.to.stream, print.notable, cache->buffer_item, range, print.notable); - fl_print_format("%['%S.%]%c", print.to.stream, print.context, after, print.context, f_string_eol_s[0]); - - controller_rule_print_error_cache(print, cache->action, F_false); - - controller_unlock_print_flush(print.to, thread); - } -#endif // _di_controller_rule_setting_read_print_error_with_range_ - -#ifndef _di_controller_rule_setting_read_print_value_ - void controller_rule_setting_read_print_value(const controller_global_t global, const f_string_t name, const f_string_t name_sub, const f_string_static_t value, const f_string_t suffix) { - - if (global.main->error.verbosity != f_console_verbosity_debug_e && !(global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - return; - } - - controller_lock_print(global.main->output.to, global.thread); - - fl_print_format("%cProcessing rule item action '%[%S%]' setting ", global.main->output.to.stream, f_string_eol_s[0], global.main->context.set.title, name, global.main->context.set.title); - - if (name_sub) { - fl_print_format("'%[%S%]'", global.main->output.to.stream, global.main->context.set.notable, name_sub, global.main->context.set.notable); - } - else { - f_print_terminated("value", global.main->output.to.stream); - } - - fl_print_format(" to '%[%Q%]'", global.main->output.to.stream, global.main->context.set.important, value, global.main->context.set.important); - fl_print_format("%S.%c", global.main->output.to.stream, suffix, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->output.to, global.thread); - } -#endif // _di_controller_rule_setting_read_print_value_ - -#ifndef _di_controller_rule_setting_read_print_values_ - void controller_rule_setting_read_print_values(const controller_global_t global, const f_string_t name, const f_array_length_t index, controller_cache_t * const cache) { - - if (global.main->error.verbosity != f_console_verbosity_debug_e && !(global.main->error.verbosity == f_console_verbosity_verbose_e && global.main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e)) { - return; - } - - controller_lock_print(global.main->output.to, global.thread); - - fl_print_format("%cProcessing rule item action '%[%S%]' setting value to", global.main->output.to.stream, f_string_eol_s[0], global.main->context.set.title, name, global.main->context.set.title); - - for (f_array_length_t j = 0; j < cache->content_actions.array[index].used; ++j) { - - fl_print_format(" '%[%/Q%]'", global.main->output.to.stream, global.main->context.set.important, cache->buffer_item, cache->content_actions.array[index].array[j], global.main->context.set.important); - - if (j + 2 == cache->content_actions.array[index].used) { - if (cache->content_actions.array[index].used > 2) { - f_print_terminated(",", global.main->output.to.stream); - } - - f_print_terminated(" and", global.main->output.to.stream); - } - else if (j + 1 < cache->content_actions.array[index].used) { - f_print_terminated(",", global.main->output.to.stream); - } - } // for - - fl_print_format(".%c", global.main->output.to.stream, f_string_eol_s[0]); - - controller_unlock_print_flush(global.main->output.to, global.thread); - } -#endif // _di_controller_rule_setting_read_print_value_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-rule_print.h b/level_3/controller/c/private-rule_print.h deleted file mode 100644 index 144642a..0000000 --- a/level_3/controller/c/private-rule_print.h +++ /dev/null @@ -1,248 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_rule_print_h -#define _PRIVATE_rule_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Print generic error/warning information. - * - * This is essentially a wrapper to fll_error_print() that includes locking. - * - * @param thread - * The thread data. - * @param print - * Designates how printing is to be performed. - * @param cache - * The action cache. - * @param status - * The status code to process. - * Make sure this has F_status_set_fine() called if the status code has any error or warning bits. - * @param function - * The name of the function where the error happened. - * Set to 0 to disable. - * @param fallback - * Set to F_true to print the fallback error message for unknown errors. - * @param item - * If TRUE, then this error is associated with an item. - * If FALSE, then this error is associated with a rule setting. - * - * @see fll_error_print() - * @see controller_rule_print_error_cache() - */ -#ifndef _di_controller_rule_print_error_ - extern void controller_rule_print_error(controller_thread_t * const thread, const fl_print_t print, const controller_cache_action_t cache, const f_status_t status, const f_string_t function, const bool fallback, const bool item) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_print_error_ - -/** - * Print additional error/warning information in addition to existing error. - * - * This is explicitly intended to be used in addition to the error message. - * - * This neither locks the thread nor does it check to see if output is enabled or disabled. - * - * @param print - * The error or warning output structure. - * @param cache - * A structure for containing and caching relevant data. - * @param item - * If TRUE, then this error is associated with an item. - * If FALSE, then this error is associated with a rule setting. - * - * @see controller_rule_action_read() - * @see controller_rule_item_read() - * @see controller_rule_items_read() - * @see controller_rule_read() - * @see controller_rule_setting_read() - */ -#ifndef _di_controller_rule_print_error_cache_ - extern void controller_rule_print_error_cache(const fl_print_t print, const controller_cache_action_t cache, const bool item) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_print_error_cache_ - -/** - * Print additional error/warning information in addition to existing error. - * - * This is explicitly intended to be used in addition to the error message. - * - * @param thread - * The thread data. - * @param print - * The error or warning print structure. - * @param cache - * A structure for containing and caching relevant data. - * @param item - * If TRUE, then this error is associated with an item. - * If FALSE, then this error is associated with a rule setting. - * @param status - * The status code representing the failure (without the error bit set). - * - * @see controller_rule_print_error_cache() - */ -#ifndef _di_controller_rule_item_print_error_ - extern void controller_rule_item_print_error(controller_thread_t * const thread, const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_print_error_ - -/** - * Print an error or warning message related to the failed execution of some program or script. - * - * @param script_is - * If TRUE, then this represents a script. - * If FALSE, then this represents a program. - * @param name - * The name of the program or script. - * @param code - * The code returned by the executed program or script. - * @param status - * The status code representing the failure (without the error bit set). - * @param process - * The process to use. - */ -#ifndef _di_controller_rule_item_print_error_execute_ - extern void controller_rule_item_print_error_execute(const bool script_is, const f_string_t name, const f_status_t status, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_print_error_execute_ - -/** - * Print an error or warning message about some rule not having the pid file information. - * - * @param print - * The error or warning output structure. - * @param alias - * The rule alias of the rule that is missing the pid file designation. - */ -#ifndef _di_controller_rule_action_print_error_missing_pid_ - extern void controller_rule_action_print_error_missing_pid(const fl_print_t print, const f_string_t alias) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_action_print_error_missing_pid_ - -/** - * Print an error or warning message related to need/want/wish settings of some rule. - * - * @param print - * The error or warning output structure. - * @param need_want_wish - * The appropriate string, such as "needs", "wants", or "wishes for" to output when describing this error/warning. - * This string is expected to already be "safe" (no control characters, etc..). - * @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_item_print_error_need_want_wish_ - extern void controller_rule_item_print_error_need_want_wish(const fl_print_t print, const f_string_t need_want_wish, const f_string_t value, const f_string_t why) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_print_error_need_want_wish_ - -/** - * Print an error or warning message about some rule not being loaded. - * - * @param print - * The error or warning output structure. - * @param alias - * The rule alias of the rule that is not loaded. - */ -#ifndef _di_controller_rule_item_print_error_rule_not_loaded_ - extern void controller_rule_item_print_error_rule_not_loaded(const fl_print_t print, const f_string_t alias) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_item_print_error_rule_not_loaded_ - -/** - * Print a message about a rule setting problem. - * - * This is intended to be explicitly called by controller_rule_setting_read(). - * This is intended only to be used for simple messages. - * - * @param print - * The error or warning output structure. - * @param message - * The string to append to the message being printed. - * @param index - * The position in the object actions cache representing the object. - * @param line_item - * The current line number. - * @param thread - * The thread data. - * @param cache - * A structure for containing and caching relevant data. - * - * @see controller_rule_setting_read() - */ -#ifndef _di_controller_rule_setting_read_print_error_ - extern void controller_rule_setting_read_print_error(const fl_print_t print, const f_string_t message, const f_array_length_t index, const f_array_length_t line_item, controller_thread_t * const thread, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_setting_read_print_error_ - -/** - * Print a message about a rule setting problem, with additional messages about the value. - * - * This is intended to be explicitly called by controller_rule_setting_read(). - * This is intended only to be used for simple messages. - * - * @param print - * The error or warning output structure. - * @param before - * The string to add to the message being printed (before the value). - * @param range - * The range within the cache item buffer representing the value. - * @param after - * The string to add to the message being printed (after the value). - * @param index - * The position in the object actions cache representing the object. - * @param line_item - * The current line number. - * @param thread - * The thread data. - * @param cache - * A structure for containing and caching relevant data. - * - * @see controller_rule_setting_read() - */ -#ifndef _di_controller_rule_setting_read_print_error_with_range_ - extern void controller_rule_setting_read_print_error_with_range(const fl_print_t print, const f_string_t before, const f_string_range_t range, const f_string_t after, const f_array_length_t index, const f_array_length_t line_item, controller_thread_t * const thread, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_setting_read_print_error_with_range_ - -/** - * Print message regarding the population of a setting when in simulation or verbose mode. - * - * @param global - * The global data. - * @param name - * The Object name of the setting being populated. - * @param name_sub - * (optional) A sub-name associated with the setting being populated. - * Set to NULL to disable. - * @param value - * The value being set. - * @param suffix - * An additional message to append at the end (before the final period). - */ -#ifndef _di_controller_rule_setting_read_print_value_ - extern void controller_rule_setting_read_print_value(const controller_global_t global, const f_string_t name, const f_string_t name_sub, const f_string_static_t value, const f_string_t suffix) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_setting_read_print_value_ - -/** - * Print message regarding the population of a setting when in simulation or verbose mode. - * - * This handles the case where there are multiple values stored in the buffer_item at a given content_actions position. - * - * @param global - * The global data. - * @param name - * The Object name of the setting being populated. - * @param index - * Position within the content_actions range cache array. - * @param cache - * A structure for containing and caching relevant data. - */ -#ifndef _di_controller_rule_setting_read_print_values_ - extern void controller_rule_setting_read_print_values(const controller_global_t global, const f_string_t name, const f_array_length_t index, controller_cache_t * const cache) F_attribute_visibility_internal_d; -#endif // _di_controller_rule_setting_read_print_values_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_rule_print_h diff --git a/level_3/controller/c/private-task.c b/level_3/controller/c/private-task.c deleted file mode 100644 index 70973f3..0000000 --- a/level_3/controller/c/private-task.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-task.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-task.h b/level_3/controller/c/private-task.h deleted file mode 100644 index 16c620f..0000000 --- a/level_3/controller/c/private-task.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_task_h -#define _PRIVATE_task_h - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_task_h diff --git a/level_3/controller/c/private-task_print.c b/level_3/controller/c/private-task_print.c deleted file mode 100644 index 941cdca..0000000 --- a/level_3/controller/c/private-task_print.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-task.h" -#include "private-task_print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-task_print.h b/level_3/controller/c/private-task_print.h deleted file mode 100644 index 9fdea4a..0000000 --- a/level_3/controller/c/private-task_print.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_task_print_h -#define _PRIVATE_task_print_h - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_task_print_h diff --git a/level_3/controller/c/private-thread.c b/level_3/controller/c/private-thread.c deleted file mode 100644 index 15110fb..0000000 --- a/level_3/controller/c/private-thread.c +++ /dev/null @@ -1,358 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-lock.h" -#include "private-lock_print.h" -#include "private-rule.h" -#include "private-thread.h" -#include "private-thread_control.h" -#include "private-thread_entry.h" -#include "private-thread_process.h" -#include "private-thread_rule.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_cleanup_ - void * controller_thread_cleanup(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - const controller_global_t *global = (controller_global_t *) arguments; - - if (global->thread->enabled != controller_thread_enabled_e) return 0; - - const struct timespec delay = controller_time_seconds(global->main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e ? controller_thread_cleanup_interval_short_d : controller_thread_cleanup_interval_long_d); - - f_status_t status = F_none; - - while (global->thread->enabled == controller_thread_enabled_e) { - - nanosleep(&delay, 0); - - if (global->thread->enabled != controller_thread_enabled_e) break; - - if (f_thread_lock_write_try(&global->thread->lock.process) == F_none) { - controller_process_t *process = 0; - - f_array_length_t i = 0; - - for (; i < global->thread->processs.size && global->thread->enabled == controller_thread_enabled_e; ++i) { - - if (!global->thread->processs.array[i]) continue; - - process = global->thread->processs.array[i]; - - // If "active" has a read lock, then do not attempt to clean it. - if (f_thread_lock_write_try(&process->active) != F_none) { - continue; - } - - // If "lock" has a read or write lock, then do not attempt to clean it. - if (f_thread_lock_write_try(&process->lock) != F_none) { - f_thread_unlock(&process->active); - - continue; - } - - // If process is active or busy, then do not attempt to clean it. - if (process->state == controller_process_state_active_e || process->state == controller_process_state_busy_e) { - f_thread_unlock(&process->active); - f_thread_unlock(&process->lock); - - continue; - } - - // If process has a PID file, then it is running in the background, only cleanup if the PID file no longer exists. - if (process->path_pids.used) { - f_array_length_t j = 0; - - for (; j < process->path_pids.used; ++j) { - - if (process->path_pids.array[j].used && f_file_exists(process->path_pids.array[j].string) == F_true) { - break; - } - } // for - - if (j < process->path_pids.used) { - f_thread_unlock(&process->active); - f_thread_unlock(&process->lock); - - continue; - } - } - - f_thread_unlock(&process->lock); - - // Close any still open thread. - if (process->id_thread) { - status = f_thread_join(process->id_thread, 0); - - if (F_status_is_error_not(status) || F_status_set_fine(status) == F_found_not) { - status = f_thread_lock_write(&process->lock); - - if (F_status_is_error(status)) { - controller_lock_print_error_critical(global->main->error, F_status_set_fine(status), F_false, global->thread); - - f_thread_unlock(&process->active); - continue; - } - - process->state = controller_process_state_idle_e; - process->id_thread = 0; - - f_thread_mutex_lock(&process->wait_lock); - f_thread_condition_signal_all(&process->wait); - f_thread_mutex_unlock(&process->wait_lock); - - f_thread_unlock(&process->lock); - } - else { - f_thread_unlock(&process->active); - - continue; - } - } - - // Deallocate dynamic portions of the structure that are only ever needed while the process is running. - controller_cache_delete_simple(&process->cache); - f_type_array_lengths_resize(0, &process->stack); - - // Shrink the childs array. - if (process->childs.used) { - for (; process->childs.used; --process->childs.used) { - if (process->childs.array[process->childs.used]) break; - } // for - - if (process->childs.used < process->childs.size) { - controller_pids_resize(process->childs.used, &process->childs); - } - } - - // Deallocate the PID files. - if (process->path_pids.used) { - process->path_pids.used = 0; - f_string_dynamics_resize(0, &process->path_pids); - } - - // Deallocate any rules in the space that is declared to be unused. - if (i >= global->thread->processs.used) { - controller_rule_delete_simple(&process->rule); - } - - f_thread_unlock(&process->active); - } // for - - f_thread_unlock(&global->thread->lock.process); - } - } // while - - return 0; - } -#endif // _di_controller_thread_cleanup_ - -#ifndef _di_controller_thread_is_enabled_ - f_status_t controller_thread_is_enabled(const bool is_normal, controller_thread_t * const thread) { - - if (is_normal) { - return thread->enabled == controller_thread_enabled_e; - } - - return thread->enabled; - } -#endif // _di_controller_thread_is_enabled_ - -#ifndef _di_controller_thread_is_enabled_process_ - f_status_t controller_thread_is_enabled_process(controller_process_t * const process, controller_thread_t * const thread) { - - return controller_thread_is_enabled_process_type(process->type, thread); - } -#endif // _di_controller_thread_is_enabled_process_ - -#ifndef _di_controller_thread_is_enabled_process_type_ - f_status_t controller_thread_is_enabled_process_type(const uint8_t type, controller_thread_t * const thread) { - - return controller_thread_is_enabled(type != controller_process_type_exit_e, thread); - } -#endif // _di_controller_thread_is_enabled_process_type_ - -#ifndef _di_controller_thread_main_ - f_status_t controller_thread_main(controller_main_t * const main, controller_setting_t * const setting) { - - f_status_t status = F_none; - - controller_thread_t thread = controller_thread_t_initialize; - controller_global_t global = macro_controller_global_t_initialize(main, setting, &thread); - - // The global locks must be initialized, but only once, so initialize immediately upon allocation. - status = controller_lock_create(&thread.lock); - - if (F_status_is_error(status)) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - fll_error_print(main->error, status, "controller_lock_create", F_true); - } - } - else { - status = controller_processs_increase(&thread.processs); - - if (F_status_is_error(status)) { - controller_print_error(&thread, main->error, F_status_set_fine(status), "controller_processs_increase", F_true); - } - } - - if (F_status_is_error_not(status)) { - status = f_thread_create(0, &thread.id_signal, &controller_thread_signal_normal, (void *) &global); - } - - if (F_status_is_error(status)) { - thread.id_signal = 0; - - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(&thread, main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - } - else { - if (main->parameters[controller_parameter_daemon_e].result == f_console_result_found_e) { - setting->ready = controller_setting_ready_done_e; - - if (f_file_exists(setting->path_pid.string) == F_true) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, &thread); - - fl_print_format("%c%[%SThe pid file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%S%]", main->error.to.stream, main->error.notable, setting->path_pid.string, main->error.notable); - fl_print_format("%[' must not already exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, &thread); - } - - setting->ready = controller_setting_ready_abort_e; - status = F_status_set_error(F_available_not); - } - } - else if (global.setting->name_entry.used) { - const controller_main_entry_t entry = macro_controller_main_entry_t_initialize(&global, global.setting); - - status = f_thread_create(0, &thread.id_entry, &controller_thread_entry, (void *) &entry); - - if (F_status_is_error(status)) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(&thread, main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - } - else { - controller_thread_join(&thread.id_entry); - - status = thread.status; - thread.id_entry = 0; - } - } - } - - // Only make the rule and control threads available once any/all pre-processing and are completed. - if (F_status_is_error_not(status) && status != F_failure && status != F_child && thread.enabled == controller_thread_enabled_e) { - if (main->parameters[controller_parameter_validate_e].result == f_console_result_none_e) { - - // Wait for the entry thread to complete before starting the rule thread. - controller_thread_join(&thread.id_rule); - - if (thread.enabled && setting->mode == controller_setting_mode_service_e) { - status = f_thread_create(0, &thread.id_rule, &controller_thread_rule, (void *) &global); - - if (F_status_is_error(status)) { - thread.id_rule = 0; - } - else { - status = f_thread_create(0, &thread.id_cleanup, &controller_thread_cleanup, (void *) &global); - } - - if (F_status_is_error(status)) { - thread.id_cleanup = 0; - - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(&thread, main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - } - } - } - } - - if (status == F_child) { - controller_thread_delete_simple(&thread); - - return F_child; - } - - if (F_status_is_error_not(status) && status != F_failure && main->parameters[controller_parameter_validate_e].result == f_console_result_none_e && controller_thread_is_enabled(F_true, &thread)) { - - if (setting->mode == controller_setting_mode_service_e) { - controller_thread_join(&thread.id_signal); - } - else if (setting->mode == controller_setting_mode_program_e) { - status = controller_rule_wait_all(global, F_true, F_false, 0); - } - } - - controller_thread_process_cancel(global, F_true, controller_thread_cancel_call_e, 0); - - controller_thread_process_exit(&global); - - if (thread.id_listen) { - f_thread_cancel(thread.id_listen); - } - - if (thread.id_signal) f_thread_join(thread.id_signal, 0); - if (thread.id_cleanup) f_thread_join(thread.id_cleanup, 0); - if (thread.id_control) f_thread_join(thread.id_control, 0); - if (thread.id_listen) f_thread_join(thread.id_listen, 0); - if (thread.id_entry) f_thread_join(thread.id_entry, 0); - if (thread.id_rule) f_thread_join(thread.id_rule, 0); - - thread.id_cleanup = 0; - thread.id_control = 0; - thread.id_listen = 0; - thread.id_entry = 0; - thread.id_rule = 0; - thread.id_signal = 0; - - controller_thread_delete_simple(&thread); - - if (F_status_is_error(status)) { - return F_status_set_error(F_failure); - } - - if (F_status_set_fine(status) == F_interrupt) { - controller_print_signal_received(main, thread.signal); - - if (main->output.verbosity != f_console_verbosity_quiet_e) { - fll_print_terminated(f_string_eol_s, main->output.to.stream); - } - - return F_status_set_error(F_interrupt); - } - - return F_none; - } -#endif // _di_controller_thread_main_ - -#ifndef _di_controller_thread_join_ - f_status_t controller_thread_join(f_thread_id_t * const id) { - - if (!id || !*id) return F_data_not; - - const f_status_t status = f_thread_join(*id, 0); - - if (F_status_is_error_not(status) || F_status_set_fine(status) == F_found_not) { - *id = 0; - } - - return status; - } -#endif // _di_controller_thread_join_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread.h b/level_3/controller/c/private-thread.h deleted file mode 100644 index cc63292..0000000 --- a/level_3/controller/c/private-thread.h +++ /dev/null @@ -1,126 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_h -#define _PRIVATE_thread_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Thread for periodically cleanup data when not busy. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_cleanup_ - extern void * controller_thread_cleanup(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_cleanup_ - -/** - * Check to see if thread is enabled for the normal operations like entry and control or for exit operations. - * - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param thread - * The thread data. - * - * @return - * TRUE when enabled. - * FALSE when disabled. - */ -#ifndef _di_controller_thread_is_enabled_ - extern f_status_t controller_thread_is_enabled(const bool is_normal, controller_thread_t * const thread) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_is_enabled_ - -/** - * Check to see if thread is enabled for the normal operations like entry and control or for exit operations for some process. - * - * @param process - * The process to use when checking if thread is enabled. - * @param thread - * The thread data. - * - * @return - * - * Success from controller_thread_is_enabled_process_type(). - * - * @see controller_thread_is_enabled_process_type() - */ -#ifndef _di_controller_thread_is_enabled_process_ - extern f_status_t controller_thread_is_enabled_process(controller_process_t * const process, controller_thread_t * const thread) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_is_enabled_process_ - -/** - * Check to see if thread is enabled for the normal operations like entry and control or for exit operations for some process type. - * - * @param type - * The process type to use when checking if thread is enabled. - * @param thread - * The thread data. - * - * @return - * - * Success from controller_thread_is_enabled(). - * - * @see controller_thread_is_enabled() - */ -#ifndef _di_controller_thread_is_enabled_process_type_ - extern f_status_t controller_thread_is_enabled_process_type(const uint8_t type, controller_thread_t * const thread) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_is_enabled_process_type_ - -/** - * Start all threads, wait on threads, and handle requests. - * - * @param main - * The main program data. - * @param setting - * The controller settings data. - * - * @return - * F_none on success. - * F_child on child process exiting. - * - * F_failure (with error bit) on any failure. - * F_interrupt (with error bit) on receiving a process signal, such as an interrupt signal. - */ -#ifndef _di_controller_thread_main_ - extern f_status_t controller_thread_main(controller_main_t * const main, controller_setting_t * const setting) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_main_ - -/*** - * Join a thread, assigning id to NULL on success. - * - * If the ID is not found, then it is also set to NULL. - * - * @param id - * The thread ID. - * - * @return - * F_none on success. - * - * Success from: f_thread_join(). - * - * Errors (with error bit) from: f_thread_join(). - * - * @see f_thread_join() - */ -#ifndef _di_controller_thread_join_ - extern f_status_t controller_thread_join(f_thread_id_t * const id) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_join_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_h diff --git a/level_3/controller/c/private-thread_control.c b/level_3/controller/c/private-thread_control.c deleted file mode 100644 index cb65183..0000000 --- a/level_3/controller/c/private-thread_control.c +++ /dev/null @@ -1,64 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-control.h" -#include "private-controller_print.h" -#include "private-thread.h" -#include "private-thread_control.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_control_ - void * controller_thread_control(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - const controller_global_t *global = (controller_global_t *) arguments; - - if (global->thread->enabled != controller_thread_enabled_e) return 0; - - f_status_t status = F_none; - f_socket_t * const server = &global->setting->control_socket; - controller_packet_t packet = controller_packet_t_initialize; - - controller_control_configure_server(global, server); - - do { - status = controller_control_accept(global, server, &packet); - } while (F_status_is_fine(status) && status != F_child && global->thread->enabled == controller_thread_enabled_e); - - controller_packet_delete_simple(&packet); - - return 0; - } -#endif // _di_controller_thread_control_ - -#ifndef _di_controller_thread_control_listen_ - void * controller_thread_control_listen(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_ASYNCHRONOUS, 0); - - const controller_global_t *global = (controller_global_t *) arguments; - - if (global->thread->enabled != controller_thread_enabled_e) return 0; - - if (global->setting->interruptible) { - f_signal_mask(SIG_UNBLOCK, &global->main->signal.set, 0); - } - - f_socket_t * const server = &global->setting->control_socket; - - const f_status_t status = f_socket_listen(server, controller_control_default_socket_backlog_d); - - if (F_status_is_error(status)) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_socket_listen", F_true); - } - - return 0; - } -#endif // _di_controller_thread_control_listen_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread_control.h b/level_3/controller/c/private-thread_control.h deleted file mode 100644 index b8f49d2..0000000 --- a/level_3/controller/c/private-thread_control.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_control_h -#define _PRIVATE_thread_control_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Thread for handling control requests and responses. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_control_ - extern void * controller_thread_control(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_control_ - -/** - * Thread for handling the control listener. - * - * This runs on a separate thread entirely to be interuptable and closable distinctly from the main control thread. - * This is simple and has nothing that needs to be cleaned up and so immediately exits on cancel. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_control_listen_ - extern void * controller_thread_control_listen(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_control_listen_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_control_h diff --git a/level_3/controller/c/private-thread_entry.c b/level_3/controller/c/private-thread_entry.c deleted file mode 100644 index 12fb524..0000000 --- a/level_3/controller/c/private-thread_entry.c +++ /dev/null @@ -1,259 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-entry.h" -#include "private-lock_print.h" -#include "private-thread.h" -#include "private-thread_entry.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_entry_ - void * controller_thread_entry(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_main_entry_t *entry = (controller_main_entry_t *) arguments; - - if (!controller_thread_is_enabled(F_true, entry->global->thread)) return 0; - - controller_main_t *main = entry->global->main; - controller_cache_t *cache = &entry->global->thread->cache; - f_status_t *status = &entry->global->thread->status; - - *status = controller_entry_read(*entry->global, F_true, cache); - - if (F_status_set_fine(*status) == F_interrupt) { - entry->setting->ready = controller_setting_ready_abort_e; - } - else if (F_status_is_error(*status)) { - entry->setting->ready = controller_setting_ready_fail_e; - } - else if (*status != F_child) { - *status = controller_entry_preprocess(*entry->global, F_true, cache); - } - - if (F_status_is_error_not(*status) && *status != F_child) { - if (main->parameters[controller_parameter_validate_e].result == f_console_result_none_e || main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - - if (entry->setting->entry.pid == controller_entry_pid_require_e && f_file_exists(entry->setting->path_pid.string) == F_true) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, entry->global->thread); - - fl_print_format("%c%[%SThe pid file '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->setting->path_pid, main->error.notable); - fl_print_format("%[' must not already exist.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, entry->global->thread); - } - - entry->setting->ready = controller_setting_ready_fail_e; - *status = F_status_set_error(F_available_not); - } - else { - *status = controller_entry_process(entry->global, cache, F_false, F_true); - - if (F_status_is_error(*status)) { - entry->setting->ready = controller_setting_ready_fail_e; - - if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && entry->global->setting->failsafe_enabled) { - const uint8_t original_enabled = entry->global->thread->enabled; - - // Restore operating mode so that the failsafe can execute. - *status = f_thread_mutex_lock(&entry->global->thread->lock.alert); - - if (F_status_is_error_not(*status)) { - entry->global->thread->enabled = controller_thread_enabled_e; - - f_thread_mutex_unlock(&entry->global->thread->lock.alert); - } - - // Restart the signal thread to allow for signals while operating the failsafe Items. - if (!entry->global->thread->id_signal) { - f_thread_create(0, &entry->global->thread->id_signal, &controller_thread_signal_normal, (void *) entry->global); - } - - const f_status_t status_failsafe = controller_entry_process(entry->global, cache, F_true, F_true); - - if (F_status_is_error(status_failsafe)) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, entry->global->thread); - - fl_print_format("%c%[%SFailed while processing requested failsafe item '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->global->setting->entry.items.array[entry->global->setting->failsafe_enabled].name, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, entry->global->thread); - } - - *status = F_status_set_error(F_failure); - } - else { - - // Restore operating mode to value prior to failsafe mode. - *status = f_thread_mutex_lock(&entry->global->thread->lock.alert); - - if (F_status_is_error_not(*status)) { - entry->global->thread->enabled = original_enabled; - - f_thread_mutex_unlock(&entry->global->thread->lock.alert); - } - - *status = F_failure; - } - } - } - else if (F_status_set_fine(*status) == F_interrupt) { - entry->setting->ready = controller_setting_ready_abort_e; - } - else if (*status != F_child) { - entry->setting->ready = controller_setting_ready_done_e; - } - } - } - } - - if (*status == F_child) { - - // A forked child process should deallocate memory on exit. - // It seems that this function doesn't return to the calling thread for a forked child process, even with the "return 0;" below. - // Deallocate as much as possible. - controller_thread_delete_simple(entry->global->thread); - controller_setting_delete_simple(entry->global->setting); - controller_main_delete(entry->global->main); - - // According to the manpages, pthread_exit() calls exit(0), which is not good because a non-zero exit code may be returned. - if (main->child) exit(main->child); - - return 0; - } - - f_thread_condition_signal_all(&entry->global->thread->lock.alert_condition); - - return 0; - } -#endif // _di_controller_thread_entry_ - -#ifndef _di_controller_thread_exit_ - void * controller_thread_exit(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_main_entry_t *entry = (controller_main_entry_t *) arguments; - - controller_main_t *main = entry->global->main; - controller_cache_t *cache = &entry->global->thread->cache; - f_status_t *status = &entry->global->thread->status; - - *status = controller_entry_read(*entry->global, F_false, cache); - - if (F_status_set_fine(*status) == F_interrupt) { - entry->setting->ready = controller_setting_ready_abort_e; - } - else if (F_status_is_error(*status)) { - entry->setting->ready = controller_setting_ready_fail_e; - } - else if (*status == F_file_found_not) { - entry->setting->ready = controller_setting_ready_done_e; - } - else if (*status != F_child) { - *status = controller_entry_preprocess(*entry->global, F_false, cache); - } - - if (F_status_is_error_not(*status) && *status != F_child && *status != F_file_found_not) { - if (main->parameters[controller_parameter_validate_e].result == f_console_result_none_e || main->parameters[controller_parameter_simulate_e].result == f_console_result_found_e) { - - *status = controller_entry_process(entry->global, cache, F_false, F_false); - - if (F_status_is_error(*status)) { - entry->setting->ready = controller_setting_ready_fail_e; - - if ((F_status_set_fine(*status) == F_execute || F_status_set_fine(*status) == F_require) && entry->global->setting->failsafe_enabled) { - - const uint8_t original_enabled = entry->global->thread->enabled; - - // Restore operating mode so that the failsafe can execute. - if (F_status_set_fine(*status) == F_execute) { - *status = f_thread_mutex_lock(&entry->global->thread->lock.alert); - - if (F_status_is_error_not(*status)) { - entry->global->thread->enabled = controller_thread_enabled_exit_e; - - f_thread_mutex_unlock(&entry->global->thread->lock.alert); - } - - // Restart the signal thread to allow for signals while operating the failsafe Items. - if (!entry->global->thread->id_signal) { - f_thread_create(0, &entry->global->thread->id_signal, &controller_thread_signal_other, (void *) entry->global); - } - } - - const f_status_t status_failsafe = controller_entry_process(entry->global, cache, F_true, F_false); - - if (F_status_is_error(status_failsafe)) { - if (main->error.verbosity != f_console_verbosity_quiet_e) { - controller_lock_print(main->error.to, entry->global->thread); - - fl_print_format("%c%[%SFailed while processing requested failsafe item '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix ? main->error.prefix : f_string_empty_s, main->error.context); - fl_print_format("%[%Q%]", main->error.to.stream, main->error.notable, entry->global->setting->entry.items.array[entry->global->setting->failsafe_enabled].name, main->error.notable); - fl_print_format("%['.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); - - controller_unlock_print_flush(main->error.to, entry->global->thread); - } - - *status = F_status_set_error(F_failure); - } - else { - - // Restore operating mode to value prior to failsafe mode. - *status = f_thread_mutex_lock(&entry->global->thread->lock.alert); - - if (F_status_is_error_not(*status)) { - entry->global->thread->enabled = original_enabled; - - f_thread_mutex_unlock(&entry->global->thread->lock.alert); - } - - *status = F_failure; - } - } - } - else if (F_status_set_fine(*status) == F_interrupt) { - entry->setting->ready = controller_setting_ready_abort_e; - } - else if (*status != F_child) { - entry->setting->ready = controller_setting_ready_done_e; - } - } - } - - if (*status == F_child) { - - // A forked child process should deallocate memory on exit. - // It seems that this function doesn't return to the calling thread for a forked child process, even with the "return 0;" below. - // Deallocate as much as possible. - - controller_thread_delete_simple(entry->global->thread); - controller_setting_delete_simple(entry->global->setting); - controller_main_delete(entry->global->main); - - return 0; - } - - if (F_status_is_error_not(f_thread_mutex_lock(&entry->global->thread->lock.alert))) { - entry->global->thread->enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&entry->global->thread->lock.alert); - } - - f_thread_condition_signal_all(&entry->global->thread->lock.alert_condition); - - return 0; - } -#endif // _di_controller_thread_exit_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread_entry.h b/level_3/controller/c/private-thread_entry.h deleted file mode 100644 index 553096e..0000000 --- a/level_3/controller/c/private-thread_entry.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_entry_h -#define _PRIVATE_thread_entry_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Thread for handling entry processing. - * - * This acts as the main rule thread during entry processing. - * This runs all synchronous rules or spawns asynchronous rules. - * - * @param arguments - * The thread arguments. - * Must be of type controller_main_entry_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_entry_ - extern void * controller_thread_entry(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_entry_ - -/** - * Thread for handling exit file processing. - * - * This acts as the main rule thread during exit processing. - * This runs all synchronous rules or spawns asynchronous rules. - * - * Do not confuse this with exiting a thread, this is the what process the exit files (similar to that of an entry file). - * Exit files process the "stop" action, whereas the Entry files process the "start" Action - * - * @param arguments - * The thread arguments. - * Must be of type controller_main_entry_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_exit_ - extern void * controller_thread_exit(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_exit_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_entry_h diff --git a/level_3/controller/c/private-thread_process.c b/level_3/controller/c/private-thread_process.c deleted file mode 100644 index a254215..0000000 --- a/level_3/controller/c/private-thread_process.c +++ /dev/null @@ -1,372 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-controller_print.h" -#include "private-rule.h" -#include "private-thread.h" -#include "private-thread_entry.h" -#include "private-thread_process.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_process_ - void controller_thread_process(const bool is_normal, controller_process_t * const process) { - - { - controller_thread_t *thread = (controller_thread_t *) process->main_thread; - - if (!controller_thread_is_enabled(is_normal, thread)) return; - } - - const f_status_t status = controller_rule_process_do(controller_process_option_asynchronous_d, process); - - if (status == F_child) { - - // A forked child process should deallocate memory on exit. - // It seems that this function doesn't return to the calling thread for a forked child process, even with the "return 0;" below. - // Deallocate as much as possible. - controller_main_t *main = (controller_main_t *) process->main_data; - controller_setting_t *setting = (controller_setting_t *) process->main_setting; - controller_thread_t *thread = (controller_thread_t *) process->main_thread; - - controller_thread_delete_simple(thread); - controller_setting_delete_simple(setting); - controller_main_delete(main); - - // According to the manpages, pthread_exit() calls exit(0), which is not good because a non-zero exit code may be returned. - if (main->child) exit(main->child); - } - } -#endif // _di_controller_thread_process_ - -#ifndef _di_controller_thread_process_cancel_ - void controller_thread_process_cancel(const controller_global_t global, const bool is_normal, const uint8_t by, controller_process_t * const caller) { - - // Only cancel when enabled. - if (!controller_thread_is_enabled(is_normal, global.thread)) { - return; - } - - // Use the alert lock to toggle enabled (being used as if it were a write like and signal lock). - f_status_t status = f_thread_mutex_lock(&global.thread->lock.alert); - - if (F_status_is_error(status)) { - global.thread->enabled = controller_thread_enabled_not_e; - } - else { - if (by == controller_thread_cancel_execute_e) { - global.thread->enabled = controller_thread_enabled_execute_e; - } - else if (by == controller_thread_cancel_exit_e) { - global.thread->enabled = controller_thread_enabled_not_e; - } - else if (by == controller_thread_cancel_exit_execute_e) { - global.thread->enabled = controller_thread_enabled_exit_execute_e; - } - else { - global.thread->enabled = controller_thread_enabled_exit_e; - } - - f_thread_mutex_unlock(&global.thread->lock.alert); - } - - f_array_length_t spent = 0; - - struct timespec time; - - controller_process_t *process = 0; - - f_array_length_t i = 0; - f_array_length_t j = 0; - pid_t pid = 0; - - if (global.thread->id_cleanup) { - f_thread_cancel(global.thread->id_cleanup); - f_thread_join(global.thread->id_cleanup, 0); - - global.thread->id_cleanup = 0; - } - - // The sigtimedwait() function that is run inside of signal must be interrupted via the f_thread_cancel(). - if (by != controller_thread_cancel_signal_e && global.thread->id_signal) { - f_thread_cancel(global.thread->id_signal); - f_thread_join(global.thread->id_signal, 0); - - global.thread->id_signal = 0; - } - - for (; i < global.thread->processs.used; ++i) { - - if (!global.thread->processs.array[i]) continue; - if (caller && i == caller->id) continue; - - process = global.thread->processs.array[i]; - - // Do not cancel exit processes, when not performing "execute" during exit. - if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) { - continue; - } - - for (j = 0; j < process->childs.used; ++j) { - - if (process->childs.array[j] > 0) { - f_signal_send(global.thread->signal ? global.thread->signal : F_signal_termination, process->childs.array[j]); - } - } // for - - for (j = 0; j < process->path_pids.used; ++j) { - - if (process->path_pids.array[j].used && f_file_exists(process->path_pids.array[j].string) == F_true) { - status = controller_file_pid_read(process->path_pids.array[j], &pid); - - if (pid) { - f_signal_send(global.thread->signal ? global.thread->signal : F_signal_termination, pid); - } - } - } // for - } // for - - for (i = 0; i < global.thread->processs.size && spent < controller_thread_exit_process_cancel_total_d; ++i) { - - if (!global.thread->processs.array[i]) continue; - if (caller && i == caller->id) continue; - - process = global.thread->processs.array[i]; - - // Do not cancel exit processes, when not performing "execute" during exit. - if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) continue; - - do { - if (!process->id_thread) break; - - f_thread_signal(process->id_thread, global.thread->signal ? global.thread->signal : F_signal_termination); - - controller_time(0, controller_thread_exit_process_cancel_wait_d, &time); - - status = f_thread_join_timed(process->id_thread, time, 0); - - if (status == F_none) { - for (j = 0; j < process->childs.size; ++j) { - process->childs.array[j] = 0; - } // for - - process->childs.used = 0; - process->id_thread = 0; - } - - ++spent; - - } while (status == F_time && spent < controller_thread_exit_process_cancel_total_d); - - if (process->path_pids.used) { - for (j = 0; j < process->path_pids.used; ++j) { - - for (; spent < controller_thread_exit_process_cancel_total_d; ++spent) { - - if (process->path_pids.array[j].used && f_file_exists(process->path_pids.array[j].string) == F_true) { - status = controller_file_pid_read(process->path_pids.array[j], &pid); - - if (pid) { - - // A hackish way to determine if the pid exists while waiting. - if (getpgid(pid) >= 0) { - time.tv_sec = 0; - time.tv_nsec = controller_thread_exit_process_cancel_wait_d; - - nanosleep(&time, 0); - - continue; - } - else { - f_file_remove(process->path_pids.array[j].string); - process->path_pids.array[j].used = 0; - } - } - } - - break; - } // for - } // for - } - } // for - - for (i = 0; i < global.thread->processs.size; ++i) { - - if (!global.thread->processs.array[i]) continue; - if (caller && i == caller->id) continue; - - process = global.thread->processs.array[i]; - - // Do not kill exit processes, when not performing "execute" during exit. - if (process->type == controller_process_type_exit_e && global.thread->enabled != controller_thread_enabled_exit_execute_e) continue; - - if (process->id_thread) { - if (process->childs.used) { - for (j = 0; j < process->childs.used; ++j) { - - if (process->childs.array[j] > 0) { - f_signal_send(F_signal_kill, process->childs.array[j]); - - time.tv_sec = 0; - time.tv_nsec = controller_thread_exit_process_cancel_wait_d; - - process->childs.array[j] = 0; - } - } // for - - nanosleep(&time, 0); - } - - f_thread_join(process->id_thread, 0); - - process->id_thread = 0; - } - - for (j = 0; j < process->childs.size; ++j) { - process->childs.array[j] = 0; - } // for - - process->childs.used = 0; - - for (j = 0; j < process->path_pids.used; ++j) { - - if (f_file_exists(process->path_pids.array[j].string) == F_true) { - status = controller_file_pid_read(process->path_pids.array[j], &pid); - - if (pid) { - f_signal_send(F_signal_kill, pid); - } - - f_file_remove(process->path_pids.array[j].string); - process->path_pids.array[j].used = 0; - } - } // for - - process->path_pids.used = 0; - } // for - } -#endif // _di_controller_thread_process_cancel_ - -#ifndef _di_controller_thread_process_exit_ - void controller_thread_process_exit(controller_global_t * const global) { - - if (global->thread->enabled != controller_thread_enabled_exit_e) { - return; - } - - if (global->setting->ready == controller_setting_ready_done_e) { - - // The exit processing runs using the entry thread. - if (global->thread->id_entry) { - f_thread_cancel(global->thread->id_entry); - f_thread_join(global->thread->id_entry, 0); - - global->thread->id_entry = 0; - } - - // Restart the signal thread to allow for signals while operating the Exit. - if (!global->thread->id_signal) { - f_thread_create(0, &global->thread->id_signal, &controller_thread_signal_other, (void *) global); - } - - const controller_main_entry_t entry = macro_controller_main_entry_t_initialize(global, global->setting); - - f_status_t status = f_thread_create(0, &global->thread->id_entry, &controller_thread_exit, (void *) &entry); - - if (F_status_is_error(status)) { - if (global->main->error.verbosity != f_console_verbosity_quiet_e) { - controller_print_error(global->thread, global->main->error, F_status_set_fine(status), "f_thread_create", F_true); - } - - if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) { - global->thread->enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&global->thread->lock.alert); - } - else { - global->thread->enabled = controller_thread_enabled_not_e; - } - } - else { - struct timespec time; - - do { - status = f_thread_mutex_lock(&global->thread->lock.alert); - - if (F_status_is_error(status)) { - global->thread->enabled = controller_thread_enabled_not_e; - - break; - } - - controller_time(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time); - - status = f_thread_condition_wait_timed(&time, &global->thread->lock.alert_condition, &global->thread->lock.alert); - - f_thread_mutex_unlock(&global->thread->lock.alert); - - } while (F_status_is_error_not(status) && global->thread->enabled == controller_thread_enabled_exit_e); - - if (F_status_is_error(status)) { - if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) { - global->thread->enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&global->thread->lock.alert); - } - else { - global->thread->enabled = controller_thread_enabled_not_e; - } - } - } - - // The sigtimedwait() function that is run inside of signal must be interrupted via the f_thread_cancel(). - if (global->thread->id_signal) { - f_thread_cancel(global->thread->id_signal); - f_thread_join(global->thread->id_signal, 0); - - global->thread->id_signal = 0; - } - - controller_thread_process_cancel(*global, F_false, controller_thread_cancel_exit_e, 0); - } - else { - if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) { - global->thread->enabled = controller_thread_enabled_not_e; - - f_thread_mutex_unlock(&global->thread->lock.alert); - } - else { - global->thread->enabled = controller_thread_enabled_not_e; - } - } - } -#endif // _di_controller_thread_process_exit_ - -#ifndef _di_controller_thread_process_normal_ - void * controller_thread_process_normal(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_thread_process(F_true, (controller_process_t *) arguments); - - return 0; - } -#endif // _di_controller_thread_process_normal_ - -#ifndef _di_controller_thread_process_other_ - void * controller_thread_process_other(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_thread_process(F_false, (controller_process_t *) arguments); - - return 0; - } -#endif // _di_controller_thread_process_other_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread_process.h b/level_3/controller/c/private-thread_process.h deleted file mode 100644 index 2e9cbf5..0000000 --- a/level_3/controller/c/private-thread_process.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_process_h -#define _PRIVATE_thread_process_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Asynchronously execute a Rule process. - * - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param process - * The process data. - * - * @see controller_rule_process_do() - */ -#ifndef _di_controller_thread_process_ - extern void controller_thread_process(const bool is_normal, controller_process_t * const process) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_process_ - -/** - * Cancel all process threads. - * - * @param global - * The global thread data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - * @param by - * Designate the way in which the cancellation should operate. - * - * If controller_thread_cancel_signal_e, then this was called from within the signal handling thread, so do not cancel the signal thread. - * If controller_thread_cancel_call_e, then this was not called from within the signal handling thread, so cancel the signal thread. - * If controller_thread_cancel_execute_e, then this was called from within the Entry/Exit for executing a process, so cancel the signal thread but not the Entry thread. - * @param caller - * (optional) The process that is calling the cancel so that this process itself does not get cancelled. - * Set to NULL to not use. - */ -#ifndef _di_controller_thread_process_cancel_ - extern void controller_thread_process_cancel(const controller_global_t global, const bool is_normal, const uint8_t by, controller_process_t * const caller) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_process_cancel_ - -/** - * Process the Exit file, if applicable. - * - * @param global - * The global thread data. - */ -#ifndef _di_controller_thread_process_exit_ - extern void controller_thread_process_exit(controller_global_t * const global) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_process_exit_ - -/** - * Asynchronously execute a Rule process during normal operations. - * - * @param arguments - * The thread arguments. - * Must be of type controller_process_t. - * - * @return - * 0, always. - * - * @see controller_thread_process() - */ -#ifndef _di_controller_thread_process_normal_ - extern void * controller_thread_process_normal(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_process_normal_ - -/** - * Asynchronously execute a Rule process during other operations. - * - * @param arguments - * The thread arguments. - * Must be of type controller_process_t. - * - * @return - * 0, always. - * - * @see controller_thread_process() - */ -#ifndef _di_controller_thread_process_other_ - extern void * controller_thread_process_other(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_process_other_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_process_h diff --git a/level_3/controller/c/private-thread_rule.c b/level_3/controller/c/private-thread_rule.c deleted file mode 100644 index c8a0655..0000000 --- a/level_3/controller/c/private-thread_rule.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-thread.h" -#include "private-thread_rule.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_rule_ - void * controller_thread_rule(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - const controller_global_t *global = (controller_global_t *) arguments; - - if (!controller_thread_is_enabled(F_true, global->thread)) return 0; - - return 0; - } -#endif // _di_controller_thread_rule_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread_rule.h b/level_3/controller/c/private-thread_rule.h deleted file mode 100644 index 61cf96d..0000000 --- a/level_3/controller/c/private-thread_rule.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_rule_h -#define _PRIVATE_thread_rule_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Thread for handling rule processing. - * - * This acts as the main rule thread after entry processing. - * This runs all synchronous rules or spawns asynchronous rules. - * - * @todo the control thread should send commands to this thread, somehow. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - */ -#ifndef _di_controller_thread_rule_ - extern void * controller_thread_rule(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_rule_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_rule_h diff --git a/level_3/controller/c/private-thread_signal.c b/level_3/controller/c/private-thread_signal.c deleted file mode 100644 index d216ab5..0000000 --- a/level_3/controller/c/private-thread_signal.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "controller.h" -#include "private-common.h" -#include "private-controller.h" -#include "private-thread.h" -#include "private-thread_entry.h" -#include "private-thread_process.h" -#include "private-thread_signal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _di_controller_thread_signal_ - void controller_thread_signal(controller_global_t * const global, const bool is_normal) { - - if (!controller_thread_is_enabled(is_normal, global->thread)) return; - - siginfo_t information; - struct timespec time; - int error = 0; - - while (controller_thread_is_enabled(is_normal, global->thread)) { - - controller_time(controller_thread_exit_ready_timeout_seconds_d, controller_thread_exit_ready_timeout_nanoseconds_d, &time); - - error = sigtimedwait(&global->main->signal.set, &information, &time); - - if (error == -1) { - if (errno == EAGAIN) continue; - } - - if (global->setting->interruptible) { - if (information.si_signo == F_signal_interrupt || information.si_signo == F_signal_abort || information.si_signo == F_signal_quit || information.si_signo == F_signal_termination) { - global->thread->signal = information.si_signo; - - controller_thread_process_cancel(*global, is_normal, controller_thread_cancel_signal_e, 0); - - break; - } - } - } // while - } -#endif // _di_controller_thread_signal_ - -#ifndef _di_controller_thread_signal_state_fss_ - f_status_t controller_thread_signal_state_fss(void * const state, void * const internal) { - - if (!state) { - return F_interrupt_not; - } - - f_state_t *state_ptr = (f_state_t *) state; - - if (!state_ptr->custom) { - return F_interrupt_not; - } - - controller_state_interrupt_t *custom = (controller_state_interrupt_t *) state_ptr->custom; - controller_thread_t *thread = custom->thread; - - if (!controller_thread_is_enabled(custom->is_normal, thread)) { - return F_status_set_error(F_interrupt); - } - - if (thread->signal == F_signal_interrupt || thread->signal == F_signal_abort || thread->signal == F_signal_quit || thread->signal == F_signal_termination) { - return F_status_set_error(F_interrupt); - } - - return F_interrupt_not; - } -#endif // _di_controller_thread_signal_state_fss_ - -#ifndef _di_controller_thread_signal_state_iki_ - f_status_t controller_thread_signal_state_iki(void * const state, void * const internal) { - - if (!state) { - return F_interrupt_not; - } - - f_state_t *state_ptr = (f_state_t *) state; - - if (!state_ptr->custom) { - return F_interrupt_not; - } - - controller_state_interrupt_t *custom = (controller_state_interrupt_t *) state_ptr->custom; - controller_thread_t *thread = custom->thread; - - if (!controller_thread_is_enabled(custom->is_normal, thread)) { - return F_status_set_error(F_interrupt); - } - - if (thread->signal == F_signal_interrupt || thread->signal == F_signal_abort || thread->signal == F_signal_quit || thread->signal == F_signal_termination) { - return F_status_set_error(F_interrupt); - } - - return F_interrupt_not; - } -#endif // _di_controller_thread_signal_state_iki_ - -#ifndef _di_controller_thread_signal_normal_ - void * controller_thread_signal_normal(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_thread_signal((controller_global_t *) arguments, F_true); - - return 0; - } -#endif // _di_controller_thread_signal_normal_ - -#ifndef _di_controller_thread_signal_other_ - void * controller_thread_signal_other(void * const arguments) { - - f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0); - - controller_thread_signal((controller_global_t *) arguments, F_false); - - return 0; - } -#endif // _di_controller_thread_signal_other_ - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/level_3/controller/c/private-thread_signal.h b/level_3/controller/c/private-thread_signal.h deleted file mode 100644 index e0fefd6..0000000 --- a/level_3/controller/c/private-thread_signal.h +++ /dev/null @@ -1,102 +0,0 @@ -/** - * FLL - Level 3 - * - * Project: Controller - * API Version: 0.5 - * Licenses: lgpl-2.1-or-later - */ -#ifndef _PRIVATE_thread_signal_h -#define _PRIVATE_thread_signal_h - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Thread for handling signals/interrupts. - * - * @param global - * The global data. - * @param is_normal - * If TRUE, then process as if this operates during a normal operation (entry and control). - * If FALSE, then process as if this operates during a an exit operation. - */ -#ifndef _di_controller_thread_signal_ - extern void controller_thread_signal(controller_global_t * const global, const bool is_normal) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_signal_ - -/** - * Callback passed to FSS functions for checking for interrupts. - * - * @param state - * The f_state_t data. - * @param internal - * Not used. - * - * @return - * F_interrupt_not if not interrupted. - * - * F_interrupt (with error bit) if interrupted. - */ -#ifndef _di_controller_thread_signal_state_fss_ - extern f_status_t controller_thread_signal_state_fss(void * const state, void * const internal) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_signal_state_fss_ - -/** - * Callback passed to IKI functions for checking for interrupts. - * - * @param state - * The f_state_t data. - * @param internal - * Not used. - * - * @return - * F_interrupt_not if not interrupted. - * - * F_interrupt (with error bit) if interrupted. - */ -#ifndef _di_controller_thread_signal_state_iki_ - extern f_status_t controller_thread_signal_state_iki(void * const state, void * const internal) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_signal_state_iki_ - -/** - * Thread for handling signals/interrupts during normal operations. - * - * Currently this only handles signals to exist, but may be updated to handle interrupt and hangup signals. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - * - * @see controller_thread_signal() - */ -#ifndef _di_controller_thread_signal_normal_ - extern void * controller_thread_signal_normal(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_signal_normal_ - -/** - * Thread for handling signals/interrupts during other operations. - * - * Currently this only handles signals to exist, but may be updated to handle interrupt and hangup signals. - * - * @param arguments - * The thread arguments. - * Must be of type controller_global_t. - * - * @return - * 0, always. - * - * @see controller_thread_signal() - */ -#ifndef _di_controller_thread_signal_other_ - extern void * controller_thread_signal_other(void * const arguments) F_attribute_visibility_internal_d; -#endif // _di_controller_thread_signal_other_ - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _PRIVATE_thread_signal_h diff --git a/level_3/fss_basic_list_read/c/fss_basic_list_read.c b/level_3/fss_basic_list_read/c/fss_basic_list_read.c index 7744de6..fbb01b9 100644 --- a/level_3/fss_basic_list_read/c/fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/fss_basic_list_read.c @@ -1,6 +1,7 @@ #include "fss_basic_list_read.h" #include "private-common.h" -#include "private-fss_basic_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_list_read/c/private-print.c b/level_3/fss_basic_list_read/c/private-print.c new file mode 100644 index 0000000..921bdd6 --- /dev/null +++ b/level_3/fss_basic_list_read/c/private-print.c @@ -0,0 +1,119 @@ +#include "fss_basic_list_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_basic_list_read_print_at_ + void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_list_read_data_t * const data) { + + if (at >= data->contents.used) { + return; + } + + if ((data->option & fss_basic_list_read_data_option_object_d) || (data->option & fss_basic_list_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_basic_list_read_data_option_empty_d))) { + flockfile(main->output.to.stream); + + if (data->option & fss_basic_list_read_data_option_object_d) { + if (data->option & fss_basic_list_read_data_option_trim_d) { + fl_print_trim_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); + } + else { + f_print_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); + } + + fss_basic_list_read_print_object_end(main); + } + + if (data->option & fss_basic_list_read_data_option_content_d) { + if (data->contents.array[at].used) { + fss_basic_list_read_print_content_ignore(main); + + f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); + + fss_basic_list_read_print_content_ignore(main); + } + } + + fss_basic_list_read_print_set_end(main); + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_basic_list_read_print_at_ + +#ifndef _di_fss_basic_list_read_print_at_object_ + void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { + + if (at >= data->objects.used) { + return; + } + + if (data->option & fss_basic_list_read_data_option_trim_d) { + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + else { + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + + fss_basic_list_read_print_object_end(main); + } +#endif // _di_fss_basic_list_read_print_at_object_ + +#ifndef _di_fss_basic_list_read_print_content_ignore_ + void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) { + + if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_basic_list_read_pipe_content_ignore_s, main->output.to.stream); + } + } +#endif // _di_fss_basic_list_read_print_content_ignore_ + +#ifndef _di_fss_basic_list_read_print_object_end_ + void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) { + + if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_basic_list_read_pipe_content_start_s, main->output.to.stream); + } + else { + if (main->parameters[fss_basic_list_read_parameter_content_e].result == f_console_result_found_e) { + f_print_character(f_fss_basic_list_open_s[0], main->output.to.stream); + f_print_character(f_fss_basic_list_open_end_s[0], main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } + } +#endif // _di_fss_basic_list_read_print_object_end_ + +#ifndef _di_fss_basic_list_read_print_set_end_ + void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) { + + if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_basic_list_read_pipe_content_end_s, main->output.to.stream); + } + } +#endif // _di_fss_basic_list_read_print_set_end_ + +#ifndef _di_fss_basic_list_read_print_one_ + void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) { + + f_print_character(f_string_ascii_1_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_basic_list_read_print_one_ + +#ifndef _di_fss_basic_list_read_print_zero_ + void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) { + + f_print_character(f_string_ascii_0_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_basic_list_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_basic_list_read/c/private-print.h b/level_3/fss_basic_list_read/c/private-print.h new file mode 100644 index 0000000..7d988ac --- /dev/null +++ b/level_3/fss_basic_list_read/c/private-print.h @@ -0,0 +1,107 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the Object and Content at the given position. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_basic_list_read_print_at_ + extern void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_list_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_at_ + +/** + * Explicitly print the Object at the given position. + * + * @param main + * The main program data. + * @param data + * The program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + */ +#ifndef _di_fss_basic_list_read_print_at_object_ + extern void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_at_object_ + +/** + * Print the ignore character for Content. + * + * This is only used in pipe output mode. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_list_read_print_content_ignore_ + extern void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_content_ignore_ + +/** + * Print the end of an Object (which is essentially the start of Content). + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_list_read_print_object_end_ + extern void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_object_end_ + +/** + * Print the number one and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_list_read_print_one_ + extern void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_one_ + +/** + * Print the end of an Object/Content set. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_list_read_print_set_end_ + extern void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_set_end_ + +/** + * Print the number zero and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_list_read_print_zero_ + extern void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_list_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c b/level_3/fss_basic_list_read/c/private-read.c similarity index 86% rename from level_3/fss_basic_list_read/c/private-fss_basic_list_read.c rename to level_3/fss_basic_list_read/c/private-read.c index 371a8e6..512c530 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.c +++ b/level_3/fss_basic_list_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_basic_list_read.h" #include "private-common.h" -#include "private-fss_basic_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -301,114 +302,6 @@ extern "C" { } #endif // _di_fss_basic_list_read_load_number_ -#ifndef _di_fss_basic_list_read_print_at_ - void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_list_read_data_t * const data) { - - if (at >= data->contents.used) { - return; - } - - if ((data->option & fss_basic_list_read_data_option_object_d) || (data->option & fss_basic_list_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_basic_list_read_data_option_empty_d))) { - flockfile(main->output.to.stream); - - if (data->option & fss_basic_list_read_data_option_object_d) { - if (data->option & fss_basic_list_read_data_option_trim_d) { - fl_print_trim_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); - } - else { - f_print_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); - } - - fss_basic_list_read_print_object_end(main); - } - - if (data->option & fss_basic_list_read_data_option_content_d) { - if (data->contents.array[at].used) { - fss_basic_list_read_print_content_ignore(main); - - f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); - - fss_basic_list_read_print_content_ignore(main); - } - } - - fss_basic_list_read_print_set_end(main); - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_basic_list_read_print_at_ - -#ifndef _di_fss_basic_list_read_print_at_object_ - void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { - - if (at >= data->objects.used) { - return; - } - - if (data->option & fss_basic_list_read_data_option_trim_d) { - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - else { - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - - fss_basic_list_read_print_object_end(main); - } -#endif // _di_fss_basic_list_read_print_at_object_ - -#ifndef _di_fss_basic_list_read_print_content_ignore_ - void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) { - - if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_basic_list_read_pipe_content_ignore_s, main->output.to.stream); - } - } -#endif // _di_fss_basic_list_read_print_content_ignore_ - -#ifndef _di_fss_basic_list_read_print_object_end_ - void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) { - - if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_basic_list_read_pipe_content_start_s, main->output.to.stream); - } - else { - if (main->parameters[fss_basic_list_read_parameter_content_e].result == f_console_result_found_e) { - f_print_character(f_fss_basic_list_open_s[0], main->output.to.stream); - f_print_character(f_fss_basic_list_open_end_s[0], main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } - } -#endif // _di_fss_basic_list_read_print_object_end_ - -#ifndef _di_fss_basic_list_read_print_set_end_ - void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) { - - if (main->parameters[fss_basic_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_basic_list_read_pipe_content_end_s, main->output.to.stream); - } - } -#endif // _di_fss_basic_list_read_print_set_end_ - -#ifndef _di_fss_basic_list_read_print_one_ - void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) { - - f_print_character(f_string_ascii_1_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_basic_list_read_print_one_ - -#ifndef _di_fss_basic_list_read_print_zero_ - void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) { - - f_print_character(f_string_ascii_0_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_basic_list_read_print_zero_ - #ifndef _di_fss_basic_list_read_process_ f_status_t fss_basic_list_read_process(fss_basic_list_read_main_t * const main, const f_console_arguments_t *arguments, fss_basic_list_read_data_t *data) { diff --git a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h b/level_3/fss_basic_list_read/c/private-read.h similarity index 76% rename from level_3/fss_basic_list_read/c/private-fss_basic_list_read.h rename to level_3/fss_basic_list_read/c/private-read.h index c9dcba6..8361f50 100644 --- a/level_3/fss_basic_list_read/c/private-fss_basic_list_read.h +++ b/level_3/fss_basic_list_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_basic_list_read_h -#define _PRIVATE_fss_basic_list_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -152,94 +152,6 @@ extern "C" { #endif // _di_fss_basic_list_read_load_number_ /** - * Print the Object and Content at the given position. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_basic_list_read_print_at_ - extern void fss_basic_list_read_print_at(fss_basic_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_list_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_at_ - -/** - * Explicitly print the Object at the given position. - * - * @param main - * The main program data. - * @param data - * The program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - */ -#ifndef _di_fss_basic_list_read_print_at_object_ - extern void fss_basic_list_read_print_at_object(fss_basic_list_read_main_t * const main, fss_basic_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_at_object_ - -/** - * Print the ignore character for Content. - * - * This is only used in pipe output mode. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_list_read_print_content_ignore_ - extern void fss_basic_list_read_print_content_ignore(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_content_ignore_ - -/** - * Print the end of an Object (which is essentially the start of Content). - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_list_read_print_object_end_ - extern void fss_basic_list_read_print_object_end(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_object_end_ - -/** - * Print the number one and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_list_read_print_one_ - extern void fss_basic_list_read_print_one(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_one_ - -/** - * Print the end of an Object/Content set. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_list_read_print_set_end_ - extern void fss_basic_list_read_print_set_end(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_set_end_ - -/** - * Print the number zero and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_list_read_print_zero_ - extern void fss_basic_list_read_print_zero(fss_basic_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_list_read_print_zero_ - -/** * Perform the basic list read processing on the buffer. * * This will print an error message on error. @@ -406,4 +318,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_basic_list_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_basic_list_read/data/build/settings b/level_3/fss_basic_list_read/data/build/settings index 02d202d..69aede5 100644 --- a/level_3/fss_basic_list_read/data/build/settings +++ b/level_3/fss_basic_list_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_basic_list_read.c private-common.c private-fss_basic_list_read.c +build_sources_library fss_basic_list_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_basic_list_write/c/fss_basic_list_write.c b/level_3/fss_basic_list_write/c/fss_basic_list_write.c index 5767f46..b9baf78 100644 --- a/level_3/fss_basic_list_write/c/fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/fss_basic_list_write.c @@ -1,6 +1,6 @@ #include "fss_basic_list_write.h" #include "private-common.h" -#include "private-fss_basic_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c b/level_3/fss_basic_list_write/c/private-write.c similarity index 99% rename from level_3/fss_basic_list_write/c/private-fss_basic_list_write.c rename to level_3/fss_basic_list_write/c/private-write.c index 2139530..ebcfcb0 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.c +++ b/level_3/fss_basic_list_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_basic_list_write.h" #include "private-common.h" -#include "private-fss_basic_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h b/level_3/fss_basic_list_write/c/private-write.h similarity index 96% rename from level_3/fss_basic_list_write/c/private-fss_basic_list_write.h rename to level_3/fss_basic_list_write/c/private-write.h index eab1b54..f4c351b 100644 --- a/level_3/fss_basic_list_write/c/private-fss_basic_list_write.h +++ b/level_3/fss_basic_list_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_basic_list_write_h -#define _PRIVATE_fss_basic_list_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -98,4 +98,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_basic_list_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_basic_list_write/data/build/settings b/level_3/fss_basic_list_write/data/build/settings index ac86fee..a118cf7 100644 --- a/level_3/fss_basic_list_write/data/build/settings +++ b/level_3/fss_basic_list_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_basic_list_write.c private-common.c private-fss_basic_list_write.c +build_sources_library fss_basic_list_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_basic_read/c/fss_basic_read.c b/level_3/fss_basic_read/c/fss_basic_read.c index 8d06542..563f4d0 100644 --- a/level_3/fss_basic_read/c/fss_basic_read.c +++ b/level_3/fss_basic_read/c/fss_basic_read.c @@ -1,6 +1,7 @@ #include "fss_basic_read.h" #include "private-common.h" -#include "private-fss_basic_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_read/c/private-print.c b/level_3/fss_basic_read/c/private-print.c new file mode 100644 index 0000000..1916e1d --- /dev/null +++ b/level_3/fss_basic_read/c/private-print.c @@ -0,0 +1,116 @@ +#include "fss_basic_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_basic_read_print_at_ + void fss_basic_read_print_at(fss_basic_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_read_data_t * const data) { + + if (at >= data->contents.used) { + return; + } + + if ((data->option & fss_basic_read_data_option_object_d) || (data->option & fss_basic_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_basic_read_data_option_empty_d))) { + flockfile(main->output.to.stream); + + if (data->option & fss_basic_read_data_option_object_d) { + if (data->option & fss_basic_read_data_option_trim_d) { + if (data->option & fss_basic_read_data_option_raw_d) { + if (data->quotes.array[at]) { + f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + fl_print_trim_dynamic_partial(data->buffer, data->objects.array[at], main->output.to.stream); + + if (data->quotes.array[at]) { + f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + else { + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + } + else { + if (data->option & fss_basic_read_data_option_raw_d) { + if (data->quotes.array[at]) { + f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_dynamic_partial(data->buffer, data->objects.array[at], main->output.to.stream); + + if (data->quotes.array[at]) { + f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + else { + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + } + + if (data->option & fss_basic_read_data_option_content_d) { + fss_basic_read_print_object_end(main); + } + } + + if ((data->option & fss_basic_read_data_option_content_d) && data->contents.array[at].used) { + if (data->option & fss_basic_read_data_option_raw_d) { + f_print_dynamic_partial(data->buffer, data->contents.array[at].array[0], main->output.to.stream); + } + else { + f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, main->output.to.stream); + } + } + + fss_basic_read_print_set_end(main); + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_basic_read_print_at_ + +#ifndef _di_fss_basic_read_print_object_end_ + void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) { + + if (main->parameters[fss_basic_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_basic_read_pipe_content_start_s, main->output.to.stream); + } + else { + f_print_character(F_fss_space_s[0], main->output.to.stream); + } + } +#endif // _di_fss_basic_read_print_object_end_ + +#ifndef _di_fss_basic_read_print_one_ + void fss_basic_read_print_one(fss_basic_read_main_t * const main) { + + f_print_character(f_string_ascii_1_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_basic_read_print_one_ + +#ifndef _di_fss_basic_read_print_set_end_ + void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) { + + if (main->parameters[fss_basic_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_basic_read_pipe_content_end_s, main->output.to.stream); + } + else { + f_print_character(f_string_eol_s[0], main->output.to.stream); + } + } +#endif // _di_fss_basic_read_print_set_end_ + +#ifndef _di_fss_basic_read_print_zero_ + void fss_basic_read_print_zero(fss_basic_read_main_t * const main) { + + f_print_character(f_string_ascii_0_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_basic_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_basic_read/c/private-print.h b/level_3/fss_basic_read/c/private-print.h new file mode 100644 index 0000000..5ac0017 --- /dev/null +++ b/level_3/fss_basic_read/c/private-print.h @@ -0,0 +1,79 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the Object and Content at the given position. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_basic_read_print_at_ + extern void fss_basic_read_print_at(fss_basic_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_read_print_at_ + +/** + * Print the end of an Object (which is essentially the start of Content). + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_read_print_object_end_ + extern void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_read_print_object_end_ + +/** + * Print the number one and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_read_print_one_ + extern void fss_basic_read_print_one(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_read_print_one_ + +/** + * Print the end of an Object/Content set. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_read_print_set_end_ + extern void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_read_print_set_end_ + +/** + * Print the number zero and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_basic_read_print_zero_ + extern void fss_basic_read_print_zero(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_basic_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.c b/level_3/fss_basic_read/c/private-read.c similarity index 83% rename from level_3/fss_basic_read/c/private-fss_basic_read.c rename to level_3/fss_basic_read/c/private-read.c index 130d099..9e20132 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.c +++ b/level_3/fss_basic_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_basic_read.h" #include "private-common.h" -#include "private-fss_basic_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -266,111 +267,6 @@ extern "C" { } #endif // _di_fss_basic_read_load_number_ -#ifndef _di_fss_basic_read_print_at_ - void fss_basic_read_print_at(fss_basic_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_read_data_t * const data) { - - if (at >= data->contents.used) { - return; - } - - if ((data->option & fss_basic_read_data_option_object_d) || (data->option & fss_basic_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_basic_read_data_option_empty_d))) { - flockfile(main->output.to.stream); - - if (data->option & fss_basic_read_data_option_object_d) { - if (data->option & fss_basic_read_data_option_trim_d) { - if (data->option & fss_basic_read_data_option_raw_d) { - if (data->quotes.array[at]) { - f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - fl_print_trim_dynamic_partial(data->buffer, data->objects.array[at], main->output.to.stream); - - if (data->quotes.array[at]) { - f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - else { - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - } - else { - if (data->option & fss_basic_read_data_option_raw_d) { - if (data->quotes.array[at]) { - f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_dynamic_partial(data->buffer, data->objects.array[at], main->output.to.stream); - - if (data->quotes.array[at]) { - f_print_character_safely(data->quotes.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - else { - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - } - - if (data->option & fss_basic_read_data_option_content_d) { - fss_basic_read_print_object_end(main); - } - } - - if ((data->option & fss_basic_read_data_option_content_d) && data->contents.array[at].used) { - if (data->option & fss_basic_read_data_option_raw_d) { - f_print_dynamic_partial(data->buffer, data->contents.array[at].array[0], main->output.to.stream); - } - else { - f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, main->output.to.stream); - } - } - - fss_basic_read_print_set_end(main); - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_basic_read_print_at_ - -#ifndef _di_fss_basic_read_print_object_end_ - void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) { - - if (main->parameters[fss_basic_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_basic_read_pipe_content_start_s, main->output.to.stream); - } - else { - f_print_character(F_fss_space_s[0], main->output.to.stream); - } - } -#endif // _di_fss_basic_read_print_object_end_ - -#ifndef _di_fss_basic_read_print_one_ - void fss_basic_read_print_one(fss_basic_read_main_t * const main) { - - f_print_character(f_string_ascii_1_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_basic_read_print_one_ - -#ifndef _di_fss_basic_read_print_set_end_ - void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) { - - if (main->parameters[fss_basic_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_basic_read_pipe_content_end_s, main->output.to.stream); - } - else { - f_print_character(f_string_eol_s[0], main->output.to.stream); - } - } -#endif // _di_fss_basic_read_print_set_end_ - -#ifndef _di_fss_basic_read_print_zero_ - void fss_basic_read_print_zero(fss_basic_read_main_t * const main) { - - f_print_character(f_string_ascii_0_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_basic_read_print_zero_ - #ifndef _di_fss_basic_read_process_ f_status_t fss_basic_read_process(fss_basic_read_main_t * const main, const f_console_arguments_t *arguments, fss_basic_read_data_t *data) { diff --git a/level_3/fss_basic_read/c/private-fss_basic_read.h b/level_3/fss_basic_read/c/private-read.h similarity index 80% rename from level_3/fss_basic_read/c/private-fss_basic_read.h rename to level_3/fss_basic_read/c/private-read.h index ca2153e..0859834 100644 --- a/level_3/fss_basic_read/c/private-fss_basic_read.h +++ b/level_3/fss_basic_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_basic_read_h -#define _PRIVATE_fss_basic_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -134,66 +134,6 @@ extern "C" { #endif // _di_fss_basic_read_load_number_ /** - * Print the Object and Content at the given position. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_basic_read_print_at_ - extern void fss_basic_read_print_at(fss_basic_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_basic_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_read_print_at_ - -/** - * Print the end of an Object (which is essentially the start of Content). - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_read_print_object_end_ - extern void fss_basic_read_print_object_end(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_read_print_object_end_ - -/** - * Print the number one and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_read_print_one_ - extern void fss_basic_read_print_one(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_read_print_one_ - -/** - * Print the end of an Object/Content set. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_read_print_set_end_ - extern void fss_basic_read_print_set_end(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_read_print_set_end_ - -/** - * Print the number zero and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_basic_read_print_zero_ - extern void fss_basic_read_print_zero(fss_basic_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_basic_read_print_zero_ - -/** * Perform the basic read processing on the buffer. * * This will print an error message on error. @@ -335,4 +275,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_basic_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_basic_read/data/build/settings b/level_3/fss_basic_read/data/build/settings index 86ffb14..6555cb5 100644 --- a/level_3/fss_basic_read/data/build/settings +++ b/level_3/fss_basic_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_basic_read.c private-common.c private-fss_basic_read.c +build_sources_library fss_basic_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_basic_write/c/fss_basic_write.c b/level_3/fss_basic_write/c/fss_basic_write.c index 14140ce..298af88 100644 --- a/level_3/fss_basic_write/c/fss_basic_write.c +++ b/level_3/fss_basic_write/c/fss_basic_write.c @@ -1,6 +1,6 @@ #include "fss_basic_write.h" #include "private-common.h" -#include "private-fss_basic_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.c b/level_3/fss_basic_write/c/private-write.c similarity index 99% rename from level_3/fss_basic_write/c/private-fss_basic_write.c rename to level_3/fss_basic_write/c/private-write.c index 5e03365..077f4c5 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.c +++ b/level_3/fss_basic_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_basic_write.h" #include "private-common.h" -#include "private-fss_basic_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_basic_write/c/private-fss_basic_write.h b/level_3/fss_basic_write/c/private-write.h similarity index 97% rename from level_3/fss_basic_write/c/private-fss_basic_write.h rename to level_3/fss_basic_write/c/private-write.h index 992591a..8c456c6 100644 --- a/level_3/fss_basic_write/c/private-fss_basic_write.h +++ b/level_3/fss_basic_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_basic_write_h -#define _PRIVATE_fss_basic_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -116,4 +116,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_basic_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_basic_write/data/build/settings b/level_3/fss_basic_write/data/build/settings index 49e0a84..74e288e 100644 --- a/level_3/fss_basic_write/data/build/settings +++ b/level_3/fss_basic_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_basic_write.c private-common.c private-fss_basic_write.c +build_sources_library fss_basic_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_embedded_list_read/c/fss_embedded_list_read.c b/level_3/fss_embedded_list_read/c/fss_embedded_list_read.c index 4443cfa..04142a2 100644 --- a/level_3/fss_embedded_list_read/c/fss_embedded_list_read.c +++ b/level_3/fss_embedded_list_read/c/fss_embedded_list_read.c @@ -1,6 +1,7 @@ #include "fss_embedded_list_read.h" #include "private-common.h" -#include "private-fss_embedded_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_embedded_list_read/c/private-print.c b/level_3/fss_embedded_list_read/c/private-print.c new file mode 100644 index 0000000..9279cfd --- /dev/null +++ b/level_3/fss_embedded_list_read/c/private-print.c @@ -0,0 +1,56 @@ +#include "fss_embedded_list_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_embedded_list_read_print_object_end_ + void fss_embedded_list_read_print_object_end(fss_embedded_list_read_main_t * const main) { + + if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_embedded_list_read_pipe_content_start_s, main->output.to.stream); + } + else { + if (main->parameters[fss_embedded_list_read_parameter_object_e].result == f_console_result_found_e && main->parameters[fss_embedded_list_read_parameter_content_e].result == f_console_result_found_e) { + f_print_character(f_fss_embedded_list_open_s[0], main->output.to.stream); + f_print_character(f_fss_embedded_list_open_end_s[0], main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } + } +#endif // _di_fss_embedded_list_read_print_object_end_ + +#ifndef _di_fss_embedded_list_read_print_content_ignore_ + void fss_embedded_list_read_print_content_ignore(fss_embedded_list_read_main_t * const main) { + + if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_embedded_list_read_pipe_content_ignore_s, main->output.to.stream); + } + } +#endif // _di_fss_embedded_list_read_print_content_ignore_ + +#ifndef _di_fss_embedded_list_read_print_set_end_ + void fss_embedded_list_read_print_set_end(fss_embedded_list_read_main_t * const main) { + + if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_embedded_list_read_pipe_content_end_s, main->output.to.stream); + } + else { + if (main->parameters[fss_embedded_list_read_parameter_object_e].result == f_console_result_found_e && main->parameters[fss_embedded_list_read_parameter_content_e].result == f_console_result_found_e) { + f_print_character(f_fss_embedded_list_close_s[0], main->output.to.stream); + f_print_character(f_fss_embedded_list_close_end_s[0], main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } + } +#endif // _di_fss_embedded_list_read_print_set_end_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_embedded_list_read/c/private-print.h b/level_3/fss_embedded_list_read/c/private-print.h new file mode 100644 index 0000000..635c005 --- /dev/null +++ b/level_3/fss_embedded_list_read/c/private-print.h @@ -0,0 +1,51 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the ignore character for content. + * + * This is only used in pipe output mode. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_embedded_list_read_print_content_ignore_ + extern void fss_embedded_list_read_print_content_ignore(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_embedded_list_read_print_content_ignore_ + +/** + * Print the end of an object (which is essentially the start of a content). + * + * @param main + * The main program data. + */ +#ifndef _di_fss_embedded_list_read_print_object_end_ + extern void fss_embedded_list_read_print_object_end(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_embedded_list_read_print_object_end_ + +/** + * Print the end of an object/content set. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_embedded_list_read_print_set_end_ + extern void fss_embedded_list_read_print_set_end(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_embedded_list_read_print_set_end_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c b/level_3/fss_embedded_list_read/c/private-read.c similarity index 93% rename from level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c rename to level_3/fss_embedded_list_read/c/private-read.c index d7cb423..02de6c8 100644 --- a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c +++ b/level_3/fss_embedded_list_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_embedded_list_read.h" #include "private-common.h" -#include "private-fss_embedded_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -675,51 +676,6 @@ extern "C" { } #endif // _di_fss_embedded_list_read_main_process_for_depth_ -#ifndef _di_fss_embedded_list_read_print_object_end_ - void fss_embedded_list_read_print_object_end(fss_embedded_list_read_main_t * const main) { - - if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_embedded_list_read_pipe_content_start_s, main->output.to.stream); - } - else { - if (main->parameters[fss_embedded_list_read_parameter_object_e].result == f_console_result_found_e && main->parameters[fss_embedded_list_read_parameter_content_e].result == f_console_result_found_e) { - f_print_character(f_fss_embedded_list_open_s[0], main->output.to.stream); - f_print_character(f_fss_embedded_list_open_end_s[0], main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } - } -#endif // _di_fss_embedded_list_read_print_object_end_ - -#ifndef _di_fss_embedded_list_read_print_content_ignore_ - void fss_embedded_list_read_print_content_ignore(fss_embedded_list_read_main_t * const main) { - - if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_embedded_list_read_pipe_content_ignore_s, main->output.to.stream); - } - } -#endif // _di_fss_embedded_list_read_print_content_ignore_ - -#ifndef _di_fss_embedded_list_read_print_set_end_ - void fss_embedded_list_read_print_set_end(fss_embedded_list_read_main_t * const main) { - - if (main->parameters[fss_embedded_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_embedded_list_read_pipe_content_end_s, main->output.to.stream); - } - else { - if (main->parameters[fss_embedded_list_read_parameter_object_e].result == f_console_result_found_e && main->parameters[fss_embedded_list_read_parameter_content_e].result == f_console_result_found_e) { - f_print_character(f_fss_embedded_list_close_s[0], main->output.to.stream); - f_print_character(f_fss_embedded_list_close_end_s[0], main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } - } -#endif // _di_fss_embedded_list_read_print_set_end_ - #ifndef _di_fss_embedded_list_read_process_delimits_ void fss_embedded_list_read_process_delimits(fss_embedded_list_read_main_t * const main, f_fss_delimits_t *objects_delimits, f_fss_delimits_t *contents_delimits) { diff --git a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.h b/level_3/fss_embedded_list_read/c/private-read.h similarity index 85% rename from level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.h rename to level_3/fss_embedded_list_read/c/private-read.h index 6fe820d..e7c9e2b 100644 --- a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.h +++ b/level_3/fss_embedded_list_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_embedded_list_read_h -#define _PRIVATE_fss_embedded_list_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -101,38 +101,6 @@ extern "C" { #endif // _di_fss_embedded_list_read_main_process_for_depth_ /** - * Print the ignore character for content. - * - * This is only used in pipe output mode. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_embedded_list_read_print_content_ignore_ - extern void fss_embedded_list_read_print_content_ignore(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_embedded_list_read_print_content_ignore_ - -/** - * Print the end of an object (which is essentially the start of a content). - * - * @param main - * The main program data. - */ -#ifndef _di_fss_embedded_list_read_print_object_end_ - extern void fss_embedded_list_read_print_object_end(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_embedded_list_read_print_object_end_ - -/** - * Print the end of an object/content set. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_embedded_list_read_print_set_end_ - extern void fss_embedded_list_read_print_set_end(fss_embedded_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_embedded_list_read_print_set_end_ - -/** * Rewrite the object and content delimit ranges to be within the given depth range. * * @param main @@ -213,4 +181,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_embedded_list_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_embedded_list_read/data/build/settings b/level_3/fss_embedded_list_read/data/build/settings index a17dfad..8a0b67c 100644 --- a/level_3/fss_embedded_list_read/data/build/settings +++ b/level_3/fss_embedded_list_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_embedded_list_read.c private-common.c private-fss_embedded_list_read.c +build_sources_library fss_embedded_list_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c index a78dd9a..2c6dba5 100644 --- a/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c +++ b/level_3/fss_embedded_list_write/c/fss_embedded_list_write.c @@ -1,6 +1,6 @@ #include "fss_embedded_list_write.h" #include "private-common.h" -#include "private-fss_embedded_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c b/level_3/fss_embedded_list_write/c/private-write.c similarity index 99% rename from level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c rename to level_3/fss_embedded_list_write/c/private-write.c index 65dd847..58f5cd0 100644 --- a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.c +++ b/level_3/fss_embedded_list_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_embedded_list_write.h" #include "private-common.h" -#include "private-fss_embedded_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.h b/level_3/fss_embedded_list_write/c/private-write.h similarity index 97% rename from level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.h rename to level_3/fss_embedded_list_write/c/private-write.h index 209526f..b6abc13 100644 --- a/level_3/fss_embedded_list_write/c/private-fss_embedded_list_write.h +++ b/level_3/fss_embedded_list_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_embedded_list_write_h -#define _PRIVATE_fss_embedded_list_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -126,4 +126,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_embedded_list_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_embedded_list_write/data/build/settings b/level_3/fss_embedded_list_write/data/build/settings index 0187127..c953bdd 100644 --- a/level_3/fss_embedded_list_write/data/build/settings +++ b/level_3/fss_embedded_list_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_embedded_list_write.c private-common.c private-fss_embedded_list_write.c +build_sources_library fss_embedded_list_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_extended_list_read/c/fss_extended_list_read.c b/level_3/fss_extended_list_read/c/fss_extended_list_read.c index 77e0e8b..6090923 100644 --- a/level_3/fss_extended_list_read/c/fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/fss_extended_list_read.c @@ -1,6 +1,7 @@ #include "fss_extended_list_read.h" #include "private-common.h" -#include "private-fss_extended_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_list_read/c/private-print.c b/level_3/fss_extended_list_read/c/private-print.c new file mode 100644 index 0000000..24de534 --- /dev/null +++ b/level_3/fss_extended_list_read/c/private-print.c @@ -0,0 +1,129 @@ +#include "fss_extended_list_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_extended_list_read_print_at_ + void fss_extended_list_read_print_at(fss_extended_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_list_read_data_t * const data) { + + if (at >= data->contents.used) { + return; + } + + if ((data->option & fss_extended_list_read_data_option_object_d) || ((data->option & fss_extended_list_read_data_option_content_d) && (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop || (data->option & fss_extended_list_read_data_option_empty_d)))) { + flockfile(main->output.to.stream); + + if (data->option & fss_extended_list_read_data_option_object_d) { + if (data->option & fss_extended_list_read_data_option_trim_d) { + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + else { + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + + fss_extended_list_read_print_object_end(main, data); + } + + if (data->option & fss_extended_list_read_data_option_content_d) { + if (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop) { + if (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop) { + fss_extended_list_read_print_content_ignore(main); + + f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); + + fss_extended_list_read_print_content_ignore(main); + } + } + } + + fss_extended_list_read_print_set_end(main, data); + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_extended_list_read_print_at_ + +#ifndef _di_fss_extended_list_read_print_at_object_ + void fss_extended_list_read_print_at_object(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { + + if (at >= data->objects.used) { + return; + } + + if (data->option & fss_extended_list_read_data_option_trim_d) { + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + else { + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + + fss_extended_list_read_print_object_end(main, data); + } +#endif // _di_fss_extended_list_read_print_at_object_ + +#ifndef _di_fss_extended_list_read_print_content_ignore_ + void fss_extended_list_read_print_content_ignore(fss_extended_list_read_main_t * const main) { + + if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_list_read_pipe_content_ignore, main->output.to.stream); + } + } +#endif // _di_fss_extended_list_read_print_content_ignore_ + +#ifndef _di_fss_extended_list_read_print_object_end_ + void fss_extended_list_read_print_object_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) { + + if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_list_read_pipe_content_start, main->output.to.stream); + } + else { + if ((data->option & fss_extended_list_read_data_option_object_d) && (data->option & fss_extended_list_read_data_option_content_d)) { + f_print_character(f_fss_extended_list_open_s[0], main->output.to.stream); + f_print_character(f_fss_extended_list_open_end_s[0], main->output.to.stream); + } + } + } +#endif // _di_fss_extended_list_read_print_object_end_ + +#ifndef _di_fss_extended_list_read_print_set_end_ + void fss_extended_list_read_print_set_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) { + + if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_list_read_pipe_content_end, main->output.to.stream); + } + else { + if (data->option & fss_extended_list_read_data_option_object_d) { + if (data->option & fss_extended_list_read_data_option_content_d) { + f_print_character(f_fss_extended_list_close_s[0], main->output.to.stream); + f_print_character(f_fss_extended_list_close_end_s[0], main->output.to.stream); + } + else if (!(data->option & fss_extended_list_read_data_option_content_d)) { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } + } + } +#endif // _di_fss_extended_list_read_print_set_end_ + +#ifndef _di_fss_extended_list_read_print_one_ + void fss_extended_list_read_print_one(fss_extended_list_read_main_t * const main) { + + f_print_character(f_string_ascii_1_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_extended_list_read_print_one_ + +#ifndef _di_fss_extended_list_read_print_zero_ + void fss_extended_list_read_print_zero(fss_extended_list_read_main_t * const main) { + + f_print_character(f_string_ascii_0_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_extended_list_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_extended_list_read/c/private-print.h b/level_3/fss_extended_list_read/c/private-print.h new file mode 100644 index 0000000..c30e38e --- /dev/null +++ b/level_3/fss_extended_list_read/c/private-print.h @@ -0,0 +1,111 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the Object and Content at the given position. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_extended_list_read_print_at_ + extern void fss_extended_list_read_print_at(fss_extended_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_at_ + +/** + * Explicitly print the Object at the given position. + * + * @param main + * The main program data. + * @param data + * The program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + */ +#ifndef _di_fss_extended_list_read_print_at_object_ + extern void fss_extended_list_read_print_at_object(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_at_object_ + +/** + * Print the ignore character for Content. + * + * This is only used in pipe output mode. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_list_read_print_content_ignore_ + extern void fss_extended_list_read_print_content_ignore(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_content_ignore_ + +/** + * Print the end of an Object (which is essentially the start of Content). + * + * @param main + * The main program data. + * @param data + * The program data. + */ +#ifndef _di_fss_extended_list_read_print_object_end_ + extern void fss_extended_list_read_print_object_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_object_end_ + +/** + * Print the number one and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_list_read_print_one_ + extern void fss_extended_list_read_print_one(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_one_ + +/** + * Print the end of an Object/Content set. + * + * @param main + * The main program data. + * @param data + * The program data. + */ +#ifndef _di_fss_extended_list_read_print_set_end_ + extern void fss_extended_list_read_print_set_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_set_end_ + +/** + * Print the number zero and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_list_read_print_zero_ + extern void fss_extended_list_read_print_zero(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_list_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c b/level_3/fss_extended_list_read/c/private-read.c similarity index 84% rename from level_3/fss_extended_list_read/c/private-fss_extended_list_read.c rename to level_3/fss_extended_list_read/c/private-read.c index 4512045..8983ae0 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.c +++ b/level_3/fss_extended_list_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_extended_list_read.h" #include "private-common.h" -#include "private-fss_extended_list_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -288,124 +289,6 @@ extern "C" { } #endif // _di_fss_extended_list_read_load_number_ -#ifndef _di_fss_extended_list_read_print_at_ - void fss_extended_list_read_print_at(fss_extended_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_list_read_data_t * const data) { - - if (at >= data->contents.used) { - return; - } - - if ((data->option & fss_extended_list_read_data_option_object_d) || ((data->option & fss_extended_list_read_data_option_content_d) && (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop || (data->option & fss_extended_list_read_data_option_empty_d)))) { - flockfile(main->output.to.stream); - - if (data->option & fss_extended_list_read_data_option_object_d) { - if (data->option & fss_extended_list_read_data_option_trim_d) { - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - else { - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - - fss_extended_list_read_print_object_end(main, data); - } - - if (data->option & fss_extended_list_read_data_option_content_d) { - if (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop) { - if (data->contents.array[at].used && data->contents.array[at].array[0].start <= data->contents.array[at].array[0].stop) { - fss_extended_list_read_print_content_ignore(main); - - f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); - - fss_extended_list_read_print_content_ignore(main); - } - } - } - - fss_extended_list_read_print_set_end(main, data); - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_extended_list_read_print_at_ - -#ifndef _di_fss_extended_list_read_print_at_object_ - void fss_extended_list_read_print_at_object(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { - - if (at >= data->objects.used) { - return; - } - - if (data->option & fss_extended_list_read_data_option_trim_d) { - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - else { - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - - fss_extended_list_read_print_object_end(main, data); - } -#endif // _di_fss_extended_list_read_print_at_object_ - -#ifndef _di_fss_extended_list_read_print_content_ignore_ - void fss_extended_list_read_print_content_ignore(fss_extended_list_read_main_t * const main) { - - if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_list_read_pipe_content_ignore, main->output.to.stream); - } - } -#endif // _di_fss_extended_list_read_print_content_ignore_ - -#ifndef _di_fss_extended_list_read_print_object_end_ - void fss_extended_list_read_print_object_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) { - - if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_list_read_pipe_content_start, main->output.to.stream); - } - else { - if ((data->option & fss_extended_list_read_data_option_object_d) && (data->option & fss_extended_list_read_data_option_content_d)) { - f_print_character(f_fss_extended_list_open_s[0], main->output.to.stream); - f_print_character(f_fss_extended_list_open_end_s[0], main->output.to.stream); - } - } - } -#endif // _di_fss_extended_list_read_print_object_end_ - -#ifndef _di_fss_extended_list_read_print_set_end_ - void fss_extended_list_read_print_set_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) { - - if (main->parameters[fss_extended_list_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_list_read_pipe_content_end, main->output.to.stream); - } - else { - if (data->option & fss_extended_list_read_data_option_object_d) { - if (data->option & fss_extended_list_read_data_option_content_d) { - f_print_character(f_fss_extended_list_close_s[0], main->output.to.stream); - f_print_character(f_fss_extended_list_close_end_s[0], main->output.to.stream); - } - else if (!(data->option & fss_extended_list_read_data_option_content_d)) { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } - } - } -#endif // _di_fss_extended_list_read_print_set_end_ - -#ifndef _di_fss_extended_list_read_print_one_ - void fss_extended_list_read_print_one(fss_extended_list_read_main_t * const main) { - - f_print_character(f_string_ascii_1_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_extended_list_read_print_one_ - -#ifndef _di_fss_extended_list_read_print_zero_ - void fss_extended_list_read_print_zero(fss_extended_list_read_main_t * const main) { - - f_print_character(f_string_ascii_0_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_extended_list_read_print_zero_ - #ifndef _di_fss_extended_list_read_process_ f_status_t fss_extended_list_read_process(fss_extended_list_read_main_t * const main, const f_console_arguments_t *arguments, fss_extended_list_read_data_t *data) { diff --git a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h b/level_3/fss_extended_list_read/c/private-read.h similarity index 75% rename from level_3/fss_extended_list_read/c/private-fss_extended_list_read.h rename to level_3/fss_extended_list_read/c/private-read.h index 76dadf9..a2ddfcb 100644 --- a/level_3/fss_extended_list_read/c/private-fss_extended_list_read.h +++ b/level_3/fss_extended_list_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_extended_list_read_h -#define _PRIVATE_fss_extended_list_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -150,98 +150,6 @@ extern "C" { #endif // _di_fss_extended_list_read_load_number_ /** - * Print the Object and Content at the given position. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_extended_list_read_print_at_ - extern void fss_extended_list_read_print_at(fss_extended_list_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_at_ - -/** - * Explicitly print the Object at the given position. - * - * @param main - * The main program data. - * @param data - * The program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - */ -#ifndef _di_fss_extended_list_read_print_at_object_ - extern void fss_extended_list_read_print_at_object(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_at_object_ - -/** - * Print the ignore character for Content. - * - * This is only used in pipe output mode. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_list_read_print_content_ignore_ - extern void fss_extended_list_read_print_content_ignore(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_content_ignore_ - -/** - * Print the end of an Object (which is essentially the start of Content). - * - * @param main - * The main program data. - * @param data - * The program data. - */ -#ifndef _di_fss_extended_list_read_print_object_end_ - extern void fss_extended_list_read_print_object_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_object_end_ - -/** - * Print the number one and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_list_read_print_one_ - extern void fss_extended_list_read_print_one(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_one_ - -/** - * Print the end of an Object/Content set. - * - * @param main - * The main program data. - * @param data - * The program data. - */ -#ifndef _di_fss_extended_list_read_print_set_end_ - extern void fss_extended_list_read_print_set_end(fss_extended_list_read_main_t * const main, fss_extended_list_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_set_end_ - -/** - * Print the number zero and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_list_read_print_zero_ - extern void fss_extended_list_read_print_zero(fss_extended_list_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_list_read_print_zero_ - -/** * Perform the extended list read processing on the buffer. * * This will print an error message on error. @@ -408,4 +316,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_extended_list_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_extended_list_read/data/build/settings b/level_3/fss_extended_list_read/data/build/settings index 8da434c..1c22e56 100644 --- a/level_3/fss_extended_list_read/data/build/settings +++ b/level_3/fss_extended_list_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_extended_list_read.c private-common.c private-fss_extended_list_read.c +build_sources_library fss_extended_list_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_extended_list_write/c/fss_extended_list_write.c b/level_3/fss_extended_list_write/c/fss_extended_list_write.c index 0a14e91..7a60378 100644 --- a/level_3/fss_extended_list_write/c/fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/fss_extended_list_write.c @@ -1,6 +1,6 @@ #include "fss_extended_list_write.h" #include "private-common.h" -#include "private-fss_extended_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c b/level_3/fss_extended_list_write/c/private-write.c similarity index 99% rename from level_3/fss_extended_list_write/c/private-fss_extended_list_write.c rename to level_3/fss_extended_list_write/c/private-write.c index 0cc6d75..4412f6b 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.c +++ b/level_3/fss_extended_list_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_extended_list_write.h" #include "private-common.h" -#include "private-fss_extended_list_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h b/level_3/fss_extended_list_write/c/private-write.h similarity index 97% rename from level_3/fss_extended_list_write/c/private-fss_extended_list_write.h rename to level_3/fss_extended_list_write/c/private-write.h index 9f678a1..bdcb28c 100644 --- a/level_3/fss_extended_list_write/c/private-fss_extended_list_write.h +++ b/level_3/fss_extended_list_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_extended_list_write_h -#define _PRIVATE_fss_extended_list_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -126,4 +126,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_extended_list_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_extended_list_write/data/build/settings b/level_3/fss_extended_list_write/data/build/settings index 2240e96..27b3a09 100644 --- a/level_3/fss_extended_list_write/data/build/settings +++ b/level_3/fss_extended_list_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_extended_list_write.c private-common.c private-fss_extended_list_write.c +build_sources_library fss_extended_list_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_extended_read/c/fss_extended_read.c b/level_3/fss_extended_read/c/fss_extended_read.c index 4352951..af69169 100644 --- a/level_3/fss_extended_read/c/fss_extended_read.c +++ b/level_3/fss_extended_read/c/fss_extended_read.c @@ -1,6 +1,7 @@ #include "fss_extended_read.h" #include "private-common.h" -#include "private-fss_extended_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_read/c/private-print.c b/level_3/fss_extended_read/c/private-print.c new file mode 100644 index 0000000..0ea91b1 --- /dev/null +++ b/level_3/fss_extended_read/c/private-print.c @@ -0,0 +1,210 @@ +#include "fss_extended_read.h" +#include "private-common.h" +#include "private-print.h" +#include "private-read.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_extended_read_print_at_ + void fss_extended_read_print_at(fss_extended_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_read_data_t * const data) { + + if (at >= data->contents.used) { + return; + } + + flockfile(main->output.to.stream); + + if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_extended_read_data_option_empty_d))) { + if (data->option & fss_extended_read_data_option_object_d) { + if (data->option & fss_extended_read_data_option_trim_d) { + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { + f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { + f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + else { + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { + f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { + f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + + if (data->option & fss_extended_read_data_option_content_d) { + fss_extended_read_print_object_end(main); + } + } + + bool content_printed = F_false; + + if ((data->option & fss_extended_read_data_option_content_d) && data->contents.array[at].used) { + if (data->option & fss_extended_read_data_option_select_d) { + if (data->select < data->contents.array[at].used) { + content_printed = F_true; + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[data->select]) { + f_print_character_safely(data->quotes_content.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[data->select], delimits_content, main->output.to.stream); + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[data->select]) { + f_print_character_safely(data->quotes_content.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + } + else { + for (f_array_length_t i = 0; i < data->contents.array[at].used; ++i) { + + if (data->contents.array[at].array[i].start > data->contents.array[at].array[i].stop) { + continue; + } + + content_printed = F_true; + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[i]) { + f_print_character_safely(data->quotes_content.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[i], delimits_content, main->output.to.stream); + + if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[i]) { + f_print_character_safely(data->quotes_content.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + if (i + 1 < data->contents.array[at].used && data->contents.array[at].array[i + 1].start <= data->contents.array[at].array[i + 1].stop) { + fss_extended_read_print_content_end(main); + } + } // for + } + } + + if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_content_d) && (content_printed || (data->option & fss_extended_read_data_option_empty_d))) { + fss_extended_read_print_set_end(main); + } + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_extended_read_print_at_ + +#ifndef _di_fss_extended_read_print_at_total_ + f_status_t fss_extended_read_print_at_total(fss_extended_read_main_t * const main, const f_array_length_t at, fss_extended_read_data_t *data) { + + if (data->option & fss_extended_read_data_option_select_d) { + if (data->option & fss_extended_read_data_option_object_d) { + flockfile(main->output.to.stream); + + fss_extended_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + + if (data->select < data->contents.array[at].used) { + if (data->contents.array[at].array[data->select].start <= data->contents.array[at].array[data->select].stop || (data->option & fss_extended_read_data_option_empty_d)) { + flockfile(main->output.to.stream); + + fss_extended_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + } + } + else if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_empty_d)) { + flockfile(main->output.to.stream); + + fss_extended_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + else if (data->contents.array[at].used) { + for (f_array_length_t j = 0; j < data->contents.array[at].used; ++j) { + + if (data->contents.array[at].array[j].start <= data->contents.array[at].array[j].stop) { + flockfile(main->output.to.stream); + + fss_extended_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + } // for + } + + return F_none; + } +#endif // _di_fss_extended_read_print_at_total_ + +#ifndef _di_fss_extended_read_print_content_end_ + void fss_extended_read_print_content_end(fss_extended_read_main_t * const main) { + + if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_read_pipe_content_start_s, main->output.to.stream); + } + else { + f_print_character(F_fss_space_s[0], main->output.to.stream); + } + } +#endif // _di_fss_extended_read_print_content_end_ + +#ifndef _di_fss_extended_read_print_object_end_ + void fss_extended_read_print_object_end(fss_extended_read_main_t * const main) { + + if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_read_pipe_content_end_s, main->output.to.stream); + } + else { + f_print_character(F_fss_space_s[0], main->output.to.stream); + } + } +#endif // _di_fss_extended_read_print_object_end_ + +#ifndef _di_fss_extended_read_print_one_ + void fss_extended_read_print_one(fss_extended_read_main_t * const main) { + + f_print_character(f_string_ascii_1_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_extended_read_print_one_ + +#ifndef _di_fss_extended_read_print_set_end_ + void fss_extended_read_print_set_end(fss_extended_read_main_t * const main) { + + if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_extended_read_pipe_content_end_s, main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } +#endif // _di_fss_extended_read_print_set_end_ + +#ifndef _di_fss_extended_read_print_zero_ + void fss_extended_read_print_zero(fss_extended_read_main_t * const main) { + + f_print_character(f_string_ascii_0_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_extended_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_extended_read/c/private-print.h b/level_3/fss_extended_read/c/private-print.h new file mode 100644 index 0000000..dbc2bb4 --- /dev/null +++ b/level_3/fss_extended_read/c/private-print.h @@ -0,0 +1,107 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the Object and Content at the given position. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_extended_read_print_at_ + extern void fss_extended_read_print_at(fss_extended_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_at_ + +/** + * Print total count at the specified Object/Content position. + * + * @param main + * The main program data. + * @param at + * The Object/Content position. + * @param data + * The program data. + * + * @return + * F_none on success but nothig was matched (and total was printed). + * F_success on success and something was matched (and total was printed). + */ +#ifndef _di_fss_extended_read_print_at_total_ + extern f_status_t fss_extended_read_print_at_total(fss_extended_read_main_t * const main, const f_array_length_t at, fss_extended_read_data_t *data) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_at_total_ + +/** + * Print the end of a Content. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_read_print_content_end_ + extern void fss_extended_read_print_content_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_content_end_ + +/** + * Print the end of an Object (which is essentially the start of Content). + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_read_print_object_end_ + extern void fss_extended_read_print_object_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_object_end_ + +/** + * Print the number one and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_read_print_one_ + extern void fss_extended_read_print_one(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_one_ + +/** + * Print the end of an Object/Content set. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_read_print_set_end_ + extern void fss_extended_read_print_set_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_set_end_ + +/** + * Print the number zero and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_extended_read_print_zero_ + extern void fss_extended_read_print_zero(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_extended_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.c b/level_3/fss_extended_read/c/private-read.c similarity index 75% rename from level_3/fss_extended_read/c/private-fss_extended_read.c rename to level_3/fss_extended_read/c/private-read.c index e4cf681..20c595e 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.c +++ b/level_3/fss_extended_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_extended_read.h" #include "private-common.h" -#include "private-fss_extended_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -303,204 +304,6 @@ extern "C" { } #endif // _di_fss_extended_read_load_number_ -#ifndef _di_fss_extended_read_print_at_ - void fss_extended_read_print_at(fss_extended_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_read_data_t * const data) { - - if (at >= data->contents.used) { - return; - } - - flockfile(main->output.to.stream); - - if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_extended_read_data_option_empty_d))) { - if (data->option & fss_extended_read_data_option_object_d) { - if (data->option & fss_extended_read_data_option_trim_d) { - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { - f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { - f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - else { - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { - f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_object.array[at]) { - f_print_character_safely(data->quotes_object.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - - if (data->option & fss_extended_read_data_option_content_d) { - fss_extended_read_print_object_end(main); - } - } - - bool content_printed = F_false; - - if ((data->option & fss_extended_read_data_option_content_d) && data->contents.array[at].used) { - if (data->option & fss_extended_read_data_option_select_d) { - if (data->select < data->contents.array[at].used) { - content_printed = F_true; - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[data->select]) { - f_print_character_safely(data->quotes_content.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[data->select], delimits_content, main->output.to.stream); - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[data->select]) { - f_print_character_safely(data->quotes_content.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - } - else { - for (f_array_length_t i = 0; i < data->contents.array[at].used; ++i) { - - if (data->contents.array[at].array[i].start > data->contents.array[at].array[i].stop) { - continue; - } - - content_printed = F_true; - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[i]) { - f_print_character_safely(data->quotes_content.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->contents.array[at].array[i], delimits_content, main->output.to.stream); - - if ((data->option & fss_extended_read_data_option_raw_d) && data->quotes_content.array[at].array[i]) { - f_print_character_safely(data->quotes_content.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - if (i + 1 < data->contents.array[at].used && data->contents.array[at].array[i + 1].start <= data->contents.array[at].array[i + 1].stop) { - fss_extended_read_print_content_end(main); - } - } // for - } - } - - if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_content_d) && (content_printed || (data->option & fss_extended_read_data_option_empty_d))) { - fss_extended_read_print_set_end(main); - } - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_extended_read_print_at_ - -#ifndef _di_fss_extended_read_print_at_total_ - f_status_t fss_extended_read_print_at_total(fss_extended_read_main_t * const main, const f_array_length_t at, fss_extended_read_data_t *data) { - - if (data->option & fss_extended_read_data_option_select_d) { - if (data->option & fss_extended_read_data_option_object_d) { - flockfile(main->output.to.stream); - - fss_extended_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - - if (data->select < data->contents.array[at].used) { - if (data->contents.array[at].array[data->select].start <= data->contents.array[at].array[data->select].stop || (data->option & fss_extended_read_data_option_empty_d)) { - flockfile(main->output.to.stream); - - fss_extended_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - } - } - else if ((data->option & fss_extended_read_data_option_object_d) || (data->option & fss_extended_read_data_option_empty_d)) { - flockfile(main->output.to.stream); - - fss_extended_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - else if (data->contents.array[at].used) { - for (f_array_length_t j = 0; j < data->contents.array[at].used; ++j) { - - if (data->contents.array[at].array[j].start <= data->contents.array[at].array[j].stop) { - flockfile(main->output.to.stream); - - fss_extended_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - } // for - } - - return F_none; - } -#endif // _di_fss_extended_read_print_at_total_ - -#ifndef _di_fss_extended_read_print_content_end_ - void fss_extended_read_print_content_end(fss_extended_read_main_t * const main) { - - if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_read_pipe_content_start_s, main->output.to.stream); - } - else { - f_print_character(F_fss_space_s[0], main->output.to.stream); - } - } -#endif // _di_fss_extended_read_print_content_end_ - -#ifndef _di_fss_extended_read_print_object_end_ - void fss_extended_read_print_object_end(fss_extended_read_main_t * const main) { - - if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_read_pipe_content_end_s, main->output.to.stream); - } - else { - f_print_character(F_fss_space_s[0], main->output.to.stream); - } - } -#endif // _di_fss_extended_read_print_object_end_ - -#ifndef _di_fss_extended_read_print_one_ - void fss_extended_read_print_one(fss_extended_read_main_t * const main) { - - f_print_character(f_string_ascii_1_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_extended_read_print_one_ - -#ifndef _di_fss_extended_read_print_set_end_ - void fss_extended_read_print_set_end(fss_extended_read_main_t * const main) { - - if (main->parameters[fss_extended_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_extended_read_pipe_content_end_s, main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } -#endif // _di_fss_extended_read_print_set_end_ - -#ifndef _di_fss_extended_read_print_zero_ - void fss_extended_read_print_zero(fss_extended_read_main_t * const main) { - - f_print_character(f_string_ascii_0_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_extended_read_print_zero_ - #ifndef _di_fss_extended_read_process_ f_status_t fss_extended_read_process(fss_extended_read_main_t * const main, const f_console_arguments_t *arguments, fss_extended_read_data_t *data) { diff --git a/level_3/fss_extended_read/c/private-fss_extended_read.h b/level_3/fss_extended_read/c/private-read.h similarity index 77% rename from level_3/fss_extended_read/c/private-fss_extended_read.h rename to level_3/fss_extended_read/c/private-read.h index e38f12a..7462de5 100644 --- a/level_3/fss_extended_read/c/private-fss_extended_read.h +++ b/level_3/fss_extended_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_extended_read_h -#define _PRIVATE_fss_extended_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -150,94 +150,6 @@ extern "C" { #endif // _di_fss_extended_read_load_number_ /** - * Print the Object and Content at the given position. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_extended_read_print_at_ - extern void fss_extended_read_print_at(fss_extended_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_extended_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_at_ - -/** - * Print total count at the specified Object/Content position. - * - * @param main - * The main program data. - * @param at - * The Object/Content position. - * @param data - * The program data. - * - * @return - * F_none on success but nothig was matched (and total was printed). - * F_success on success and something was matched (and total was printed). - */ -#ifndef _di_fss_extended_read_print_at_total_ - extern f_status_t fss_extended_read_print_at_total(fss_extended_read_main_t * const main, const f_array_length_t at, fss_extended_read_data_t *data) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_at_total_ - -/** - * Print the end of a Content. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_read_print_content_end_ - extern void fss_extended_read_print_content_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_content_end_ - -/** - * Print the end of an Object (which is essentially the start of Content). - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_read_print_object_end_ - extern void fss_extended_read_print_object_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_object_end_ - -/** - * Print the number one and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_read_print_one_ - extern void fss_extended_read_print_one(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_one_ - -/** - * Print the end of an Object/Content set. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_read_print_set_end_ - extern void fss_extended_read_print_set_end(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_set_end_ - -/** - * Print the number zero and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_extended_read_print_zero_ - extern void fss_extended_read_print_zero(fss_extended_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_extended_read_print_zero_ - -/** * Perform the extended read processing on the buffer. * * This will print an error message on error. @@ -422,4 +334,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_extended_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_extended_read/data/build/settings b/level_3/fss_extended_read/data/build/settings index 0abf179..f82ea34 100644 --- a/level_3/fss_extended_read/data/build/settings +++ b/level_3/fss_extended_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_extended_read.c private-common.c private-fss_extended_read.c +build_sources_library fss_extended_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_extended_write/c/fss_extended_write.c b/level_3/fss_extended_write/c/fss_extended_write.c index 92df616..3fbda4a 100644 --- a/level_3/fss_extended_write/c/fss_extended_write.c +++ b/level_3/fss_extended_write/c/fss_extended_write.c @@ -1,6 +1,6 @@ #include "fss_extended_write.h" #include "private-common.h" -#include "private-fss_extended_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.c b/level_3/fss_extended_write/c/private-write.c similarity index 99% rename from level_3/fss_extended_write/c/private-fss_extended_write.c rename to level_3/fss_extended_write/c/private-write.c index c3a9e4c..ba224c5 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.c +++ b/level_3/fss_extended_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_extended_write.h" #include "private-common.h" -#include "private-fss_extended_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_extended_write/c/private-fss_extended_write.h b/level_3/fss_extended_write/c/private-write.h similarity index 96% rename from level_3/fss_extended_write/c/private-fss_extended_write.h rename to level_3/fss_extended_write/c/private-write.h index 101fcc6..bae6eb9 100644 --- a/level_3/fss_extended_write/c/private-fss_extended_write.h +++ b/level_3/fss_extended_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_extended_write_h -#define _PRIVATE_fss_extended_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -110,4 +110,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_extended_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_extended_write/data/build/settings b/level_3/fss_extended_write/data/build/settings index 3aa2e77..d512262 100644 --- a/level_3/fss_extended_write/data/build/settings +++ b/level_3/fss_extended_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_extended_write.c private-common.c private-fss_extended_write.c +build_sources_library fss_extended_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_identify/c/fss_identify.c b/level_3/fss_identify/c/fss_identify.c index 91d73cb..3bdabad 100644 --- a/level_3/fss_identify/c/fss_identify.c +++ b/level_3/fss_identify/c/fss_identify.c @@ -1,6 +1,6 @@ #include "fss_identify.h" #include "private-common.h" -#include "private-fss_identify.h" +#include "private-identify.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_identify/c/private-fss_identify.c b/level_3/fss_identify/c/private-identify.c similarity index 79% rename from level_3/fss_identify/c/private-fss_identify.c rename to level_3/fss_identify/c/private-identify.c index 23fb245..076d58f 100644 --- a/level_3/fss_identify/c/private-fss_identify.c +++ b/level_3/fss_identify/c/private-identify.c @@ -1,6 +1,7 @@ #include "fss_identify.h" #include "private-common.h" -#include "private-fss_identify.h" +#include "private-identify.h" +#include "private-print.h" #ifdef __cplusplus extern "C" { @@ -62,29 +63,6 @@ extern "C" { } #endif // _di_fss_identify_load_line_ -#ifndef _di_fss_identify_print_ - void fss_identify_print(fss_identify_main_t * const main, f_fll_id_t id) { - - flockfile(main->output.to.stream); - - if (main->parameters[fss_identify_parameter_object_e].result == f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result != f_console_result_found_e) { - f_print(id.name, id.used, main->output.to.stream); - - if (main->parameters[fss_identify_parameter_object_e].result != f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result == f_console_result_found_e) { - f_print_terminated(f_fss_type_header_part5_s, main->output.to.stream); - } - } - - if (main->parameters[fss_identify_parameter_object_e].result != f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result == f_console_result_found_e) { - fl_print_format("%04_ui", main->output.to.stream, id.type); - } - - f_print_character(f_string_eol_s[0], main->output.to.stream); - - funlockfile(main->output.to.stream); - } -#endif // _di_fss_identify_print_ - #ifndef _di_fss_identify_process_ f_status_t fss_identify_process(fss_identify_main_t * const main, const f_string_t name, const f_string_static_t buffer, f_string_range_t *range, fss_identify_data_t *data) { diff --git a/level_3/fss_identify/c/private-fss_identify.h b/level_3/fss_identify/c/private-identify.h similarity index 82% rename from level_3/fss_identify/c/private-fss_identify.h rename to level_3/fss_identify/c/private-identify.h index 42b16cd..11db1e5 100644 --- a/level_3/fss_identify/c/private-fss_identify.h +++ b/level_3/fss_identify/c/private-identify.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_identify_h -#define _PRIVATE_fss_identify_h +#ifndef _PRIVATE_identify_h +#define _PRIVATE_identify_h #ifdef __cplusplus extern "C" { @@ -41,18 +41,6 @@ extern "C" { #endif // _di_fss_identify_load_line_ /** - * Print the given FLL Identifier. - * - * @param main - * The main program data. - * @param id - * The Identifier to print. - */ -#ifndef _di_fss_identify_print_ - extern void fss_identify_print(fss_identify_main_t * const main, f_fll_id_t id) F_attribute_visibility_internal_d; -#endif // _di_fss_identify_print_ - -/** * Process a given pipe or file. * * @param main @@ -82,4 +70,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_identify_h +#endif // _PRIVATE_identify_h diff --git a/level_3/fss_identify/c/private-print.c b/level_3/fss_identify/c/private-print.c new file mode 100644 index 0000000..af50a2e --- /dev/null +++ b/level_3/fss_identify/c/private-print.c @@ -0,0 +1,34 @@ +#include "fss_identify.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_identify_print_ + void fss_identify_print(fss_identify_main_t * const main, f_fll_id_t id) { + + flockfile(main->output.to.stream); + + if (main->parameters[fss_identify_parameter_object_e].result == f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result != f_console_result_found_e) { + f_print(id.name, id.used, main->output.to.stream); + + if (main->parameters[fss_identify_parameter_object_e].result != f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result == f_console_result_found_e) { + f_print_terminated(f_fss_type_header_part5_s, main->output.to.stream); + } + } + + if (main->parameters[fss_identify_parameter_object_e].result != f_console_result_found_e || main->parameters[fss_identify_parameter_content_e].result == f_console_result_found_e) { + fl_print_format("%04_ui", main->output.to.stream, id.type); + } + + f_print_character(f_string_eol_s[0], main->output.to.stream); + + funlockfile(main->output.to.stream); + } +#endif // _di_fss_identify_print_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_identify/c/private-print.h b/level_3/fss_identify/c/private-print.h new file mode 100644 index 0000000..cc92489 --- /dev/null +++ b/level_3/fss_identify/c/private-print.h @@ -0,0 +1,31 @@ +/** + * FLL - Level 3 + * + * Project: FSS Identify + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the given FLL Identifier. + * + * @param main + * The main program data. + * @param id + * The Identifier to print. + */ +#ifndef _di_fss_identify_print_ + extern void fss_identify_print(fss_identify_main_t * const main, f_fll_id_t id) F_attribute_visibility_internal_d; +#endif // _di_fss_identify_print_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_identify/data/build/settings b/level_3/fss_identify/data/build/settings index d7cb3ce..9dd12fa 100644 --- a/level_3/fss_identify/data/build/settings +++ b/level_3/fss_identify/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_identify.c private-common.c private-fss_identify.c +build_sources_library fss_identify.c private-common.c private-identify.c private-print.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_payload_read/c/fss_payload_read.c b/level_3/fss_payload_read/c/fss_payload_read.c index fe45a11..f11cccd 100644 --- a/level_3/fss_payload_read/c/fss_payload_read.c +++ b/level_3/fss_payload_read/c/fss_payload_read.c @@ -1,6 +1,7 @@ #include "fss_payload_read.h" #include "private-common.h" -#include "private-fss_payload_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_payload_read/c/private-print.c b/level_3/fss_payload_read/c/private-print.c new file mode 100644 index 0000000..4e79f01 --- /dev/null +++ b/level_3/fss_payload_read/c/private-print.c @@ -0,0 +1,312 @@ +#include "fss_payload_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_fss_payload_read_print_at_ + void fss_payload_read_print_at(fss_payload_read_main_t * const main, const bool is_payload, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) { + + if (at >= data->contents.used) { + return; + } + + if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_payload_read_data_option_empty_d))) { + flockfile(main->output.to.stream); + + if (data->option & fss_payload_read_data_option_object_d) { + if (data->option & fss_payload_read_data_option_trim_d) { + fl_print_trim_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); + } + else { + f_print_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); + } + + fss_payload_read_print_object_end(main); + } + + if (data->option & fss_payload_read_data_option_content_d) { + if (data->contents.array[at].used) { + if (!is_payload) { + fss_payload_read_print_content_ignore(main); + } + + if (is_payload) { + f_print_dynamic_partial_raw(data->buffer, data->contents.array[at].array[0], main->output.to.stream); + } + else { + f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); + } + + if (!is_payload) { + fss_payload_read_print_content_ignore(main); + } + } + } + + if (!is_payload) { + fss_payload_read_print_set_end(main); + } + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_at_ + +#ifndef _di_fss_payload_read_print_at_extended_ + void fss_payload_read_print_at_extended(fss_payload_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) { + + if (at >= data->contents_header.used) { + return; + } + + flockfile(main->output.to.stream); + + if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (data->contents_header.array[at].used || (data->option & fss_payload_read_data_option_empty_d))) { + if (data->option & fss_payload_read_data_option_object_d) { + if (data->option & fss_payload_read_data_option_trim_d) { + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { + f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + fl_print_trim_except_dynamic_partial(data->buffer, data->objects_header.array[at], delimits_object, main->output.to.stream); + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { + f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + else { + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { + f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->objects_header.array[at], delimits_object, main->output.to.stream); + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { + f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + + if (data->option & fss_payload_read_data_option_content_d) { + fss_payload_read_print_object_end_extended(main); + } + } + + bool content_printed = F_false; + + if ((data->option & fss_payload_read_data_option_content_d) && data->contents_header.array[at].used) { + if (data->option & fss_payload_read_data_option_select_d) { + if (data->select < data->contents_header.array[at].used) { + content_printed = F_true; + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[data->select]) { + f_print_character_safely(data->quotes_content_header.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->contents_header.array[at].array[data->select], delimits_content, main->output.to.stream); + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[data->select]) { + f_print_character_safely(data->quotes_content_header.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + } + } + else { + for (f_array_length_t i = 0; i < data->contents_header.array[at].used; ++i) { + + if (data->contents_header.array[at].array[i].start > data->contents_header.array[at].array[i].stop) { + continue; + } + + content_printed = F_true; + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[i]) { + f_print_character_safely(data->quotes_content_header.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + f_print_except_dynamic_partial(data->buffer, data->contents_header.array[at].array[i], delimits_content, main->output.to.stream); + + if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[i]) { + f_print_character_safely(data->quotes_content_header.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); + } + + if (i + 1 < data->contents_header.array[at].used && data->contents_header.array[at].array[i + 1].start <= data->contents_header.array[at].array[i + 1].stop) { + fss_payload_read_print_content_end_extended(main); + } + } // for + } + } + + if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (content_printed || (data->option & fss_payload_read_data_option_empty_d))) { + fss_payload_read_print_set_end_extended(main); + } + + funlockfile(main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_at_extended_ + +#ifndef _di_fss_payload_read_print_at_object_ + void fss_payload_read_print_at_object(fss_payload_read_main_t * const main, fss_payload_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { + + if (at >= data->objects.used) { + return; + } + + if (data->option & fss_payload_read_data_option_trim_d) { + fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + else { + f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); + } + + fss_payload_read_print_object_end(main); + } +#endif // _di_fss_payload_read_print_at_object_ + +#ifndef _di_fss_payload_read_print_at_total_exteded_ + f_status_t fss_payload_read_print_at_total_extended(fss_payload_read_main_t * const main, const f_array_length_t at, fss_payload_read_data_t *data) { + + if (data->option & fss_payload_read_data_option_select_d) { + if (data->option & fss_payload_read_data_option_object_d) { + flockfile(main->output.to.stream); + + fss_payload_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + + if (data->select < data->contents_header.array[at].used) { + if (data->contents_header.array[at].array[data->select].start <= data->contents_header.array[at].array[data->select].stop || (data->option & fss_payload_read_data_option_empty_d)) { + flockfile(main->output.to.stream); + + fss_payload_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + } + } + else if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_empty_d)) { + flockfile(main->output.to.stream); + + fss_payload_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + else if (data->contents_header.array[at].used) { + for (f_array_length_t j = 0; j < data->contents_header.array[at].used; ++j) { + + if (data->contents_header.array[at].array[j].start <= data->contents_header.array[at].array[j].stop) { + flockfile(main->output.to.stream); + + fss_payload_read_print_one(main); + + funlockfile(main->output.to.stream); + + return F_success; + } + } // for + } + + return F_none; + } +#endif // _di_fss_payload_read_print_at_total_extended_ + +#ifndef _di_fss_payload_read_print_content_end_extended_ + void fss_payload_read_print_content_end_extended(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_start_s, main->output.to.stream); + } + else { + f_print_character(F_fss_space_s[0], main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_content_end_extended_ + +#ifndef _di_fss_payload_read_print_content_ignore_ + void fss_payload_read_print_content_ignore(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_ignore_s, main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_content_ignore_ + +#ifndef _di_fss_payload_read_print_object_end_ + void fss_payload_read_print_object_end(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_start_s, main->output.to.stream); + } + else { + if (main->parameters[fss_payload_read_parameter_content_e].result == f_console_result_found_e) { + f_print_character(f_fss_basic_list_open_s[0], main->output.to.stream); + f_print_character(f_fss_basic_list_open_end_s[0], main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } + } +#endif // _di_fss_payload_read_print_object_end_ + +#ifndef _di_fss_payload_read_print_object_end_extended_ + void fss_payload_read_print_object_end_extended(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); + } + else { + f_print_character(F_fss_space_s[0], main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_object_end_extended_ + +#ifndef _di_fss_payload_read_print_set_end_ + void fss_payload_read_print_set_end(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_set_end_ + +#ifndef _di_fss_payload_read_print_set_end_extended_ + void fss_payload_read_print_set_end_extended(fss_payload_read_main_t * const main) { + + if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { + f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); + } + else { + f_print_character(f_fss_eol_s[0], main->output.to.stream); + } + } +#endif // _di_fss_payload_read_print_set_end_extended_ + +#ifndef _di_fss_payload_read_print_one_ + void fss_payload_read_print_one(fss_payload_read_main_t * const main) { + + f_print_character(f_string_ascii_1_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_payload_read_print_one_ + +#ifndef _di_fss_payload_read_print_zero_ + void fss_payload_read_print_zero(fss_payload_read_main_t * const main) { + + f_print_character(f_string_ascii_0_s[0], main->output.to.stream); + f_print_character(f_string_eol_s[0], main->output.to.stream); + } +#endif // _di_fss_payload_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/fss_payload_read/c/private-print.h b/level_3/fss_payload_read/c/private-print.h new file mode 100644 index 0000000..e3abe57 --- /dev/null +++ b/level_3/fss_payload_read/c/private-print.h @@ -0,0 +1,177 @@ +/** + * FLL - Level 3 + * + * Project: FSS + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print the Object and Content at the given position. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param is_payload + * If TRUE, then this is associated with a "payload" Object. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_payload_read_print_at_ + extern void fss_payload_read_print_at(fss_payload_read_main_t * const main, const bool is_payload, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_at_ + +/** + * Print the Object and Content at the given position for the FSS-0001 Extended Content at depth 1. + * + * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. + * + * @param main + * The main program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + * @param delimits_content + * The delimits to be applied to Content. + * @param data + * The program data. + */ +#ifndef _di_fss_payload_read_print_at_extended_ + extern void fss_payload_read_print_at_extended(fss_payload_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_at_extended_ + +/** + * Explicitly print the Object at the given position. + * + * @param main + * The main program data. + * @param data + * The program data. + * @param at + * The index in the Objects and Contents to print. + * @param delimits_object + * The delimits to be applied to an Object. + */ +#ifndef _di_fss_payload_read_print_at_object_ + extern void fss_payload_read_print_at_object(fss_payload_read_main_t * const main, fss_payload_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_at_object_ + +/** + * Print total count at the specified Object/Content position for the FSS-0001 Extended Content at depth 1. + * + * @param main + * The main program data. + * @param at + * The Object/Content position. + * @param data + * The program data. + * + * @return + * F_none on success but nothig was matched (and total was printed). + * F_success on success and something was matched (and total was printed). + */ +#ifndef _di_fss_payload_read_print_at_total_extended_ + extern f_status_t fss_payload_read_print_at_total_extended(fss_payload_read_main_t * const main, const f_array_length_t at, fss_payload_read_data_t *data) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_at_total_extended_ + +/** + * Print the end of a Content for the FSS-0001 Extended Content at depth 1. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_content_end_extended_ + extern void fss_payload_read_print_content_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_content_end_extended_ + +/** + * Print the ignore character for Content. + * + * This is only used in pipe output mode. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_content_ignore_ + extern void fss_payload_read_print_content_ignore(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_content_ignore_ + +/** + * Print the end of an Object (which is essentially the start of Content). + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_object_end_ + extern void fss_payload_read_print_object_end(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_object_end_ + +/** + * Print the end of an Object (which is essentially the start of Content) for the FSS-0001 Extended Content at depth 1. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_object_end_extended_ + extern void fss_payload_read_print_object_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_object_end_extended_ + +/** + * Print the number one and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_one_ + extern void fss_payload_read_print_one(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_one_ + +/** + * Print the end of an Object/Content set. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_set_end_ + extern void fss_payload_read_print_set_end(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_set_end_ + +/** + * Print the end of an Object/Content set for the FSS-0001 Extended Content at depth 1. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_set_end_extended_ + extern void fss_payload_read_print_set_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_set_end_extended_ + +/** + * Print the number zero and a newline. + * + * @param main + * The main program data. + */ +#ifndef _di_fss_payload_read_print_zero_ + extern void fss_payload_read_print_zero(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; +#endif // _di_fss_payload_read_print_zero_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/fss_payload_read/c/private-fss_payload_read.c b/level_3/fss_payload_read/c/private-read.c similarity index 76% rename from level_3/fss_payload_read/c/private-fss_payload_read.c rename to level_3/fss_payload_read/c/private-read.c index 6da1a81..8c36dbc 100644 --- a/level_3/fss_payload_read/c/private-fss_payload_read.c +++ b/level_3/fss_payload_read/c/private-read.c @@ -1,6 +1,7 @@ #include "fss_payload_read.h" #include "private-common.h" -#include "private-fss_payload_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -334,307 +335,6 @@ extern "C" { } #endif // _di_fss_payload_read_load_number_ -#ifndef _di_fss_payload_read_print_at_ - void fss_payload_read_print_at(fss_payload_read_main_t * const main, const bool is_payload, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) { - - if (at >= data->contents.used) { - return; - } - - if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (data->contents.array[at].used || (data->option & fss_payload_read_data_option_empty_d))) { - flockfile(main->output.to.stream); - - if (data->option & fss_payload_read_data_option_object_d) { - if (data->option & fss_payload_read_data_option_trim_d) { - fl_print_trim_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); - } - else { - f_print_except_in_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, data->comments, main->output.to.stream); - } - - fss_payload_read_print_object_end(main); - } - - if (data->option & fss_payload_read_data_option_content_d) { - if (data->contents.array[at].used) { - if (!is_payload) { - fss_payload_read_print_content_ignore(main); - } - - if (is_payload) { - f_print_dynamic_partial_raw(data->buffer, data->contents.array[at].array[0], main->output.to.stream); - } - else { - f_print_except_in_dynamic_partial(data->buffer, data->contents.array[at].array[0], delimits_content, data->comments, main->output.to.stream); - } - - if (!is_payload) { - fss_payload_read_print_content_ignore(main); - } - } - } - - if (!is_payload) { - fss_payload_read_print_set_end(main); - } - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_at_ - -#ifndef _di_fss_payload_read_print_at_extended_ - void fss_payload_read_print_at_extended(fss_payload_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) { - - if (at >= data->contents_header.used) { - return; - } - - flockfile(main->output.to.stream); - - if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (data->contents_header.array[at].used || (data->option & fss_payload_read_data_option_empty_d))) { - if (data->option & fss_payload_read_data_option_object_d) { - if (data->option & fss_payload_read_data_option_trim_d) { - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { - f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - fl_print_trim_except_dynamic_partial(data->buffer, data->objects_header.array[at], delimits_object, main->output.to.stream); - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { - f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - else { - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { - f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->objects_header.array[at], delimits_object, main->output.to.stream); - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_object_header.array[at]) { - f_print_character_safely(data->quotes_object_header.array[at] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - - if (data->option & fss_payload_read_data_option_content_d) { - fss_payload_read_print_object_end_extended(main); - } - } - - bool content_printed = F_false; - - if ((data->option & fss_payload_read_data_option_content_d) && data->contents_header.array[at].used) { - if (data->option & fss_payload_read_data_option_select_d) { - if (data->select < data->contents_header.array[at].used) { - content_printed = F_true; - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[data->select]) { - f_print_character_safely(data->quotes_content_header.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->contents_header.array[at].array[data->select], delimits_content, main->output.to.stream); - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[data->select]) { - f_print_character_safely(data->quotes_content_header.array[at].array[data->select] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - } - } - else { - for (f_array_length_t i = 0; i < data->contents_header.array[at].used; ++i) { - - if (data->contents_header.array[at].array[i].start > data->contents_header.array[at].array[i].stop) { - continue; - } - - content_printed = F_true; - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[i]) { - f_print_character_safely(data->quotes_content_header.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - f_print_except_dynamic_partial(data->buffer, data->contents_header.array[at].array[i], delimits_content, main->output.to.stream); - - if ((data->option & fss_payload_read_data_option_raw_d) && data->quotes_content_header.array[at].array[i]) { - f_print_character_safely(data->quotes_content_header.array[at].array[i] == f_fss_quote_type_single_e ? f_fss_quote_single_s[0] : f_fss_quote_double_s[0], main->output.to.stream); - } - - if (i + 1 < data->contents_header.array[at].used && data->contents_header.array[at].array[i + 1].start <= data->contents_header.array[at].array[i + 1].stop) { - fss_payload_read_print_content_end_extended(main); - } - } // for - } - } - - if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_content_d) && (content_printed || (data->option & fss_payload_read_data_option_empty_d))) { - fss_payload_read_print_set_end_extended(main); - } - - funlockfile(main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_at_extended_ - -#ifndef _di_fss_payload_read_print_at_object_ - void fss_payload_read_print_at_object(fss_payload_read_main_t * const main, fss_payload_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) { - - if (at >= data->objects.used) { - return; - } - - if (data->option & fss_payload_read_data_option_trim_d) { - fl_print_trim_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - else { - f_print_except_dynamic_partial(data->buffer, data->objects.array[at], delimits_object, main->output.to.stream); - } - - fss_payload_read_print_object_end(main); - } -#endif // _di_fss_payload_read_print_at_object_ - -#ifndef _di_fss_payload_read_print_at_total_exteded_ - f_status_t fss_payload_read_print_at_total_extended(fss_payload_read_main_t * const main, const f_array_length_t at, fss_payload_read_data_t *data) { - - if (data->option & fss_payload_read_data_option_select_d) { - if (data->option & fss_payload_read_data_option_object_d) { - flockfile(main->output.to.stream); - - fss_payload_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - - if (data->select < data->contents_header.array[at].used) { - if (data->contents_header.array[at].array[data->select].start <= data->contents_header.array[at].array[data->select].stop || (data->option & fss_payload_read_data_option_empty_d)) { - flockfile(main->output.to.stream); - - fss_payload_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - } - } - else if ((data->option & fss_payload_read_data_option_object_d) || (data->option & fss_payload_read_data_option_empty_d)) { - flockfile(main->output.to.stream); - - fss_payload_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - else if (data->contents_header.array[at].used) { - for (f_array_length_t j = 0; j < data->contents_header.array[at].used; ++j) { - - if (data->contents_header.array[at].array[j].start <= data->contents_header.array[at].array[j].stop) { - flockfile(main->output.to.stream); - - fss_payload_read_print_one(main); - - funlockfile(main->output.to.stream); - - return F_success; - } - } // for - } - - return F_none; - } -#endif // _di_fss_payload_read_print_at_total_extended_ - -#ifndef _di_fss_payload_read_print_content_end_extended_ - void fss_payload_read_print_content_end_extended(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_start_s, main->output.to.stream); - } - else { - f_print_character(F_fss_space_s[0], main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_content_end_extended_ - -#ifndef _di_fss_payload_read_print_content_ignore_ - void fss_payload_read_print_content_ignore(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_ignore_s, main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_content_ignore_ - -#ifndef _di_fss_payload_read_print_object_end_ - void fss_payload_read_print_object_end(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_start_s, main->output.to.stream); - } - else { - if (main->parameters[fss_payload_read_parameter_content_e].result == f_console_result_found_e) { - f_print_character(f_fss_basic_list_open_s[0], main->output.to.stream); - f_print_character(f_fss_basic_list_open_end_s[0], main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } - } -#endif // _di_fss_payload_read_print_object_end_ - -#ifndef _di_fss_payload_read_print_object_end_extended_ - void fss_payload_read_print_object_end_extended(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); - } - else { - f_print_character(F_fss_space_s[0], main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_object_end_extended_ - -#ifndef _di_fss_payload_read_print_set_end_ - void fss_payload_read_print_set_end(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_set_end_ - -#ifndef _di_fss_payload_read_print_set_end_extended_ - void fss_payload_read_print_set_end_extended(fss_payload_read_main_t * const main) { - - if (main->parameters[fss_payload_read_parameter_pipe_e].result == f_console_result_found_e) { - f_print_character(fss_payload_read_pipe_content_end_s, main->output.to.stream); - } - else { - f_print_character(f_fss_eol_s[0], main->output.to.stream); - } - } -#endif // _di_fss_payload_read_print_set_end_extended_ - -#ifndef _di_fss_payload_read_print_one_ - void fss_payload_read_print_one(fss_payload_read_main_t * const main) { - - f_print_character(f_string_ascii_1_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_payload_read_print_one_ - -#ifndef _di_fss_payload_read_print_zero_ - void fss_payload_read_print_zero(fss_payload_read_main_t * const main) { - - f_print_character(f_string_ascii_0_s[0], main->output.to.stream); - f_print_character(f_string_eol_s[0], main->output.to.stream); - } -#endif // _di_fss_payload_read_print_zero_ - #ifndef _di_fss_payload_read_process_ f_status_t fss_payload_read_process(fss_payload_read_main_t * const main, const f_console_arguments_t *arguments, fss_payload_read_data_t *data) { diff --git a/level_3/fss_payload_read/c/private-fss_payload_read.h b/level_3/fss_payload_read/c/private-read.h similarity index 70% rename from level_3/fss_payload_read/c/private-fss_payload_read.h rename to level_3/fss_payload_read/c/private-read.h index 5ff982a..39494af 100644 --- a/level_3/fss_payload_read/c/private-fss_payload_read.h +++ b/level_3/fss_payload_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_payload_read_h -#define _PRIVATE_fss_payload_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -152,164 +152,6 @@ extern "C" { #endif // _di_fss_payload_read_load_number_ /** - * Print the Object and Content at the given position. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param is_payload - * If TRUE, then this is associated with a "payload" Object. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_payload_read_print_at_ - extern void fss_payload_read_print_at(fss_payload_read_main_t * const main, const bool is_payload, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_at_ - -/** - * Print the Object and Content at the given position for the FSS-0001 Extended Content at depth 1. - * - * Only what is requested to print (Object, Content, both, or neither) will be printed, if there is something to print. - * - * @param main - * The main program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - * @param delimits_content - * The delimits to be applied to Content. - * @param data - * The program data. - */ -#ifndef _di_fss_payload_read_print_at_extended_ - extern void fss_payload_read_print_at_extended(fss_payload_read_main_t * const main, const f_array_length_t at, const f_fss_delimits_t delimits_object, const f_fss_delimits_t delimits_content, fss_payload_read_data_t * const data) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_at_extended_ - -/** - * Explicitly print the Object at the given position. - * - * @param main - * The main program data. - * @param data - * The program data. - * @param at - * The index in the Objects and Contents to print. - * @param delimits_object - * The delimits to be applied to an Object. - */ -#ifndef _di_fss_payload_read_print_at_object_ - extern void fss_payload_read_print_at_object(fss_payload_read_main_t * const main, fss_payload_read_data_t * const data, const f_array_length_t at, const f_fss_delimits_t delimits_object) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_at_object_ - -/** - * Print total count at the specified Object/Content position for the FSS-0001 Extended Content at depth 1. - * - * @param main - * The main program data. - * @param at - * The Object/Content position. - * @param data - * The program data. - * - * @return - * F_none on success but nothig was matched (and total was printed). - * F_success on success and something was matched (and total was printed). - */ -#ifndef _di_fss_payload_read_print_at_total_extended_ - extern f_status_t fss_payload_read_print_at_total_extended(fss_payload_read_main_t * const main, const f_array_length_t at, fss_payload_read_data_t *data) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_at_total_extended_ - -/** - * Print the end of a Content for the FSS-0001 Extended Content at depth 1. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_content_end_extended_ - extern void fss_payload_read_print_content_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_content_end_extended_ - -/** - * Print the ignore character for Content. - * - * This is only used in pipe output mode. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_content_ignore_ - extern void fss_payload_read_print_content_ignore(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_content_ignore_ - -/** - * Print the end of an Object (which is essentially the start of Content). - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_object_end_ - extern void fss_payload_read_print_object_end(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_object_end_ - -/** - * Print the end of an Object (which is essentially the start of Content) for the FSS-0001 Extended Content at depth 1. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_object_end_extended_ - extern void fss_payload_read_print_object_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_object_end_extended_ - -/** - * Print the number one and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_one_ - extern void fss_payload_read_print_one(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_one_ - -/** - * Print the end of an Object/Content set. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_set_end_ - extern void fss_payload_read_print_set_end(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_set_end_ - -/** - * Print the end of an Object/Content set for the FSS-0001 Extended Content at depth 1. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_set_end_extended_ - extern void fss_payload_read_print_set_end_extended(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_set_end_extended_ - -/** - * Print the number zero and a newline. - * - * @param main - * The main program data. - */ -#ifndef _di_fss_payload_read_print_zero_ - extern void fss_payload_read_print_zero(fss_payload_read_main_t * const main) F_attribute_visibility_internal_d; -#endif // _di_fss_payload_read_print_zero_ - -/** * Perform the payload read processing on the buffer. * * This will print an error message on error. @@ -568,4 +410,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_payload_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/fss_payload_read/data/build/settings b/level_3/fss_payload_read/data/build/settings index db7c5aa..32430dc 100644 --- a/level_3/fss_payload_read/data/build/settings +++ b/level_3/fss_payload_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_payload_read.c private-common.c private-fss_payload_read.c +build_sources_library fss_payload_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/fss_payload_write/c/fss_payload_write.c b/level_3/fss_payload_write/c/fss_payload_write.c index 00a5950..b6c79d0 100644 --- a/level_3/fss_payload_write/c/fss_payload_write.c +++ b/level_3/fss_payload_write/c/fss_payload_write.c @@ -1,6 +1,6 @@ #include "fss_payload_write.h" #include "private-common.h" -#include "private-fss_payload_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_payload_write/c/private-fss_payload_write.c b/level_3/fss_payload_write/c/private-write.c similarity index 99% rename from level_3/fss_payload_write/c/private-fss_payload_write.c rename to level_3/fss_payload_write/c/private-write.c index 5db4116..694adf7 100644 --- a/level_3/fss_payload_write/c/private-fss_payload_write.c +++ b/level_3/fss_payload_write/c/private-write.c @@ -1,6 +1,6 @@ #include "fss_payload_write.h" #include "private-common.h" -#include "private-fss_payload_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/fss_payload_write/c/private-fss_payload_write.h b/level_3/fss_payload_write/c/private-write.h similarity index 96% rename from level_3/fss_payload_write/c/private-fss_payload_write.h rename to level_3/fss_payload_write/c/private-write.h index 8ecf302..dedaa62 100644 --- a/level_3/fss_payload_write/c/private-fss_payload_write.h +++ b/level_3/fss_payload_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_fss_payload_write_h -#define _PRIVATE_fss_payload_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -98,4 +98,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_fss_payload_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/fss_payload_write/data/build/settings b/level_3/fss_payload_write/data/build/settings index 4386341..3c8f149 100644 --- a/level_3/fss_payload_write/data/build/settings +++ b/level_3/fss_payload_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library fss_payload_write.c private-common.c private-fss_payload_write.c +build_sources_library fss_payload_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/iki_read/c/iki_read.c b/level_3/iki_read/c/iki_read.c index 1b718f2..77fda83 100644 --- a/level_3/iki_read/c/iki_read.c +++ b/level_3/iki_read/c/iki_read.c @@ -1,6 +1,6 @@ #include "iki_read.h" #include "private-common.h" -#include "private-iki_read.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/iki_read/c/private-print.c b/level_3/iki_read/c/private-print.c new file mode 100644 index 0000000..b995e85 --- /dev/null +++ b/level_3/iki_read/c/private-print.c @@ -0,0 +1,53 @@ +#include "iki_read.h" +#include "private-common.h" +#include "private-print.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _di_iki_read_substitutions_print_ + void iki_read_substitutions_print(iki_read_main_t * const main, const iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) { + + f_status_t status = F_none; + + f_array_length_t i = 0; + f_string_range_t range = f_string_range_t_initialize; + + range.start = 0; + + for (; i < substitutions.used; ++i) { + + range.stop = substitutions.array[i].replace.used - 1; + + status = fl_string_dynamic_partial_compare(substitutions.array[i].replace, main->buffer, range, iki_data.content.array[index]); + if (status == F_equal_to) break; + } // for + + if (status == F_equal_to) { + if (content_only) { + f_print_dynamic(substitutions.array[i].with, main->output.to.stream); + } + else { + range.start = iki_data.variable.array[index].start; + range.stop = iki_data.content.array[index].start - 1; + + f_print_dynamic_partial(main->buffer, range, main->output.to.stream); + + f_print_dynamic(substitutions.array[i].with, main->output.to.stream); + + range.start = iki_data.content.array[index].stop + 1; + range.stop = iki_data.variable.array[index].stop; + + f_print_dynamic_partial(main->buffer, range, main->output.to.stream); + } + } + else { + f_print_dynamic_partial(main->buffer, ranges.array[index], main->output.to.stream); + } + } +#endif // _di_iki_read_substitutions_print_ + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/level_3/iki_read/c/private-print.h b/level_3/iki_read/c/private-print.h new file mode 100644 index 0000000..bda54fb --- /dev/null +++ b/level_3/iki_read/c/private-print.h @@ -0,0 +1,40 @@ +/** + * FLL - Level 3 + * + * Project: IKI + * API Version: 0.5 + * Licenses: lgpl-2.1-or-later + */ +#ifndef _PRIVATE_print_h +#define _PRIVATE_print_h + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Print any applicable substition and if there is non then print the given range at the given index. + * + * @param main + * The main program data. + * @param iki_data + * The IKI data. + * @param ranges + * The ranges containing the desired range to print as specified by index. + * @param substitutions + * The substitions associated with the variable for the given range at the given index to use for potential printing. + * @param index + * The index used to identify the desired range in variable, content, and ranges. + * @param content_only + * Set to TRUE to only print the content when printing substituted text. + * Set to FALSE to print the entire variable when printing substituted text. + */ +#ifndef _di_iki_read_substitutions_print_ + extern void iki_read_substitutions_print(iki_read_main_t * const main, const iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d; +#endif // _di_iki_read_substitutions_print_ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // _PRIVATE_print_h diff --git a/level_3/iki_read/c/private-iki_read.c b/level_3/iki_read/c/private-read.c similarity index 93% rename from level_3/iki_read/c/private-iki_read.c rename to level_3/iki_read/c/private-read.c index 41e80fb..121aff0 100644 --- a/level_3/iki_read/c/private-iki_read.c +++ b/level_3/iki_read/c/private-read.c @@ -1,6 +1,7 @@ #include "iki_read.h" #include "private-common.h" -#include "private-iki_read.h" +#include "private-print.h" +#include "private-read.h" #ifdef __cplusplus extern "C" { @@ -604,48 +605,6 @@ extern "C" { } #endif // _di_iki_read_substitutions_identify_ -#ifndef _di_iki_read_substitutions_print_ - void iki_read_substitutions_print(iki_read_main_t * const main, const iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) { - - f_status_t status = F_none; - - f_array_length_t i = 0; - f_string_range_t range = f_string_range_t_initialize; - - range.start = 0; - - for (; i < substitutions.used; ++i) { - - range.stop = substitutions.array[i].replace.used - 1; - - status = fl_string_dynamic_partial_compare(substitutions.array[i].replace, main->buffer, range, iki_data.content.array[index]); - if (status == F_equal_to) break; - } // for - - if (status == F_equal_to) { - if (content_only) { - f_print_dynamic(substitutions.array[i].with, main->output.to.stream); - } - else { - range.start = iki_data.variable.array[index].start; - range.stop = iki_data.content.array[index].start - 1; - - f_print_dynamic_partial(main->buffer, range, main->output.to.stream); - - f_print_dynamic(substitutions.array[i].with, main->output.to.stream); - - range.start = iki_data.content.array[index].stop + 1; - range.stop = iki_data.variable.array[index].stop; - - f_print_dynamic_partial(main->buffer, range, main->output.to.stream); - } - } - else { - f_print_dynamic_partial(main->buffer, ranges.array[index], main->output.to.stream); - } - } -#endif // _di_iki_read_substitutions_print_ - #ifdef __cplusplus } // extern "C" #endif diff --git a/level_3/iki_read/c/private-iki_read.h b/level_3/iki_read/c/private-read.h similarity index 82% rename from level_3/iki_read/c/private-iki_read.h rename to level_3/iki_read/c/private-read.h index ec1aa50..5fa6fe1 100644 --- a/level_3/iki_read/c/private-iki_read.h +++ b/level_3/iki_read/c/private-read.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_iki_read_h -#define _PRIVATE_iki_read_h +#ifndef _PRIVATE_read_h +#define _PRIVATE_read_h #ifdef __cplusplus extern "C" { @@ -156,29 +156,8 @@ extern "C" { extern f_status_t iki_read_substitutions_identify(iki_read_main_t * const main, const f_console_arguments_t *arguments, const f_string_t file_name, f_iki_vocabulary_t *vocabulary, iki_read_substitutions_t *substitutionss) F_attribute_visibility_internal_d; #endif // _di_iki_read_substitutions_identify_ -/** - * Print any applicable substition and if there is non then print the given range at the given index. - * - * @param main - * The main program data. - * @param iki_data - * The IKI data. - * @param ranges - * The ranges containing the desired range to print as specified by index. - * @param substitutions - * The substitions associated with the variable for the given range at the given index to use for potential printing. - * @param index - * The index used to identify the desired range in variable, content, and ranges. - * @param content_only - * Set to TRUE to only print the content when printing substituted text. - * Set to FALSE to print the entire variable when printing substituted text. - */ -#ifndef _di_iki_read_substitutions_print_ - extern void iki_read_substitutions_print(iki_read_main_t * const main, const iki_data_t iki_data, const f_string_ranges_t ranges, const iki_read_substitutions_t substitutions, const f_array_length_t index, const bool content_only) F_attribute_visibility_internal_d; -#endif // _di_iki_read_substitutions_print_ - #ifdef __cplusplus } // extern "C" #endif -#endif // _PRIVATE_iki_read_h +#endif // _PRIVATE_read_h diff --git a/level_3/iki_read/data/build/settings b/level_3/iki_read/data/build/settings index 53837e4..731e775 100644 --- a/level_3/iki_read/data/build/settings +++ b/level_3/iki_read/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library iki_read.c private-common.c private-iki_read.c +build_sources_library iki_read.c private-common.c private-print.c private-read.c build_sources_library_shared build_sources_library_static build_sources_program main.c diff --git a/level_3/iki_write/c/iki_write.c b/level_3/iki_write/c/iki_write.c index a3711b1..a882f63 100644 --- a/level_3/iki_write/c/iki_write.c +++ b/level_3/iki_write/c/iki_write.c @@ -1,6 +1,6 @@ #include "iki_write.h" #include "private-common.h" -#include "private-iki_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/iki_write/c/private-iki_write.c b/level_3/iki_write/c/private-write.c similarity index 98% rename from level_3/iki_write/c/private-iki_write.c rename to level_3/iki_write/c/private-write.c index 1fec4f2..45acea7 100644 --- a/level_3/iki_write/c/private-iki_write.c +++ b/level_3/iki_write/c/private-write.c @@ -1,6 +1,6 @@ #include "iki_write.h" #include "private-common.h" -#include "private-iki_write.h" +#include "private-write.h" #ifdef __cplusplus extern "C" { diff --git a/level_3/iki_write/c/private-iki_write.h b/level_3/iki_write/c/private-write.h similarity index 92% rename from level_3/iki_write/c/private-iki_write.h rename to level_3/iki_write/c/private-write.h index a08169f..7c5a1a9 100644 --- a/level_3/iki_write/c/private-iki_write.h +++ b/level_3/iki_write/c/private-write.h @@ -5,8 +5,8 @@ * API Version: 0.5 * Licenses: lgpl-2.1-or-later */ -#ifndef _PRIVATE_iki_write_h -#define _PRIVATE_iki_write_h +#ifndef _PRIVATE_write_h +#define _PRIVATE_write_h #ifdef __cplusplus extern "C" { @@ -41,4 +41,4 @@ extern "C" { } // extern "C" #endif -#endif // _PRIVATE_iki_write_h +#endif // _PRIVATE_write_h diff --git a/level_3/iki_write/data/build/settings b/level_3/iki_write/data/build/settings index 5a0b2c7..f9f8e92 100644 --- a/level_3/iki_write/data/build/settings +++ b/level_3/iki_write/data/build/settings @@ -26,7 +26,7 @@ build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_libraries_shared build_libraries_static -build_sources_library iki_write.c private-common.c private-iki_write.c +build_sources_library iki_write.c private-common.c private-write.c build_sources_library_shared build_sources_library_static build_sources_program main.c -- 1.8.3.1