[asterisk-commits] kpfleming: branch kpfleming/optional_api r157235 - in /team/kpfleming/optiona...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Nov 16 20:05:19 CST 2008


Author: kpfleming
Date: Sun Nov 16 20:05:19 2008
New Revision: 157235

URL: http://svn.digium.com/view/asterisk?view=rev&rev=157235
Log:
save away some work in progress


Added:
    team/kpfleming/optional_api/
      - copied from r157234, trunk/
    team/kpfleming/optional_api/include/asterisk/optional_api.h   (with props)
Modified:
    team/kpfleming/optional_api/apps/app_stack.c
    team/kpfleming/optional_api/autoconf/ast_gcc_attribute.m4
    team/kpfleming/optional_api/configure
    team/kpfleming/optional_api/configure.ac
    team/kpfleming/optional_api/contrib/asterisk-ng-doxygen
    team/kpfleming/optional_api/include/asterisk/agi.h
    team/kpfleming/optional_api/include/asterisk/autoconfig.h.in
    team/kpfleming/optional_api/res/res_agi.c

Modified: team/kpfleming/optional_api/apps/app_stack.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/apps/app_stack.c?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/apps/app_stack.c (original)
+++ team/kpfleming/optional_api/apps/app_stack.c Sun Nov 16 20:05:19 2008
@@ -38,9 +38,6 @@
 #include "asterisk/app.h"
 #include "asterisk/manager.h"
 #include "asterisk/channel.h"
-
-/* usage of AGI is optional, so indicate that to the header file */
-#define ASTERISK_AGI_OPTIONAL
 #include "asterisk/agi.h"
 
 /*** DOCUMENTATION
@@ -152,6 +149,8 @@
 static const char *app_return = "Return";
 static const char *app_pop = "StackPop";
 
+static int agi_registered;
+
 static void gosub_free(void *data);
 
 static struct ast_datastore_info stack_info = {
@@ -576,12 +575,12 @@
 {
 	struct ast_context *con;
 
-	if (ast_agi_unregister) {
-		ast_agi_unregister(ast_module_info->self, &gosub_agi_command);
-
-		if ((con = ast_context_find("app_stack_gosub_virtual_context"))) {
-			ast_context_remove_extension2(con, "s", 1, NULL, 0);
-			ast_context_destroy(con, "app_stack"); /* leave nothing behind */
+	if (agi_registered) {
+		if (ast_agi_unregister(ast_module_info->self, &gosub_agi_command)) {
+			if ((con = ast_context_find("app_stack_gosub_virtual_context"))) {
+				ast_context_remove_extension2(con, "s", 1, NULL, 0);
+				ast_context_destroy(con, "app_stack"); /* leave nothing behind */
+			}
 		}
 	}
 
@@ -598,19 +597,15 @@
 {
 	struct ast_context *con;
 
-	/* usage of AGI is optional, so check to see if the ast_agi_register()
-	   function is available; if so, use it.
-	*/
-	if (ast_agi_register) {
-		con = ast_context_find_or_create(NULL, NULL, "app_stack_gosub_virtual_context", "app_stack");
-		if (!con) {
+	if (ast_agi_register(ast_module_info->self, &gosub_agi_command) == 1) {
+		if (!(con = ast_context_find_or_create(NULL, NULL, "app_stack_gosub_virtual_context", "app_stack"))) {
 			ast_log(LOG_ERROR, "Virtual context 'app_stack_gosub_virtual_context' does not exist and unable to create\n");
 			return AST_MODULE_LOAD_DECLINE;
 		} else {
 			ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_stack");
 		}
 
-		ast_agi_register(ast_module_info->self, &gosub_agi_command);
+		agi_registered = 1;
 	}
 
 	ast_register_application_xml(app_pop, pop_exec);

Modified: team/kpfleming/optional_api/autoconf/ast_gcc_attribute.m4
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/autoconf/ast_gcc_attribute.m4?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/autoconf/ast_gcc_attribute.m4 (original)
+++ team/kpfleming/optional_api/autoconf/ast_gcc_attribute.m4 Sun Nov 16 20:05:19 2008
@@ -1,17 +1,31 @@
 # Helper function to check for gcc attributes.
-# AST_GCC_ATTRIBUTE([attribute name])
+# AST_GCC_ATTRIBUTE([attribute name], [attribute syntax])
 
 AC_DEFUN([AST_GCC_ATTRIBUTE],
 [
 AC_MSG_CHECKING(for compiler 'attribute $1' support)
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
+
+if test "x$2" = "x"
+then
 AC_COMPILE_IFELSE(
 	AC_LANG_PROGRAM([void __attribute__(($1)) *test(void *muffin, ...) {}],
 			[]),
 	AC_MSG_RESULT(yes)
 	AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]),
-	AC_MSG_RESULT(no))
+	AC_MSG_RESULT(no)
+)
+else
+AC_COMPILE_IFELSE(
+	AC_LANG_PROGRAM([void __attribute__(($2)) *test(void *muffin, ...) {}],
+			[]),
+	AC_MSG_RESULT(yes)
+	AC_DEFINE_UNQUOTED([HAVE_ATTRIBUTE_$1], 1, [Define to 1 if your GCC C compiler supports the '$1' attribute.]),
+	AC_MSG_RESULT(no)
+)
+fi
+
+CFLAGS="$saved_CFLAGS"
 ]
-CFLAGS="$saved_CFLAGS"
 )

Modified: team/kpfleming/optional_api/configure.ac
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/configure.ac?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/configure.ac (original)
+++ team/kpfleming/optional_api/configure.ac Sun Nov 16 20:05:19 2008
@@ -473,6 +473,7 @@
 AST_GCC_ATTRIBUTE(sentinel)
 AST_GCC_ATTRIBUTE(warn_unused_result)
 AST_GCC_ATTRIBUTE(weak)
+AST_GCC_ATTRIBUTE(alias, [alias("foo")])
 
 AC_MSG_CHECKING(for -ffunction-sections support)
 saved_CFLAGS="${CFLAGS}"

Modified: team/kpfleming/optional_api/contrib/asterisk-ng-doxygen
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/contrib/asterisk-ng-doxygen?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/contrib/asterisk-ng-doxygen (original)
+++ team/kpfleming/optional_api/contrib/asterisk-ng-doxygen Sun Nov 16 20:05:19 2008
@@ -1098,7 +1098,9 @@
 			AST_RWDLLIST_HEAD_STATIC \
 			AST_DLLIST_ENTRY \
 			AST_RWDLLIST_ENTRY \
-			AST_CLI_DEFINE
+			AST_CLI_DEFINE \
+			AST_OPTIONAL_API \
+			AST_OPTIONAL_API_ATTR
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 

Modified: team/kpfleming/optional_api/include/asterisk/agi.h
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/include/asterisk/agi.h?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/include/asterisk/agi.h (original)
+++ team/kpfleming/optional_api/include/asterisk/agi.h Sun Nov 16 20:05:19 2008
@@ -28,6 +28,7 @@
 #endif
 
 #include "asterisk/cli.h"
+#include "asterisk/optional_api.h"
 
 typedef struct agi_state {
 	int fd;		        /*!< FD for general output */
@@ -60,17 +61,14 @@
 	AST_LIST_ENTRY(agi_command) list;
 } agi_command;
 
-#if defined(ASTERISK_AGI_OPTIONAL)
-#define AGI_WEAK attribute_weak
-#else
-#define AGI_WEAK
-#endif
+AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
+		 { return AST_OPTIONAL_API_UNAVAILABLE; });
+int ast_agi_unregister(struct ast_module *mod, agi_command *cmd);
 
-int AGI_WEAK ast_agi_fdprintf(struct ast_channel *chan, int fd, char *fmt, ...);
-int AGI_WEAK ast_agi_register(struct ast_module *mod, agi_command *cmd);
-int AGI_WEAK ast_agi_unregister(struct ast_module *mod, agi_command *cmd);
-void AGI_WEAK ast_agi_register_multiple(struct ast_module *mod, agi_command *cmd, int len);
-void AGI_WEAK ast_agi_unregister_multiple(struct ast_module *mod, agi_command *cmd, int len);
+void ast_agi_register_multiple(struct ast_module *mod, agi_command *cmd, int len);
+void ast_agi_unregister_multiple(struct ast_module *mod, agi_command *cmd, int len);
+
+int __attribute__((format(printf, 3, 4))) ast_agi_fdprintf(struct ast_channel *chan, int fd, char *fmt, ...);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/kpfleming/optional_api/include/asterisk/autoconfig.h.in
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/include/asterisk/autoconfig.h.in?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/include/asterisk/autoconfig.h.in (original)
+++ team/kpfleming/optional_api/include/asterisk/autoconfig.h.in Sun Nov 16 20:05:19 2008
@@ -90,6 +90,9 @@
 
 /* Define to 1 if you have the `atexit' function. */
 #undef HAVE_ATEXIT
+
+/* Define to 1 if your GCC C compiler supports the 'alias' attribute. */
+#undef HAVE_ATTRIBUTE_alias
 
 /* Define to 1 if your GCC C compiler supports the 'always_inline' attribute.
    */

Added: team/kpfleming/optional_api/include/asterisk/optional_api.h
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/include/asterisk/optional_api.h?view=auto&rev=157235
==============================================================================
--- team/kpfleming/optional_api/include/asterisk/optional_api.h (added)
+++ team/kpfleming/optional_api/include/asterisk/optional_api.h Sun Nov 16 20:05:19 2008
@@ -1,0 +1,123 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2008, Digium, Inc.
+ *
+ * Kevin P. Fleming <kpfleming at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef __ASTERISK_OPTIONAL_API_H
+#define __ASTERISK_OPTIONAL_API_H
+
+/*!
+ * \file
+ * \brief Optional API function macros
+ *
+ * Some Asterisk API functions are provided by loadable modules, thus,
+ * they may or may not be available at run time depending on whether the
+ * providing module has been loaded or not. In addition, there are some
+ * modules that are consumers of these APIs that *optionally* use them; they
+ * have only a part of their functionality dependent on the APIs, and can
+ * provide the remainder even if the APIs are not available.
+ *
+ * To accomodate this situation, the AST_OPTIONAL_API macro allows an API
+ * function to be declared in a special way, if Asterisk being built on a
+ * platform that supports the GCC 'weak' and 'alias' attributes. If so,
+ * the API function is actually a weak symbol, which means if the provider
+ * of the API is not loaded, the symbol can still be referenced (unlike a
+ * strong symbol, which would cause an immediate fault if not defined when
+ * referenced), but it will return NULL signifying the linker/loader was
+ * not able to resolve the symbol. In addition, the macro defines a hidden
+ * 'stub' version of the API call, using a provided function body, and uses
+ * the alias attribute to make the API function symbol actually resolve to
+ * that hidden stub, but only when the *real* provider of the symbol has
+ * not been found.
+ *
+ * An example can be found in agi.h:
+ *
+ * \code
+ * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
+ *                  { return AST_OPTIONAL_API_UNAVAILABLE; });
+ * \endcode
+ *
+ * This defines the 'ast_agi_register' function as an optional API; if a
+ * consumer of this API is loaded when there is no provider of it, then
+ * calling this function will actually call the hidden stub, and return
+ * the value AST_OPTIONAL_API_UNAVAILABLE. This allows the consumer to
+ * safely know that the API is not available, and to avoid using any
+ * other APIs from the not-present provider.
+ *
+ * In the module providing the API, the AST_OPTIONAL_API macro must
+ * be informed that it should not build the hidden stub function or
+ * apply special aliases to the function prototype; this can be done
+ * by defining AST_API_MODULE just before including the header file
+ * containing the AST_OPTIONAL_API macro calls.
+ *
+ * \note If the GCC 'weak' and 'alias' attributes are not available,
+ * then the AST_OPTIONAL_API macro will result in a non-optional function
+ * definition; this means that any consumers of the API functions so
+ * defined will require that the provider of the API functions be
+ * loaded before they can reference the symbols.
+ */
+
+#define __stringify_1(x)	#x
+#define __stringify(x)		__stringify_1(x)
+
+/*!
+ * \brief A common value for optional API stub functions to return
+ *
+ * This value is defined as INT_MIN, the minimum value for an integer
+ * (maximum negative value), which can be used by any optional API
+ * functions that return a signed integer value and would not be
+ * able to return such a value under normal circumstances.
+ */
+#define AST_OPTIONAL_API_UNAVAILABLE	INT_MIN
+
+#if defined(HAVE_ATTRIBUTE_weak) && defined(HAVE_ATTRIBUTE_alias) && !defined(AST_API_MODULE)
+#define AST_OPTIONAL_API(result, name, proto, stub)	\
+	static result __##name proto stub;		\
+	result __attribute__((weak, alias("__" __stringify(name)))) name proto;
+#define AST_OPTIONAL_API_ATTR(result, name, attr, proto, stub)		\
+	static result __attribute__((attr)) __##name proto stub;	\
+	result __attribute__((weak, alias("__" __stringify(name)), attr)) name proto;
+#else
+/*!
+ * \brief Define an optional API function
+ *
+ * \param result The type of result the function returns
+ * \param name The name of the function
+ * \param proto The prototype (arguments) of the function
+ * \param stub The code block that will be used by the hidden stub when needed
+ *
+ * Example usage:
+ * \code
+ * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
+ *                  { return AST_OPTIONAL_API_UNAVAILABLE; });
+ * \endcode		 
+ */
+#define AST_OPTIONAL_API(result, name, proto, stub) result name proto;
+/*!
+ * \brief Define an optional API function with compiler attributes
+ *
+ * \param result The type of result the function returns
+ * \param attr Any compiler attributes to be applied to the function (without the __attribute__ wrapper)
+ * \param name The name of the function
+ * \param proto The prototype (arguments) of the function
+ * \param stub The code block that will be used by the hidden stub when needed
+ */
+#define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) result __attribute__((attr)) name proto;
+#endif
+
+#undef AST_API_MODULE
+
+#endif /* __ASTERISK_OPTIONAL_API_H */

