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_matches
  3. match_xc_child
  4. pcmk__xc_update

   1 /*
   2  * Copyright 2024-2025 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 <stdbool.h>                    // bool, false
  13 #include <stdio.h>                      // NULL
  14 
  15 #include <libxml/tree.h>                // xmlDoc, xmlNode, etc.
  16 #include <libxml/xmlstring.h>           // xmlChar
  17 
  18 #include "crmcommon_private.h"
  19 
  20 /*!
  21  * \internal
  22  * \brief Create a new XML comment belonging to a given document
  23  *
  24  * \param[in] doc      Document that new comment will belong to
  25  * \param[in] content  Comment content
  26  *
  27  * \return Newly created XML comment (guaranteed not to be \c NULL)
  28  */
  29 xmlNode *
  30 pcmk__xc_create(xmlDoc *doc, const char *content)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32     xmlNode *node = NULL;
  33 
  34     // Pacemaker typically assumes every xmlNode has a doc
  35     pcmk__assert(doc != NULL);
  36 
  37     node = xmlNewDocComment(doc, (const xmlChar *) content);
  38     pcmk__mem_assert(node);
  39     pcmk__xml_new_private_data(node);
  40     return node;
  41 }
  42 
  43 /*!
  44  * \internal
  45  * \brief Check whether two comments have matching content (case-insensitive)
  46  *
  47  * \param[in] comment1  First comment node to compare
  48  * \param[in] comment2  Second comment node to compare
  49  *
  50  * \return \c true if \p comment1 and \p comment2 have matching content (by
  51  *         case-insensitive string comparison), or \c false otherwise
  52  */
  53 bool
  54 pcmk__xc_matches(const xmlNode *comment1, const xmlNode *comment2)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56     pcmk__assert((comment1 != NULL) && (comment1->type == XML_COMMENT_NODE)
  57                  && (comment2 != NULL) && (comment2->type == XML_COMMENT_NODE));
  58 
  59     return pcmk__str_eq((const char *) comment1->content,
  60                         (const char *) comment2->content, pcmk__str_casei);
  61 }
  62 
  63 /*!
  64  * \internal
  65  * \brief Find a comment with matching content among children of specified XML
  66  *
  67  * \param[in] parent  XML whose children to search
  68  * \param[in] search  Comment whose content should be searched for
  69  *
  70  * \return Matching comment, or \c NULL if no match is found
  71  */
  72 static xmlNode *
  73 match_xc_child(const xmlNode *parent, const xmlNode *search)
     /* [previous][next][first][last][top][bottom][index][help] */
  74 {
  75     pcmk__assert((search != NULL) && (search->type == XML_COMMENT_NODE));
  76 
  77     for (xmlNode *child = pcmk__xml_first_child(parent); child != NULL;
  78          child = pcmk__xml_next(child)) {
  79 
  80         if (child->type != XML_COMMENT_NODE) {
  81             continue;
  82         }
  83 
  84         if (pcmk__xc_matches(child, search)) {
  85             return child;
  86         }
  87     }
  88 
  89     return NULL;
  90 }
  91 
  92 /*!
  93  * \internal
  94  * \brief Make one XML comment match another (in content)
  95  *
  96  * \param[in,out] parent   If \p target is NULL and this is not, add or update
  97  *                         comment child of this XML node that matches \p update
  98  * \param[in,out] target   If not NULL, update this XML comment node
  99  * \param[in]     update   Make comment content match this (must not be NULL)
 100  *
 101  * \note At least one of \parent and \target must be non-NULL
 102  */
 103 void
 104 pcmk__xc_update(xmlNode *parent, xmlNode *target, xmlNode *update)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106     CRM_CHECK(update != NULL, return);
 107     CRM_CHECK(update->type == XML_COMMENT_NODE, return);
 108 
 109     if (target == NULL) {
 110         target = match_xc_child(parent, update);
 111     }
 112 
 113     if (target == NULL) {
 114         pcmk__xml_copy(parent, update);
 115 
 116     } else if (!pcmk__str_eq((const char *)target->content, (const char *)update->content, pcmk__str_casei)) {
 117         xmlFree(target->content);
 118         target->content = xmlStrdup(update->content);
 119     }
 120 }

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