[asterisk-commits] twilson: branch twilson/config_work r366739 - in /team/twilson/config_work: a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed May 16 14:39:10 CDT 2012


Author: twilson
Date: Wed May 16 14:39:05 2012
New Revision: 366739

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=366739
Log:
Address many of Matt's suggestions

This doesn't have:
1) Rewriting of app_skel to be better for more complex examples
2) Documentation additions to .c files
3) Improved support for handling multiple config files

Modified:
    team/twilson/config_work/apps/app_skel.c
    team/twilson/config_work/configs/app_skel.conf.sample
    team/twilson/config_work/include/asterisk/config_options.h
    team/twilson/config_work/include/asterisk/utils.h
    team/twilson/config_work/main/astobj2.c
    team/twilson/config_work/main/config_options.c
    team/twilson/config_work/main/udptl.c

Modified: team/twilson/config_work/apps/app_skel.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/apps/app_skel.c?view=diff&rev=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Wed May 16 14:39:05 2012
@@ -16,7 +16,7 @@
  * at the top of the source tree.
  *
  * Please follow coding guidelines
- * http://svn.digium.com/view/asterisk/trunk/doc/CODING-GUIDELINES
+ * https://wiki.asterisk.org/wiki/display/AST/Coding+Guidelines
  */
 
 /*! \file
@@ -164,7 +164,7 @@
 static AO2_GLOBAL_OBJ_STATIC(globals);
 
 CONFIG_INFO_STANDARD(cfg_info, "app_skel.conf", globals, skel_config_alloc,
-	.types = { &general_options, &private_options, NULL },
+	.types = ACO_TYPES(&general_options, &private_options),
 );
 
 static void skel_global_config_destructor(void *obj)

Modified: team/twilson/config_work/configs/app_skel.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/configs/app_skel.conf.sample?view=diff&rev=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/configs/app_skel.conf.sample (original)
+++ team/twilson/config_work/configs/app_skel.conf.sample Wed May 16 14:39:05 2012
@@ -19,3 +19,7 @@
 bit2=yes
 
 [pvt3]
+
+[pvt4]
+bit1=yes
+bit2=yes

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=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/include/asterisk/config_options.h (original)
+++ team/twilson/config_work/include/asterisk/config_options.h Wed May 16 14:39:05 2012
@@ -35,6 +35,7 @@
 
 struct aco_option;
 struct aco_type;
+struct aco_info_internal;
 
 enum aco_type_t {
 	ACO_GLOBAL_OBJ,
@@ -142,14 +143,24 @@
 struct aco_info {
 	const char *module;         /*!< The name of the module whose config is being processed */
 	const char *filename;       /*!< The config filename */
-	struct ao2_container *opts; /*!< Internal use - options to parse */
 	aco_pre_apply_config pre_apply_config; /*!< A callback called after processing, but before changes are applied */
 	aco_snapshot_alloc snapshot_alloc;     /*!< Allocate an object to hold all global configs and private containers */
 	struct ao2_global_obj *global_obj;     /*!< The global object array that holds the user-defined config object */
-	void *new_config;         /*!< Internal use - A cache of newly created config */
 	const char **preload;     /*!< Categories to parse first. Do something like char *arr[] = {"general", NULL}; and do .preload = arr */
+	struct aco_info_internal *internal;
 	struct aco_type *types[]; /*!< The list of types for this config. Required. Use a sentinel! */
 };
+
+/*! \brief A helper macro to ensure that aco_info types always have a sentinel */
+#define ACO_TYPES(...) { __VA_ARGS__, NULL, }
+
+/*! \brief Get pending config changes
+ * \note This will most likely be called from the pre_apply_config callback function
+ * \param info An initialized aco_info
+ * \retval NULL error
+ * \retval non-NULL A pointer to the user-defined config object with un-applied changes
+ */
+void *aco_pending_config(struct aco_info *info);
 
 /*! \def CONFIG_INFO_STANDARD
  * \brief Declare an aco_info struct with default module and preload values
@@ -238,21 +249,26 @@
  */
 struct aco_option *aco_option_find(struct ao2_container *container, const char *name, const char *category);
 
