[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