summaryrefslogtreecommitdiff
path: root/main/sorcery.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2013-03-01 18:01:56 +0000
committerJoshua Colp <jcolp@digium.com>2013-03-01 18:01:56 +0000
commita4f45a2c959e67f90ea3b44f2a0226292dd61163 (patch)
tree7e682a97c7a7490fe1ef9cfd35be2b7a2311591d /main/sorcery.c
parenta3ad8b28e6fcb515741e13c927818ffdb73f2398 (diff)
Add support for registering a sorcery handler which supports multiple fields using a regex.
Review: https://reviewboard.asterisk.org/r/2332/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@382340 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/sorcery.c')
-rw-r--r--main/sorcery.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/main/sorcery.c b/main/sorcery.c
index 242d65bdc..df2f57740 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -90,9 +90,12 @@ struct ast_sorcery_object_field {
/*! \brief Name of the field */
char name[MAX_OBJECT_FIELD];
- /*! \brief Callback function for translation */
+ /*! \brief Callback function for translation of a single value */
sorcery_field_handler handler;
+ /*! \brief Callback function for translation of multiple values */
+ sorcery_fields_handler multiple_handler;
+
/*! \brief Position of the field */
intptr_t args[];
};
@@ -516,6 +519,24 @@ void ast_sorcery_object_set_diff_handler(struct ast_sorcery *sorcery, const char
object_type->diff = diff;
}
+int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
+{
+ 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);
+
+ if (!object_type || !object_type->type.item_alloc || !config_handler || !(object_field = ao2_alloc(sizeof(*object_field), NULL))) {
+ return -1;
+ }
+
+ ast_copy_string(object_field->name, regex, sizeof(object_field->name));
+ object_field->multiple_handler = sorcery_handler;
+
+ ao2_link(object_type->fields, object_field);
+ __aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 0);
+
+ return 0;
+}
+
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, size_t argc, ...)
{
@@ -662,24 +683,30 @@ struct ast_variable *ast_sorcery_objectset_create(const struct ast_sorcery *sorc
i = ao2_iterator_init(object_type->fields, 0);
- for (; (object_field = ao2_iterator_next(&i)); ao2_ref(object_field, -1)) {
- RAII_VAR(char *, buf, NULL, ast_free);
- struct ast_variable *tmp;
+ 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);
+ }
+ } 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;
+ }
- /* Any fields with no handler just get skipped */
- if (!object_field->handler) {
+ ast_free(buf);
+ } else {
continue;
}
- if ((res = object_field->handler(object, object_field->args, &buf)) ||
- !(tmp = ast_variable_new(object_field->name, S_OR(buf, ""), ""))) {
- res = -1;
- ao2_ref(object_field, -1);
- break;
+ if (!res) {
+ tmp->next = fields;
+ fields = tmp;
}
-
- tmp->next = fields;
- fields = tmp;
}
ao2_iterator_destroy(&i);