-/*! \brief Completely handle simple configs
- *
- * \note This is for configs that have no relationship between global options and
- * those for any private objects (peers, etc.) If a config is well designed, this
- * should be the case since config templates should be used for setting default
- * values for individual objects.
+/*! \brief Process a config info via the options registered with an aco_info
  *
  * \param info The config_options_info to be used for handling the config
- * \param filename The filename of the config
  * \param reload Whether or not this is a reload
  *
  * \retval 0 Success
  * \retval -1 Failure
  */
 int aco_process_config(struct aco_info *info, int reload);
+
+/*! \brief Process config info from an ast_config via options registered with an aco_info
+ *
+ * \param info The aco_info to be used for handling the config
+ * \param cfg A pointer to a loaded ast_config to parse
+ * \param reload Whether or not this is a reload
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int aco_process_ast_config(struct aco_info *info, struct ast_config *cfg, int reload);
 
 /*! \brief Parse each option defined in a config category
  * \param container The container of options from which to configure \a obj
@@ -275,7 +291,7 @@
  */
 int aco_set_defaults(struct ao2_container *container, const char *category, void *obj);
 
-/*! \brief build a config option
+/*! \brief register a config option
  *
  * \note this should probably only be called by one of the aco_option_register* macros
  *
@@ -288,9 +304,10 @@
  * \param argc The number for variadic arguments
  * \param ... field offsets to store for default handlers
  *
- * \returns An option on success, NULL on failure
- */
-struct aco_option *__aco_option_build(const char *name, struct aco_type *obj,
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int __aco_option_register(struct aco_info *info, const char *name, struct aco_type *obj,
 	const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, size_t argc, ...);
 
 /* \brief Register a config option
@@ -303,13 +320,8 @@
  *
  * \returns An option on success, NULL on failure
  */
-#define aco_option_register(info, name, obj, default_val, opt_type, flags, ...) {\
-	struct aco_option *__opt; \
-	if ((__opt = __aco_option_build(name, obj, default_val, opt_type, NULL, flags, VA_NARGS(__VA_ARGS__), __VA_ARGS__))){ \
-		ao2_link((info)->opts, __opt); \
-		ao2_ref(__opt, -1); \
-	} \
-}
+#define aco_option_register(info, name, obj, default_val, opt_type, flags, ...) \
+	__aco_option_register(info, name, obj, default_val, opt_type, NULL, flags, VA_NARGS(__VA_ARGS__), __VA_ARGS__);
 
 /* \brief Register a config option
  * \param info A pointer to the aco_info struct
@@ -321,13 +333,8 @@
  *
  * \returns An option on success, NULL on failure
  */
-#define aco_option_register_custom(info, name, obj, default_val, handler, flags) { \
-	struct aco_option *__opt = __aco_option_build(name, obj, default_val, OPT_CUSTOM_T, handler, flags, 0); \
-	if (__opt) { \
-		ao2_link((info)->opts, __opt); \
-		ao2_ref(__opt, -1); \
-	} \
-}
+#define aco_option_register_custom(info, name, obj, default_val, handler, flags) \
+	__aco_option_register(info, name, obj, default_val, OPT_CUSTOM_T, handler, flags, 0);
 
 /*! \note  Everything below this point is to handle converting varargs
  * containing field names, to varargs containing a count of args, followed
@@ -345,14 +352,18 @@
  * \param varargs The rest of the fields
  *
  * Example usage:
- *     struct foo {
- *         int a;
- *         char *b;
- *         foo *c;
- *     };
- *     ARGMAP(offsetof, struct foo, a, c)
+ * \code
+ * struct foo {
+ *     int a;
+ *     char *b;
+ *     foo *c;
+ * };
+ * ARGMAP(offsetof, struct foo, a, c)
+ * \endcode
  * produces the string:
- *     2, offsetof(struct foo, a), offsetof(struct foo, b)
+ * \code
+ * 2, offsetof(struct foo, a), offsetof(struct foo, b)
+ * \encode
  * which can be passed as the varargs to some other function
  *
  * The macro isn't limited to offsetof, but that is the only purpose for
@@ -432,7 +443,7 @@
  * \brief Convert a struct and list of fields to an argument list of field offsets
  * \param type The type with the fields (e.g. "struct my_struct")
  * \param varags The fields in the struct whose offsets are needed as arguments
- * 
+ *
  * For example:
  * \code
  * struct foo {int a, char b[128], char *c};

Modified: team/twilson/config_work/include/asterisk/utils.h
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/include/asterisk/utils.h?view=diff&rev=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/include/asterisk/utils.h (original)
+++ team/twilson/config_work/include/asterisk/utils.h Wed May 16 14:39:05 2012
@@ -863,7 +863,49 @@
  */
 char *ast_utils_which(const char *binary, char *fullpath, size_t fullpath_size);
 
