diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/bucket.c | 8 | ||||
-rw-r--r-- | main/config.c | 20 | ||||
-rw-r--r-- | main/sorcery.c | 87 |
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) |