pacemaker  2.1.9-49aab99839
Scalable High-Availability cluster resource manager
xml_comment.c
Go to the documentation of this file.
1 /*
2  * Copyright 2024 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <stdio.h> // NULL
13 
14 #include <libxml/tree.h> // xmlDoc, xmlNode, etc.
15 
16 #include "crmcommon_private.h"
17 
27 xmlNode *
28 pcmk__xc_create(xmlDoc *doc, const char *content)
29 {
30  xmlNode *node = NULL;
31 
32  // Pacemaker typically assumes every xmlNode has a doc
33  pcmk__assert(doc != NULL);
34 
35  node = xmlNewDocComment(doc, (pcmkXmlStr) content);
36  pcmk__mem_assert(node);
38  return node;
39 }
40 
49 xmlNode *
50 pcmk__xc_match(const xmlNode *root, const xmlNode *search_comment, bool exact)
51 {
52  xmlNode *a_child = NULL;
53  int search_offset = pcmk__xml_position(search_comment, pcmk__xf_skip);
54 
55  CRM_CHECK(search_comment->type == XML_COMMENT_NODE, return NULL);
56 
57  for (a_child = pcmk__xml_first_child(root); a_child != NULL;
58  a_child = pcmk__xml_next(a_child)) {
59  if (exact) {
60  int offset = pcmk__xml_position(a_child, pcmk__xf_skip);
61  xml_node_private_t *nodepriv = a_child->_private;
62 
63  if (offset < search_offset) {
64  continue;
65 
66  } else if (offset > search_offset) {
67  return NULL;
68  }
69 
70  if (pcmk_is_set(nodepriv->flags, pcmk__xf_skip)) {
71  continue;
72  }
73  }
74 
75  if (a_child->type == XML_COMMENT_NODE
76  && pcmk__str_eq((const char *)a_child->content, (const char *)search_comment->content, pcmk__str_casei)) {
77  return a_child;
78 
79  } else if (exact) {
80  return NULL;
81  }
82  }
83 
84  return NULL;
85 }
86 
98 void
99 pcmk__xc_update(xmlNode *parent, xmlNode *target, xmlNode *update)
100 {
101  CRM_CHECK(update != NULL, return);
102  CRM_CHECK(update->type == XML_COMMENT_NODE, return);
103 
104  if (target == NULL) {
105  target = pcmk__xc_match(parent, update, false);
106  }
107 
108  if (target == NULL) {
109  pcmk__xml_copy(parent, update);
110 
111  } else if (!pcmk__str_eq((const char *)target->content, (const char *)update->content, pcmk__str_casei)) {
112  xmlFree(target->content);
113  target->content = xmlStrdup(update->content);
114  }
115 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:245
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
Definition: xml.c:974
G_GNUC_INTERNAL int pcmk__xml_position(const xmlNode *xml, enum xml_private_flags ignore_if_set)
Definition: xml.c:383
xmlNode * pcmk__xc_match(const xmlNode *root, const xmlNode *search_comment, bool exact)
Definition: xml_comment.c:50
G_GNUC_INTERNAL void pcmk__xml_new_private_data(xmlNode *xml)
Definition: xml.c:326
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:94
const xmlChar * pcmkXmlStr
Definition: xml.h:41
xmlNode * pcmk__xc_create(xmlDoc *doc, const char *content)
Definition: xml_comment.c:28
#define pcmk__assert(expr)
const char * target
Definition: pcmk_fence.c:29
#define pcmk__mem_assert(ptr)
void pcmk__xc_update(xmlNode *parent, xmlNode *target, xmlNode *update)
Definition: xml_comment.c:99
const char * parent
Definition: cib.c:27