-#define RAII_VAR(vartype,varname,initval,dtor) \
+/*! \brief Declare a variable that will call a destructor function when it goes out of scope
+ * \param vartype The type of the variable
+ * \param varname The name of the variable
+ * \param initval The initial value of the variable
+ * \param dtor The destructor function of type' void func(vartype *)'
+ * 
+ * \code
+ * void mything_cleanup(struct mything *t)
+ * {
+ *     if (t) {
+ *         ast_free(t->stuff);
+ *     }
+ * }
+ *
+ * void do_stuff(const char *name)
+ * {
+ *     RAII_VAR(struct mything *, thing, mything_alloc(name), mything_cleanup);
+ *     ...
+ * }
+ *
+ * \note This macro is especially useful for working with ao2 objects. A common idiom
+ * would be a function that needed to look up an ao2 object and might have several error
+ * conditions after the allocation that would normally need to unref the ao2 object.
+ * With RAII_VAR, it is possible to just return and leave the cleanup to the destructor
+ * function. For example:
+ * \code
+ * void do_stuff(const char *name)
+ * {
+ *     RAII_VAR(struct mything *, thing, find_mything(name), ao2_cleanup);
+ *     if (!thing) {
+ *         return;
+ *     }
+ *     if (error) {
+ *         return;
+ *     }
+ *     do_stuff_with_thing(thing);
+ *     return;
+ *     }
+ * }
+ * \encode
+ *
+ */
+#define RAII_VAR(vartype, varname, initval, dtor) \
     auto void _dtor_ ## varname (vartype * v); \
     auto void _dtor_ ## varname (vartype * v) { dtor(*v); } \
     vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)

