#define controller_string_group "group"
#define controller_string_name "name"
#define controller_string_pid "pid"
- #define controller_string_program "program"
#define controller_string_restart "restart"
#define controller_string_reload "reload"
#define controller_string_script "script"
#define controller_string_settings "settings"
#define controller_string_start "start"
#define controller_string_stop "stop"
+ #define controller_string_use "use"
#define controller_string_user "user"
#define controller_string_create_length 6
#define controller_string_group_length 5
#define controller_string_name_length 4
#define controller_string_pid_length 3
- #define controller_string_program_length 7
#define controller_string_restart_length 7
#define controller_string_reload_length 6
#define controller_string_script_length 6
#define controller_string_settings_length 8
#define controller_string_start_length 5
#define controller_string_stop_length 4
+ #define controller_string_use_length 3
#define controller_string_user_length 4
enum {
f_file_t output;
fll_error_print_t error;
+ fll_error_print_t warning;
f_color_context_t context;
} controller_data_t;
F_false, \
f_macro_file_t_initialize(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \
fll_error_print_t_initialize, \
+ fll_macro_error_print_t_initialize_warning(f_console_verbosity_debug) \
f_color_context_t_initialize, \
}
#endif // _di_controller_data_t_
-#ifndef _di_controller_rule_item_t_
+#ifndef _di_controller_rule_action_t_
enum {
- controller_rule_item_type_single = 1,
- controller_rule_item_type_multiple,
+ controller_rule_action_type_basic = 1,
+ controller_rule_action_type_extended,
+ controller_rule_action_type_extended_list,
};
enum {
- controller_rule_item_intent_create = 1,
- controller_rule_item_intent_program,
- controller_rule_item_intent_group,
- controller_rule_item_intent_restart,
- controller_rule_item_intent_reload,
- controller_rule_item_intent_start,
- controller_rule_item_intent_stop,
- controller_rule_item_intent_user,
+ controller_rule_action_intent_create = 1,
+ controller_rule_action_intent_group,
+ controller_rule_action_intent_restart,
+ controller_rule_action_intent_reload,
+ controller_rule_action_intent_start,
+ controller_rule_action_intent_stop,
+ controller_rule_action_intent_use,
+ controller_rule_action_intent_user,
};
- // @fixme rule_item needs to contain a list of actions which is essentially what rule_item is currently acting as.
+ typedef struct {
+ f_string_length_t line;
+ f_string_dynamic_t content;
+ } controller_rule_action_t;
+
+ #define controller_rule_action_t_initialize \
+ { \
+ 0, \
+ f_string_dynamic_t_initialize, \
+ }
+
+ #define f_macro_controller_rule_action_t_delete_simple(action) \
+ f_macro_string_dynamic_t_delete_simple(action.content)
+#endif // _di_controller_rule_action_t_
+
+#ifndef _di_controller_rule_actions_t_
typedef struct {
uint8_t type;
uint8_t intent;
+ controller_rule_action_t *array;
+
+ f_array_length_t size;
+ f_array_length_t used;
+ } controller_rule_actions_t;
+
+ #define controller_rule_actions_t_initialize \
+ { \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ }
+
+ #define f_macro_controller_rule_actions_t_delete_simple(actions) \
+ actions.used = actions.size; \
+ while (actions.used > 0) { \
+ actions.used--; \
+ f_macro_controller_rule_item_t_delete_simple(actions.array[actions.used]); \
+ if (!actions.used) { \
+ if (f_memory_delete((void **) & actions.array, sizeof(controller_rule_action_t), actions.size)) { \
+ actions.size = 0; \
+ } \
+ } \
+ }
+#endif // _di_controller_rule_actions_t_
+
+#ifndef _di_controller_rule_item_t_
+ enum {
+ controller_rule_item_type_command = 1,
+ controller_rule_item_type_script,
+ controller_rule_item_type_service,
+ controller_rule_item_type_settings,
+ };
+
+ typedef struct {
+ uint8_t type;
f_string_length_t line;
- f_string_dynamic_t name;
- f_string_dynamic_t content;
+ controller_rule_actions_t create;
+ controller_rule_actions_t group;
+ controller_rule_actions_t restart;
+ controller_rule_actions_t reload;
+ controller_rule_actions_t start;
+ controller_rule_actions_t stop;
+ controller_rule_actions_t use;
+ controller_rule_actions_t user;
} controller_rule_item_t;
#define controller_rule_item_t_initialize \
{ \
0, \
0, \
- 0, \
- f_string_dynamic_t_initialize, \
- f_string_dynamic_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
+ controller_rule_actions_t_initialize, \
}
- #define f_macro_controller_rule_item_t_delete_simple(rule_item) \
- f_macro_string_dynamic_t_delete_simple(rule_item.name) \
- f_macro_string_dynamic_t_delete_simple(rule_item.content)
+ #define f_macro_controller_rule_item_t_delete_simple(item) \
+ f_macro_controller_rule_actions_t_delete_simple(item.create) \
+ f_macro_controller_rule_actions_t_delete_simple(item.group) \
+ f_macro_controller_rule_actions_t_delete_simple(item.restart) \
+ f_macro_controller_rule_actions_t_delete_simple(item.reload) \
+ f_macro_controller_rule_actions_t_delete_simple(item.start) \
+ f_macro_controller_rule_actions_t_delete_simple(item.stop) \
+ f_macro_controller_rule_actions_t_delete_simple(item.use) \
+ f_macro_controller_rule_actions_t_delete_simple(item.user)
#endif // _di_controller_rule_item_t_
#ifndef _di_controller_rule_items_t_
typedef struct {
- f_string_length_t line;
- f_string_dynamic_t name;
-
controller_rule_item_t *array;
f_array_length_t size;
#define controller_rule_items_initialize \
{ \
0, \
- f_string_dynamic_t_initialize, \
- 0, \
0, \
0, \
}
items.used--; \
f_macro_controller_rule_item_t_delete_simple(items.array[items.used]); \
if (!items.used) { \
- if (f_memory_delete((void **) & items.array, sizeof(f_string_dynamic_t), items.size)) { \
+ if (f_memory_delete((void **) & items.array, sizeof(controller_rule_item_t), items.size)) { \
items.size = 0; \
} \
} \
- } \
- f_macro_string_dynamic_t_delete_simple(items.name);
+ }
#endif // _di_controller_rule_items_t_
+#ifndef _di_controller_rule_setting_t_
+ typedef struct {
+ f_string_dynamic_t name;
+ f_string_dynamic_t pid;
+
+ f_string_dynamics_t defines; // @todo this probably should a list of name and value pairs.
+ f_string_dynamics_t environment;
+ } controller_rule_setting_t;
+
+ #define controller_rule_setting_t_initialize \
+ { \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ f_string_dynamics_t_initialize, \
+ }
+
+ #define f_macro_controller_rule_setting_t_delete_simple(setting) \
+ f_string_dynamic_t_delete_simple(setting.name) \
+ f_string_dynamic_t_delete_simple(setting.pid) \
+ f_string_dynamics_t_delete_simple(setting.defines) \
+ f_string_dynamics_t_delete_simple(setting.environments)
+#endif // _di_controller_rule_setting_t_
+
/**
* Print help.
*
extern "C" {
#endif
+#ifndef _di_controller_rule_actions_read_
+ f_return_status controller_rule_actions_read(const controller_data_t data, const bool multiple, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions) {
+ f_status_t status = F_none;
+
+ f_fss_objects_t objects = f_fss_objects_t_initialize;
+ f_fss_contents_t contents = f_fss_contents_t_initialize;
+
+ f_string_range_t range = cache->range_action;
+
+ if (multiple) {
+ // @todo
+ //fll_fss_extended_list_read();
+ }
+ else {
+ status = f_fss_seek_to_eol(*buffer, range);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "f_fss_seek_to_eol", F_true);
+ controller_rule_error_print(data.error, *cache);
+ }
+
+ range.stop = range.start;
+ range.start = cache->range_action.start;
+
+ // @fixme I just noticed an inconsistency in the naming, should it be quoted_objects and delimit_objects or instead objects_quoted, and objects_delimit?
+ // @fixme also, I think that the buffer in the fll_fss read functions no longer need to be pointers (it should be possible to make them constants now).
+ status = fll_fss_extended_read(buffer, &range, &objects, &contents, "ed_objects, "ed_contents, &delimit_objects, &delimit_contents);
+ // @todo
+ }
+
+ if (!content.used) {
+ if (data.warning.verbosity == f_console_verbosity_debug) {
+ fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
+
+ if (actions) {
+ fprintf(data.warning.to.stream, "%s%sUnknown action, nothing to do.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
+ }
+ else {
+ fprintf(data.warning.to.stream, "%s%sAction is empty, nothing to do.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
+ }
+
+ controller_rule_error_print(data.error, *cache);
+ }
+
+ return F_data_not;
+ }
+
+ action->type = type;
+ action->line = line;
+ action->content.used = 0;
+
+ // @todo now that the type and intent are known, the content may be loaded.
+ // @todo a "script" type uses basic and a "service" type uses extended because the script is passed to bash whereas the service is directly called.
+ // @todo additional line-by-line processing needs to be performed for multi-line services OR services should not support multiple lines.
+ /*
+ comments.used = 0;
+ status = fl_fss_extended_list_content_read(content, &range, &child_content, &delimits, &comments);
+
+ if (F_status_is_error(status)) {
+ fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true, file_name.string, "process", fll_error_file_type_file);
+ controller_rule_error_print(data.error, *cache);
+ break;
+ }
+
+ if (status == FL_fss_found_content) {
+ type = controller_rule_item_type_multiple;
+ }
+ */
+ /*
+ status = fl_fss_basic_content_read(content, &range, &child_content, &delimits);
+
+ if (F_status_is_error(status)) {
+ fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_basic_content_read", F_true, file_name.string, "process", fll_error_file_type_file);
+ controller_rule_error_print(data.error, *cache);
+ break;
+ }
+
+ if (status == FL_fss_found_content) {
+ type = controller_rule_action_type_basic;
+ }*/
+
+ return status;
+ }
+#endif // _di_controller_rule_actions_read_
+
+#ifndef _di_controller_rule_error_print_
+ void controller_rule_error_print(const fll_error_print_t output, const controller_rule_cache_t cache) {
+
+ if (output.verbosity != f_console_verbosity_quiet) {
+ fprintf(output.to.stream, "%s%sWhile processing ", output.context.before->string, output.prefix ? output.prefix : "");
+
+ if (cache.name_action) {
+ fprintf(output.to.stream, "action '");
+ fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_action.string, output.notable.after->string);
+ fprintf(output.to.stream, "%s' on line ", output.context.before->string);
+ fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_action, output.notable.after->string);
+ fprintf(output.to.stream, "%s for ", output.context.before->string);
+ }
+
+ if (cache.name_item) {
+ fprintf(output.to.stream, "item '");
+ fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_item.string, output.notable.after->string);
+ fprintf(output.to.stream, "%s' on line ", output.context.before->string);
+ fprintf(output.to.stream, "%s%s%llu%s", output.context.after->string, output.notable.before->string, cache.line_item, output.notable.after->string);
+ fprintf(output.to.stream, "%s for ", output.context.before->string);
+ }
+
+ fprintf(output.to.stream, "file '");
+ fprintf(output.to.stream, "%s%s%s%s", output.context.after->string, output.notable.before->string, cache.name_file.string, output.notable.after->string);
+ fprintf(output.to.stream, "%s'.%s%c", output.context.before->string, output.context.after->string, f_string_eol[0]);
+ }
+ }
+#endif // _di_controller_rule_error_print_
+
+#ifndef _di_controller_rule_item_read_
+ f_return_status controller_rule_item_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item) {
+ f_status_t status = F_none;
+
+ f_string_range_t range = f_macro_string_range_t_initialize(buffer->used);
+
+ f_fss_delimits_t delimits = f_fss_delimits_t_initialize;
+ f_fss_comments_t comments = f_fss_comments_t_initialize;
+ f_fss_quote_t quote = f_fss_quote_t_initialize;
+
+ controller_rule_actions_t *actions = 0;
+
+ bool multiple = f_false;
+
+ for (range.start = 0; range.start < buffer->used && range.start <= range.stop; delimits.used = 0, comments.used = 0) {
+
+ status = fl_fss_extended_list_object_read(buffer, &range, &cache->range_action, &delimits);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true);
+ break;
+ }
+
+ if (range.start >= range.stop || range.start >= buffer->used) {
+ if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) {
+ if (error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fprintf(data.error.to.stream, "%s%sUnterminated FSS Extended List at end of rule file.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]);
+ }
+
+ status = F_status_set_error(FL_fss_found_object_content_not);
+ }
+
+ break;
+ }
+
+ if (status == FL_fss_found_object) {
+ multiple = F_true;
+ }
+ else {
+ multiple = f_false;
+
+ // The current line is not an Extended List object, so the next possibility is a Basic List (and Extended List, both use the same Object structure).
+ status = fl_fss_basic_object_read(buffer, &range, &cache->range_action, "e, &delimits);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data->error, F_status_set_fine(status), "fl_fss_basic_object_read", F_true);
+ break;
+ }
+ }
+
+ if (status == FL_fss_found_object_content_not || range.start >= range.stop || range.start >= buffer->used) {
+ // object ended without any content.
+ break;
+ }
+
+ if (status == FL_fss_found_object) {
+ status = fl_fss_apply_delimit(delimits, &data_make->buffer);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true);
+ break;
+ }
+
+ status = f_fss_count_lines(buffer, cache->range_action.start, &cache->line_action);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
+ break;
+ }
+
+ cache->line_action += item->line;
+
+ action_name->used = 0;
+ status = fl_string_dynamic_rip_nulless(buffer, cache->range_action, action_name);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true);
+ break;
+ }
+
+ status = fl_string_dynamic_terminate_after(action_name);
+
+ if (F_status_is_error(status)) {
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
+ break;
+ }
+
+ actions = 0;
+
+ if (fl_string_dynamic_compare_string(controller_string_create, *action_name, controller_string_create_length) == f_equal_to) {
+ actions = &item->create;
+ actions->intent = controller_rule_action_intent_create;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_group, *action_name, controller_string_group_length) == f_equal_to) {
+ actions = &item->group;
+ actions->intent = controller_rule_action_intent_group;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_restart, *action_name, controller_string_restart_length) == f_equal_to) {
+ actions = &item->restart;
+ actions->intent = controller_rule_action_intent_restart;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_reload, *action_name, controller_string_reload_length) == f_equal_to) {
+ actions = &item->reload;
+ actions->intent = controller_rule_action_intent_reload;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_start, *action_name, controller_string_start_length) == f_equal_to) {
+ actions = &item->start;
+ actions->intent = controller_rule_action_intent_start;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_stop, *action_name, controller_string_stop_length) == f_equal_to) {
+ actions = &item->stop;
+ actions->intent = controller_rule_action_intent_stop;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_use, *action_name, controller_string_use_length) == f_equal_to) {
+ actions = &item->use;
+ actions->intent = controller_rule_action_intent_use;
+ }
+ else if (fl_string_dynamic_compare_string(controller_string_user, *action_name, controller_string_user_length) == f_equal_to) {
+ actions = &item->user;
+ actions->intent = controller_rule_action_intent_user;
+ }
+ else {
+ if (data.warning.verbosity == f_console_verbosity_debug) {
+ fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
+ fprintf(data.warning.to.stream, "%s%sUnknown action type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
+
+ controller_rule_error_print(data.warning, *cache);
+ }
+
+ continue;
+ }
+
+ if (multiple) {
+ if (actions->intent == controller_rule_action_intent_create || actions->intent == controller_rule_action_intent_group || actions->intent == controller_rule_action_intent_use || actions->intent == controller_rule_action_intent_user) {
+ if (error.verbosity != f_console_verbosity_quiet) {
+ fprintf(data.error.to.stream, "%c", f_string_eol[0]);
+ fprintf(data.error.to.stream, "%s%sFSS Extended List is not allowed for this item action type.%s%c", data.error.context.before->string, data.error.prefix ? data.error.prefix : "", data.error.context.after->string, f_string_eol[0]);
+ }
+
+ status = F_status_set_error(F_unsupported);
+ break;
+ }
+ }
+
+ status = controller_rule_actions_read(data, multiple, buffer, cache, item, actions);
+ if (F_status_is_error(status)) break;
+ }
+ } // for
+
+ f_macro_fss_delimits_t_delete_simple(delimits);
+ f_macro_fss_comments_t_delete_simple(comments);
+
+ if (F_status_is_error(status)) {
+ controller_rule_error_print(data.error, *cache);
+ }
+
+ return status;
+ }
+#endif // _di_controller_rule_item_read_
+
#ifndef _di_controller_rule_items_increase_by_
f_return_status controller_rule_items_increase_by(const f_array_length_t amount, controller_rule_items_t *items) {
f_status_t status = F_none;
#endif // _di_controller_rule_items_increase_by_
#ifndef _di_controller_rule_read_
- f_return_status controller_rule_read(const controller_data_t data, const f_string_static_t file_name, controller_rule_items_t *items) {
+ f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) {
f_status_t status = F_none;
f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
status = f_file_stream_open(arguments.argv[data->remaining.array[i]], 0, &file);
if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_open", F_true, file_name.string, "open", fll_error_file_type_file);
+ fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_open", F_true, cache->name_file.string, "open", fll_error_file_type_file);
}
else {
status = f_file_stream_read(file, 1, &buffer);
if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_read", F_true, file_name.string, "read", fll_error_file_type_file);
+ fll_error_file_print(data->error, F_status_set_fine(status), "f_file_stream_read", F_true, cache->name_file.string, "read", fll_error_file_type_file);
}
}
for (f_array_length_t i = 0; i < objects.used; ++i) {
- status = f_fss_count_lines(buffer, objects.array[i], &items->array[items->used].line);
+ cache->name_file.used = 0;
+ cache->name_item.used = 0;
+ cache->name_action.used = 0;
+
+ cache->line_item = 0;
+ cache->line_action = 0;
+
+ cache->range_item = objects.array[i];
+ cache->range_action = 0;
+
+ status = f_fss_count_lines(buffer, cache->range_item.start, &cache->line_item);
if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
break;
}
- status = fl_string_dynamic_partial_append_nulless(buffer, objects.array[i], items->array[items->used].name);
+ items->array[items->used].line = cache->line_item;
+
+ status = fl_string_dynamic_rip_nulless(buffer, cache->range_item, &cache->name_item);
if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+ fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_rip_nulless", F_true);
break;
}
- status = fl_string_dynamic_terminate_after(items->array[items->used].name);
+ status = fl_string_dynamic_terminate_after(&cache->name_item);
if (F_status_is_error(status)) {
fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
break;
}
- status = controller_rule_read_content(data, file_name, items->array[items->used].line, &content, items);
- if (F_status_is_error(status)) break;
-
- items->used++;
- } // for
-
- f_macro_fss_content_t_delete_simple(content);
- }
- }
-
- f_macro_fss_objects_t_delete_simple(objects);
- f_macro_fss_contents_t_delete_simple(contents);
- f_macro_string_dynamic_t_delete_simple(buffer);
-
- return status;
- }
-#endif // _di_controller_rule_read_
-
-#ifndef _di_controller_rule_read_content_
- f_return_status controller_rule_read_content(const controller_data_t data, const f_string_static_t file_name, const f_string_length_t line, f_string_static_t *content, controller_rule_items_t *items) {
- f_status_t status = F_none;
-
- f_string_range_t range = f_macro_string_range_t_initialize(content->used);
- f_string_length_t last = 0;
-
- f_fss_delimits_t delimits = f_fss_delimits_t_initialize;
- f_fss_comments_t comments = f_fss_comments_t_initialize;
- f_fss_object_t child_object = f_fss_object_t_initialize;
- f_fss_content_t child_content = f_fss_content_t_initialize;
- f_fss_quote_t quote = f_fss_quote_t_initialize;
-
- uint8_t type = 0;
-
- for (range.start = 0; range.start < content->used; last = range.start, type = 0) {
-
- delimits.used = 0;
- status = fl_fss_extended_list_object_read(content, &range, &child_object, &delimits);
-
- if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_object_read", F_true, file_name.string, "read", fll_error_file_type_file);
- break;
- }
-
- if (range.start >= range.stop || range.start >= content->used) {
- if (status == FL_fss_found_object || status == FL_fss_found_object_content_not) {
- if (error.verbosity != f_console_verbosity_quiet) {
- fprintf(data.error.to.stream, "%c", f_string_eol[0]);
- fprintf(data.error.to.stream, "%s%sUnterminated FSS Extended List at end of file '", data.error.context.before->string, data.error.prefix ? data.error.prefix : "");
- fprintf(data.error.to.stream, "%s%s%s%s", data.error.context.after->string, data.error.notable.before->string, file_name.string, data.error.notable.after->string);
- fprintf(data.error.to.stream, "%s'.%s%c", data.error.context.before->string, data.error.context.after->string, f_string_eol[0]);
+ if (fl_string_dynamic_compare_string(controller_string_settings, cache->name_item, controller_string_settings_length) == f_equal_to) {
+ items->array[items->used].type = 0;
}
-
- status = F_status_set_error(FL_fss_found_object_content_not);
- }
-
- break;
- }
-
- if (status == FL_fss_found_object) {
- // @fixme I just noticed that Extended List wasn't intended to be recursive, this will be updated.
- comments.used = 0;
- status = fl_fss_extended_list_content_read(content, &range, &child_content, &delimits, &comments);
-
- if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_extended_list_content_read", F_true, file_name.string, "read", fll_error_file_type_file);
- break;
- }
-
- if (status == FL_fss_found_content) {
- type = controller_rule_item_type_multiple;
- }
- }
- else {
- status = fl_fss_basic_object_read(content, &range, &child_object, "e, &delimits);
-
- if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_basic_object_read", F_true, file_name.string, "read", fll_error_file_type_file);
- break;
- }
-
- if (range.start >= range.stop || range.start >= content->used) {
- // in this case, if status is FL_fss_found_object or FL_fss_found_object_content_not, there is no content so do not save this item.
- break;
- }
-
- if (status == FL_fss_found_object) {
- status = fl_fss_basic_content_read(content, &range, &child_content, &delimits);
-
- if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_basic_content_read", F_true, file_name.string, "read", fll_error_file_type_file);
- break;
+ else if (fl_string_dynamic_compare_string(controller_string_command, cache->name_item, controller_string_command_length) == f_equal_to) {
+ items->array[items->used].type = controller_rule_item_type_command;
}
-
- if (status == FL_fss_found_content) {
- type = controller_rule_item_type_single;
+ else if (fl_string_dynamic_compare_string(controller_string_script, cache->name_item, controller_string_script_length) == f_equal_to) {
+ items->array[items->used].type = controller_rule_item_type_script;
}
- }
- }
+ else if (fl_string_dynamic_compare_string(controller_string_service, cache->name_item, controller_string_service_length) == f_equal_to) {
+ items->array[items->used].type = controller_rule_item_type_service;
+ }
+ else {
+ if (warning.verbosity == f_console_verbosity_debug) {
+ fprintf(data.warning.to.stream, "%c", f_string_eol[0]);
+ fprintf(data.warning.to.stream, "%s%sUnknown item type.%s%c", data.warning.context.before->string, data.warning.prefix ? data.warning.prefix : "", data.warning.context.after->string, f_string_eol[0]);
- if (type) {
- status = fl_fss_apply_delimit(delimits, &data_make->buffer);
+ controller_rule_error_print(data.warning, *cache);
+ }
- if (F_status_is_error(status)) {
- fll_error_file_print(data->error, F_status_set_fine(status), "fl_fss_apply_delimit", F_true, file_name.string, "read", fll_error_file_type_file);
- break;
- }
+ continue;
+ }
- status = f_fss_count_lines(buffer, contents.array[i], &items->array[items->used].line);
+ if (items->array[items->used].type) {
+ status = controller_rule_item_read(data, &content, cache, &items->array[items->used]);
+ if (F_status_is_error(status)) break;
- if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "f_fss_count_lines", F_true);
- break;
- }
+ items->used++;
+ }
+ else {
+ // @todo handle rule settings population.
+ }
+ } // for
- // @todo
- //if (fl_string_dynamic_compare_string(x, items->array[i].name) == f_equal_to) {
- //items->array[i].name
- // @todo
- //}
+ f_macro_string_dynamic_t_delete_simple(content);
}
- } // for
-
- f_macro_fss_delimits_t_delete_simple(delimits);
- f_macro_fss_comments_t_delete_simple(comments);
- f_macro_fss_content_t_delete_simple(child_content);
-
- if (F_status_is_error(status)) return status;
-
- /*
- uint8_t type;
- uint8_t intent;
-
- f_string_length_t line;
-
- f_string_dynamic_t name;
- f_string_dynamic_t content;
- */
- /*
- status = fl_string_dynamic_partial_append_nulless(buffer, objects.array[i], items->array[i].name);
-
- if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
- break;
- }
-
- status = fl_string_dynamic_terminate_after(items->array[i].name);
-
- if (F_status_is_error(status)) {
- fll_error_print(data.error, F_status_set_fine(status), "fl_string_dynamic_terminate_after", F_true);
- break;
}
+ f_macro_fss_objects_t_delete_simple(objects);
+ f_macro_fss_contents_t_delete_simple(contents);
+ f_macro_string_dynamic_t_delete_simple(buffer);
- */
+ return status;
}
-#endif // _di_controller_rule_read_content_
+#endif // _di_controller_rule_read_
#ifdef __cplusplus
} // extern "C"
extern "C" {
#endif
+#ifndef _di_controller_rule_cache_t_
+ typedef struct {
+ f_string_length_t line_item;
+ f_string_length_t line_action;
+
+ f_string_range_t range_item;
+ f_string_range_t range_action;
+
+ f_string_dynamic_t name_file;
+ f_string_dynamic_t name_item;
+ f_string_dynamic_t name_action
+ } controller_rule_cache_t;
+
+ #define controller_rule_cache_t_initialize \
+ { \
+ 0, \
+ 0, \
+ 0, \
+ 0, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ f_string_dynamic_t_initialize, \
+ }
+
+ #define f_macro_controller_rule_name_t_delete_simple(cache) \
+ f_string_dynamic_t_delete_simple(cache.name_file) \
+ f_string_dynamic_t_delete_simple(cache.name_item) \
+ f_string_dynamic_t_delete_simple(cache.name_action)
+#endif // _di_controller_rule_cache_t_
+
+/**
+ * Read the content within the buffer, extracting all valid actions for the current processed item.
+ *
+ * @param data
+ * The program data.
+ * @param multiple
+ * If TRUE, then the Object expects multiple lines of Content (which ends up being an extended list).
+ * If FALSE, then the Object expects only a single line of Content (which is either basic or extended).
+ * @param buffer
+ * The buffer containing the content.
+ * @param cache
+ * A structure for containing and caching the file name, item name, and action name.
+ * @param item
+ * The processed item.
+ * @param actions
+ * The processed actions.
+ *
+ * @return
+ * F_none on success.
+ * @todo add response codes.
+ *
+ * Errors (with error bit) from: f_fss_count_lines().
+ */
+#ifndef _di_controller_rule_actions_read_
+ f_return_status controller_rule_actions_read(const controller_data_t data, const bool multiple, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item, controller_rule_actions_t *actions) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_actions_read_
+
+/**
+ * Print additional error/warning information in addition to existing error.
+ *
+ * This is explicitly intended to be used in addition to the error message.
+ *
+ * @param output
+ * The error or warning output structure.
+ * @param cache
+ * A structure for containing and caching the file name, item name, and action name.
+ *
+ * @see controller_rule_actions_read()
+ * @see controller_rule_items_read()
+ * @see controller_rule_settings_read()
+ */
+#ifndef _di_controller_rule_error_print_
+ void controller_rule_error_print(const fll_error_print_t output, const controller_rule_cache_t cache) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_error_print_
+
+/**
+ * Read the content within the buffer, extracting all valid items after determining their type for some rule file.
+ *
+ * This will perform additional FSS read functions as appropriate.
+ *
+ * @param data
+ * The program data.
+ * @param buffer
+ * The buffer containing the content.
+ * @param cache
+ * A structure for containing and caching the file name, item name, and action name.
+ * @param item
+ * The processed item.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Errors (with error bit) from: f_fss_count_lines().
+ * Errors (with error bit) from: fl_string_dynamic_partial_append_nulless().
+ * Errors (with error bit) from: fl_string_dynamic_terminate_after().
+ *
+ * @see controller_rule_actions_read()
+ */
+#ifndef _di_controller_rule_item_read_
+ extern f_return_status controller_rule_item_read(const controller_data_t data, f_string_static_t *buffer, controller_rule_cache_t *cache, controller_rule_item_t *item) f_gcc_attribute_visibility_internal;
+#endif // _di_controller_rule_item_read_
+
/**
* Increase the size of the rule items array by the specified amount, but only if necessary.
*
*
* @param data
* The program data.
- * @param file_name
- * The file name string.
+ * @param cache
+ * A structure for containing and caching the file name, item name, and action name.
* @param items
- * An array of items associated with the rule.
+ * The processed array of items.
*
* @return
* F_none on success.
*
* Errors (with error bit) from: controller_rule_items_increase_by().
- * Errors (with error bit) from: controller_rule_read_content().
+ * Errors (with error bit) from: controller_rule_item_read().
* Errors (with error bit) from: f_file_stream_open().
* Errors (with error bit) from: f_file_stream_read().
* Errors (with error bit) from: f_fss_count_lines().
* Errors (with error bit) from: fl_string_dynamic_partial_append_nulless().
* Errors (with error bit) from: fl_string_dynamic_terminate_after().
* Errors (with error bit) from: fll_fss_basic_list_read().
+ *
+ * @see controller_rule_item_read()
*/
#ifndef _di_controller_rule_read_
- extern f_return_status controller_rule_read(const controller_data_t data, const f_string_static_t file_name, controller_rule_items_t *items) f_gcc_attribute_visibility_internal;
+ extern f_return_status controller_rule_read(const controller_data_t data, controller_rule_cache_t *cache, controller_rule_items_t *items) f_gcc_attribute_visibility_internal;
#endif // _di_controller_rule_read_
-/**
- * Read the content within the buffer, extracting all valid items after determining their type for some rule file.
- *
- * This will perform additional FSS read functions as appropriate.
- *
- * @param data
- * The program data.
- * @param file_name
- * The file name string.
- * @param line
- * The line number where the content begins.
- * @param content
- * The buffer containing the content.
- * @param items
- * An array of items associated with the rule.
- *
- * @return
- * F_none on success.
- *
- * Errors (with error bit) from: f_fss_count_lines().
- * Errors (with error bit) from: fl_string_dynamic_partial_append_nulless().
- * Errors (with error bit) from: fl_string_dynamic_terminate_after().
- */
-#ifndef _di_controller_rule_read_content_
- extern f_return_status controller_rule_read_content(const controller_data_t data, const f_string_static_t file_name, const f_string_length_t line, f_string_static_t *content, controller_rule_items_t *items) f_gcc_attribute_visibility_internal;
-#endif // _di_controller_rule_read_content_
-
#ifdef __cplusplus
} // extern "C"
#endif