diff options
Diffstat (limited to 'collectors/log2journal/log2journal-replace.c')
-rw-r--r-- | collectors/log2journal/log2journal-replace.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/collectors/log2journal/log2journal-replace.c b/collectors/log2journal/log2journal-replace.c new file mode 100644 index 00000000..429d615d --- /dev/null +++ b/collectors/log2journal/log2journal-replace.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "log2journal.h" + +void replace_node_free(REPLACE_NODE *rpn) { + hashed_key_cleanup(&rpn->name); + rpn->next = NULL; + freez(rpn); +} + +void replace_pattern_cleanup(REPLACE_PATTERN *rp) { + if(rp->pattern) { + freez((void *)rp->pattern); + rp->pattern = NULL; + } + + while(rp->nodes) { + REPLACE_NODE *rpn = rp->nodes; + rp->nodes = rpn->next; + replace_node_free(rpn); + } +} + +static REPLACE_NODE *replace_pattern_add_node(REPLACE_NODE **head, bool is_variable, const char *text) { + REPLACE_NODE *new_node = callocz(1, sizeof(REPLACE_NODE)); + if (!new_node) + return NULL; + + hashed_key_set(&new_node->name, text); + new_node->is_variable = is_variable; + new_node->next = NULL; + + if (*head == NULL) + *head = new_node; + + else { + REPLACE_NODE *current = *head; + + // append it + while (current->next != NULL) + current = current->next; + + current->next = new_node; + } + + return new_node; +} + +bool replace_pattern_set(REPLACE_PATTERN *rp, const char *pattern) { + replace_pattern_cleanup(rp); + + rp->pattern = strdupz(pattern); + const char *current = rp->pattern; + + while (*current != '\0') { + if (*current == '$' && *(current + 1) == '{') { + // Start of a variable + const char *end = strchr(current, '}'); + if (!end) { + log2stderr("Error: Missing closing brace in replacement pattern: %s", rp->pattern); + return false; + } + + size_t name_length = end - current - 2; // Length of the variable name + char *variable_name = strndupz(current + 2, name_length); + if (!variable_name) { + log2stderr("Error: Memory allocation failed for variable name."); + return false; + } + + REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), true, variable_name); + if (!node) { + freez(variable_name); + log2stderr("Error: Failed to add replacement node for variable."); + return false; + } + + current = end + 1; // Move past the variable + } + else { + // Start of literal text + const char *start = current; + while (*current != '\0' && !(*current == '$' && *(current + 1) == '{')) { + current++; + } + + size_t text_length = current - start; + char *text = strndupz(start, text_length); + if (!text) { + log2stderr("Error: Memory allocation failed for literal text."); + return false; + } + + REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), false, text); + if (!node) { + freez(text); + log2stderr("Error: Failed to add replacement node for text."); + return false; + } + } + } + + for(REPLACE_NODE *node = rp->nodes; node; node = node->next) { + if(node->is_variable) { + rp->has_variables = true; + break; + } + } + + return true; +} |