root/lib/common/xml_idref.c

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

DEFINITIONS

This source file includes following definitions.
  1. pcmk__add_idref
  2. pcmk__free_idref
  3. pcmk__xe_resolve_idref

   1 /*
   2  * Copyright 2004-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 #include <stdlib.h>             // free()
  14 #include <glib.h>               // GList, GHashTable, etc.
  15 #include <libxml/tree.h>        // xmlNode
  16 
  17 #include <crm/crm.h>
  18 #include <crm/common/xml.h>     // get_xpath_object(), PCMK_XA_ID_REF
  19 
  20 /*!
  21  * \internal
  22  * \brief Add an XML ID reference to a table
  23  *
  24  * \param[in,out] table      Table of ID references to add to
  25  * \param[in]     id         ID of primary element being referred to
  26  * \param[in]     referrer   ID of element referring to \p id
  27  *
  28  * \note This refers to an ID reference in general, not necessarily connected to
  29  *       an id-ref attribute.
  30  */
  31 void
  32 pcmk__add_idref(GHashTable *table, const char *id, const char *referrer)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34     pcmk__idref_t *idref = NULL;
  35 
  36     pcmk__assert((table != NULL) && (id != NULL) && (referrer != NULL));
  37 
  38     idref = g_hash_table_lookup(table, id);
  39     if (idref == NULL) {
  40         idref = pcmk__assert_alloc(1, sizeof(pcmk__idref_t));
  41         idref->id = pcmk__str_copy(id);
  42         g_hash_table_insert(table, pcmk__str_copy(id), idref);
  43     }
  44     for (GList *iter = idref->refs; iter != NULL; iter = iter->next) {
  45         if (pcmk__str_eq(referrer, (const char *) iter->data,
  46                          pcmk__str_none)) {
  47             return; // Already present
  48         }
  49     }
  50     idref->refs = g_list_append(idref->refs, pcmk__str_copy(referrer));
  51     crm_trace("Added ID %s referrer %s", id, referrer);
  52 }
  53 
  54 /*!
  55  * \internal
  56  * \brief Free a pcmk__idref_t
  57  *
  58  * \param[in,out] data  pcmk__idref_t to free
  59  */
  60 void
  61 pcmk__free_idref(gpointer data)
     /* [previous][next][first][last][top][bottom][index][help] */
  62 {
  63     pcmk__idref_t *idref = data;
  64 
  65     if (idref != NULL) {
  66         free(idref->id);
  67         g_list_free_full(idref->refs, free);
  68         free(idref);
  69     }
  70 }
  71 
  72 /*!
  73  * \internal
  74  * \brief Get the XML element whose \c PCMK_XA_ID matches an \c PCMK_XA_ID_REF
  75  *
  76  * \param[in] xml     Element whose \c PCMK_XA_ID_REF attribute to check
  77  * \param[in] search  Node whose document to search for node with matching
  78  *                    \c PCMK_XA_ID (\c NULL to use \p xml)
  79  *
  80  * \return If \p xml has a \c PCMK_XA_ID_REF attribute, node in
  81  *         <tt>search</tt>'s document whose \c PCMK_XA_ID attribute matches;
  82  *         otherwise, \p xml
  83  */
  84 xmlNode *
  85 pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87     char *xpath = NULL;
  88     const char *ref = NULL;
  89     xmlNode *result = NULL;
  90 
  91     if (xml == NULL) {
  92         return NULL;
  93     }
  94 
  95     ref = crm_element_value(xml, PCMK_XA_ID_REF);
  96     if (ref == NULL) {
  97         return xml;
  98     }
  99 
 100     if (search == NULL) {
 101         search = xml;
 102     }
 103 
 104     xpath = crm_strdup_printf("//%s[@" PCMK_XA_ID "='%s']", xml->name, ref);
 105     result = get_xpath_object(xpath, search, LOG_DEBUG);
 106     if (result == NULL) {
 107         // Not possible with schema validation enabled
 108         pcmk__config_err("Ignoring invalid %s configuration: "
 109                          PCMK_XA_ID_REF " '%s' does not reference "
 110                          "a valid object " QB_XS " xpath=%s",
 111                          xml->name, ref, xpath);
 112     }
 113     free(xpath);
 114     return result;
 115 }

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