root/lib/common/xml_comment.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcmk__xc_create
  2. pcmk__xc_match
  3. pcmk__xc_update

   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 
  18 /*!
  19  * \internal
  20  * \brief Create a new XML comment belonging to a given document
  21  *
  22  * \param[in] doc      Document that new comment will belong to
  23  * \param[in] content  Comment content
  24  *
  25  * \return Newly created XML comment (guaranteed not to be \c NULL)
  26  */
  27 xmlNode *
  28 pcmk__xc_create(xmlDoc *doc, const char *content)
     /* [previous][next][first][last][top][bottom][index][help] */
  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);
  37     pcmk__xml_new_private_data(node);
  38     return node;
  39 }
  40 
  41 /*!
  42  * \internal
  43  * \brief Find a comment with matching content in specified XML
  44  *
  45  * \param[in] root            XML to search
  46  * \param[in] search_comment  Comment whose content should be searched for
  47  * \param[in] exact           If true, comment must also be at same position
  48  */
  49 xmlNode *
  50 pcmk__xc_match(const xmlNode *root, const xmlNode *search_comment, bool exact)
     /* [previous][next][first][last][top][bottom][index][help] */
  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 
  87 /*!
  88  * \internal
  89  * \brief Make one XML comment match another (in content)
  90  *
  91  * \param[in,out] parent   If \p target is NULL and this is not, add or update
  92  *                         comment child of this XML node that matches \p update
  93  * \param[in,out] target   If not NULL, update this XML comment node
  94  * \param[in]     update   Make comment content match this (must not be NULL)
  95  *
  96  * \note At least one of \parent and \target must be non-NULL
  97  */
  98 void
  99 pcmk__xc_update(xmlNode *parent, xmlNode *target, xmlNode *update)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */