#include #include #include #include "action.h" #include "block.h" #include "any_log.h" void action_perform(action_t *action, block_t *block, config_t *config) { block_t *target = block; bool warned = false; for (size_t i = 0; i < action->length; i++) { const char *key = action->parts[i].key; const char *value = action->parts[i].value; switch (action->parts[i].type) { case ACTION_TARGET: { if (strncmp(value, "block.", 6)) log_panic("Invalid target %s", value); if (!strcmp(value + 6, "default")) { target = block; } else { for (size_t i = 0; i < config->n_blocks; i++) { if (!strcmp(value + 6, config->blocks[i]->label)) { target = config->blocks[i]; break; } } } warned = false; break; } case ACTION_SET_PAIR: { assert(target != NULL); if (!warned && target->scheme->change_fn == NULL) { log_warn("Block '%s' does not support changing values", target->label); warned = true; continue; } // Skip "set-" target->scheme->change_fn(target, config, key + 4, value); break; } case ACTION_RUN_SCRIPT: { log_panic("TODO"); break; } default: unreachable(); } log_value_trace("Performed action step", "i:type", action->parts[i].type, "s:key", key, "s:value", value); } log_debug("Performed action '%s'", action->label); } int action_validate(action_t *action, config_t *config) { // TODO return 0; } void action_free(action_t *action) { for (size_t i = 0; i < action->length; i++) { free(action->parts[i].key); free(action->parts[i].value); } free(action->parts); free(action->label); }