1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// 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;
}
freez(variable_name);
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;
}
freez(text);
}
}
for(REPLACE_NODE *node = rp->nodes; node; node = node->next) {
if(node->is_variable) {
rp->has_variables = true;
break;
}
}
return true;
}
|