improve handling of API calls provided by loaded modules through use of some GCC features; this makes app_stack's usage of AGI APIs even cleaner, and will allow it to work 'as expected' either with or without res_agi being loaded

reviewed at http://reviewboard.digium.com/r/62



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@159631 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.2
Kevin P. Fleming 17 years ago
parent aa0e888629
commit e14dfcbedc

@ -38,9 +38,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#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
@ -576,9 +573,7 @@ static int unload_module(void)
{
struct ast_context *con;
if (ast_agi_unregister) {
ast_agi_unregister(ast_module_info->self, &gosub_agi_command);
if (ast_agi_unregister(ast_module_info->self, &gosub_agi_command) == 1) {
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 +593,13 @@ static int load_module(void)
{
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);
}
ast_register_application_xml(app_pop, pop_exec);

@ -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"
]
)

692
configure vendored

@ -17093,6 +17093,9 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
echo $ECHO_N "checking for compiler 'attribute pure' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@ -17138,17 +17141,73 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_pure 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute malloc' support" >&5
echo $ECHO_N "checking for compiler 'attribute malloc' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@ -17194,17 +17253,73 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_malloc 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute const' support" >&5
echo $ECHO_N "checking for compiler 'attribute const' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@ -17250,17 +17365,73 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_const 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute unused' support" >&5
echo $ECHO_N "checking for compiler 'attribute unused' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
@ -17306,24 +17477,18 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute always_inline' support" >&5
echo $ECHO_N "checking for compiler 'attribute always_inline' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((always_inline)) *test(void *muffin, ...) {}
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
@ -17353,7 +17518,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_always_inline 1
#define HAVE_ATTRIBUTE_unused 1
_ACEOF
else
@ -17362,24 +17527,30 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute deprecated' support" >&5
echo $ECHO_N "checking for compiler 'attribute deprecated' support... $ECHO_C" >&6; }
{ echo "$as_me:$LINENO: checking for compiler 'attribute always_inline' support" >&5
echo $ECHO_N "checking for compiler 'attribute always_inline' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((deprecated)) *test(void *muffin, ...) {}
void __attribute__((always_inline)) *test(void *muffin, ...) {}
int
main ()
{
@ -17409,7 +17580,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_deprecated 1
#define HAVE_ATTRIBUTE_always_inline 1
_ACEOF
else
@ -17418,24 +17589,18 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute sentinel' support" >&5
echo $ECHO_N "checking for compiler 'attribute sentinel' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((sentinel)) *test(void *muffin, ...) {}
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
@ -17465,7 +17630,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_sentinel 1
#define HAVE_ATTRIBUTE_always_inline 1
_ACEOF
else
@ -17474,24 +17639,30 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute warn_unused_result' support" >&5
echo $ECHO_N "checking for compiler 'attribute warn_unused_result' support... $ECHO_C" >&6; }
{ echo "$as_me:$LINENO: checking for compiler 'attribute deprecated' support" >&5
echo $ECHO_N "checking for compiler 'attribute deprecated' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((warn_unused_result)) *test(void *muffin, ...) {}
void __attribute__((deprecated)) *test(void *muffin, ...) {}
int
main ()
{
@ -17521,7 +17692,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_warn_unused_result 1
#define HAVE_ATTRIBUTE_deprecated 1
_ACEOF
else
@ -17530,24 +17701,18 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute weak' support" >&5
echo $ECHO_N "checking for compiler 'attribute weak' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((weak)) *test(void *muffin, ...) {}
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
@ -17577,7 +17742,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_weak 1
#define HAVE_ATTRIBUTE_deprecated 1
_ACEOF
else
@ -17586,13 +17751,464 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute sentinel' support" >&5
echo $ECHO_N "checking for compiler 'attribute sentinel' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((sentinel)) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_sentinel 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_sentinel 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute warn_unused_result' support" >&5
echo $ECHO_N "checking for compiler 'attribute warn_unused_result' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((warn_unused_result)) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_warn_unused_result 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_warn_unused_result 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute weak' support" >&5
echo $ECHO_N "checking for compiler 'attribute weak' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "x" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((weak)) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_weak 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__(()) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_weak 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for compiler 'attribute alias' support" >&5
echo $ECHO_N "checking for compiler 'attribute alias' support... $ECHO_C" >&6; }
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test "xalias("foo")" = "x"
then
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((alias)) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_alias 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
void __attribute__((alias("foo"))) *test(void *muffin, ...) {}
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
{ echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; }
cat >>confdefs.h <<_ACEOF
#define HAVE_ATTRIBUTE_alias 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
CFLAGS="$saved_CFLAGS"
{ echo "$as_me:$LINENO: checking for -ffunction-sections support" >&5
echo $ECHO_N "checking for -ffunction-sections support... $ECHO_C" >&6; }
saved_CFLAGS="${CFLAGS}"

@ -480,6 +480,7 @@ AST_GCC_ATTRIBUTE(deprecated)
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}"

@ -1098,7 +1098,9 @@ EXPAND_AS_DEFINED = \
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

@ -28,6 +28,7 @@ extern "C" {
#endif
#include "asterisk/cli.h"
#include "asterisk/optional_api.h"
typedef struct agi_state {
int fd; /*!< FD for general output */
@ -60,26 +61,31 @@ typedef struct agi_command {
AST_LIST_ENTRY(agi_command) list;
} agi_command;
#if defined(ASTERISK_AGI_OPTIONAL)
#define AGI_WEAK attribute_weak
#else
#define AGI_WEAK
#endif
/*!
* \brief
*
* Registers an AGI command.
*
* \param mod Pointer to the module_info structure for the module that is registering the command
* \param cmd Pointer to the descriptor for the command
* \return 1 on success, 0 if the command is already registered
*
*/
AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
{ return AST_OPTIONAL_API_UNAVAILABLE; });
/*!
* \brief
*
* Sends a string of text to an application connected via AGI.
* Unregisters an AGI command.
*
* \param fd The file descriptor for the AGI session (from struct agi_state)
* \param chan Pointer to an associated Asterisk channel, if any
* \param fmt printf-style format string
* \return 0 for success, -1 for failure
* \param mod Pointer to the module_info structure for the module that is unregistering the command
* \param cmd Pointer to the descriptor for the command
* \return 1 on success, 0 if the command was not already registered
*
*/
int AGI_WEAK ast_agi_send(int fd, struct ast_channel *chan, char *fmt, ...) __attribute__((format(printf, 3, 4)));
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);
AST_OPTIONAL_API(int, ast_agi_unregister, (struct ast_module *mod, agi_command *cmd),
{ return AST_OPTIONAL_API_UNAVAILABLE; });
/*!
* \brief
@ -88,15 +94,16 @@ int AGI_WEAK ast_agi_unregister(struct ast_module *mod, agi_command *cmd);
* entries.
*
* \param mod Pointer to the module_info structure for the module that is registering the commands
* \param cmd Pointer to the first entry in the array of commands
* \param cmd Pointer to the first entry in the array of command descriptors
* \param len Length of the array (use the ARRAY_LEN macro to determine this easily)
* \return 0 on success, -1 on failure
* \return 0 on success, -1 on failure, AST_OPTIONAL_API_UNAVAILABLE if res_agi is not loaded
*
* \note If any command fails to register, all commands previously registered during the operation
* will be unregistered. In other words, this function registers all the provided commands, or none
* of them.
*/
int AGI_WEAK ast_agi_register_multiple(struct ast_module *mod, struct agi_command *cmd, unsigned int len);
AST_OPTIONAL_API(int, ast_agi_register_multiple, (struct ast_module *mod, struct agi_command *cmd, unsigned int len),
{ return AST_OPTIONAL_API_UNAVAILABLE; });
/*!
* \brief
@ -105,14 +112,29 @@ int AGI_WEAK ast_agi_register_multiple(struct ast_module *mod, struct agi_comman
* entries.
*
* \param mod Pointer to the module_info structure for the module that is unregistering the commands
* \param cmd Pointer to the first entry in the array of commands
* \param cmd Pointer to the first entry in the array of command descriptors
* \param len Length of the array (use the ARRAY_LEN macro to determine this easily)
* \return 0 on success, -1 on failure
* \return 0 on success, -1 on failure, AST_OPTIONAL_API_UNAVAILABLE if res_agi is not loaded
*
* \note If any command fails to unregister, this function will continue to unregister the
* remaining commands in the array; it will not reregister the already-unregistered commands.
*/
int AGI_WEAK ast_agi_unregister_multiple(struct ast_module *mod, struct agi_command *cmd, unsigned int len);
AST_OPTIONAL_API(int, ast_agi_unregister_multiple, (struct ast_module *mod, struct agi_command *cmd, unsigned int len),
{ return AST_OPTIONAL_API_UNAVAILABLE; });
/*!
* \brief
*
* Sends a string of text to an application connected via AGI.
*
* \param fd The file descriptor for the AGI session (from struct agi_state)
* \param chan Pointer to an associated Asterisk channel, if any
* \param fmt printf-style format string
* \return 0 for success, -1 for failure, AST_OPTIONAL_API_UNAVAILABLE if res_agi is not loaded
*
*/
AST_OPTIONAL_API_ATTR(int, format(printf, 3, 4), ast_agi_send, (int fd, struct ast_channel *chan, char *fmt, ...),
{ return AST_OPTIONAL_API_UNAVAILABLE; });
#if defined(__cplusplus) || defined(c_plusplus)
}

@ -91,6 +91,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.
*/
#undef HAVE_ATTRIBUTE_always_inline

@ -0,0 +1,123 @@
/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2008, Digium, Inc.
*
* Kevin P. Fleming <kpfleming@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, attr, name, 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 */

@ -51,7 +51,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#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"
@ -60,6 +59,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/term.h"
#include "asterisk/xmldoc.h"
#define AST_API_MODULE
#include "asterisk/agi.h"
/*** DOCUMENTATION
<agi name="answer" language="en_US">
<synopsis>

Loading…
Cancel
Save