Propchange: team/kpfleming/optional_api/include/asterisk/optional_api.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kpfleming/optional_api/include/asterisk/optional_api.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kpfleming/optional_api/include/asterisk/optional_api.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kpfleming/optional_api/res/res_agi.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/optional_api/res/res_agi.c?view=diff&rev=157235&r1=157234&r2=157235
==============================================================================
--- team/kpfleming/optional_api/res/res_agi.c (original)
+++ team/kpfleming/optional_api/res/res_agi.c Sun Nov 16 20:05:19 2008
@@ -51,7 +51,6 @@
 #include "asterisk/utils.h"
 #include "asterisk/lock.h"
 #include "asterisk/strings.h"
-#include "asterisk/agi.h"
 #include "asterisk/manager.h"
 #include "asterisk/ast_version.h"
 #include "asterisk/speech.h"
@@ -59,6 +58,9 @@
 #include "asterisk/features.h"
 #include "asterisk/term.h"
 #include "asterisk/xmldoc.h"
+
+#define AST_API_MODULE
+#include "asterisk/agi.h"
 
 /*** DOCUMENTATION
 	<agi name="answer" language="en_US">
@@ -2702,7 +2704,7 @@
 		switch(res) {
 		case RESULT_SHOWUSAGE:
 			ast_agi_fdprintf(chan, agi->fd, "520-Invalid command syntax.  Proper usage follows:\n");
-			ast_agi_fdprintf(chan, agi->fd, c->usage);
+			ast_agi_fdprintf(chan, agi->fd, "%s", c->usage);
 			ast_agi_fdprintf(chan, agi->fd, "520 End of proper usage.\n");
 			break;
 		case AST_PBX_KEEPALIVE:




More information about the asterisk-commits mailing list