]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
core: Config and XML tweaks needed for geolocation
authorGeorge Joseph <gjoseph@digium.com>
Sun, 20 Feb 2022 20:16:22 +0000 (13:16 -0700)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Mon, 28 Feb 2022 14:29:20 +0000 (08:29 -0600)
Added:

Replace a variable in a list:
int ast_variable_list_replace_variable(struct ast_variable **head,
    struct ast_variable *old, struct ast_variable *new);
Added test as well.

Create a "name=value" string from a variable list:
'name1="val1",name2="val2"', etc.
struct ast_str *ast_variable_list_join(
    const struct ast_variable *head, const char *item_separator,
    const char *name_value_separator, const char *quote_char,
    struct ast_str **str);
Added test as well.

Allow the name of an XML element to be changed.
void ast_xml_set_name(struct ast_xml_node *node, const char *name);

Change-Id: I330a5f63dc0c218e0d8dfc0745948d2812141ccb

include/asterisk/config.h
include/asterisk/xml.h
main/config.c
main/xml.c
tests/test_config.c

index f4d1dd29d0d02b6252f00b4afc96a709157924b4..f4f6c9d5f7951b7f93840300432c16ad605a8975 100644 (file)
@@ -967,6 +967,44 @@ struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, s
  */
 int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement);
 
+/*!
+ * \brief Replace a variable in the given list with a new variable
+ *
+ * \param head A pointer to the current variable list head.  Since the variable to be
+ *             replaced, this pointer may be updated with the new head.
+ * \param old  A pointer to the existing variable to be replaced.
+ * \param new  A pointer to the new variable that will replace the old one.
+ *
+ * \retval 0 if a variable was replaced in the list
+ * \retval -1 if no replacement occured
+ *
+ * \note The search for the old variable is done simply on the pointer.
+ * \note If a variable is replaced, its memory is freed.
+ */
+int ast_variable_list_replace_variable(struct ast_variable **head, struct ast_variable *old,
+       struct ast_variable *new);
+
+/*!
+ * \brief Join an ast_variable list with specified separators and quoted values
+ *
+ * \param head                 A pointer to an ast_variable list head.
+ * \param item_separator       The string to use to separate the list items.
+ *                             If NULL, "," will be used.
+ * \param name_value_separator The string to use to separate each item's name and value.
+ *                             If NULL, "=" will be used.
+ * \param str                  A pointer to a pre-allocated ast_str in which to put the results.
+ *                             If NULL, one will be allocated and returned.
+ * \param quote_char           The quote char to use for the values.
+ *                             May be NULL or empty for no quoting.
+ *
+ * \retval A pointer to the result ast_str. This may NOT be the same as the pointer
+ *         passed in if the original ast_str wasn't large enough to hold the result.
+ *         Regardless, the pointer MUST be freed after use.
+ * \retval NULL if there was an error.
+ */
+struct ast_str *ast_variable_list_join(const struct ast_variable *head, const char *item_separator,
+       const char *name_value_separator, const char *quote_char, struct ast_str **str);
+
 /*!
  * \brief Update variable value within a config
  *
index 3217750ad170fb0d0902937fdfa69ed9106de4c2..13af3c6b601dd29631114a5ebff1a2ad9e9091b2 100644 (file)
@@ -201,6 +201,13 @@ const char *ast_xml_get_text(struct ast_xml_node *node);
  */
 void ast_xml_set_text(struct ast_xml_node *node, const char *content);
 
+/*!
+ * \brief Set or reset an element's name.
+ * \param node Node whose name is to be set.
+ * \param name New name.
+ */
+void ast_xml_set_name(struct ast_xml_node *node, const char *name);
+
 /*!
  * \brief Get the name of a node. */
 const char *ast_xml_node_get_name(struct ast_xml_node *node);
index 7b3b457d72ae393d6f5e235e847e3b3cc874389c..92a24de6345507f25ca965d325c9f4f7c32285f9 100644 (file)
@@ -679,6 +679,49 @@ int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *r
        return -1;
 }
 