Modified: team/twilson/config_work/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/astobj2.c?view=diff&rev=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/main/astobj2.c (original)
+++ team/twilson/config_work/main/astobj2.c Wed May 16 14:39:05 2012
@@ -638,6 +638,7 @@
 {
 	if (!holder) {
 		/* For sanity */
+		ast_log(LOG_ERROR, "Must be called with a global object!\n");
 		return;
 	}
 	if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) {
@@ -660,6 +661,7 @@
 
 	if (!holder) {
 		/* For sanity */
+		ast_log(LOG_ERROR, "Must be called with a global object!\n");
 		return NULL;
 	}
 	if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) {
@@ -696,8 +698,10 @@
 
 	if (!holder) {
 		/* For sanity */
-		return NULL;
-	}
+		ast_log(LOG_ERROR, "Must be called with a global object!\n");
+		return NULL;
+	}
+
 	if (__ast_rwlock_rdlock(file, line, func, &holder->lock, name)) {
 		/* Could not get the read lock. */
 		return NULL;

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=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Wed May 16 14:39:05 2012
@@ -39,6 +39,14 @@
 #define CONFIG_OPT_BUCKETS 53
 #endif /* LOW_MEMORY */
 
+/*! \brief Bits of aco_info that shouldn't be assigned outside this file
+ * \internal
+ */
+struct aco_info_internal {
+	struct ao2_container *opts; /*!< The container of options registered to the aco_info */
+	void *pending;              /*!< The user-defined config object awaiting application */
+};
+
 struct aco_option {
 	const char *name;
 	const char *default_val;
@@ -51,6 +59,15 @@
 	size_t args[0];
 };
 
+void *aco_pending_config(struct aco_info *info)
+{
+	if (!(info && info->internal)) {
+		ast_log(LOG_ERROR, "This may not be called without an initialized aco_info!\n");
+		return NULL;
+	}
+	return info->internal->pending;
+}
+
 static void config_option_destroy(void *obj)
 {
 	return;
@@ -93,8 +110,9 @@
 	}
 
 	if ((res = regcomp(regex, text, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
-		char buf[80];
-		regerror(res, regex, buf, sizeof(buf));
+		size_t len = regerror(res, regex, NULL, 0);
+		char buf[len];
+		regerror(res, regex, buf, len);
 		ast_log(LOG_ERROR, "Could not compile regex '%s': %s\n", text, buf);
 		ast_free(regex);
 		return NULL;
@@ -103,10 +121,7 @@
 	return regex;
 }
 
-/*! \brief build a config option
- * \note this should probably only be called by one of the aco_option_register* macros
- */
-struct aco_option *__aco_option_build(const char *name, struct aco_type *obj,
+int __aco_option_register(struct aco_info *info, const char *name, struct aco_type *obj,
 	const char *default_val, enum aco_option_type type, aco_option_handler handler, unsigned int flags, size_t argc, ...)
 {
 	struct aco_option *opt;
@@ -115,15 +130,15 @@
 
 	/* Custom option types require a handler */
 	if (!handler && type == OPT_CUSTOM_T) {
-		return NULL;
+		return -1;
 	}
 
 	if (!obj) {
-		return NULL;
+		return -1;
 	}
 
 	if (!(opt = ao2_alloc(sizeof(*opt) + argc * sizeof(opt->args[0]), config_option_destroy))) {
-		return NULL;
+		return -1;
 	}
 
 	va_start(ap, argc);
@@ -141,11 +156,18 @@
 	opt->argc = argc;
 
 	if (!opt->handler && !(opt->handler = ast_config_option_default_handler(opt->type))) {
+		/* This should never happen */
+		ast_log(LOG_ERROR, "No handler provided, and no default handler exists for type %d\n", opt->type);
 		ao2_ref(opt, -1);
-		return NULL;
+		return -1;
 	};
 
-	return opt;
+	if (!ao2_link(info->internal->opts, opt)) {
+		ao2_ref(opt, -1);
+		return -1;
+	}
+
+	return 0;
 }
 
 static int config_opt_hash(const void *obj, const int flags)
@@ -242,19 +264,19 @@
 	}
 
 	/* if type == GLOBAL_OBJ, set defaults and configure the cached cfg object */
-	if (obj->type == ACO_GLOBAL_OBJ && info->new_config + obj->cfg_offset) {
-		void **field = info->new_config + obj->cfg_offset;
-
-		if (aco_set_defaults(info->opts, cat, *field)) {
+	if (obj->type == ACO_GLOBAL_OBJ && info->internal->pending + obj->cfg_offset) {
+		void **field = info->internal->pending + obj->cfg_offset;
+
+		if (aco_set_defaults(info->internal->opts, cat, *field)) {
 			ast_log(LOG_ERROR, "In %s: Setting defaults for %s failed\n", info->filename, cat);
 			return -1;
 		}
-		if (aco_process_category_options(info->opts, cfg, cat, *field)) {
+		if (aco_process_category_options(info->internal->opts, cfg, cat, *field)) {
 			ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", info->filename, cat);
 			return -1;
 		}
 	} else if (obj->type == ACO_PRIVATE_OBJ) {
-		void **field = info->new_config + obj->pvt_offset;
+		void **field = info->internal->pending + obj->pvt_offset;
 		/* If we've already linked a private for cat in newpvts, don't add a second one with the same name */
 		if (*field) {
 			if ((tmppvt = obj->find_pvt(*field, cat))) {
@@ -276,7 +298,7 @@
 			return -1;
 		}
 
-		if (aco_set_defaults(info->opts, cat, tmpcfg)) {
+		if (aco_set_defaults(info->internal->opts, cat, tmpcfg)) {
 			ast_log(LOG_ERROR, "In %s: Setting defaults for %s failed\n", info->filename, cat);
 			return -1;
 		}
@@ -286,7 +308,7 @@
 			return -1;
 		}
 
-		if (aco_process_category_options(info->opts, cfg, cat, tmpcfg)) {
+		if (aco_process_category_options(info->internal->opts, cfg, cat, tmpcfg)) {
 			ast_log(LOG_ERROR, "In %s: Processing options for %s failed\n", info->filename, cat);
 			return -1;
 		}
@@ -301,7 +323,7 @@
 			ast_log(LOG_ERROR, "In %s: Linking private for %s failed\n", info->filename, cat);
 			return -1;
 		}
-		field = info->new_config + obj->cfg_offset;
+		field = info->internal->pending + obj->cfg_offset;
 		if (!ao2_link(*field, tmpcfg)) {
 			ast_log(LOG_ERROR, "In %s: Linking config for %s failed\n", info->filename, cat);
 			return -1;
@@ -312,38 +334,17 @@
 
 static int apply_config(struct aco_info *info)
 {
-	ao2_global_obj_replace_unref(*info->global_obj, info->new_config);
-
-	return 0;
-}
-
-int aco_process_config(struct aco_info *info, int reload)
-{
-	struct ast_config *cfg;
-	struct ast_flags cfg_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0, };
+	ao2_global_obj_replace_unref(*info->global_obj, info->internal->pending);
+
+	return 0;
+}
+
+int aco_process_ast_config(struct aco_info *info, struct ast_config *cfg, int reload)
+{
 	const char *cat = NULL;
 	int res;
 
-	if (ast_strlen_zero(info->filename)) {
-		ast_log(LOG_ERROR, "No filename given, cannot proceed!\n");
-		return -1;
-	}
-
-	if (!(cfg = ast_config_load(info->filename, cfg_flags))) {
-		ast_log(LOG_ERROR, "Unable to load config file '%s'\n", info->filename);
-		return -1;
-	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
-		ast_debug(1, "%s was unchanged\n", info->filename);
-		return 0;
-	} else if (cfg == CONFIG_STATUS_FILEINVALID) {
-		ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", info->filename);
-		return -1;
-	} else if (cfg == CONFIG_STATUS_FILEMISSING) {
-		ast_log(LOG_ERROR, "%s is missing! Cannot load %s\n", info->filename, info->module);
-		return -1;
-	}
-
-	if (!(info->new_config = info->snapshot_alloc())) {
+	if (!(info->internal->pending = info->snapshot_alloc())) {
 		ast_log(LOG_ERROR, "In %s: Could not allocate temporary objects\n", info->filename);
 		goto error;
 	}
@@ -363,21 +364,49 @@
 		}
 	}
 
-	ast_config_destroy(cfg);
-
 	if (info->pre_apply_config && info->pre_apply_config()) {
 		goto error;
 	}
 
 	res = apply_config(info); /* The module already knows where the objects are */
-	ao2_ref(info->new_config, -1);
-
+	ao2_ref(info->internal->pending, -1);
 	return res;
 
 error:
 	ast_config_destroy(cfg);
-	ao2_ref(info->new_config, -1);
+	ao2_ref(info->internal->pending, -1);
 	return -1;
+}
+
+int aco_process_config(struct aco_info *info, int reload)
+{
+	struct ast_config *cfg;
+	struct ast_flags cfg_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0, };
+	int res;
+
+	if (ast_strlen_zero(info->filename)) {
+		ast_log(LOG_ERROR, "No filename given, cannot proceed!\n");
+		return -1;
+	}
+
+	if (!(cfg = ast_config_load(info->filename, cfg_flags))) {
+		ast_log(LOG_ERROR, "Unable to load config file '%s'\n", info->filename);
+		return -1;
+	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
+		ast_debug(1, "%s was unchanged\n", info->filename);
+		return 0;
+	} else if (cfg == CONFIG_STATUS_FILEINVALID) {
+		ast_log(LOG_ERROR, "Contents of %s are invalid and cannot be parsed\n", info->filename);
+		return -1;
+	} else if (cfg == CONFIG_STATUS_FILEMISSING) {
+		ast_log(LOG_ERROR, "%s is missing! Cannot load %s\n", info->filename, info->module);
+		return -1;
+	}
+
+	res = aco_process_ast_config(info, cfg, reload);
+	ast_config_destroy(cfg);
+
+	return res;
 }
 
 int aco_process_category_options(struct ao2_container *container, struct ast_config *cfg, const char *cat, void *obj)
@@ -435,31 +464,39 @@
 {
 	size_t x;
 	struct aco_type *t;
-	if (!(info->opts = aco_option_container_alloc())) {
-		return -1;
+
+	if (!(info->internal = ast_calloc(1, sizeof(*info->internal)))) {
+		return -1;
+	}
+
+	if (!(info->internal->opts = aco_option_container_alloc())) {
+		goto error;
 	}
 
 	for (x = 0, t = info->types[x]; t; t = info->types[++x]) {
 		if (internal_type_init(t)) {
-			ao2_ref(info->opts, -1);
-			info->opts = NULL;
-			internal_info_types_destroy(info);
-			return -1;
-		}
-	}
-
-	return 0;
+			goto error;
+		}
+	}
+
+	return 0;
+error:
+	aco_info_destroy(info);
+	return -1;
 }
 
 void aco_info_destroy(struct aco_info *info)
 {
-	if (info->opts) {
-		ao2_ref(info->opts, -1);
+	if (info->internal) {
+		ao2_cleanup(info->internal->opts);
+		ast_free(info->internal);
+		info->internal = NULL;
 	}
 	internal_info_types_destroy(info);
 }
 
 /*! \brief match for anything where the category passes (or fails if !category_allow) the category regex
+ * \internal
  */
 static int match_option_by_category(void *obj, void *arg, int flags)
 {

Modified: team/twilson/config_work/main/udptl.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/udptl.c?view=diff&rev=366739&r1=366738&r2=366739
==============================================================================
--- team/twilson/config_work/main/udptl.c (original)
+++ team/twilson/config_work/main/udptl.c Wed May 16 14:39:05 2012
@@ -82,9 +82,6 @@
 #define DEFAULT_UDPTLSTART 4000
 #define DEFAULT_UDPTLEND 4999
 
-#define STR(x) STR1(x)
-#define STR1(x) #x
-
 static int udptldebug;	                    /*!< Are we debugging? */
 static struct ast_sockaddr udptldebugaddr;   /*!< Debug packets to/from this host */
 
@@ -202,7 +199,7 @@
 };
 
 CONFIG_INFO_STANDARD(cfg_info, "udptl.conf", globals, udptl_snapshot_alloc,
-	.types = { &general_options, NULL },
+	.types = ACO_TYPES(&general_options),
 	.pre_apply_config = udptl_pre_apply_config,
 );
 
@@ -1412,7 +1409,7 @@
 }
 
 static int udptl_pre_apply_config(void) {
-	struct udptl_config *cfg = cfg_info.new_config;
+	struct udptl_config *cfg = aco_pending_config(&cfg_info);
 
 	if (!cfg->general) {
 		return -1;
@@ -1431,7 +1428,7 @@
 		ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %d\n", cfg->general->start);
 	}
 	if (cfg->general->start > cfg->general->end) {
-		ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to %s-%s.\n", STR(DEFAULT_UDPTLSTART), STR(DEFAULT_UDPTLEND));
+		ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to %s-%s.\n", __stringify(DEFAULT_UDPTLSTART), __stringify(DEFAULT_UDPTLEND));
 		cfg->general->start = DEFAULT_UDPTLSTART;
 		cfg->general->end = DEFAULT_UDPTLEND;
 	}
@@ -1455,11 +1452,11 @@
 		return;
 	}
 
-	aco_option_register(&cfg_info, "udptlstart", &general_options, STR(DEFAULT_UDPTLSTART),
+	aco_option_register(&cfg_info, "udptlstart", &general_options, __stringify(DEFAULT_UDPTLSTART),
 		OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
 		FLDSET(struct udptl_global_options, start), DEFAULT_UDPTLSTART, 1024, 65535);
 
-	aco_option_register(&cfg_info, "udptlend", &general_options, STR(DEFAULT_UDPTLEND),
+	aco_option_register(&cfg_info, "udptlend", &general_options, __stringify(DEFAULT_UDPTLEND),
 		OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
 		FLDSET(struct udptl_global_options, end), DEFAULT_UDPTLEND, 1024, 65535);
 




More information about the asterisk-commits mailing list