log2journal-replace.c 3.1 KB

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