+int ast_variable_list_replace_variable(struct ast_variable **head, struct ast_variable *old,
+       struct ast_variable *new)
+{
+       struct ast_variable *v, **prev = head;
+
+       for (v = *head; v; prev = &v->next, v = v->next) {
+               if (v == old) {
+                       new->next = v->next;
+                       *prev = new;
+                       ast_free(v);
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+struct ast_str *ast_variable_list_join(const struct ast_variable *head, const char *item_separator,
+       const char *name_value_separator, const char *quote_char, struct ast_str **str)
+{
+       struct ast_variable *var = (struct ast_variable *)head;
+       struct ast_str *local_str = NULL;
+
+       if (str == NULL || *str == NULL) {
+               local_str = ast_str_create(AST_MAX_USER_FIELD);
+               if (!local_str) {
+                       return NULL;
+               }
+       } else {
+               local_str = *str;
+       }
+
+       for (; var; var = var->next) {
+               ast_str_append(&local_str, 0, "%s%s%s%s%s%s", var->name, name_value_separator, S_OR(quote_char, ""),
+                       var->value, S_OR(quote_char, ""), var->next ? item_separator : "");
+       }
+
+       if (str != NULL) {
+               *str = local_str;
+       }
+       return local_str;
+}
+
 const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
 {
        const char *tmp;
index d60dd90bcdd3788ad070515a57b61114aef801bb..88c9edffde5c23e18fe91c3a6ed984e3433983a2 100644 (file)
@@ -332,6 +332,15 @@ void ast_xml_set_text(struct ast_xml_node *node, const char *content)
        xmlNodeSetContent((xmlNode *) node, (const xmlChar *) content);
 }
 
+void ast_xml_set_name(struct ast_xml_node *node, const char *name)
+{
+       if (!node || !name) {
+               return;
+       }
+
+       xmlNodeSetName((xmlNode *) node, (const xmlChar *) name);
+}
+
 int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
 {
        return xmlDocDump(output, (xmlDocPtr)doc);
index 770aa15bb9e0a10c4dedc9f125f3857d7dc41833..5b44b446e003a1700cfe8282aaa6237c8a478d81 100644 (file)
@@ -1893,6 +1893,56 @@ AST_TEST_DEFINE(variable_lists_match)
        return AST_TEST_PASS;
 }
 
+AST_TEST_DEFINE(variable_list_join_replace)
+{
+       RAII_VAR(struct ast_variable *, list, NULL, ast_variables_destroy);
+       RAII_VAR(struct ast_str *, str, NULL, ast_free);
+       struct ast_variable *bbb;
+       int rc;
+
+       switch (cmd) {
+       case TEST_INIT:
+               info->name = "variable_list_join_replace";
+               info->category = "/main/config/";
+               info->summary = "Test joining a variable list";
+               info->description =     info->summary;
+               return AST_TEST_NOT_RUN;
+       case TEST_EXECUTE:
+               break;
+       }
+
+       list = ast_variable_new("aaa", "111", "");
+       bbb = ast_variable_new("bbb", "222", "");
+       ast_variable_list_append(&list, bbb);
+       ast_variable_list_append(&list, ast_variable_new("ccc", "33 33", ""));
+
+       str = ast_variable_list_join(list, ", ", " = ", "\"", &str);
+       ast_test_validate(test, strcmp(ast_str_buffer(str), "aaa = \"111\", bbb = \"222\", ccc = \"33 33\"") == 0);
+       ast_free(str);
+
+       str = ast_str_create(AST_MAX_USER_FIELD);
+       str = ast_variable_list_join(list, ", ", " = ", "\"", &str);
+       ast_test_validate(test, strcmp(ast_str_buffer(str), "aaa = \"111\", bbb = \"222\", ccc = \"33 33\"") == 0);
+       ast_free(str);
+
+       str = ast_variable_list_join(list, ", ", " = ", "\"", NULL);
+       ast_test_validate(test, strcmp(ast_str_buffer(str), "aaa = \"111\", bbb = \"222\", ccc = \"33 33\"") == 0);
+       ast_free(str);
+
+       /* Replace the head item in the list */
+       rc = ast_variable_list_replace_variable(&list, list, ast_variable_new("ddd", "444", ""));
+       ast_test_validate(test, rc == 0);
+       str = ast_variable_list_join(list, ", ", " = ", "\"", NULL);
+       ast_test_validate(test, strcmp(ast_str_buffer(str), "ddd = \"444\", bbb = \"222\", ccc = \"33 33\"") == 0);
+       ast_free(str);
+
+       rc = ast_variable_list_replace_variable(&list, bbb, ast_variable_new("eee", "555", ""));
+       ast_test_validate(test, rc == 0);
+       str = ast_variable_list_join(list, ", ", " = ", "\"", NULL);
+       ast_test_validate(test, strcmp(ast_str_buffer(str), "ddd = \"444\", eee = \"555\", ccc = \"33 33\"") == 0);
+
+       return AST_TEST_PASS;
+}
 static int unload_module(void)
 {
        AST_TEST_UNREGISTER(config_save);
@@ -1905,6 +1955,7 @@ static int unload_module(void)
        AST_TEST_UNREGISTER(config_options_test);
        AST_TEST_UNREGISTER(config_dialplan_function);
        AST_TEST_UNREGISTER(variable_lists_match);
+       AST_TEST_UNREGISTER(variable_list_join_replace);
        return 0;
 }
 
@@ -1920,6 +1971,7 @@ static int load_module(void)
        AST_TEST_REGISTER(config_options_test);
        AST_TEST_REGISTER(config_dialplan_function);
        AST_TEST_REGISTER(variable_lists_match);
+       AST_TEST_REGISTER(variable_list_join_replace);
        return AST_MODULE_LOAD_SUCCESS;
 }