The functions have gotten too large an are in a need of cleanup.
Create additional source files and move functions around as appropriate.
Do some function renaming as well.
Move the print functions into separate print source files.
This is done only for functions whose sole purpose is printing and is not nor should it be done for functions that happen to have printing within them.
The entry pre-process and process functions should be in the entry source files.
Fix the name of those functions to start with "controller_entry_" rather than starting with "controller_process_".
Move any structure construct and destruct functions into the common.h and common.c that are not already there.
Break out the build settings file settings into multiple lines.
I prefer not to have too many extra lines, but there is a point when the lines get absurdly too long.
The lines are broken up by some context or pattern.
#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"
-#include "private-controller.h"
#ifdef __cplusplus
extern "C" {
#ifndef _di_controller_print_help_
f_status_t controller_print_help(const controller_main_t main) {
- controller_print_lock(main.output.to, 0);
+ 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);
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_print_unlock_flush(main.output.to, 0);
+ controller_unlock_print_flush(main.output.to, 0);
return F_none;
}
}
if (main->parameters[controller_parameter_version].result == f_console_result_found) {
- controller_print_lock(main->output.to, 0);
+ controller_lock_print(main->output.to, 0);
fll_program_print_version(main->output.to, controller_program_version_s);
- controller_print_unlock_flush(main->output.to, 0);
+ controller_unlock_print_flush(main->output.to, 0);
controller_main_delete(main);
return F_none;
if (main->parameters[controller_parameter_settings].result == f_console_result_found) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, 0);
+ 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("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
- controller_print_unlock_flush(main->error.to, 0);
+ controller_unlock_print_flush(main->error.to, 0);
}
status = F_status_set_error(F_parameter);
if (F_status_is_error_not(status)) {
if (main->parameters[controller_parameter_pid].result == f_console_result_found) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, 0);
+ 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("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
- controller_print_unlock_flush(main->error.to, 0);
+ controller_unlock_print_flush(main->error.to, 0);
}
status = F_status_set_error(F_parameter);
if (F_status_is_error_not(status)) {
if (main->parameters[controller_parameter_control].result == f_console_result_found) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, 0);
+ 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_control_s, main->context.set.notable);
fl_print_format("%[' was specified, but no value was given.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]);
- controller_print_unlock_flush(main->error.to, 0);
+ controller_unlock_print_flush(main->error.to, 0);
}
status = F_status_set_error(F_parameter);
}
else {
if (main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(main->warning.to, 0);
+ 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_control_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_print_unlock_flush(main->warning.to, 0);
+ controller_unlock_print_flush(main->warning.to, 0);
}
}
}
if (F_status_is_error_not(status) && main->parameters[controller_parameter_daemon].result == f_console_result_found) {
if (main->parameters[controller_parameter_validate].result == f_console_result_found) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, 0);
+ 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_print_unlock_flush(main->error.to, 0);
+ controller_unlock_print_flush(main->error.to, 0);
}
status = F_status_set_error(F_parameter);
if (F_status_is_error(status_delete) && main->warning.verbosity == f_console_verbosity_debug) {
if (F_status_set_fine(status_delete) == F_number_not) {
- controller_print_lock(main->warning.to, 0);
+ 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("%[%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_print_unlock_flush(main->warning.to, 0);
+ controller_unlock_print_flush(main->warning.to, 0);
}
else {
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);
#include "controller.h"
#include "private-common.h"
-#include "private-thread.h"
-#include "private-rule.h"
#ifdef __cplusplus
extern "C" {
}
#endif // _di_controller_entry_actions_delete_simple_
+#ifndef _di_controller_entry_actions_increase_by_
+ f_status_t controller_entry_actions_increase_by(const f_array_length_t amount, controller_entry_actions_t *actions) {
+
+ if (actions->used + amount > actions->size) {
+ if (actions->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(actions->size, actions->used + amount, sizeof(controller_entry_action_t), (void **) & actions->array);
+
+ if (F_status_is_error_not(status)) {
+ actions->size = actions->used + amount;
+ }
+
+ return status;
+ }
+
+ return F_data_not;
+ }
+#endif // _di_controller_entry_actions_increase_by_
+
#ifndef _di_controller_entry_item_delete_simple_
void controller_entry_item_delete_simple(controller_entry_item_t *item) {
}
#endif // _di_controller_entry_items_delete_simple_
-#ifndef _di_controller_error_file_print_
- void controller_error_file_print(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, controller_thread_t *thread) {
+#ifndef _di_controller_entry_items_increase_by_
+ f_status_t controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *items) {
- if (print.verbosity == f_console_verbosity_quiet) return;
-
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
- 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_error_file_print_
-#ifndef _di_controller_error_print_
- void controller_error_print(const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) {
-
- if (print.verbosity == f_console_verbosity_quiet) return;
- if (status == F_interrupt) return;
+ 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);
+ }
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
- if (thread) {
- f_thread_mutex_lock(&thread->lock.print);
- }
+ const f_status_t status = f_memory_resize(items->size, items->used + amount, sizeof(controller_entry_item_t), (void **) & items->array);
- fll_error_print(print, status, function, fallback);
+ if (F_status_is_error_not(status)) {
+ items->size = items->used + amount;
+ }
- if (thread) {
- f_thread_mutex_unlock(&thread->lock.print);
+ return status;
}
- }
-#endif // _di_controller_error_print_
-#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;
+ return F_data_not;
}
-#endif // _di_controller_lock_create_
+#endif // _di_controller_entry_items_increase_by_
#ifndef _di_controller_lock_delete_mutex_
void controller_lock_delete_mutex(f_thread_mutex_t *mutex) {
}
#endif // _di_controller_lock_delete_simple_
-#ifndef _di_controller_lock_error_critical_print_
- void controller_lock_error_critical_print(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_signal) {
- return;
- }
-
- if (print.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(print.to, thread);
- }
- }
-#endif // _di_controller_lock_error_critical_print_
-
-#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_signal;
- }
- }
- 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, 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_signal;
- }
- }
- 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, thread, lock);
- }
-#endif // _di_controller_lock_write_process_type_
-
#ifndef _di_controller_pids_increase_
f_status_t controller_pids_increase(controller_pids_t *pids) {
}
#endif // _di_controller_pids_resize_
-#ifndef _di_controller_print_lock_
- void controller_print_lock(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_print_lock_
-
-#ifndef _di_controller_print_unlock_flush_
- void controller_print_unlock_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_print_unlock_flush_
-
#ifndef _di_controller_process_delete_simple_
void controller_process_delete_simple(controller_process_t *process) {
}
#endif // _di_controller_process_delete_simple_
-#ifndef _di_controller_process_wait_
- f_status_t controller_process_wait(const controller_global_t global, controller_process_t *process) {
-
- if (!controller_thread_is_enabled_process(process, global.thread)) {
- return F_signal;
- }
-
- 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_signal;
- }
-
- if (F_status_is_error(status)) {
- break;
- }
-
- status_lock = controller_lock_read_process(process, global.thread, &process->lock);
-
- if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(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 || process->state == controller_process_state_busy)) {
- f_thread_unlock(&process->lock);
-
- return F_none;
- }
- else 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_
-
#ifndef _di_controller_processs_delete_simple_
void controller_processs_delete_simple(controller_processs_t *processs) {
}
#endif // _di_controller_rule_actions_delete_simple_
+#ifndef _di_controller_rule_actions_increase_by_
+ f_status_t controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) {
+
+ if (actions->used + amount > actions->size) {
+ if (actions->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(actions->size, actions->used + amount, sizeof(controller_rule_action_t), (void **) & actions->array);
+
+ if (F_status_is_error_not(status)) {
+ actions->size = actions->used + amount;
+ }
+
+ return status;
+ }
+
+ return F_data_not;
+ }
+#endif // _di_controller_rule_actions_increase_by_
+
#ifndef _di_controller_rule_delete_simple_
void controller_rule_delete_simple(controller_rule_t *rule) {
}
#endif // _di_controller_thread_delete_simple_
-#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) {
-
- if (setting->interruptible) {
- f_signal_mask(SIG_UNBLOCK, &main->signal.set, 0);
- }
-
- const int result = nanosleep(&time, 0);
-
- if (setting->interruptible) {
- f_signal_mask(SIG_BLOCK, &main->signal.set, 0);
- }
-
- return result;
- }
-#endif // _di_controller_time_sleep_nanoseconds_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_controller_entry_actions_delete_simple_
/**
+ * Increase the size of the entry item actions 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 actions
+ * The entry item actions 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_entry_actions_increase_by_
+ extern f_status_t controller_entry_actions_increase_by(const f_array_length_t amount, controller_entry_actions_t *actions) F_attribute_visibility_internal_d;
+#endif // _di_controller_entry_actions_increase_by_
+
+/**
* Fully deallocate all memory for the given entry item without caring about return status.
*
* @param item
#endif // _di_controller_entry_items_delete_simple_
/**
- * Print the file error, locking the print mutex during the print.
- *
- * @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.
- * @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).
- *
- * @see fll_error_file_print()
- */
-#ifndef _di_controller_error_file_print_
- extern void controller_error_file_print(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, controller_thread_t *thread) F_attribute_visibility_internal_d;
-#endif // _di_controller_error_file_print_
-
-/**
- * Print the error, locking the print mutex during the print.
+ * Increase the size of the entry items array by the specified amount, but only if necessary.
*
- * @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 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).
- *
- * @see fll_error_print()
- */
-#ifndef _di_controller_error_print_
- extern void controller_error_print(const fl_print_t print, 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_error_print_
-
-/**
- * Perform the initial, required, allocation for the lock.
+ * This only increases size if the current used plus amount is greater than the currently allocated size.
*
- * @param lock
- * The lock to allocate.
+ * @param amount
+ * A positive number representing how much to increase the size by.
+ * @param items
+ * The entry 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_thread_lock_delete().
- * Errors (with error bit) from: f_thread_mutex_delete().
+ * Errors (with error bit) from: f_memory_resize().
*
- * @see f_thread_lock_delete()
- * @see f_thread_mutex_delete()
+ * @see f_memory_resize()
*/
-#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_
+#ifndef _di_controller_entry_items_increase_by_
+ extern f_status_t controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *items) F_attribute_visibility_internal_d;
+#endif // _di_controller_entry_items_increase_by_
/**
* Delete the mutex lock and if the mutex lock is busy, forcibly unlock it and then delete it.
#endif // _di_controller_lock_delete_simple_
/**
- * Print a r/w lock related error message, locking the print mutex during the print.
- *
- * This will ignore F_signal 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.
- *
- * @see fll_error_print()
- * @see controller_entry_error_print_cache()
- */
-#ifndef _di_controller_lock_error_critical_print_
- extern void controller_lock_error_critical_print(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_error_critical_print_
-
-/**
- * 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_signal on (exit) signal received, lock will not be set when this is returned.
- * F_status if main thread is disabled and write lock was never achieved.
- *
- * 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_signal on (exit) signal received, lock will not be set when this is returned.
- * F_status if main thread is disabled and write lock was never achieved.
- *
- * 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_
-
-/**
* Increase the size of the pid array, but only if necessary.
*
* If the given length is too large for the buffer, then attempt to set max buffer size (F_array_length_t_size_d).
#endif // _di_controller_pids_resize_
/**
- * Lock the mutex and the stream.
- *
- * This is implemented as a compliment to controller_print_unlock_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_print_lock_
- extern void controller_print_lock(const f_file_t to, controller_thread_t * const thread) F_attribute_visibility_internal_d;
-#endif // _di_controller_print_lock_
-
-/**
- * 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_print_unlock_flush_
- void controller_print_unlock_flush(const f_file_t to, controller_thread_t * const thread) F_attribute_visibility_internal_d;
-#endif // _di_controller_print_unlock_flush_
-
-/**
* Fully deallocate all memory for the given process without caring about return status.
*
* @param process
extern void controller_process_delete_simple(controller_process_t *process) F_attribute_visibility_internal_d;
#endif // _di_controller_process_delete_simple_
-/***
- * 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_signal on success and signal found.
- *
- * 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 *process) F_attribute_visibility_internal_d;
-#endif // _di_controller_process_wait_
-
/**
* Fully deallocate all memory for the given processs without caring about return status.
*
#endif // _di_controller_rule_actions_delete_simple_
/**
+ * Increase the size of the rule actions 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 actions
+ * The actions 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().
+ */
+#ifndef _di_controller_rule_actions_increase_by_
+ extern f_status_t controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) F_attribute_visibility_internal_d;
+#endif // _di_controller_rule_actions_increase_by_
+
+/**
* Fully deallocate all memory for the given rule without caring about return status.
*
* @param rule
extern void controller_thread_delete_simple(controller_thread_t *thread) F_attribute_visibility_internal_d;
#endif // _di_controller_thread_delete_simple_
-/**
- * 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.
- *
- * The nanosleep() function handles signals within itself.
- * Temporarily unblock signals so that the nanosleep can receive the signal and then restore the signals once done.
- *
- * The signals will not be unblocked when in uninterruptible mode.
- *
- * @param main
- * The program main data.
- * @param setting
- * The settings.
- * @param time
- * The number of nanoseconds to sleep.
- *
- * @return
- * The results of nanosleep().
- *
- * @see nanosleep()
- * @see controller_time_milliseconds()
- */
-#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_
-
#ifdef __cplusplus
} // extern "C"
#endif
#include "controller.h"
#include "private-common.h"
#include "private-control.h"
-#include "private-thread.h"
#ifdef __cplusplus
extern "C" {
--- /dev/null
+#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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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
#include "controller.h"
#include "private-common.h"
-#include "private-control.h"
-#include "private-entry.h"
-#include "private-rule.h"
-#include "private-thread.h"
#include "private-controller.h"
+#include "private-controller_print.h"
+#include "private-entry_print.h"
+#include "private-lock_print.h"
#ifdef __cplusplus
extern "C" {
if (F_status_is_error(status)) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_append", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_append", F_true, global.thread);
}
return status;
if (F_status_is_error(status)) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
return status;
}
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_open", F_true, path, "open", fll_error_file_type_file, global.thread);
+ controller_print_error_file(global.main->error, F_status_set_fine(status), "f_file_stream_open", F_true, path, "open", fll_error_file_type_file, global.thread);
}
}
else {
if (F_status_is_error(status)) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stream_read", F_true, path, "read", fll_error_file_type_file, global.thread);
+ controller_print_error_file(global.main->error, F_status_set_fine(status), "f_file_stream_read", F_true, path, "read", fll_error_file_type_file, global.thread);
}
}
}
if (F_status_is_error(status)) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_file_print(global.main->error, F_status_set_fine(status), "f_file_stat", F_true, path, "stat", fll_error_file_type_file, global.thread);
+ controller_print_error_file(global.main->error, F_status_set_fine(status), "f_file_stat", F_true, path, "stat", fll_error_file_type_file, global.thread);
}
}
else {
}
#endif // _di_controller_file_pid_read_
-#ifndef _di_controller_find_process_
- f_status_t controller_find_process(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_find_process_
-
#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 *cache, uid_t *id) {
// Always return immediately on memory errors.
if (F_status_set_fine(status) == F_memory_not) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_error_file_print(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, 0);
+ controller_print_error_file(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, 0);
flockfile(global.main->error.to.stream);
- controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->error, cache->action);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return status;
}
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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.prefix : f_string_empty_s, global.main->warning.context);
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_error_file_print(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, 0);
+ controller_print_error_file(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, 0);
}
- controller_entry_error_print_cache(is_entry, global.main->warning, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->warning, cache->action);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
status = F_none;
}
#endif // _di_controller_perform_ready_
-#ifndef _di_controller_preprocess_entry_
- f_status_t controller_preprocess_entry(const bool is_entry, controller_global_t global, controller_cache_t *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.
- global.setting->ready = controller_setting_ready_no;
-
- 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_error_print(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_error_print(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_error_print(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) {
-
- if (global.setting->ready == controller_setting_ready_wait) {
- if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(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_error_print_cache(is_entry, global.main->warning, cache->action);
-
- controller_print_unlock_flush(global.main->warning.to, global.thread);
- }
- }
- else {
- global.setting->ready = controller_setting_ready_wait;
- }
- }
- else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_item) {
- 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) {
- controller_print_lock(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_error_print_cache(is_entry, global.main->error, cache->action);
-
- controller_print_unlock_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_error_print(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_error_print(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) {
- controller_print_lock(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_error_print_cache(is_entry, global.main->error, cache->action);
-
- controller_print_unlock_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_error_print(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_signal;
- }
-
- // if ready was never found in the entry, then default to always ready.
- if (global.setting->ready == controller_setting_ready_no) {
- global.setting->ready = controller_setting_ready_yes;
- }
-
- return status;
- }
-#endif // _di_controller_preprocess_entry_
-
-#ifndef _di_controller_process_entry_
- f_status_t controller_process_entry(const bool failsafe, const bool is_entry, controller_global_t *global, controller_cache_t *cache) {
-
- 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_error_print(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_error_print(is_entry, global->main->error, cache->action, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global->thread);
+#ifndef _di_controller_status_simplify_error_
+ f_status_t controller_status_simplify_error(const f_status_t status) {
- return status;
+ if (status == F_memory_not) {
+ return F_status_set_error(F_memory);
}
- if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
- if (global->main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(global->main->output.to, global->thread);
- }
+ if (status == F_file_open_max || status == F_space_not || status == F_busy) {
+ return F_status_set_error(F_resource);
}
- 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_error_print(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].result == f_console_result_found) {
- if (global->main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_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 || !(entry_action->code & controller_entry_rule_code_require_d) && (global->main->warning.verbosity == f_console_verbosity_verbose || global->main->warning.verbosity == f_console_verbosity_debug)) {
- 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_print_lock(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_error_print_cache(is_entry, *output, cache->action);
-
- controller_print_unlock_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) {
- if ((entry_action->code & controller_entry_rule_code_wait_d) || global->setting->ready == controller_setting_ready_wait) {
- if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || entry->show == controller_entry_show_init) {
- if (global->main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(global->main->output.to, global->thread);
- }
- }
-
- if (global->main->parameters[controller_parameter_validate].result == f_console_result_none) {
- status = controller_rule_wait_all(is_entry, *global, F_false, process);
- if (F_status_is_error(status)) return status;
- }
- }
-
- if (global->setting->ready == controller_setting_ready_yes) {
- if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
- if (global->main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(global->main->output.to, global->thread);
- }
- }
- }
- else {
- if (!failsafe && (global->main->error.verbosity == f_console_verbosity_verbose || entry->show == controller_entry_show_init) && global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
- 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(is_entry, *global, cache);
- if (F_status_is_error(status)) return status;
- }
- }
- else if (entry_action->type == controller_entry_action_type_item) {
- 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) {
- controller_print_lock(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_error_print_cache(is_entry, global->main->error, cache->action);
-
- controller_print_unlock_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_error_print(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_error_print(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].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
- if (global->main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_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 || controller_entry_action_type_is_rule(entry_action->type)) {
- status_lock = controller_lock_write(is_entry, global->thread, &global->thread->lock.rule);
-
- if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(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_error_print(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 (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(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].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || (entry->show == controller_entry_show_init && entry_action->type != controller_entry_action_type_consider)) {
- if (global->main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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 ? "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 && global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
- 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_print_unlock_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 (!(status_lock == F_signal || F_status_is_error(status_lock))) {
- status = controller_rule_read(is_entry, alias_rule, *global, 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 (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global->main->error, F_status_set_fine(status_lock), F_false, global->thread);
-
- break;
- }
-
- if (status == F_signal || !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) {
- if (F_status_set_fine(status) != F_interrupt) {
- controller_print_lock(global->main->error.to, global->thread);
-
- controller_entry_error_print_cache(is_entry, global->main->error, cache->action);
-
- controller_print_unlock_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].result == f_console_result_none) {
- 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].result == f_console_result_found) {
- 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].result == f_console_result_found) {
- options_process |= controller_process_option_validate_d;
- }
-
- if (entry_action->code & controller_entry_rule_code_asynchronous_d) {
- if (global->main->parameters[controller_parameter_validate].result == f_console_result_none) {
- options_force |= controller_process_option_asynchronous_d;
- }
-
- options_process |= controller_process_option_asynchronous_d;
- }
-
- status = controller_rule_process_begin(options_force, alias_rule, controller_entry_action_type_to_rule_action_type(entry_action->type), options_process, is_entry ? controller_process_type_entry : controller_process_type_exit, stack, *global, *cache);
-
- if (F_status_set_fine(status) == F_memory_not || status == F_child || status == F_signal) {
- break;
- }
-
- if (F_status_is_error(status) && global->main->parameters[controller_parameter_simulate].result == f_console_result_none && (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) {
- if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || entry->show == controller_entry_show_init) {
- if (global->main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(global->main->output.to, global->thread);
- }
- }
-
- if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found) {
- return F_execute;
- }
-
- controller_thread_process_cancel(is_entry, is_entry ? controller_thread_cancel_execute : controller_thread_cancel_exit_execute, global, process);
-
- int result = 0;
- int option = FL_execute_parameter_option_path_d;
-
- if (entry->session == controller_entry_session_new) {
- 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) {
- controller_print_lock(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_error_print_cache(is_entry, global->main->error, cache->action);
-
- controller_print_unlock_flush(global->main->error.to, global->thread);
- }
- }
- else {
- controller_entry_error_print(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) {
- controller_print_lock(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_error_print_cache(is_entry, global->main->error, cache->action);
-
- controller_print_unlock_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) {
- const f_string_t suffix = " MegaTime (milliseconds)";
-
- if (entry_action->code == controller_entry_timeout_code_kill_d) {
- entry->timeout_kill = entry_action->number;
-
- controller_process_entry_print_simulate_setting_value(is_entry, *global, 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_process_entry_print_simulate_setting_value(is_entry, *global, 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_process_entry_print_simulate_setting_value(is_entry, *global, 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) {
-
- if (failsafe) {
- if (global->main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(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.prefix : f_string_empty_s, global->main->warning.context, f_string_eol_s[0]);
-
- controller_entry_error_print_cache(is_entry, global->main->warning, cache->action);
-
- controller_print_unlock_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) {
- controller_print_lock(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_error_print_cache(is_entry, global->main->error, cache->action);
-
- controller_print_unlock_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_process_entry_print_simulate_setting_value(is_entry, *global, controller_failsafe_s, 0, entry->items.array[global->setting->failsafe_item_id].name, 0);
- }
- }
- }
- } // for
-
- if (status == F_child || status == F_signal) 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_error_print(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_signal;
+ 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_child) {
- return status;
+ 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 (F_status_is_error(status_lock)) {
- return status_lock;
+ if (status == F_number || status == F_number_negative || status == F_number_positive || status == F_number_overflow) {
+ return F_status_set_error(F_number);
}
- // 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].result == f_console_result_none) {
- const f_status_t status_wait = controller_rule_wait_all(is_entry, *global, F_true, 0);
-
- if (status_wait == F_signal || F_status_is_error(status_wait)) {
- return status_wait;
- }
-
- if (F_status_set_fine(status_wait) == F_require) {
- return F_status_set_error(F_require);
- }
+ 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 ((global->main->parameters[controller_parameter_simulate].result == f_console_result_found && global->main->error.verbosity != f_console_verbosity_quiet) || global->main->error.verbosity == f_console_verbosity_verbose) {
- controller_print_lock(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_print_unlock_flush(global->main->output.to, global->thread);
+ if (status == F_valid_not) {
+ return F_status_set_error(F_valid_not);
}
- return status;
+ return F_status_set_error(F_failure);
}
-#endif // _di_controller_process_entry_
+#endif // _di_controller_status_simplify_error_
-#ifndef _di_controller_process_entry_print_simulate_setting_value_
- void controller_process_entry_print_simulate_setting_value(const bool is_entry, 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) {
+#ifndef _di_controller_time_
+ void controller_time(const time_t seconds, const long nanoseconds, struct timespec *time) {
- if (global.main->error.verbosity != f_console_verbosity_debug && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
- return;
- }
+ struct timeval now;
- controller_print_lock(global.main->output.to, global.thread);
+ gettimeofday(&now, 0);
- 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);
+ time->tv_sec = now.tv_sec + seconds;
+ time->tv_nsec = (now.tv_usec * 1000) + nanoseconds;
- fl_print_format("%[%S%]' setting ", global.main->output.to.stream, global.main->context.set.title, name, global.main->context.set.title);
+ // If tv_nsec is 1 second or greater, then increment seconds.
+ if (time->tv_nsec >= 1000000000) {
+ ++(time->tv_sec);
- if (name_sub) {
- fl_print_format("'%[%S%]'", global.main->output.to.stream, global.main->context.set.notable, name_sub, global.main->context.set.notable);
+ time->tv_nsec -= 1000000000;
}
- 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_print_unlock_flush(global.main->output.to, global.thread);
}
-#endif // _di_controller_process_entry_print_simulate_setting_value_
-
-#ifndef _di_controller_process_prepare_
- f_status_t controller_process_prepare(const bool is_normal, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) {
-
- f_status_t status = F_none;
-
- if (status == F_signal || F_status_is_error(status)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status), F_true, global.thread);
-
- return status;
- }
-
- if (controller_find_process(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 (status == F_signal || F_status_is_error(status)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status), F_false, global.thread);
-
- const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
-
- if (status_lock == F_signal || F_status_is_error(status_lock)) {
- return F_status_set_error(F_lock);
- }
-
- return status;
- }
-
- 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);
+#endif // _di_controller_time_
- if (status == F_signal || F_status_is_error(status)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status), F_false, global.thread);
+#ifndef _di_controller_time_milliseconds_
+ struct timespec controller_time_milliseconds(const f_number_unsigned_t milliseconds) {
- f_thread_unlock(&global.thread->lock.process);
+ struct timespec time;
+ time.tv_sec = milliseconds > 1000 ? milliseconds / 1000 : 0;
+ time.tv_nsec = (time.tv_sec ? milliseconds - time.tv_sec : milliseconds) * 1000;
- const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
-
- if (status_lock == F_signal || F_status_is_error(status_lock)) {
- return F_status_set_error(F_lock);
- }
-
- return status;
- }
-
- 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);
-
- const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
-
- if (status_lock == F_signal || F_status_is_error(status_lock)) {
- return F_status_set_error(F_lock);
- }
- }
- else {
- status = F_found;
- }
-
- return status;
+ return time;
}
-#endif // _di_controller_process_prepare_
-
-#ifndef _di_controller_process_prepare_process_type_
- f_status_t controller_process_prepare_process_type(const uint8_t type, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) {
+#endif // _di_controller_time_milliseconds_
- return controller_process_prepare(type != controller_process_type_exit, action, alias, global, id);
- }
-#endif // _di_controller_process_prepare_process_type_
+#ifndef _di_controller_time_seconds_
+ struct timespec controller_time_seconds(const f_number_unsigned_t seconds) {
-#ifndef _di_controller_status_simplify_error_
- f_status_t controller_status_simplify_error(const f_status_t status) {
+ struct timespec time;
+ time.tv_sec = seconds;
+ time.tv_nsec = 0;
- 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);
- }
+ return time;
+ }
+#endif // _di_controller_time_seconds_
- 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);
- }
+#ifndef _di_controller_time_sleep_nanoseconds_
+ int controller_time_sleep_nanoseconds(controller_main_t * const main, controller_setting_t * const setting, struct timespec time) {
- if (status == F_number || status == F_number_negative || status == F_number_positive || status == F_number_overflow) {
- return F_status_set_error(F_number);
+ if (setting->interruptible) {
+ f_signal_mask(SIG_UNBLOCK, &main->signal.set, 0);
}
- if (status == F_parameter || status == F_found_not || status == F_interrupt || status == F_supported_not || status == F_critical) {
- return F_status_set_error(status);
- }
+ const int result = nanosleep(&time, 0);
- if (status == F_valid_not) {
- return F_status_set_error(F_valid_not);
+ if (setting->interruptible) {
+ f_signal_mask(SIG_BLOCK, &main->signal.set, 0);
}
- return F_status_set_error(F_failure);
+ return result;
}
-#endif // _di_controller_status_simplify_error_
+#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) {
#endif // _di_controller_file_pid_read_
/**
- * 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_find_process_
- f_status_t controller_find_process(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_find_process_
-
-/**
* 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
#endif // _di_controller_perform_ready_
/**
- * Pre-process all items for the loaded entry.
+ * Given a wide range of status codes (that are errors), simplify them down to a small subset.
*
- * @param is_entry
- * If TRUE, then this operate as an entry.
- * If FALSE, then this operate as an exit.
- * @param global
- * The global data.
- * @param cache
- * The main/global cache to use.
+ * @param status
+ * The status code (without the error bit set) to simplify.
*
* @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()
+ * A subset of status codes with error bit.
*/
-#ifndef _di_controller_preprocess_entry_
- extern f_status_t controller_preprocess_entry(const bool is_entry, controller_global_t global, controller_cache_t *cache) F_attribute_visibility_internal_d;
-#endif // _di_controller_preprocess_entry_
+#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_
/**
- * Process (execute) all Items for the loaded Entry or Exit.
- *
- * @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.
- * @param global
- * The global data.
- * @param cache
- * The main/global cache to use.
+ * Get the current time, plus the given offset.
*
- * @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.
+ * @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.
*
- * 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()
+ * @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_process_entry_
- extern f_status_t controller_process_entry(const bool failsafe, const bool is_entry, controller_global_t *global, controller_cache_t *cache) F_attribute_visibility_internal_d;
-#endif // _di_controller_process_entry_
+#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_
/**
- * Print message regarding the population of a setting when in simulation or verbose mode.
+ * Convert milliseconds to nanoseconds.
*
- * @param is_entry
- * If TRUE, then this operate as an entry.
- * If FALSE, then this operate as an exit.
- * @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_process_entry_print_simulate_setting_value_
- extern void controller_process_entry_print_simulate_setting_value(const bool is_entry, 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_process_entry_print_simulate_setting_value_
-
-/**
- * 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 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 global
- * The global data.
- * @param id
- * (optional) The process ID when found or created.
- * Set to NULL to not use.
+ * @param milliseconds
+ * The number of milliseconds.
*
* @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().
+ * A time structure suitable for passing to nanosleep() and similar functions.
*
- * 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()
+ * @see nanosleep()
*/
-#ifndef _di_controller_process_prepare_
- extern f_status_t controller_process_prepare(const bool is_normal, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) F_attribute_visibility_internal_d;
-#endif // _di_controller_process_prepare_
+#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_
/**
- * 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.
+ * Convert seconds to nanoseconds.
*
- * This requires that a global.thread->lock.process lock be set on process->lock before being called.
- *
- * @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 global
- * The global data.
- * @param id
- * (optional) The process ID when found or created.
- * Set to NULL to not use.
+ * @param seconds
+ * The number of seconds.
*
* @return
- * Success from: controller_process_prepare()
- *
- * Errors (with error bit) from: controller_process_prepare().
+ * A time structure suitable for passing to nanosleep() and similar functions.
*
- * @see controller_process_prepare()
+ * @see nanosleep()
*/
-#ifndef _di_controller_process_prepare_process_type_
- extern f_status_t controller_process_prepare_process_type(const uint8_t type, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) F_attribute_visibility_internal_d;
-#endif // _di_controller_process_prepare_process_type_
+#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_
/**
- * Given a wide range of status codes (that are errors), simplify them down to a small subset.
+ * Sleep for a given number of nanoseconds.
*
- * @param status
- * The status code (without the error bit set) to simplify.
+ * The nanosleep() function handles signals within itself.
+ * Temporarily unblock signals so that the nanosleep can receive the signal and then restore the signals once done.
+ *
+ * The signals will not be unblocked when in uninterruptible mode.
+ *
+ * @param main
+ * The program main data.
+ * @param setting
+ * The settings.
+ * @param time
+ * The number of nanoseconds to sleep.
*
* @return
- * A subset of status codes with error bit.
+ * The results of nanosleep().
+ *
+ * @see nanosleep()
+ * @see controller_time_milliseconds()
*/
-#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_
+#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.
--- /dev/null
+#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(const fl_print_t print, const f_status_t status, const f_string_t function, const bool fallback, controller_thread_t *thread) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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(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, controller_thread_t *thread) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 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 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).
+ *
+ * @see fll_error_print()
+ */
+#ifndef _di_controller_print_error_
+ extern void controller_print_error(const fl_print_t print, 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_print_error_
+
+/**
+ * Print the file error, locking the print mutex during the print.
+ *
+ * @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.
+ * @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).
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_controller_print_error_file_
+ extern void controller_print_error_file(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, controller_thread_t *thread) F_attribute_visibility_internal_d;
+#endif // _di_controller_print_error_file_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_controller_print_h
#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_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_action_type_is_rule_
f_status_t controller_entry_action_type_is_rule(uint8_t type) {
}
#endif // _di_controller_entry_action_type_to_rule_action_type_
-#ifndef _di_controller_entry_actions_increase_by_
- f_status_t controller_entry_actions_increase_by(const f_array_length_t amount, controller_entry_actions_t *actions) {
-
- if (actions->used + amount > actions->size) {
- if (actions->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(actions->size, actions->used + amount, sizeof(controller_entry_action_t), (void **) & actions->array);
-
- if (F_status_is_error_not(status)) {
- actions->size = actions->used + amount;
- }
-
- return status;
- }
-
- return F_data_not;
- }
-#endif // _di_controller_entry_actions_increase_by_
-
#ifndef _di_controller_entry_actions_read_
f_status_t controller_entry_actions_read(const bool is_entry, const f_string_range_t content_range, controller_global_t global, controller_cache_t *cache, controller_entry_actions_t *actions) {
+
f_status_t status = F_none;
f_status_t status_action = F_none;
}
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread);
+ 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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ 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;
}
status = controller_entry_actions_increase_by(cache->object_actions.used, actions);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_actions_increase_by", F_true, global.thread);
+ 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;
}
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ 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;
}
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+ 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;
}
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(is_entry, global.main->warning, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->warning, cache->action);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
continue;
status = f_string_dynamics_increase_by(allocate, &action->parameters);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase_by", F_true, global.thread);
+ 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;
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
+ 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;
status = fll_path_canonical(action->parameters.array[0].string, &cache->buffer_path);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_path_canonical", F_true, global.thread);
+ 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;
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_file_name_base", F_true, global.thread);
+ 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;
status = f_string_dynamic_terminate_after(&cache->buffer_path);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ 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) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_unsigned", F_true, global.thread);
+ 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;
}
#endif // _di_controller_entry_actions_read_
-#ifndef _di_controller_entry_error_print_
- void controller_entry_error_print(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) {
+#ifndef _di_controller_entry_preprocess_
+ f_status_t controller_entry_preprocess(const bool is_entry, controller_global_t global, controller_cache_t *cache) {
- if (print.verbosity == f_console_verbosity_quiet) return;
- if (status == F_interrupt) return;
+ f_status_t status = F_none;
+ f_status_t status2 = F_none;
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
- f_thread_mutex_lock(&thread->lock.print);
+ f_array_length_t i = 0;
+ f_array_length_t j = 0;
- fll_error_print(print, status, function, fallback);
+ f_array_length_t at_i = 0;
+ f_array_length_t at_j = 1;
- flockfile(print.to.stream);
+ controller_entry_t *entry = is_entry ? &global.setting->entry : &global.setting->exit;
+ controller_entry_actions_t *actions = 0;
- controller_entry_error_print_cache(is_entry, print, cache);
+ uint8_t error_has = F_false;
- controller_print_unlock_flush(print.to, thread);
- }
-#endif // _di_controller_entry_error_print_
+ // 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.
+ global.setting->ready = controller_setting_ready_no;
+
+ 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;
-#ifndef _di_controller_entry_error_print_cache_
- void controller_entry_error_print_cache(const bool is_entry, const fl_print_t output, const controller_cache_action_t cache) {
+ macro_f_array_lengths_t_increase_by(status, cache->ats, controller_common_allocation_small_d)
- fl_print_format("%c%[%SWhile processing ", output.to.stream, f_string_eol_s[0], output.context, output.prefix);
+ 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);
- 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);
+ return status;
}
- 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);
+ // 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) {
+
+ if (global.setting->ready == controller_setting_ready_wait) {
+ if (global.main->warning.verbosity == f_console_verbosity_debug) {
+ 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;
+ }
+ }
+ else if (actions->array[cache->ats.array[at_j]].type == controller_entry_action_type_item) {
+ 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) {
+ 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) {
+ 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_signal;
}
- 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);
+ // if ready was never found in the entry, then default to always ready.
+ if (global.setting->ready == controller_setting_ready_no) {
+ global.setting->ready = controller_setting_ready_yes;
}
- fl_print_format(".%]%c", output.to.stream, output.context, f_string_eol_s[0]);
+ return status;
}
-#endif // _di_controller_entry_error_print_cache_
+#endif // _di_controller_entry_preprocess_
+
+#ifndef _di_controller_entry_process_
+ f_status_t controller_entry_process(const bool failsafe, const bool is_entry, controller_global_t *global, controller_cache_t *cache) {
+
+ 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;
-#ifndef _di_controller_entry_items_increase_by_
- f_status_t controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *items) {
+ status = controller_dynamic_append_terminated(entry->items.array[cache->ats.array[0]].name, &cache->action.name_item);
- 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);
+ 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].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
+ if (global->main->error.verbosity != f_console_verbosity_quiet) {
+ 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);
}
+ }
+
+ 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].result == f_console_result_found) {
+ if (global->main->error.verbosity != f_console_verbosity_quiet) {
+ 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 || !(entry_action->code & controller_entry_rule_code_require_d) && (global->main->warning.verbosity == f_console_verbosity_verbose || global->main->warning.verbosity == f_console_verbosity_debug)) {
+ 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) {
+ if ((entry_action->code & controller_entry_rule_code_wait_d) || global->setting->ready == controller_setting_ready_wait) {
+ if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || entry->show == controller_entry_show_init) {
+ if (global->main->output.verbosity != f_console_verbosity_quiet) {
+ 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].result == f_console_result_none) {
+ status = controller_rule_wait_all(is_entry, *global, F_false, process);
+ if (F_status_is_error(status)) return status;
+ }
+ }
+
+ if (global->setting->ready == controller_setting_ready_yes) {
+ if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
+ if (global->main->output.verbosity != f_console_verbosity_quiet) {
+ 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 || entry->show == controller_entry_show_init) && global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
+ 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(is_entry, *global, cache);
+ if (F_status_is_error(status)) return status;
+ }
+ }
+ else if (entry_action->type == controller_entry_action_type_item) {
+ 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) {
+ 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);
+ }
- const f_status_t status = f_memory_resize(items->size, items->used + amount, sizeof(controller_entry_item_t), (void **) & items->array);
+ macro_f_array_lengths_t_increase_by(status, cache->ats, controller_common_allocation_small_d)
- if (F_status_is_error_not(status)) {
- items->size = items->used + amount;
+ 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].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug) {
+ if (global->main->output.verbosity != f_console_verbosity_quiet) {
+ 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 || controller_entry_action_type_is_rule(entry_action->type)) {
+ status_lock = controller_lock_write(is_entry, global->thread, &global->thread->lock.rule);
+
+ if (status_lock == F_signal || 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 (status_lock == F_signal || 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].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || (entry->show == controller_entry_show_init && entry_action->type != controller_entry_action_type_consider)) {
+ if (global->main->output.verbosity != f_console_verbosity_quiet) {
+ 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 ? "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 && global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
+ 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 (!(status_lock == F_signal || F_status_is_error(status_lock))) {
+ status = controller_rule_read(is_entry, alias_rule, *global, 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 (status_lock == F_signal || 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 (status == F_signal || !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) {
+ 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);
+ }
+ }
+
+ // Designate the action as failed.
+ entry_action->status = F_status_set_error(F_failure);
+
+ if (global->main->parameters[controller_parameter_simulate].result == f_console_result_none) {
+ 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].result == f_console_result_found) {
+ 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].result == f_console_result_found) {
+ options_process |= controller_process_option_validate_d;
+ }
+
+ if (entry_action->code & controller_entry_rule_code_asynchronous_d) {
+ if (global->main->parameters[controller_parameter_validate].result == f_console_result_none) {
+ options_force |= controller_process_option_asynchronous_d;
+ }
+
+ options_process |= controller_process_option_asynchronous_d;
+ }
+
+ status = controller_rule_process_begin(options_force, alias_rule, controller_entry_action_type_to_rule_action_type(entry_action->type), options_process, is_entry ? controller_process_type_entry : controller_process_type_exit, stack, *global, *cache);
+
+ if (F_status_set_fine(status) == F_memory_not || status == F_child || status == F_signal) {
+ break;
+ }
+
+ if (F_status_is_error(status) && global->main->parameters[controller_parameter_simulate].result == f_console_result_none && (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) {
+ if (global->main->parameters[controller_parameter_simulate].result == f_console_result_found || global->main->error.verbosity == f_console_verbosity_verbose || global->main->error.verbosity == f_console_verbosity_debug || entry->show == controller_entry_show_init) {
+ if (global->main->output.verbosity != f_console_verbosity_quiet) {
+ 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].result == f_console_result_found) {
+ return F_execute;
+ }
+
+ controller_thread_process_cancel(is_entry, is_entry ? controller_thread_cancel_execute : controller_thread_cancel_exit_execute, global, process);
+
+ int result = 0;
+ int option = FL_execute_parameter_option_path_d;
+
+ if (entry->session == controller_entry_session_new) {
+ 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) {
+ 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) {
+ 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) {
+ 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(is_entry, *global, 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(is_entry, *global, 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(is_entry, *global, 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) {
+
+ if (failsafe) {
+ if (global->main->warning.verbosity == f_console_verbosity_debug) {
+ 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.prefix : f_string_empty_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 {
+ 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) {
+ 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(is_entry, *global, controller_failsafe_s, 0, entry->items.array[global->setting->failsafe_item_id].name, 0);
+ }
+ }
+ }
+ } // for
+
+ if (status == F_child || status == F_signal) 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_signal;
+ }
+ if (status == F_child) {
return status;
}
- return F_data_not;
+ 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].result == f_console_result_none) {
+ const f_status_t status_wait = controller_rule_wait_all(is_entry, *global, F_true, 0);
+
+ if (status_wait == F_signal || F_status_is_error(status_wait)) {
+ return status_wait;
+ }
+
+ if (F_status_set_fine(status_wait) == F_require) {
+ return F_status_set_error(F_require);
+ }
+ }
+
+ if ((global->main->parameters[controller_parameter_simulate].result == f_console_result_found && global->main->error.verbosity != f_console_verbosity_quiet) || global->main->error.verbosity == f_console_verbosity_verbose) {
+ 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_items_increase_by_
+#endif // _di_controller_entry_process_
#ifndef _di_controller_entry_read_
f_status_t controller_entry_read(const bool is_entry, controller_global_t global, controller_cache_t *cache) {
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_error_print(global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, global.thread);
}
else {
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ 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) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_data_not);
status = controller_entry_items_increase_by(cache->object_items.used, &entry->items);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_items_increase_by", F_true, global.thread);
+ 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 {
status = controller_entry_items_increase_by(controller_common_allocation_small_d, &entry->items);
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_entry_items_increase_by", F_true, global.thread);
+ 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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_partial_append_terminated", F_true, global.thread);
+ 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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ 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;
}
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) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(is_entry, global.main->warning, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->warning, cache->action);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
code |= 0x2;
status = controller_dynamic_append_terminated(cache->action.name_item, &entry->items.array[at].name);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread);
break;
}
if (F_status_is_error(status)) {
if (F_status_set_fine(status) != F_interrupt) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->error, cache->action);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_set_fine(status) == F_memory_not) {
if (!(code & 0x1)) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_found_not);
status = controller_dynamic_append_terminated(entry->items.array[i].name, &cache->action.name_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, global.thread);
break;
}
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(is_entry, global.main->error, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->error, cache->action);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
action->number = 0;
if (F_status_is_error(status)) {
if (F_status_set_fine(status) != F_interrupt) {
- controller_entry_error_print_cache(is_entry, global.main->error, cache->action);
+ controller_entry_print_error_cache(is_entry, global.main->error, cache->action);
}
entry->status = controller_status_simplify_error(F_status_set_fine(status));
}
if (F_status_is_error(status)) {
- controller_entry_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread);
+ 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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ 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;
}
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ 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;
}
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_error_print(is_entry, global.main->error, cache->action, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+ 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;
}
}
#endif // _di_controller_entry_settings_read_
-#ifndef _di_controller_entry_settings_read_print_setting_requires_exactly_
- void controller_entry_settings_read_print_setting_requires_exactly(const bool is_entry, const controller_global_t global, const controller_cache_t cache, const f_number_unsigned_t total) {
-
- if (global.main->error.verbosity == f_console_verbosity_quiet) return;
-
- controller_print_lock(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_error_print_cache(is_entry, global.main->error, cache.action);
-
- controller_print_unlock_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 bool is_entry, const controller_global_t global, const controller_cache_t cache) {
-
- if (global.main->warning.verbosity != f_console_verbosity_debug) return;
-
- controller_print_lock(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_error_print_cache(is_entry, global.main->warning, cache.action);
-
- controller_print_unlock_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 bool is_entry, const controller_global_t global, const controller_cache_t cache, const f_array_length_t index) {
-
- if (global.main->warning.verbosity != f_console_verbosity_debug) return;
-
- controller_print_lock(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_error_print_cache(is_entry, global.main->warning, cache.action);
-
- controller_print_unlock_flush(global.main->warning.to, global.thread);
- }
-#endif // _di_controller_entry_settings_read_print_setting_unknown_action_value_
-
#ifdef __cplusplus
} // extern "C"
#endif
#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_
-
-/**
* Determine if the type code represents a Rule type.
*
* @param type
#endif // _di_controller_entry_action_type_to_rule_action_type_
/**
- * Increase the size of the entry item actions 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 actions
- * The entry item actions 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_entry_actions_increase_by_
- extern f_status_t controller_entry_actions_increase_by(const f_array_length_t amount, controller_entry_actions_t *actions) F_attribute_visibility_internal_d;
-#endif // _di_controller_entry_actions_increase_by_
-
-/**
* Read the entry list, extracting all items and values.
*
* @param is_entry
#endif // _di_controller_entry_actions_read_
/**
- * Print the entry related error, locking the print mutex during the print.
+ * Pre-process all items for the loaded entry.
*
* @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.
+ * If TRUE, then this operate as an entry.
+ * If FALSE, then this operate as an exit.
+ * @param global
+ * The global data.
* @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.
+ * The main/global cache to use.
*
- * @see fll_error_print()
- * @see controller_entry_error_print_cache()
- */
-#ifndef _di_controller_entry_error_print_
- extern void controller_entry_error_print(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_error_print_
-
-/**
- * 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.
+ * @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.
*
- * @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.
+ * 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().
*
- * @see controller_entry_actions_read()
- * @see controller_entry_read()
+ * 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_error_print_cache_
- extern void controller_entry_error_print_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_error_print_cache_
+#ifndef _di_controller_entry_preprocess_
+ extern f_status_t controller_entry_preprocess(const bool is_entry, controller_global_t global, controller_cache_t *cache) F_attribute_visibility_internal_d;
+#endif // _di_controller_entry_preprocess_
/**
- * Increase the size of the entry 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.
+ * Process (execute) all Items for the loaded Entry or Exit.
*
- * @param amount
- * A positive number representing how much to increase the size by.
- * @param items
- * The entry items to resize.
+ * @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.
+ * @param global
+ * The global data.
+ * @param cache
+ * The main/global cache to use.
*
* @return
* F_none on success.
- * F_array_too_large (with error bit) if the resulting new size is bigger than the max array length.
+ * F_execute on success and program exiting (scripts may result in this) or when execute would have been executed but is instead simulated.
*
- * Errors (with error bit) from: f_memory_resize().
+ * 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.
*
- * @see f_memory_resize()
+ * 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_items_increase_by_
- extern f_status_t controller_entry_items_increase_by(const f_array_length_t amount, controller_entry_items_t *items) F_attribute_visibility_internal_d;
-#endif // _di_controller_entry_items_increase_by_
+#ifndef _di_controller_entry_process_
+ extern f_status_t controller_entry_process(const bool failsafe, const bool is_entry, controller_global_t *global, controller_cache_t *cache) F_attribute_visibility_internal_d;
+#endif // _di_controller_entry_process_
/**
* Read the entry, extracting all lists.
extern f_status_t controller_entry_settings_read(const bool is_entry, const f_string_range_t content_range, controller_global_t global, controller_cache_t *cache) F_attribute_visibility_internal_d;
#endif // _di_controller_entry_settings_read_
-/**
- * Print a message for when an entry setting action has the incorrect number of parameters.
- *
- * @param is_entry
- * If TRUE, then this loads as an entry.
- * If FALSE, then this loads as an exit.
- * @param global
- * The global data.
- * @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 bool is_entry, const controller_global_t global, 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 is_entry
- * If TRUE, then this loads as an entry.
- * If FALSE, then this loads as an exit.
- * @param global
- * The global data.
- * @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 bool is_entry, const controller_global_t global, 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 is_entry
- * If TRUE, then this loads as an entry.
- * If FALSE, then this loads as an exit.
- * @param global
- * The global data.
- * @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 bool is_entry, const controller_global_t global, 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
--- /dev/null
+#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 bool is_entry, 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 && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
+ 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) 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_settings_read_print_setting_requires_exactly_
+ void controller_entry_settings_read_print_setting_requires_exactly(const bool is_entry, const controller_global_t global, const controller_cache_t cache, const f_number_unsigned_t total) {
+
+ if (global.main->error.verbosity == f_console_verbosity_quiet) 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 bool is_entry, const controller_global_t global, const controller_cache_t cache) {
+
+ if (global.main->warning.verbosity != f_console_verbosity_debug) 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 bool is_entry, const controller_global_t global, const controller_cache_t cache, const f_array_length_t index) {
+
+ if (global.main->warning.verbosity != f_console_verbosity_debug) 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 is_entry
+ * If TRUE, then this operate as an entry.
+ * If FALSE, then this operate as an exit.
+ * @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_entry_preprocess_print_simulate_setting_value_
+ extern void controller_entry_preprocess_print_simulate_setting_value(const bool is_entry, 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_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 a message for when an entry setting action has the incorrect number of parameters.
+ *
+ * @param is_entry
+ * If TRUE, then this loads as an entry.
+ * If FALSE, then this loads as an exit.
+ * @param global
+ * The global data.
+ * @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 bool is_entry, const controller_global_t global, 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 is_entry
+ * If TRUE, then this loads as an entry.
+ * If FALSE, then this loads as an exit.
+ * @param global
+ * The global data.
+ * @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 bool is_entry, const controller_global_t global, 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 is_entry
+ * If TRUE, then this loads as an entry.
+ * If FALSE, then this loads as an exit.
+ * @param global
+ * The global data.
+ * @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 bool is_entry, const controller_global_t global, 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
--- /dev/null
+#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_signal;
+ }
+ }
+ 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, 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_signal;
+ }
+ }
+ 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, thread, lock);
+ }
+#endif // _di_controller_lock_write_process_type_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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_signal on (exit) signal received, lock will not be set when this is returned.
+ * F_status if main thread is disabled and write lock was never achieved.
+ *
+ * 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_signal on (exit) signal received, lock will not be set when this is returned.
+ * F_status if main thread is disabled and write lock was never achieved.
+ *
+ * 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
--- /dev/null
+#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_signal) return;
+
+ if (print.verbosity != f_console_verbosity_quiet) {
+ 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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_signal 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
--- /dev/null
+#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 bool is_normal, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) {
+
+ f_status_t status = F_none;
+
+ if (status == F_signal || F_status_is_error(status)) {
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_true, global.thread);
+
+ return status;
+ }
+
+ 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 (status == F_signal || F_status_is_error(status)) {
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_false, global.thread);
+
+ const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
+
+ if (status_lock == F_signal || F_status_is_error(status_lock)) {
+ return F_status_set_error(F_lock);
+ }
+
+ return status;
+ }
+
+ 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 (status == F_signal || 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(&global.thread->lock.process);
+
+ const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
+
+ if (status_lock == F_signal || F_status_is_error(status_lock)) {
+ return F_status_set_error(F_lock);
+ }
+
+ return status;
+ }
+
+ 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);
+
+ const f_status_t status_lock = controller_lock_read(is_normal, global.thread, &global.thread->lock.process);
+
+ if (status_lock == F_signal || 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 uint8_t type, const uint8_t action, const f_string_static_t alias, const controller_global_t global, f_array_length_t *id) {
+
+ return controller_process_prepare(type != controller_process_type_exit, action, alias, global, 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 *process) {
+
+ if (!controller_thread_is_enabled_process(process, global.thread)) {
+ return F_signal;
+ }
+
+ 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_signal;
+ }
+
+ if (F_status_is_error(status)) {
+ break;
+ }
+
+ status_lock = controller_lock_read_process(process, global.thread, &process->lock);
+
+ if (status_lock == F_signal || 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 || process->state == controller_process_state_busy)) {
+ f_thread_unlock(&process->lock);
+
+ return F_none;
+ }
+ else 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 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 global
+ * The global data.
+ * @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 bool is_normal, const uint8_t action, const f_string_static_t alias, const controller_global_t global, 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 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 global
+ * The global data.
+ * @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 uint8_t type, const uint8_t action, const f_string_static_t alias, const controller_global_t global, 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_signal on success and signal found.
+ *
+ * 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 *process) F_attribute_visibility_internal_d;
+#endif // _di_controller_process_wait_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_process_h
#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-entry.h"
+#include "private-rule_print.h"
#include "private-thread.h"
+#include "private-thread_process.h"
+#include "private-thread_signal.h"
#ifdef __cplusplus
extern "C" {
status = f_string_dynamics_increase(controller_common_allocation_small_d, parameters);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
return status;
}
status = f_string_dynamic_partial_append_nulless(buffer, *object, ¶meters->array[0]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
return status;
}
status = f_string_dynamic_terminate_after(¶meters->array[0]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
return status;
}
status = f_string_dynamics_increase(controller_common_allocation_small_d, parameters);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
return status;
}
status = f_string_dynamic_partial_append_nulless(buffer, content->array[i], ¶meters->array[parameters->used]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
return status;
}
status = f_string_dynamic_terminate_after(¶meters->array[parameters->used]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
return status;
}
}
#endif // _di_controller_rule_action_type_execute_name_
-#ifndef _di_controller_rule_actions_increase_by_
- f_status_t controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) {
-
- if (actions->used + amount > actions->size) {
- if (actions->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(actions->size, actions->used + amount, sizeof(controller_rule_action_t), (void **) & actions->array);
-
- if (F_status_is_error_not(status)) {
- actions->size = actions->used + amount;
- }
-
- return status;
- }
-
- return F_data_not;
- }
-#endif // _di_controller_rule_actions_increase_by_
-
#ifndef _di_controller_rule_action_read_
f_status_t controller_rule_action_read(const bool is_normal, const controller_global_t global, const uint8_t type, const uint8_t method, controller_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions, f_string_range_t *range) {
}
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true, global.thread);
}
else if (status == FL_fss_found_content) {
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
}
else {
status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
}
else {
actions->array[actions->used].type = type;
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_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global.thread);
}
status = f_string_dynamic_terminate_after(&actions->array[actions->used].parameters.array[0]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
else {
actions->array[actions->used++].parameters.used = 1;
}
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fll_fss_extended_read", F_true, global.thread);
}
else {
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
}
else {
f_array_length_t i = 0;
status = controller_rule_actions_increase_by(controller_common_allocation_small_d, actions);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true, global.thread);
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_error_print(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
break;
}
status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
actions->array[actions->used].status = controller_status_simplify_error(F_status_set_fine(status));
break;
}
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fll_fss_extended_content_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fll_fss_extended_content_read", F_true, global.thread);
}
else if (status == FL_fss_found_content) {
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
}
else if (type == controller_rule_action_type_pid_file) {
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_error_print(global.main->error, F_status_set_fine(status), "fl_string_dynamic_rip", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_string_dynamic_rip", F_true, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&item->pid_file);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
}
}
if (!type_rerun) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[%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_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return F_status_set_error(F_valid_not);
}
else {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[%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_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return F_status_set_error(F_valid_not);
}
else {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[%/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_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return F_status_set_error(F_valid_not);
}
else {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_valid_not);
status = f_string_dynamics_increase(controller_common_allocation_small_d, &actions->array[actions->used].parameters);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
}
else {
} // for
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_mash_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_mash_nulless", F_true, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&actions->array[actions->used].parameters.array[0]);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
else {
actions->array[actions->used++].parameters.used = 1;
status = f_fss_count_lines(cache->buffer_item, range->start, &actions->array[actions->used].line);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
}
else {
actions->array[actions->used].type = type;
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_error_print(global.main->error, F_status_set_fine(status), "controller_rule_parameters_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_rule_parameters_read", F_true, global.thread);
actions->array[actions->used++].status = controller_status_simplify_error(F_status_set_fine(status));
}
if (F_status_is_error_not(status) && status == F_data_not) {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->warning, cache->action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
}
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_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, global.thread);
}
else {
- controller_print_lock(global.main->error.to, global.thread);
+ 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);
}
}
- controller_rule_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
}
}
#endif // _di_controller_rule_copy_
-#ifndef _di_controller_rule_error_print_
- void controller_rule_error_print(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, controller_thread_t *thread) {
-
- if (print.verbosity == f_console_verbosity_quiet) return;
- if (status == F_interrupt) return;
-
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
- f_thread_mutex_lock(&thread->lock.print);
-
- fll_error_print(print, status, function, fallback);
-
- flockfile(print.to.stream);
-
- controller_rule_error_print_cache(print, cache, item);
-
- controller_print_unlock_flush(print.to, thread);
- }
-#endif // _di_controller_rule_error_print_
-
-#ifndef _di_controller_rule_error_print_cache_
- void controller_rule_error_print_cache(const fl_print_t print, const controller_cache_action_t cache, const bool item) {
-
- if (print.verbosity == f_console_verbosity_quiet) 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_error_print_cache_
-
-#ifndef _di_controller_rule_item_error_print_
- void controller_rule_item_error_print(const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status, controller_thread_t *thread) {
-
- if (print.verbosity == f_console_verbosity_quiet) return;
- if (status == F_interrupt) return;
-
- // fll_error_print() automatically locks, so manually handle only the mutex locking and flushing rather than calling controller_print_lock().
- f_thread_mutex_lock(&thread->lock.print);
-
- controller_rule_error_print_cache(print, cache, item);
-
- flockfile(print.to.stream);
-
- controller_print_unlock_flush(print.to, thread);
- }
-#endif // _di_controller_rule_item_error_print_
-
-#ifndef _di_controller_rule_item_error_print_execute_
- void controller_rule_item_error_print_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) {
- fl_print_t * const print = &((controller_main_t *) process->main_data)->error;
-
- controller_print_lock(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);
- fl_print_color_before(print->notable, print->to.stream);
-
- if (status == F_control_group) {
- f_print_terminated(controller_control_group_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_color_after(print->notable, print->to.stream);
- fl_print_format("%['.%]%c", print->to.stream, 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_print_unlock_flush(print->to, (controller_thread_t *) process->main_thread);
- }
- }
-#endif // _di_controller_rule_item_error_print_execute_
-
-#ifndef _di_controller_rule_item_error_print_need_want_wish_
- void controller_rule_item_error_print_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) 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_error_print_need_want_wish_
-
-#ifndef _di_controller_rule_item_error_print_rule_not_loaded_
- void controller_rule_item_error_print_rule_not_loaded(const fl_print_t print, const f_string_t alias) {
-
- if (print.verbosity == f_console_verbosity_quiet) 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_error_print_rule_not_loaded_
-
-#ifndef _di_controller_rule_action_error_missing_pid_
- void controller_rule_action_error_missing_pid(const fl_print_t print, const f_string_t alias) {
-
- if (print.verbosity == f_console_verbosity_quiet) 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_error_missing_pid_
-
#ifndef _di_controller_rule_execute_
f_status_t controller_rule_execute(const uint8_t action, const uint8_t options, const controller_global_t global, controller_process_t *process) {
status = fll_control_group_prepare(process->rule.control_group);
if (F_status_is_error(status)) {
- controller_error_file_print(global.main->error, F_status_set_fine(status), "fll_control_group_prepare", F_true, process->rule.control_group.path.string, "prepare control groups for", fll_error_file_type_directory, global.thread);
+ controller_print_error_file(global.main->error, F_status_set_fine(status), "fll_control_group_prepare", F_true, process->rule.control_group.path.string, "prepare control groups for", fll_error_file_type_directory, global.thread);
return status;
}
status = fl_environment_load_names(process->rule.environment, &environment);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_environment_load_names", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_environment_load_names", F_true, global.thread);
return status;
}
success = F_status_set_error(F_failure);
// @todo make this more specific.
- controller_rule_action_error_missing_pid(global.main->error, process->rule.alias.string);
+ 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) {
success = F_status_set_error(F_failure);
// @todo make this more specific.
- controller_rule_action_error_missing_pid(global.main->error, process->rule.alias.string);
+ controller_rule_action_print_error_missing_pid(global.main->error, process->rule.alias.string);
}
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
if (success == F_false) {
status = controller_pids_increase(&process->childs);
if (F_status_is_error(status)) {
- controller_error_print(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread);
return status;
}
if (options & controller_process_option_simulate_d) {
if (main->output.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->output.to, thread);
+ 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);
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_print_unlock_flush(main->output.to, thread);
+ controller_unlock_print_flush(main->output.to, thread);
}
// sleep for less than a second to better show simulation of synchronous vs asynchronous.
status_lock = controller_lock_write_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread);
if (status_lock != F_signal) {
status = controller_lock_read_process(process, thread, &process->lock);
status_lock = controller_lock_read_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread);
}
if (status_lock != F_signal) {
status_lock = controller_lock_write_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread);
if (status_lock != F_signal) {
status = controller_lock_read_process(process, thread, &process->lock);
status_lock = controller_lock_read_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread);
return F_status_set_error(F_lock);
}
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_error_print_execute(type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process);
+ controller_rule_item_print_error_execute(type == controller_rule_item_type_script, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process);
}
else {
- controller_error_print(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread);
}
status = F_status_set_error(status);
status = controller_pids_increase(&process->childs);
if (F_status_is_error(status)) {
- controller_error_print(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "controller_pids_increase", F_true, thread);
return status;
}
status = f_string_dynamics_increase(controller_common_allocation_small_d, &process->path_pids);
if (F_status_is_error(status)) {
- controller_error_print(main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "f_string_dynamics_increase", F_true, thread);
return status;
}
status = f_file_exists(pid_file.string);
if (F_status_is_error(status)) {
- controller_error_file_print(main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread);
+ controller_print_error_file(main->error, F_status_set_fine(status), "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread);
return status;
}
if (status == F_true) {
- controller_error_file_print(main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread);
+ controller_print_error_file(main->error, F_file_found, "f_file_exists", F_true, pid_file.string, "find", fll_error_file_type_file, thread);
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_error_print(main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "controller_dynamic_append_terminated", F_true, thread);
return status;
}
if (options & controller_process_option_simulate_d) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, thread);
+ 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);
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_print_unlock_flush(main->error.to, thread);
+ controller_unlock_print_flush(main->error.to, thread);
}
// sleep for less than a second to better show simulation of synchronous vs asynchronous.
status_lock = controller_lock_write_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread);
if (status_lock != F_signal) {
status = controller_lock_read_process(process, thread, &process->lock);
status_lock = controller_lock_read_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread);
}
if (status_lock != F_signal) {
status_lock = controller_lock_write_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_false, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_false, thread);
if (status_lock != F_signal) {
status = controller_lock_read_process(process, thread, &process->lock);
status_lock = controller_lock_read_process(process, thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(main->error, F_status_set_fine(status_lock), F_true, thread);
+ controller_lock_print_error_critical(main->error, F_status_set_fine(status_lock), F_true, thread);
return F_status_set_error(F_lock);
}
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_error_print_execute(type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process);
+ controller_rule_item_print_error_execute(type == controller_rule_item_type_utility, program ? program : arguments.used ? arguments.array[0].string : f_string_empty_s, status, process);
}
else {
- controller_error_print(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread);
+ controller_print_error(main->error, F_status_set_fine(status), "fll_execute_program", F_true, thread);
}
return F_status_set_error(status);
if (!rerun_item->max || rerun_item->count < rerun_item->max) {
if (main->error.verbosity == f_console_verbosity_debug) {
- controller_print_lock(main->output.to, thread);
+ 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);
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_print_unlock_flush(main->output.to, thread);
+ controller_unlock_print_flush(main->output.to, thread);
}
if (rerun_item->delay) {
status = f_string_dynamic_partial_append_nulless(source, directory, alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
return status;
}
status = f_string_append(f_path_separator_s, F_path_separator_s_length, alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_append", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_append", F_true, global.thread);
return status;
}
status = f_string_dynamic_partial_append_nulless(source, basename, alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, global.thread);
return status;
}
status = f_string_dynamic_terminate_after(alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
return status;
status = fl_fss_extended_list_object_read(cache->buffer_item, state, &range, &cache->range_action, &cache->delimits);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true, global.thread);
break;
}
status = fl_fss_extended_object_read(cache->buffer_item, state, &range, &cache->range_action, 0, &cache->delimits);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_extended_object_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_extended_object_read", F_true, global.thread);
break;
}
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
break;
}
status = f_fss_count_lines(cache->buffer_item, cache->range_action.start, &cache->action.line_action);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
break;
}
status = controller_dynamic_rip_nulless_terminated(cache->buffer_item, cache->range_action, &cache->action.name_action);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
break;
}
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->warning, cache->action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
continue;
if (type == controller_rule_action_type_group || type == controller_rule_action_type_pid_file || type == controller_rule_action_type_user) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_supported_not);
status = controller_rule_actions_increase_by(controller_common_allocation_small_d, &item->actions);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_rule_actions_increase_by", F_true, global.thread);
break;
}
default:
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->error, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return F_status_set_error(F_parameter);
}
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true, global.thread);
+ controller_rule_print_error(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true, global.thread);
return status;
}
status = f_string_dynamic_append(process->rule.alias, &process->cache.action.name_file);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_true, global.thread);
+ controller_rule_print_error(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_true, global.thread);
return status;
}
}
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true, global.thread);
+ controller_rule_print_error(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_append", F_true, F_true, global.thread);
return status;
}
status = f_string_dynamic_terminate_after(&process->cache.action.name_file);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_true, global.thread);
+ controller_rule_print_error(global.main->error, process->cache.action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_true, global.thread);
return status;
}
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.process);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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(process->type, process->action, dynamics[i]->array[j], global, &id_dependency);
}
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_rule_not_loaded(global.main->error, dynamics[i]->array[j].string);
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_false);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return status;
status_lock = controller_lock_read_process(process, global.thread, &dependency->active);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
status = F_false;
dependency = 0;
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
status = F_false;
}
id_rule = 0;
if (i == 0) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], dynamics[i]->array[j].string, "was not found");
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
status = F_status_set_error(F_found_not);
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ controller_lock_print(global.main->warning.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], dynamics[i]->array[j].string, "was not found");
+ controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], dynamics[i]->array[j].string, "was not found");
- controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
}
}
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
found = F_false;
status = status_lock;
status_lock = controller_lock_read_process(process, global.thread, &dependency->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
status = status_lock;
}
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
f_thread_unlock(&dependency->lock);
if (F_status_is_error(status)) {
if (i == 0 || i == 1 || F_status_set_fine(status) == F_memory_not) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], alias_other_buffer, "failed during execution");
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ 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);
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ controller_lock_print(global.main->warning.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "failed during execution");
+ controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "failed during execution");
- controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
}
}
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
}
}
if (status_lock == F_signal || F_status_is_error(status_lock)) {
if (F_status_is_error(status_lock)) {
- controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], alias_other_buffer, "due to lock failure");
+ controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], alias_other_buffer, "due to lock failure");
}
status = status_lock;
f_thread_unlock(&global.thread->lock.rule);
if (i == 0 || i == 1) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->error, strings[i], alias_other_buffer, "is in a failed state");
+ controller_rule_item_print_error_need_want_wish(global.main->error, strings[i], alias_other_buffer, "is in a failed state");
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->error, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
status = F_status_set_error(F_found_not);
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ controller_lock_print(global.main->warning.to, global.thread);
- controller_rule_item_error_print_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "is in a failed state");
+ controller_rule_item_print_error_need_want_wish(global.main->warning, strings[i], alias_other_buffer, "is in a failed state");
- controller_rule_error_print_cache(global.main->warning, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->warning, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
}
}
if (missing) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[') to execute.%]%c", global.main->error.to.stream, global.main->error.context, global.main->error.context, f_string_eol_s[0]);
}
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->error, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_parameter);
}
if (F_status_is_error(status)) {
- controller_rule_item_error_print(global.main->error, process->cache.action, F_true, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, process->cache.action, F_true, F_status_set_fine(status), global.thread);
}
}
}
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
if (status_lock != F_signal) {
status = controller_lock_read_process(process, global.thread, &process->lock);
status_lock = controller_lock_write_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
f_thread_unlock(&process->lock);
status_lock = controller_lock_read_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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);
}
status = controller_lock_read_process_type(type, global.thread, &global.thread->lock.process);
if (status == F_signal || F_status_is_error(status)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_true, global.thread);
return status;
}
f_thread_unlock(&global.thread->lock.process);
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_rule_not_loaded(global.main->error, alias_rule.string);
- controller_rule_error_print_cache(global.main->error, cache.action, F_false);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
return status;
status = controller_lock_read_process_type(type, global.thread, &process->active);
if (status == F_signal || F_status_is_error(status)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status), F_true, global.thread);
- controller_rule_item_error_print(global.main->error, cache.action, F_false, F_status_set_fine(status), global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status), F_true, global.thread);
+ controller_rule_item_print_error(global.main->error, cache.action, F_false, F_status_set_fine(status), global.thread);
f_thread_unlock(&global.thread->lock.process);
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
f_thread_unlock(&process->active);
}
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_type_array_lengths_resize", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_type_array_lengths_resize", F_true, global.thread);
}
else {
for (f_array_length_t i = 0; i < stack.used; ++i) {
status = f_string_dynamic_append(cache.action.name_item, &process->cache.action.name_item);
}
else {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_append", F_true, global.thread);
}
}
}
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_thread_create", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_thread_create", F_true, global.thread);
}
}
else {
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
f_thread_unlock(&process->active);
status_lock = controller_lock_read_process(process, global.thread, &process->active);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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 (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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);
status_lock = controller_lock_read_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
f_thread_unlock(&process->lock);
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
status_lock = controller_lock_read_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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);
f_thread_unlock(&global.thread->lock.rule);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_rule_copy", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_rule_copy", F_true, global.thread);
}
else if (!process->action) {
if (process->stack.array[i] == id_rule) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, process->cache.action, F_true);
+ controller_rule_print_error_cache(global.main->error, process->cache.action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
// Never continue on circular recursion errors even in simulate mode.
status = f_type_array_lengths_increase(controller_common_allocation_small_d, &process->stack);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_type_array_lengths_increase", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_type_array_lengths_increase", F_true, global.thread);
}
else {
f_thread_unlock(&process->lock);
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
status_lock = controller_lock_read_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ 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);
status = F_status_set_error(F_found_not);
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_item_error_print_rule_not_loaded(global.main->error, process->rule.alias.string);
- controller_rule_error_print_cache(global.main->error, process->cache.action, F_false);
+ 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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
}
status_lock = controller_lock_write_process(process, global.thread, &global.thread->lock.rule);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
status_lock = controller_lock_write_process(process, global.thread, &process->lock);
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
status = f_string_dynamic_append_nulless(alias, &rule->alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_append_nulless", F_true, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&rule->alias);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
}
else {
status = controller_file_load(F_true, controller_rules_s, rule->alias, controller_rule_s, controller_rules_s_length, controller_rule_s_length, global, cache);
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_error_print(global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fll_fss_basic_list_read", F_true, global.thread);
}
else {
status = fl_fss_apply_delimit(cache->delimits, &cache->buffer_file);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, global.thread);
}
}
}
status = controller_rule_items_increase_by(cache->object_items.used, &rule->items);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_rule_items_increase_by", F_true, global.thread);
}
else {
f_array_length_t i = 0;
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_error_print(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_fss_count_lines", F_true, global.thread);
break;
}
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_error_print(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
break;
}
}
else {
if (global.main->warning.verbosity == f_console_verbosity_debug) {
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->warning, cache->action, F_true);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ 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_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_partial_append", F_true, global.thread);
break;
}
status = f_string_dynamic_terminate_after(&cache->buffer_item);
if (F_status_is_error(status)) {
- controller_error_print(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, global.thread);
break;
}
}
if (F_status_is_error(status)) {
- controller_rule_item_error_print(global.main->error, cache->action, for_item, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, for_item, F_status_set_fine(status), global.thread);
rule->status[0] = controller_status_simplify_error(F_status_set_fine(status));
}
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "fll_fss_extended_read", F_true, F_false, global.thread);
return status;
}
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_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&cache->action.name_item);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->warning, cache->action, F_false);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
continue;
status = f_string_dynamic_partial_append_nulless(cache->buffer_item, range2, &cache->action.name_action);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&cache->action.name_action);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->warning.to, global.thread);
+ 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_error_print_cache(global.main->warning, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->warning, cache->action, F_false);
- controller_print_unlock_flush(global.main->warning.to, global.thread);
+ controller_unlock_print_flush(global.main->warning.to, global.thread);
}
continue;
// @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_problem_print(global.main->error, "requires one or more Content", i, line_item, global.thread, cache);
+ 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);
}
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "macro_f_int32s_t_resize", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "macro_f_int32s_t_resize", F_true, F_false, global.thread);
break;
}
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_problem_print_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);
+ 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_problem_print_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);
+ 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_problem_print_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);
+ 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);
}
}
else {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
status = F_status_set_error(status);
if (type == controller_rule_setting_type_define || type == controller_rule_setting_type_parameter) {
if (cache->content_actions.array[i].used != 2) {
- controller_rule_setting_read_problem_print(global.main->error, "requires exactly two Content", i, line_item, global.thread, cache);
+ 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);
status = f_string_maps_increase(controller_common_allocation_small_d, setting_maps);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_maps_increase", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_maps_increase", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
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_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
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_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&setting_maps->array[setting_maps->used].value);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (type == controller_rule_setting_type_control_group) {
if (cache->content_actions.array[i].used < 2 || rule->has & controller_rule_has_control_group_d) {
- controller_rule_setting_read_problem_print(global.main->error, "requires two or more Content", i, line_item, global.thread, cache);
+ 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);
rule->control_group.as_new = F_true;
}
else {
- controller_rule_setting_read_problem_print_with_range(global.main->error, "has an unknown option", cache->content_actions.array[i].array[0], "", i, line_item, global.thread, cache);
+ 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);
status = f_string_dynamic_append(global.setting->path_control, &rule->control_group.path);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_append", F_true, F_false, global.thread);
}
else {
rule->control_group.groups.used = 0;
status = f_string_dynamics_increase(controller_common_allocation_small_d, &rule->control_group.groups);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false, global.thread);
break;
}
status = f_string_dynamic_partial_append_nulless(cache->buffer_item, cache->content_actions.array[i].array[j], &rule->control_group.groups.array[rule->control_group.groups.used]);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
break;
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (type == controller_rule_setting_type_limit) {
if (cache->content_actions.array[i].used != 3) {
- controller_rule_setting_read_problem_print(global.main->error, "requires three Content", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_true);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_true);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
status = F_status_set_error(F_valid_not);
macro_f_limit_sets_t_increase(status, controller_common_allocation_small_d, rule->limits);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_limit_sets_increase", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_limit_sets_increase", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
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_problem_print_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);
+ 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_problem_print_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);
+ 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_problem_print_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);
+ 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);
}
}
else {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
status = F_status_set_error(status);
}
if (setting_value->used || cache->content_actions.array[i].used != 1) {
- controller_rule_setting_read_problem_print(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (status == F_false) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
else {
// this function should only return F_complete_not_utf on error.
- controller_rule_error_print(global.main->error, cache->action, F_complete_not_utf, "controller_validate_has_graph", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_complete_not_utf, "controller_validate_has_graph", F_true, F_false, global.thread);
if (F_status_is_error_not(status_return)) {
status_return = status;
}
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
}
setting_value->used = 0;
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_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
}
else {
status = f_string_dynamic_terminate_after(setting_value);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (type == controller_rule_setting_type_scheduler) {
if (cache->content_actions.array[i].used < 1 || cache->content_actions.array[i].used > 2 || rule->has & controller_rule_has_scheduler_d) {
- controller_rule_setting_read_problem_print(global.main->error, "requires either one or two Content", i, line_item, global.thread, cache);
+ 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);
rule->scheduler.priority = 49;
}
else {
- controller_rule_setting_read_problem_print_with_range(global.main->error, "has an unknown scheduler", cache->content_actions.array[i].array[0], "", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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);
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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
}
}
else {
- controller_rule_error_print(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
status = F_status_set_error(status);
if (F_status_is_error_not(status_return)) {
if (type == controller_rule_setting_type_timeout) {
if (cache->content_actions.array[i].used != 2) {
- controller_rule_setting_read_problem_print(global.main->error, "requires exactly two Content", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
status = F_status_set_fine(status);
if (status == F_number_overflow) {
- controller_rule_setting_read_problem_print_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);
+ 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_problem_print_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);
+ 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 {
cache->action.line_action = ++cache->action.line_item;
- controller_rule_error_print(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
}
if (F_status_is_error_not(status_return)) {
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_error_print(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
+ controller_print_error(global.main->error, F_status_set_fine(status), "controller_dynamic_rip_nulless_terminated", F_true, global.thread);
break;
}
if (type == controller_rule_setting_type_capability || type == controller_rule_setting_type_nice || type == controller_rule_setting_type_user) {
if (cache->content_actions.array[i].used != 1 || type == controller_rule_setting_type_capability && rule->capability || type == controller_rule_setting_type_group && (rule->has & controller_rule_has_group_d) || type == controller_rule_setting_type_nice && (rule->has & controller_rule_has_nice_d) || type == controller_rule_setting_type_user && (rule->has & controller_rule_has_user_d)) {
- controller_rule_setting_read_problem_print(global.main->error, "requires exactly one Content", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
- controller_rule_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
- controller_rule_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_capability_from_text", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_capability_from_text", F_true, F_false, global.thread);
- controller_rule_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
status_return = status;
break;
}
- controller_rule_setting_read_problem_print(global.main->error, "failed to process the capabilities", i, line_item, global.thread, cache);
+ 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);
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
}
}
else {
- controller_rule_error_print(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, status, "fl_conversion_string_to_number_signed", F_true, F_false, global.thread);
status = F_status_set_error(status);
if (F_status_is_error_not(status_return)) {
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ controller_lock_print(global.main->error.to, global.thread);
- controller_rule_error_print(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, global.thread);
+ controller_rule_print_error(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, global.thread);
- controller_rule_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
status = F_status_set_fine(status);
if (status == F_exist_not) {
- controller_rule_setting_read_problem_print_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);
+ 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_problem_print_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);
+ 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_problem_print_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);
+ 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 {
cache->action.line_action = ++cache->action.line_item;
- controller_rule_error_print(global.main->error, cache->action, status, "f_account_id_user_by_name", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, status, "f_account_id_user_by_name", F_true, F_false, global.thread);
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
}
if (F_status_is_error_not(status_return)) {
if (type == controller_rule_setting_type_group) {
if (!cache->content_actions.array[i].used) {
- controller_rule_setting_read_problem_print(global.main->error, "requires one or more Content", i, line_item, global.thread, cache);
+ 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);
macro_f_int32s_t_increase_by(status, rule->groups, controller_common_allocation_small_d)
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "macro_f_array_lengths_t_increase_by", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
status = F_status_set_fine(status);
if (status == F_exist_not) {
- controller_rule_setting_read_problem_print_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);
+ 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_problem_print_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);
+ 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_problem_print_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);
+ 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 {
cache->action.line_action = ++cache->action.line_item;
- controller_rule_error_print(global.main->error, cache->action, status, "f_account_id_group_by_name", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, status, "f_account_id_group_by_name", F_true, F_false, global.thread);
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
}
if (F_status_is_error_not(status_return)) {
status = f_string_dynamics_increase(controller_common_allocation_small_d, setting_values);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
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_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_partial_append_nulless", F_true, F_false, global.thread);
}
else {
status = f_string_dynamic_terminate_after(&setting_values->array[setting_values->used]);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamic_terminate_after", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (status == F_false) {
if (global.main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
else {
// this function should only return F_complete_not_utf on error.
- controller_rule_error_print(global.main->error, cache->action, F_complete_not_utf, "controller_validate_environment_name", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_complete_not_utf, "controller_validate_environment_name", F_true, F_false, global.thread);
if (F_status_is_error_not(status_return)) {
status_return = status;
setting_values->array[setting_values->used].used = 0;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
}
else {
if (global.main->error.verbosity == f_console_verbosity_debug || (global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
- controller_print_lock(global.main->output.to, global.thread);
+ 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_print_unlock_flush(global.main->output.to, global.thread);
+ controller_unlock_print_flush(global.main->output.to, global.thread);
}
}
// The "on" Rule Setting.
if (cache->content_actions.array[i].used != 4) {
- controller_rule_setting_read_problem_print(global.main->error, "requires exactly four Content", i, line_item, global.thread, cache);
+ 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);
f_thread_mutex_lock(&global.thread->lock.print);
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
}
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "controller_rule_ons_increase", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "controller_rule_ons_increase", F_true, F_false, global.thread);
}
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) {
cache->action.line_action = ++cache->action.line_item;
- controller_print_lock(global.main->error.to, global.thread);
+ 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_error_print_cache(global.main->error, cache->action, F_false);
+ controller_rule_print_error_cache(global.main->error, cache->action, F_false);
- controller_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
if (F_status_is_error_not(status_return)) {
status = f_string_dynamics_increase_by(controller_common_allocation_small_d, setting_values);
if (F_status_is_error(status)) {
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase_by", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_string_dynamics_increase_by", F_true, F_false, global.thread);
}
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
cache->action.line_action = ++cache->action.line_item;
- controller_rule_item_error_print(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
+ controller_rule_item_print_error(global.main->error, cache->action, F_false, F_status_set_fine(status), global.thread);
continue;
}
if (F_status_is_error(status)) {
setting_values->array[setting_values->used].used = 0;
- controller_rule_error_print(global.main->error, cache->action, F_status_set_fine(status), "f_file_name_base", F_true, F_false, global.thread);
+ controller_rule_print_error(global.main->error, cache->action, F_status_set_fine(status), "f_file_name_base", F_true, F_false, global.thread);
if (F_status_set_fine(status) == F_memory_not) {
status_return = status;
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) {
- controller_print_lock(global.main->error.to, global.thread);
+ 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("%[%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_print_unlock_flush(global.main->error.to, global.thread);
+ controller_unlock_print_flush(global.main->error.to, global.thread);
}
setting_values->array[setting_values->used].used = 0;
}
if (global.main->error.verbosity == f_console_verbosity_debug || (global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
- controller_print_lock(global.main->output.to, global.thread);
+ 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_print_unlock_flush(global.main->output.to, global.thread);
+ controller_unlock_print_flush(global.main->output.to, global.thread);
}
} // for
}
#endif // _di_controller_rule_setting_read_
-#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 && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
- return;
- }
-
- controller_print_lock(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_print_unlock_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 *cache) {
-
- if (global.main->error.verbosity != f_console_verbosity_debug && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
- return;
- }
-
- controller_print_lock(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_print_unlock_flush(global.main->output.to, global.thread);
- }
-#endif // _di_controller_rule_setting_read_print_value_
-
-#ifndef _di_controller_rule_setting_read_problem_print_
- void controller_rule_setting_read_problem_print(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 *thread, controller_cache_t *cache) {
-
- if (print.verbosity == f_console_verbosity_quiet) 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_print_lock(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_error_print_cache(print, cache->action, F_false);
-
- controller_print_unlock_flush(print.to, thread);
- }
-#endif // _di_controller_rule_setting_read_problem_print_
-
-#ifndef _di_controller_rule_setting_read_problem_print_with_range_
- void controller_rule_setting_read_problem_print_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 *thread, controller_cache_t *cache) {
-
- if (print.verbosity == f_console_verbosity_quiet) 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_print_lock(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_error_print_cache(print, cache->action, F_false);
-
- controller_print_unlock_flush(print.to, thread);
- }
-#endif // _di_controller_rule_setting_read_problem_print_with_range_
-
#ifndef _di_controller_rule_validate_
void controller_rule_validate(const controller_rule_t rule, const uint8_t action, const uint8_t options, const controller_global_t global, controller_cache_t *cache) {
default:
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, global.thread);
+ 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_error_print_cache(main->error, cache->action, F_true);
+ controller_rule_print_error_cache(main->error, cache->action, F_true);
- controller_print_unlock_flush(main->error.to, global.thread);
+ controller_unlock_print_flush(main->error.to, global.thread);
}
return;
} // for
if (missing) {
- controller_print_lock(main->output.to, global.thread);
+ 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("%[%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_print_unlock_flush(main->output.to, global.thread);
+ controller_unlock_print_flush(main->output.to, global.thread);
}
}
- controller_print_lock(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]);
fl_print_format("}%c", main->output.to.stream, f_string_eol_s[0]);
- controller_print_unlock_flush(main->output.to, global.thread);
+ controller_unlock_print_flush(main->output.to, global.thread);
}
#endif // _di_controller_rule_validate_
}
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
return status_lock;
}
}
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_false, global.thread);
+ 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);
} // for
if (status_lock == F_signal || F_status_is_error(status_lock)) {
- controller_lock_error_critical_print(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
+ controller_lock_print_error_critical(global.main->error, F_status_set_fine(status_lock), F_true, global.thread);
return status_lock;
}
#endif // _di_controller_rule_action_type_execute_name_
/**
- * Increase the size of the rule actions 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 actions
- * The actions 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().
- */
-#ifndef _di_controller_rule_actions_increase_by_
- extern f_status_t controller_rule_actions_increase_by(const f_array_length_t amount, controller_rule_actions_t *actions) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_actions_increase_by_
-
-/**
* 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.
#endif // _di_controller_rule_copy_
/**
- * Print generic error/warning information.
- *
- * This is essentially a wrapper to fll_error_print() that includes locking.
- *
- * @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.
- * @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_entry_error_print_cache()
- */
-#ifndef _di_controller_rule_error_print_
- extern void controller_rule_error_print(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, controller_thread_t *thread) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_error_print_
-
-/**
- * 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_error_print_cache_
- extern void controller_rule_error_print_cache(const fl_print_t print, const controller_cache_action_t cache, const bool item) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_error_print_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 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).
- * @param thread
- * The thread data.
- *
- * @see controller_rule_error_print_cache()
- */
-#ifndef _di_controller_rule_item_error_print_
- extern void controller_rule_item_error_print(const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status, controller_thread_t *thread) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_item_error_print_
-
-/**
- * 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_error_print_execute_
- extern void controller_rule_item_error_print_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_error_print_execute_
-
-/**
- * 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_error_print_need_want_wish_
- extern void controller_rule_item_error_print_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_error_print_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_error_print_rule_not_loaded_
- extern void controller_rule_item_error_print_rule_not_loaded(const fl_print_t print, const f_string_t alias) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_item_error_print_rule_not_loaded_
-
-/**
- * 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_error_missing_pid_
- extern void controller_rule_action_error_missing_pid(const fl_print_t print, const f_string_t alias) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_action_error_missing_pid_
-
-/**
* Perform an execution of the given rule.
*
* This requires that a read lock be set on process->lock before being called.
#endif // _di_controller_rule_setting_read_
/**
- * 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 *cache) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_setting_read_print_values_
-
-/**
- * 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_problem_print_
- extern void controller_rule_setting_read_problem_print(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 *thread, controller_cache_t *cache) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_setting_read_problem_print_
-
-/**
- * Print a message about a rule setting problem, with additional messages about 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 append 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 append 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_problem_print_with_range_
- extern void controller_rule_setting_read_problem_print_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 *thread, controller_cache_t *cache) F_attribute_visibility_internal_d;
-#endif // _di_controller_rule_setting_read_problem_print_with_range_
-
-/**
* Perform a simulated execution of the given rule.
*
* This simply prints information about the rule.
--- /dev/null
+#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(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, controller_thread_t *thread) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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) 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(const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status, controller_thread_t *thread) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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) {
+ 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);
+ fl_print_color_before(print->notable, print->to.stream);
+
+ if (status == F_control_group) {
+ f_print_terminated(controller_control_group_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_color_after(print->notable, print->to.stream);
+ fl_print_format("%['.%]%c", print->to.stream, 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) 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) 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) 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 *thread, controller_cache_t *cache) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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 *thread, controller_cache_t *cache) {
+
+ if (print.verbosity == f_console_verbosity_quiet) 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 && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
+ 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 *cache) {
+
+ if (global.main->error.verbosity != f_console_verbosity_debug && !(global.main->error.verbosity == f_console_verbosity_verbose && global.main->parameters[controller_parameter_simulate].result == f_console_result_found)) {
+ 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 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.
+ * @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(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, controller_thread_t *thread) 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 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).
+ * @param thread
+ * The thread data.
+ *
+ * @see controller_rule_print_error_cache()
+ */
+#ifndef _di_controller_rule_item_print_error_
+ extern void controller_rule_item_print_error(const fl_print_t print, const controller_cache_action_t cache, const bool item, const f_status_t status, controller_thread_t *thread) 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 *thread, controller_cache_t *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 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 append 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 append 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 *thread, controller_cache_t *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 *cache) F_attribute_visibility_internal_d;
+#endif // _di_controller_rule_setting_read_print_values_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_rule_print_h
#include "controller.h"
#include "private-common.h"
#include "private-controller.h"
-#include "private-entry.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" {
status = f_thread_lock_write(&process->lock);
if (F_status_is_error(status)) {
- controller_lock_error_critical_print(global->main->error, F_status_set_fine(status), F_false, global->thread);
+ controller_lock_print_error_critical(global->main->error, F_status_set_fine(status), F_false, global->thread);
f_thread_unlock(&process->active);
continue;
}
#endif // _di_controller_thread_cleanup_
-#ifndef _di_controller_thread_control_
- void * controller_thread_control(void *arguments) {
-
- f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
-
- controller_global_t *global = (controller_global_t *) arguments;
-
- if (global->thread->enabled != controller_thread_enabled) return 0;
-
- return 0;
- }
-#endif // _di_controller_thread_control_
-
#ifndef _di_controller_thread_is_enabled_
f_status_t controller_thread_is_enabled(const bool is_normal, controller_thread_t *thread) {
status = controller_processs_increase(&thread.processs);
if (F_status_is_error(status)) {
- controller_error_print(main->error, F_status_set_fine(status), "controller_processs_increase", F_true, &thread);
+ controller_print_error(main->error, F_status_set_fine(status), "controller_processs_increase", F_true, &thread);
}
}
thread.id_signal = 0;
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+ controller_print_error(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
}
}
else {
if (f_file_exists(setting->path_pid.string) == F_true) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(main->error.to, &thread);
+ 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_print_unlock_flush(main->error.to, &thread);
+ controller_unlock_print_flush(main->error.to, &thread);
}
setting->ready = controller_setting_ready_abort;
if (F_status_is_error(status)) {
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+ controller_print_error(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
}
}
else {
thread.id_cleanup = 0;
if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_error_print(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
+ controller_print_error(main->error, F_status_set_fine(status), "f_thread_create", F_true, &thread);
}
}
}
}
#endif // _di_controller_thread_main_
-#ifndef _di_controller_thread_process_
- void controller_thread_process(const bool is_normal, controller_process_t *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_normal_
- void * controller_thread_process_normal(void *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 *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_
-
-#ifndef _di_controller_thread_process_cancel_
- void controller_thread_process_cancel(const bool is_normal, const uint8_t by, controller_global_t *global, controller_process_t *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;
- }
- else {
- if (by == controller_thread_cancel_execute) {
- global->thread->enabled = controller_thread_enabled_execute;
- }
- else if (by == controller_thread_cancel_exit) {
- global->thread->enabled = controller_thread_enabled_not;
- }
- else if (by == controller_thread_cancel_exit_execute) {
- global->thread->enabled = controller_thread_enabled_exit_execute;
- }
- else {
- global->thread->enabled = controller_thread_enabled_exit;
- }
-
- 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 && 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 && global->thread->enabled != controller_thread_enabled_exit_execute) {
- 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 && global->thread->enabled != controller_thread_enabled_exit_execute) 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 && global->thread->enabled != controller_thread_enabled_exit_execute) 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 *global) {
-
- if (global->thread->enabled != controller_thread_enabled_exit) {
- return;
- }
-
- if (global->setting->ready == controller_setting_ready_done) {
-
- // 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) {
- controller_error_print(global->main->error, F_status_set_fine(status), "f_thread_create", F_true, global->thread);
- }
-
- if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
- global->thread->enabled = controller_thread_enabled_not;
-
- f_thread_mutex_unlock(&global->thread->lock.alert);
- }
- else {
- global->thread->enabled = controller_thread_enabled_not;
- }
- }
- 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;
-
- 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);
-
- 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;
-
- f_thread_mutex_unlock(&global->thread->lock.alert);
- }
- else {
- global->thread->enabled = controller_thread_enabled_not;
- }
- }
- }
-
- // 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(F_false, controller_thread_cancel_exit, global, 0);
- }
- else {
- if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
- global->thread->enabled = controller_thread_enabled_not;
-
- f_thread_mutex_unlock(&global->thread->lock.alert);
- }
- else {
- global->thread->enabled = controller_thread_enabled_not;
- }
- }
- }
-#endif // _di_controller_thread_process_exit_
-
-#ifndef _di_controller_thread_entry_
- void * controller_thread_entry(void *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(F_true, *entry->global, cache);
-
- if (F_status_is_error(*status)) {
- entry->setting->ready = controller_setting_ready_fail;
- }
- else if (*status != F_signal && *status != F_child) {
- *status = controller_preprocess_entry(F_true, *entry->global, cache);
- }
-
- if (F_status_is_error_not(*status) && *status != F_signal && *status != F_child) {
- if (main->parameters[controller_parameter_validate].result == f_console_result_none || main->parameters[controller_parameter_simulate].result == f_console_result_found) {
-
- if (entry->setting->entry.pid == controller_entry_pid_require && f_file_exists(entry->setting->path_pid.string) == F_true) {
- if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_flush(main->error.to, entry->global->thread);
- }
-
- entry->setting->ready = controller_setting_ready_fail;
- *status = F_status_set_error(F_available_not);
- }
- else {
- *status = controller_process_entry(F_false, F_true, entry->global, cache);
-
- if (F_status_is_error(*status)) {
- entry->setting->ready = controller_setting_ready_fail;
-
- 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;
-
- 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_process_entry(F_true, F_true, entry->global, cache);
-
- if (F_status_is_error(status_failsafe)) {
- if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_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 (*status == F_signal) {
- entry->setting->ready = controller_setting_ready_abort;
- }
- else if (*status != F_child) {
- entry->setting->ready = controller_setting_ready_done;
- }
- }
- }
- }
-
- 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 *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(F_false, *entry->global, cache);
-
- if (F_status_is_error(*status)) {
- entry->setting->ready = controller_setting_ready_fail;
- }
- else if (*status == F_file_found_not) {
- entry->setting->ready = controller_setting_ready_done;
- }
- else if (*status != F_signal && *status != F_child) {
- *status = controller_preprocess_entry(F_false, *entry->global, cache);
- }
-
- if (F_status_is_error_not(*status) && *status != F_signal && *status != F_child && *status != F_file_found_not) {
- if (main->parameters[controller_parameter_validate].result == f_console_result_none || main->parameters[controller_parameter_simulate].result == f_console_result_found) {
-
- *status = controller_process_entry(F_false, F_false, entry->global, cache);
-
- if (F_status_is_error(*status)) {
- entry->setting->ready = controller_setting_ready_fail;
-
- 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;
-
- 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_process_entry(F_true, F_false, entry->global, cache);
-
- if (F_status_is_error(status_failsafe)) {
- if (main->error.verbosity != f_console_verbosity_quiet) {
- controller_print_lock(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_print_unlock_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 (*status == F_signal) {
- entry->setting->ready = controller_setting_ready_abort;
- }
- else if (*status != F_child) {
- entry->setting->ready = controller_setting_ready_done;
- }
- }
- }
-
- 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;
-
- 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_
-
#ifndef _di_controller_thread_join_
f_status_t controller_thread_join(f_thread_id_t *id) {
}
#endif // _di_controller_thread_join_
-#ifndef _di_controller_thread_rule_
- void * controller_thread_rule(void *arguments) {
-
- f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
-
- 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_
-
-#ifndef _di_controller_thread_signal_
- void controller_thread_signal(const bool is_normal, controller_global_t *global) {
-
- 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(is_normal, controller_thread_cancel_signal, global, 0);
-
- break;
- }
- }
- } // while
- }
-#endif // _di_controller_thread_signal_
-
-#ifndef _di_controller_thread_signal_state_fss_
- f_status_t controller_thread_signal_state_fss(void *state, void *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 *state, void *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 *arguments) {
-
- f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
-
- controller_thread_signal(F_true, (controller_global_t *) arguments);
-
- return 0;
- }
-#endif // _di_controller_thread_signal_normal_
-
-#ifndef _di_controller_thread_signal_other_
- void * controller_thread_signal_other(void *arguments) {
-
- f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
-
- controller_thread_signal(F_false, (controller_global_t *) arguments);
-
- return 0;
- }
-#endif // _di_controller_thread_signal_other_
-
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _di_controller_thread_cleanup_
/**
- * 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 *arguments) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_control_
-
-/**
* Check to see if thread is enabled for the normal operations like entry and control or for exit operations.
*
* @param is_normal
extern f_status_t controller_thread_main(controller_main_t *main, controller_setting_t *setting) F_attribute_visibility_internal_d;
#endif // _di_controller_thread_main_
-/**
- * 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 *process) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_process_
-
-/**
- * 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 *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 *arguments) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_process_other_
-
-/**
- * Cancel all process threads.
- *
- * @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, then this was called from within the signal handling thread, so do not cancel the signal thread.
- * If controller_thread_cancel_call, then this was not called from within the signal handling thread, so cancel the signal thread.
- * If controller_thread_cancel_execute, then this was called from within the Entry/Exit for executing a process, so cancel the signal thread but not the Entry thread.
- * @param global
- * The global thread data.
- * @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 bool is_normal, const uint8_t by, controller_global_t *global, controller_process_t *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 *global) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_process_exit_
-
-/**
- * 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 *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 *arguments) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_exit_
-
/***
* Join a thread, assigning id to NULL on success.
*
extern f_status_t controller_thread_join(f_thread_id_t *id) F_attribute_visibility_internal_d;
#endif // _di_controller_thread_join_
-/**
- * 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 *arguments) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_rule_
-
-/**
- * Thread for handling signals/interrupts.
- *
- * @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 global
- * The global data.
- */
-#ifndef _di_controller_thread_signal_
- extern void controller_thread_signal(const bool is_normal, controller_global_t *global) 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 *state, void *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 *state, void *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 *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 *arguments) F_attribute_visibility_internal_d;
-#endif // _di_controller_thread_signal_other_
-
#ifdef __cplusplus
} // extern "C"
#endif
--- /dev/null
+#include "controller.h"
+#include "private-common.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 *arguments) {
+
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+ controller_global_t *global = (controller_global_t *) arguments;
+
+ if (global->thread->enabled != controller_thread_enabled) return 0;
+
+ return 0;
+ }
+#endif // _di_controller_thread_control_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 *arguments) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_control_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_thread_control_h
--- /dev/null
+#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 *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(F_true, *entry->global, cache);
+
+ if (F_status_is_error(*status)) {
+ entry->setting->ready = controller_setting_ready_fail;
+ }
+ else if (*status != F_signal && *status != F_child) {
+ *status = controller_entry_preprocess(F_true, *entry->global, cache);
+ }
+
+ if (F_status_is_error_not(*status) && *status != F_signal && *status != F_child) {
+ if (main->parameters[controller_parameter_validate].result == f_console_result_none || main->parameters[controller_parameter_simulate].result == f_console_result_found) {
+
+ if (entry->setting->entry.pid == controller_entry_pid_require && f_file_exists(entry->setting->path_pid.string) == F_true) {
+ if (main->error.verbosity != f_console_verbosity_quiet) {
+ 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;
+ *status = F_status_set_error(F_available_not);
+ }
+ else {
+ *status = controller_entry_process(F_false, F_true, entry->global, cache);
+
+ if (F_status_is_error(*status)) {
+ entry->setting->ready = controller_setting_ready_fail;
+
+ 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;
+
+ 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(F_true, F_true, entry->global, cache);
+
+ if (F_status_is_error(status_failsafe)) {
+ if (main->error.verbosity != f_console_verbosity_quiet) {
+ 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 (*status == F_signal) {
+ entry->setting->ready = controller_setting_ready_abort;
+ }
+ else if (*status != F_child) {
+ entry->setting->ready = controller_setting_ready_done;
+ }
+ }
+ }
+ }
+
+ 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 *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(F_false, *entry->global, cache);
+
+ if (F_status_is_error(*status)) {
+ entry->setting->ready = controller_setting_ready_fail;
+ }
+ else if (*status == F_file_found_not) {
+ entry->setting->ready = controller_setting_ready_done;
+ }
+ else if (*status != F_signal && *status != F_child) {
+ *status = controller_entry_preprocess(F_false, *entry->global, cache);
+ }
+
+ if (F_status_is_error_not(*status) && *status != F_signal && *status != F_child && *status != F_file_found_not) {
+ if (main->parameters[controller_parameter_validate].result == f_console_result_none || main->parameters[controller_parameter_simulate].result == f_console_result_found) {
+
+ *status = controller_entry_process(F_false, F_false, entry->global, cache);
+
+ if (F_status_is_error(*status)) {
+ entry->setting->ready = controller_setting_ready_fail;
+
+ 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;
+
+ 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(F_true, F_false, entry->global, cache);
+
+ if (F_status_is_error(status_failsafe)) {
+ if (main->error.verbosity != f_console_verbosity_quiet) {
+ 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 (*status == F_signal) {
+ entry->setting->ready = controller_setting_ready_abort;
+ }
+ else if (*status != F_child) {
+ entry->setting->ready = controller_setting_ready_done;
+ }
+ }
+ }
+
+ 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;
+
+ 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 *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 *arguments) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_exit_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_thread_entry_h
--- /dev/null
+#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 *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 bool is_normal, const uint8_t by, controller_global_t *global, controller_process_t *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;
+ }
+ else {
+ if (by == controller_thread_cancel_execute) {
+ global->thread->enabled = controller_thread_enabled_execute;
+ }
+ else if (by == controller_thread_cancel_exit) {
+ global->thread->enabled = controller_thread_enabled_not;
+ }
+ else if (by == controller_thread_cancel_exit_execute) {
+ global->thread->enabled = controller_thread_enabled_exit_execute;
+ }
+ else {
+ global->thread->enabled = controller_thread_enabled_exit;
+ }
+
+ 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 && 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 && global->thread->enabled != controller_thread_enabled_exit_execute) {
+ 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 && global->thread->enabled != controller_thread_enabled_exit_execute) 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 && global->thread->enabled != controller_thread_enabled_exit_execute) 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 *global) {
+
+ if (global->thread->enabled != controller_thread_enabled_exit) {
+ return;
+ }
+
+ if (global->setting->ready == controller_setting_ready_done) {
+
+ // 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) {
+ controller_print_error(global->main->error, F_status_set_fine(status), "f_thread_create", F_true, global->thread);
+ }
+
+ if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
+ global->thread->enabled = controller_thread_enabled_not;
+
+ f_thread_mutex_unlock(&global->thread->lock.alert);
+ }
+ else {
+ global->thread->enabled = controller_thread_enabled_not;
+ }
+ }
+ 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;
+
+ 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);
+
+ 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;
+
+ f_thread_mutex_unlock(&global->thread->lock.alert);
+ }
+ else {
+ global->thread->enabled = controller_thread_enabled_not;
+ }
+ }
+ }
+
+ // 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(F_false, controller_thread_cancel_exit, global, 0);
+ }
+ else {
+ if (F_status_is_error_not(f_thread_mutex_lock(&global->thread->lock.alert))) {
+ global->thread->enabled = controller_thread_enabled_not;
+
+ f_thread_mutex_unlock(&global->thread->lock.alert);
+ }
+ else {
+ global->thread->enabled = controller_thread_enabled_not;
+ }
+ }
+ }
+#endif // _di_controller_thread_process_exit_
+
+#ifndef _di_controller_thread_process_normal_
+ void * controller_thread_process_normal(void *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 *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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 *process) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_process_
+
+/**
+ * Cancel all process threads.
+ *
+ * @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, then this was called from within the signal handling thread, so do not cancel the signal thread.
+ * If controller_thread_cancel_call, then this was not called from within the signal handling thread, so cancel the signal thread.
+ * If controller_thread_cancel_execute, then this was called from within the Entry/Exit for executing a process, so cancel the signal thread but not the Entry thread.
+ * @param global
+ * The global thread data.
+ * @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 bool is_normal, const uint8_t by, controller_global_t *global, controller_process_t *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 *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 *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 *arguments) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_process_other_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_thread_process_h
--- /dev/null
+#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 *arguments) {
+
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+ 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
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#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 *arguments) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_rule_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_thread_rule_h
--- /dev/null
+#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(const bool is_normal, controller_global_t *global) {
+
+ 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(is_normal, controller_thread_cancel_signal, global, 0);
+
+ break;
+ }
+ }
+ } // while
+ }
+#endif // _di_controller_thread_signal_
+
+#ifndef _di_controller_thread_signal_state_fss_
+ f_status_t controller_thread_signal_state_fss(void *state, void *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 *state, void *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 *arguments) {
+
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+ controller_thread_signal(F_true, (controller_global_t *) arguments);
+
+ return 0;
+ }
+#endif // _di_controller_thread_signal_normal_
+
+#ifndef _di_controller_thread_signal_other_
+ void * controller_thread_signal_other(void *arguments) {
+
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+ controller_thread_signal(F_false, (controller_global_t *) arguments);
+
+ return 0;
+ }
+#endif // _di_controller_thread_signal_other_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Controller
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_thread_signal_h
+#define _PRIVATE_thread_signal_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Thread for handling signals/interrupts.
+ *
+ * @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 global
+ * The global data.
+ */
+#ifndef _di_controller_thread_signal_
+ extern void controller_thread_signal(const bool is_normal, controller_global_t *global) 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 *state, void *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 *state, void *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 *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 *arguments) F_attribute_visibility_internal_d;
+#endif // _di_controller_thread_signal_other_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_thread_signal_h
build_indexer_arguments rcs
build_language c
build_libraries -lc -lcap
-build_libraries-individual -lfll_control_group -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_print -lfll_program -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_print -lfl_status -lfl_string -lf_account -lf_capability -lf_color -lf_console -lf_control_group -lf_conversion -lf_directory -lf_environment -lf_execute -lf_file -lf_fss -lf_iki -lf_limit -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_thread -lf_type_array -lf_utf
+
+build_libraries-individual -lfll_control_group -lfll_error -lfll_execute -lfll_fss -lfll_path -lfll_print -lfll_program
+build_libraries-individual -lfl_console -lfl_control_group -lfl_conversion -lfl_directory -lfl_environment -lfl_fss -lfl_iki -lfl_print -lfl_status -lfl_string
+build_libraries-individual -lf_account -lf_capability -lf_color -lf_console -lf_control_group -lf_conversion -lf_directory -lf_environment -lf_execute -lf_file -lf_fss -lf_iki -lf_limit -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_thread -lf_type_array -lf_utf
+
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
build_libraries_shared
build_libraries_static
-build_sources_library controller.c private-common.c private-control.c private-controller.c private-entry.c private-rule.c private-thread.c
+
+build_sources_library controller.c private-common.c private-process.c
+build_sources_library private-control.c private-control_print.c private-controller.c private-controller_print.c private-entry.c private-entry_print.c private-lock.c private-lock_print.c private-rule.c private-rule_print.c
+build_sources_library private-thread.c private-thread_control.c private-thread_entry.c private-thread_process.c private-thread_rule.c private-thread_signal.c
+
build_sources_library_shared
build_sources_library_static
build_sources_program main.c