[asterisk-commits] twilson: branch twilson/config_work r361905 - in /team/twilson/config_work: i...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Apr 10 22:33:19 CDT 2012
Author: twilson
Date: Tue Apr 10 22:33:15 2012
New Revision: 361905
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=361905
Log:
Rearrange some stuff, add more documentation
Modified:
team/twilson/config_work/include/asterisk/config_options.h
team/twilson/config_work/main/config_options.c
Modified: team/twilson/config_work/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/config_options.h?view=diff&rev=361905&r1=361904&r2=361905
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Tue Apr 10 22:33:15 2012
@@ -34,16 +34,15 @@
struct ast_config_option;
enum ast_config_option_type {
+ OPT_ACL_T,
+ OPT_BOOL_T,
+ OPT_CODEC_T,
+ OPT_CUSTOM_T,
+ OPT_DOUBLE_T,
OPT_INT_T,
- OPT_UINT_T,
- OPT_DOUBLE_T,
OPT_SOCKADDR_T,
OPT_STRINGFIELD_T,
- OPT_BOOL_T,
- OPT_ACL_T,
- OPT_CODEC_T,
-
- OPT_CUSTOM_T,
+ OPT_UINT_T,
};
enum ast_config_option_context_op {
@@ -51,24 +50,80 @@
CONTEXT_ALLOW,
};
+/*! \brief A callback function for handling a particular option
+ * \param opt The option being configured
+ * \param var The config variable to use to configure \a obj
+ * \param obj The object to be configured
+ *
+ * \retval 0 Parsing and recording the config value succeeded
+ * \retval non-zero Failure. Parsing should stop and no reload applied
+ */
typedef int (*ast_config_option_handler)(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_int_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_uint_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_double_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_sockaddr_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_stringfield_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_bool_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_acl_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-int ast_config_option_codec_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
-
+/*! \brief Allocate a container to hold config options */
+struct ao2_container *ast_config_option_container_new(void);
+
+/*! \brief Find a config option that can handle the option \a name in \a context
+ * \param container The container of options to search
+ * \param name The field name of the option
+ * \param context The context of the option
+ *
+ * \returns An option or NULL on error
+ */
+struct ast_config_option *ast_config_option_find(struct ao2_container *container, const char *name, const char *context);
+
+/*! \brief Parse each option defined in a config context
+ * \param container The container of options from which to configure \a obj
+ * \param cfg The ast_config being parsed
+ * \param cat The config category being parsed
+ * \param obj The user-defined config object that will store the parsed config items
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_config_parse_category_options(struct ao2_container *container, struct ast_config *cfg, const char *cat, void *obj);
+
+/*! \brief Set all default options of \a obj
+ * \param container The container of options from which to apply defaults
+ * \param context The configuration context from which \a obj is being configured
+ * \param obj The object being configured
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_config_option_set_defaults(struct ao2_container *container, const char *context, void *obj);
+
+/*! \brief build a config option
+ *
+ * \note this should probably only be called by one of the ast_config_option_register* macros
+ *
+ * \param name The name of the option
+ * \param context_allow Whether or not the \a context is a whitelist of blacklist
+ * \param context A regex string defining what contexts to allow/disallow the option to apply to
+ * \param default_val The default value of the option in the same format as defined in a config file
+ * \param type The option type (only for default handlers)
+ * \param handler The handler function for the option (only for non-default types)
+ * \param flags \a type specific flags, stored in the option and available to the handler
+ * \param argc The number for variadic arguments
+ * \param ... field offsets to store for default handlers
+ *
+ * \returns An option on success, NULL on failure
+ */
struct ast_config_option *__ast_config_option_build(const char *name, enum ast_config_option_context_op context_allow,
const char *context, const char *default_val, enum ast_config_option_type type, ast_config_option_handler handler, unsigned int flags, size_t argc, ...);
-struct ao2_container *ast_config_option_container_new(void);
-struct ast_config_option *ast_config_option_find(struct ao2_container *container, const char *name, const char *cat);
-int ast_config_parse_category_options(struct ao2_container *container, struct ast_config *cfg, const char *cat, void *obj);
-int ast_config_option_set_defaults(struct ao2_container *container, const char *context, void *obj);
-
+
+/* \brief Register a config option
+ * \param container The container to store the registered option in
+ * \param name The name of the option
+ * \param op Whether or not the \a context is a whitelist of blacklist
+ * \param context A regex string defining what contexts to allow/disallow the option to apply to
+ * \param default_val The default value of the option in the same format as defined in a config file
+ * \param opt_type The option type
+ * \param struct_type The type of the struct being configured (e.g. struct skel_pvt_config)
+ * \param flags \a type specific flags, stored in the option and available to the handler
+ *
+ * \returns An option on success, NULL on failure
+ */
#define ast_config_option_register(container, name, op, context, default_val, opt_type, struct_type, flags, ...) {\
struct ast_config_option *__opt; \
__opt = opt_type == OPT_STRINGFIELD_T ? \
@@ -80,6 +135,17 @@
} \
}
+/* \brief Register a config option
+ * \param container The container to store the registered option in
+ * \param name The name of the option
+ * \param op Whether or not the \a context is a whitelist of blacklist
+ * \param context A regex string defining what contexts to allow/disallow the option to apply to
+ * \param default_val The default value of the option in the same format as defined in a config file
+ * \param handler The handler callback for the option
+ * \param flags \a type specific flags, stored in the option and available to the handler
+ *
+ * \returns An option on success, NULL on failure
+ */
#define ast_config_option_register_custom(container, name, op, context, default_val, handler, flags) { \
struct ast_config_option *__opt = __ast_config_option_build(name, op, context, default_val, OPT_CUSTOM_T, handler, flags, 0); \
if (__opt) { \
@@ -88,35 +154,64 @@
} \
}
+/*! \note Everything below this point is to handle converting varargs
+ * containing field names, to varargs containing a count of args, followed
+ * by the offset of each of the field names in the struct type that is
+ * passed in. It is currently limited to 8 arguments, but 8 variadic
+ * arguments should be good enough for anyone. If not, it is easy to add more.
+ * */
+
+/*! \def ARGMAP(func, func_arg, x, ...)
+ * \brief Map \a func(\a func_arg, field) across all fields including \a x
+ *
+ * Example usage:
+ * struct foo {
+ * int a;
+ * char *b;
+ * foo *c;
+ * };
+ * ARGMAP(offsetof, struct foo, a, c)
+ * produces the string:
+ * 2, offsetof(struct foo, a), offsetof(struct foo, b)
+ * which can be passed as the varargs of some other function
+ *
+ * The macro isn't limited to offsetof, but that is the only purpose for
+ * which it has been tested.
+ */
+#define ARGMAP(func, func_arg, x, ...) ARGMAP_(VA_NARGS(x, ##__VA_ARGS__), func, func_arg, x, __VA_ARGS__)
+
+/* This is sneaky. On the very first argument, we set "in" to N, the number of arguments, so
+ * that the accumulation both works properly for the first argument (since "in" can't be empty) and
+ * we get the number of arguments in our varargs as a bonus */
+#define ARGMAP_(N, func, func_arg, x, ...) PASTE(ARGMAP_, N)(func, func_arg, N, x, __VA_ARGS__)
+
+/* Two levels to handler the case where arg1 and arg2 are macros themselves */
#define PASTE(arg1, arg2) PASTE1(arg1, arg2)
#define PASTE1(arg1, arg2) arg1##arg2
#define ARGIFY(...) __VA_ARGS__
-#define ARGMAP_1(func, type, in, x, ...) ARGIFY(in, func(type, x))
-#define ARGMAP_2(func, type, in, x, ...)\
- ARGMAP_1(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_3(func, type, in, x, ...)\
- ARGMAP_2(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_4(func, type, in, x, ...)\
- ARGMAP_3(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_5(func, type, in, x, ...)\
- ARGMAP_4(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_6(func, type, in, x, ...)\
- ARGMAP_5(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_7(func, type, in, x, ...)\
- ARGMAP_6(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-#define ARGMAP_8(func, type, in, x, ...)\
- ARGMAP_7(func, type, ARGIFY(in, func(type, x)), __VA_ARGS__)
-
+#define ARGMAP_1(func, func_arg, in, x, ...) ARGIFY(in, func(func_arg, x))
+#define ARGMAP_2(func, func_arg, in, x, ...)\
+ ARGMAP_1(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_3(func, func_arg, in, x, ...)\
+ ARGMAP_2(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_4(func, func_arg, in, x, ...)\
+ ARGMAP_3(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_5(func, func_arg, in, x, ...)\
+ ARGMAP_4(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_6(func, func_arg, in, x, ...)\
+ ARGMAP_5(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_7(func, func_arg, in, x, ...)\
+ ARGMAP_6(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+#define ARGMAP_8(func, func_arg, in, x, ...)\
+ ARGMAP_7(func, func_arg, ARGIFY(in, func(func_arg, x)), __VA_ARGS__)
+
+/*! \brief Results in the number of arguments passed to it
+ * \note currently only up to 8, but expanding is easy
+ */
#define VA_NARGS(...) VA_NARGS1(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VA_NARGS1(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
-
-/* This is sneaky as hell. On the very first argument, we set "in" to N, the number of arguments, so
- * that the accumulation both works properly for the first argument (since "in" can't be empty) and
- * we get the number of arguments too */
-#define ARGMAP_(N, func, type, x, ...) PASTE(ARGMAP_, N)(func, type, N, x, __VA_ARGS__)
-#define ARGMAP(func, type, x, ...) ARGMAP_(VA_NARGS(x, ##__VA_ARGS__), func, type, x, __VA_ARGS__)
#if defined(__cplusplus) || defined(c_plusplus)
}
Modified: team/twilson/config_work/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/config_options.c?view=diff&rev=361905&r1=361904&r2=361905
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Tue Apr 10 22:33:15 2012
@@ -61,6 +61,15 @@
}
}
+static int ast_config_option_int_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_uint_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_double_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_sockaddr_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_stringfield_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_bool_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_acl_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+static int ast_config_option_codec_fn(const struct ast_config_option *opt, struct ast_variable *var, void *obj);
+
static ast_config_option_handler ast_config_option_default_handler(enum ast_config_option_type type)
{
switch(type) {
@@ -202,7 +211,6 @@
return 0;
}
-
/*! \brief match for anything where the context passes (or fails if !context_allow) the context regex
*/
static int match_option_by_context(void *obj, void *arg, int flags)
More information about the asterisk-commits
mailing list