[Asterisk-code-review] core: Config and XML tweaks needed for geolocation (asterisk[18])
George Joseph
asteriskteam at digium.com
Mon Feb 28 06:40:00 CST 2022
George Joseph has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18109 )
Change subject: core: Config and XML tweaks needed for geolocation
......................................................................
core: Config and XML tweaks needed for geolocation
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
---
M include/asterisk/config.h
M include/asterisk/xml.h
M main/config.c
M main/xml.c
M tests/test_config.c
5 files changed, 149 insertions(+), 0 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/09/18109/1
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index f4d1dd2..f4f6c9d 100644
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -968,6 +968,44 @@
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
*
* \param category Category element within the config
diff --git a/include/asterisk/xml.h b/include/asterisk/xml.h
index 3217750..13af3c6 100644
--- a/include/asterisk/xml.h
+++ b/include/asterisk/xml.h
@@ -202,6 +202,13 @@
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);
diff --git a/main/config.c b/main/config.c
index 7b3b457..92a24de 100644
--- a/main/config.c
+++ b/main/config.c
@@ -679,6 +679,49 @@
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;
diff --git a/main/xml.c b/main/xml.c
index d60dd90..88c9edf 100644
--- a/main/xml.c
+++ b/main/xml.c
@@ -332,6 +332,15 @@
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);
diff --git a/tests/test_config.c b/tests/test_config.c
index 770aa15..5b44b44 100644
--- a/tests/test_config.c
+++ b/tests/test_config.c
@@ -1893,6 +1893,56 @@
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 @@
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 @@
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;
}
--
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18109
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 18
Gerrit-Change-Id: I330a5f63dc0c218e0d8dfc0745948d2812141ccb
Gerrit-Change-Number: 18109
Gerrit-PatchSet: 1
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220228/77a5fa6c/attachment-0001.html>
More information about the asterisk-code-review
mailing list