summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/bucket.c8
-rw-r--r--main/config.c20
-rw-r--r--main/sorcery.c87
3 files changed, 89 insertions, 26 deletions
diff --git a/main/bucket.c b/main/bucket.c
index b3a0d3ca9..f698c570b 100644
--- a/main/bucket.c
+++ b/main/bucket.c
@@ -944,8 +944,8 @@ int ast_bucket_init(void)
}
ast_sorcery_object_field_register(bucket_sorcery, "bucket", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket, scheme));
- ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "created", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket, created));
- ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "modified", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket, modified));
+ ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, created));
+ ast_sorcery_object_field_register_custom(bucket_sorcery, "bucket", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket, modified));
if (ast_sorcery_apply_default(bucket_sorcery, "file", "bucket_file", NULL)) {
ast_log(LOG_ERROR, "Failed to apply intermediary for 'file' object type in Bucket sorcery\n");
@@ -958,8 +958,8 @@ int ast_bucket_init(void)
}
ast_sorcery_object_field_register(bucket_sorcery, "file", "scheme", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_bucket_file, scheme));
- ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket_file, created));
- ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, 0, FLDSET(struct ast_bucket_file, modified));
+ ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "created", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, created));
+ ast_sorcery_object_field_register_custom(bucket_sorcery, "file", "modified", "", timeval_str2struct, timeval_struct2str, NULL, 0, FLDSET(struct ast_bucket_file, modified));
return 0;
}
diff --git a/main/config.c b/main/config.c
index 70ef6a804..db9182a46 100644
--- a/main/config.c
+++ b/main/config.c
@@ -620,6 +620,26 @@ struct ast_variable *ast_variable_list_sort(struct ast_variable *start)
return top.next;
}
+struct ast_variable *ast_variable_list_append_hint(struct ast_variable **head, struct ast_variable *search_hint, struct ast_variable *newvar)
+{
+ struct ast_variable *curr;
+ ast_assert(head != NULL);
+
+ if (!*head) {
+ *head = newvar;
+ } else {
+ if (search_hint == NULL) {
+ search_hint = *head;
+ }
+ for (curr = search_hint; curr->next; curr = curr->next);
+ curr->next = newvar;
+ }
+
+ for (curr = newvar; curr->next; curr = curr->next);
+
+ return curr;
+}
+
const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
{
const char *tmp;
diff --git a/main/sorcery.c b/main/sorcery.c
index bbdfa8cf2..99d051ab2 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -811,7 +811,7 @@ int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *
}
int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char *type, const char *name, const char *default_val, enum aco_option_type opt_type,
- aco_option_handler config_handler, sorcery_field_handler sorcery_handler, unsigned int flags, unsigned int no_doc, size_t argc, ...)
+ aco_option_handler config_handler, sorcery_field_handler sorcery_handler, sorcery_fields_handler multiple_handler, unsigned int flags, unsigned int no_doc, size_t argc, ...)
{
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
@@ -832,6 +832,7 @@ int __ast_sorcery_object_field_register(struct ast_sorcery *sorcery, const char
ast_copy_string(object_field->name, name, sizeof(object_field->name));
object_field->handler = sorcery_handler;
+ object_field->multiple_handler = multiple_handler;
va_start(args, argc);
for (pos = 0; pos < argc; pos++) {
@@ -1015,13 +1016,47 @@ void ast_sorcery_ref(struct ast_sorcery *sorcery)
ao2_ref(sorcery, +1);
}
-struct ast_variable *ast_sorcery_objectset_create(const struct ast_sorcery *sorcery, const void *object)
+static struct ast_variable *get_single_field_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
+{
+ struct ast_variable *tmp = NULL;
+ char *buf = NULL;
+
+ if (!object_field->handler) {
+ return NULL;
+ }
+
+ if (!(object_field->handler(object, object_field->args, &buf))) {
+ tmp = ast_variable_new(object_field->name, S_OR(buf, ""), "");
+ }
+ ast_free(buf);
+
+ return tmp;
+}
+
+static struct ast_variable *get_multiple_fields_as_var_list(const void *object, struct ast_sorcery_object_field *object_field)
+{
+ struct ast_variable *tmp = NULL;
+
+ if (!object_field->multiple_handler) {
+ return NULL;
+ }
+
+ if (object_field->multiple_handler(object, &tmp)) {
+ ast_variables_destroy(tmp);
+ tmp = NULL;
+ }
+
+ return tmp;
+}
+
+struct ast_variable *ast_sorcery_objectset_create2(const struct ast_sorcery *sorcery,
+ const void *object, enum ast_sorcery_field_handler_flags flags)
{
const struct ast_sorcery_object_details *details = object;
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, details->object->type, OBJ_KEY), ao2_cleanup);
struct ao2_iterator i;
struct ast_sorcery_object_field *object_field;
- struct ast_variable *fields = NULL;
+ struct ast_variable *head = NULL, *tail = NULL;
int res = 0;
if (!object_type) {
@@ -1033,38 +1068,46 @@ struct ast_variable *ast_sorcery_objectset_create(const struct ast_sorcery *sorc
for (; (object_field = ao2_iterator_next(&i)) && !res; ao2_ref(object_field, -1)) {
struct ast_variable *tmp = NULL;
- if (object_field->multiple_handler) {
- if ((res = object_field->multiple_handler(object, &tmp))) {
- ast_variables_destroy(tmp);
+ switch (flags) {
+ case AST_HANDLER_PREFER_LIST:
+ if ((tmp = get_multiple_fields_as_var_list(object, object_field)) ||
+ (tmp = get_single_field_as_var_list(object, object_field))) {
+ break;
}
- } else if (object_field->handler) {
- char *buf = NULL;
-
- if ((res = object_field->handler(object, object_field->args, &buf)) ||
- !(tmp = ast_variable_new(object_field->name, S_OR(buf, ""), ""))) {
- res = -1;
+ continue;
+ case AST_HANDLER_PREFER_STRING:
+ if ((tmp = get_single_field_as_var_list(object, object_field)) ||
+ (tmp = get_multiple_fields_as_var_list(object, object_field))) {
+ break;
}
-
- ast_free(buf);
- } else {
+ continue;
+ case AST_HANDLER_ONLY_LIST:
+ if ((tmp = get_multiple_fields_as_var_list(object, object_field))) {
+ break;
+ }
+ continue;
+ case AST_HANDLER_ONLY_STRING:
+ if ((tmp = get_single_field_as_var_list(object, object_field))) {
+ break;
+ }
+ continue;
+ default:
continue;
}
- if (!res && tmp) {
- tmp->next = fields;
- fields = tmp;
- }
+ tail = ast_variable_list_append_hint(&head, tail, tmp);
+
}
ao2_iterator_destroy(&i);
/* If any error occurs we destroy all fields handled before so a partial objectset is not returned */
if (res) {
- ast_variables_destroy(fields);
- fields = NULL;
+ ast_variables_destroy(head);
+ head = NULL;
}
- return fields;
+ return head;
}
struct ast_json *ast_sorcery_objectset_json_create(const struct ast_sorcery *sorcery, const void *object)