master
c 113 lines 3.17 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "log2journal.h"
4
5 void replace_node_free(REPLACE_NODE *rpn) {
6 hashed_key_cleanup(&rpn->name);
7 rpn->next = NULL;
8 freez(rpn);
9 }
10
11 void replace_pattern_cleanup(REPLACE_PATTERN *rp) {
12 if(rp->pattern) {
13 freez((void *)rp->pattern);
14 rp->pattern = NULL;
15 }
16
17 while(rp->nodes) {
18 REPLACE_NODE *rpn = rp->nodes;
19 rp->nodes = rpn->next;
20 replace_node_free(rpn);
21 }
22 }
23
24 static REPLACE_NODE *replace_pattern_add_node(REPLACE_NODE **head, bool is_variable, const char *text) {
25 REPLACE_NODE *new_node = callocz(1, sizeof(REPLACE_NODE));
26 if (!new_node)
27 return NULL;
28
29 hashed_key_set(&new_node->name, text, -1);
30 new_node->is_variable = is_variable;
31 new_node->next = NULL;
32
33 if (*head == NULL)
34 *head = new_node;
35
36 else {
37 REPLACE_NODE *current = *head;
38
39 // append it
40 while (current->next != NULL)
41 current = current->next;
42
43 current->next = new_node;
44 }
45
46 return new_node;
47 }
48
49 bool replace_pattern_set(REPLACE_PATTERN *rp, const char *pattern) {
50 replace_pattern_cleanup(rp);
51
52 rp->pattern = strdupz(pattern);
53 const char *current = rp->pattern;
54
55 while (*current != '\0') {
56 if (*current == '$' && *(current + 1) == '{') {
57 // Start of a variable
58 const char *end = strchr(current, '}');
59 if (!end) {
60 l2j_log("Error: Missing closing brace in replacement pattern: %s", rp->pattern);
61 return false;
62 }
63
64 size_t name_length = end - current - 2; // Length of the variable name
65 char *variable_name = strndupz(current + 2, name_length);
66 if (!variable_name) {
67 l2j_log("Error: Memory allocation failed for variable name.");
68 return false;
69 }
70
71 REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), true, variable_name);
72 if (!node) {
73 freez(variable_name);
74 l2j_log("Error: Failed to add replacement node for variable.");
75 return false;
76 }
77 freez(variable_name);
78
79 current = end + 1; // Move past the variable
80 }
81 else {
82 // Start of literal text
83 const char *start = current;
84 while (*current != '\0' && !(*current == '$' && *(current + 1) == '{')) {
85 current++;
86 }
87
88 size_t text_length = current - start;
89 char *text = strndupz(start, text_length);
90 if (!text) {
91 l2j_log("Error: Memory allocation failed for literal text.");
92 return false;
93 }
94
95 REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), false, text);
96 if (!node) {
97 freez(text);
98 l2j_log("Error: Failed to add replacement node for text.");
99 return false;
100 }
101 freez(text);
102 }
103 }
104
105 for(REPLACE_NODE *node = rp->nodes; node; node = node->next) {
106 if(node->is_variable) {
107 rp->has_variables = true;
108 break;
109 }
110 }
111
112 return true;
113 }