[asterisk-commits] trunk r14382 - in /trunk: Makefile include/asterisk/say.h pbx.c say.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Mar 23 07:28:21 MST 2006


Author: rizzo
Date: Thu Mar 23 08:28:16 2006
New Revision: 14382

URL: http://svn.digium.com/view/asterisk?rev=14382&view=rev
Log:
Replace ast_say_* functionn with function pointers, so that modules
can override them.
On passing, fix a potential problem in the top level Makefile:

if a static library is not referenced by any of the core objects,
it is not linked in the main program, and will not be available
to modules, which leads to failure at runtime when the modules
are loaded.
This is the case of stdtime/localtime.o, which supplies some core
symbolx, but is only linked in as a library. Fix the problem by
linking in the object.

NOTE: this is intended as a temporary aid to replace the
existing say.c with a newer implementation. Once the
task is completed, we may decide whether or not the ast_say*()
functions should be pluggable or not and possibly revert
part of this change.


Modified:
    trunk/Makefile
    trunk/include/asterisk/say.h
    trunk/pbx.c
    trunk/say.c

Modified: trunk/Makefile
URL: http://svn.digium.com/view/asterisk/trunk/Makefile?rev=14382&r1=14381&r2=14382&view=diff
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Thu Mar 23 08:28:16 2006
@@ -357,7 +357,7 @@
 SUBDIRS=res channels pbx apps codecs formats agi cdr funcs utils stdtime
 
 OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o \
-	translate.o file.o say.o pbx.o cli.o md5.o term.o \
+	translate.o file.o pbx.o cli.o md5.o term.o \
 	ulaw.o alaw.o callerid.o fskmodem.o image.o app.o \
 	cdr.o tdd.o acl.o rtp.o udptl.o manager.o asterisk.o \
 	dsp.o chanvars.o indications.o autoservice.o db.o privacy.o \
@@ -365,6 +365,15 @@
 	utils.o plc.o jitterbuf.o dnsmgr.o devicestate.o \
 	netsock.o slinfactory.o ast_expr2.o ast_expr2f.o \
 	cryptostub.o sha1.o
+
+# we need to link in the objects statically, not as a library, because
+# otherwise modules will not have them available if none of the static
+# objects use it.
+OBJS+= stdtime/localtime.o
+
+# At the moment say.o is an optional component which can be overridden
+# by a module.
+OBJS+= say.o
 
 ifeq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/sys/poll.h),)
   OBJS+= poll.o

Modified: trunk/include/asterisk/say.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/say.h?rev=14382&r1=14381&r2=14382&view=diff
==============================================================================
--- trunk/include/asterisk/say.h (original)
+++ trunk/include/asterisk/say.h Thu Mar 23 08:28:16 2006
@@ -32,6 +32,35 @@
 extern "C" {
 #endif
 
+/*! \brief
+ * All ast_say_* functions are implemented as function pointers,
+ * initialized to the function say_stub() which simply returns an error.
+ * An implementation of these functions (e.g. say.c, if available, or
+ * a dynamically loaded module) will just have to reassign the pointers
+ * to the relevant functions to override the previous implementation.
+ * As the conversion from the old implementation of say.c to the new
+ * implementation will be completed, and the API suitably reworked by
+ * removing redundant functions and/or arguments, this mechanism may be
+ * reverted back to pure static functions, if needed.
+ */
+#if defined(SAY_STUBS)
+/* provide declarations for the *say*() functions
+ * and initialize them to the stub function
+ */
+static int say_stub(struct ast_channel *chan, ...)
+{
+	ast_log(LOG_WARNING, "no implementation for the say() functions\n");
+        return -1;
+};
+
+#undef SAY_STUBS
+#define	SAY_INIT(x)	 = (typeof (x))say_stub
+#define	SAY_EXTERN
+#else
+#define SAY_INIT(x)
+#define	SAY_EXTERN	extern
+#endif
+
 /* says a number
  * \param chan channel to say them number on
  * \param num number to say on the channel
@@ -41,10 +70,10 @@
  * Vocally says a number on a given channel
  * Returns 0 on success, DTMF digit on interrupt, -1 on failure
  */
-int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options);
+SAY_EXTERN int (*ast_say_number)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options) SAY_INIT(ast_say_number);
 
 /* Same as above with audiofd for received audio and returns 1 on ctrlfd being readable */
-int ast_say_number_full(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd);
+SAY_EXTERN int (* ast_say_number_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_number_full);
 
 /* says an enumeration
  * \param chan channel to say them enumeration on
@@ -56,8 +85,8 @@
  * especially useful for dates and messages. says 'last' if num equals to INT_MAX
  * Returns 0 on success, DTMF digit on interrupt, -1 on failure
  */
-int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options);
-int ast_say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd);
+SAY_EXTERN int (* ast_say_enumeration)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options) SAY_INIT(ast_say_enumeration);
+SAY_EXTERN int (* ast_say_enumeration_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_enumeration_full);
 
 /* says digits
  * \param chan channel to act upon
@@ -67,8 +96,8 @@
  * Vocally says digits of a given number
  * Returns 0 on success, dtmf if interrupted, -1 on failure
  */
-int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang);
-int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd);
+SAY_EXTERN int (*ast_say_digits)(struct ast_channel *chan, int num, const char *ints, const char *lang) SAY_INIT(ast_say_digits);
+SAY_EXTERN int (*ast_say_digits_full)(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digits_full);
 
 /* says digits of a string
  * \param chan channel to act upon
@@ -78,22 +107,27 @@
  * Vocally says the digits of a given string
  * Returns 0 on success, dtmf if interrupted, -1 on failure
  */
-int ast_say_digit_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang);
-int ast_say_digit_str_full(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd);
-int ast_say_character_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang);
-int ast_say_character_str_full(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd);
-int ast_say_phonetic_str(struct ast_channel *chan, const char *num, const char *ints, const char *lang);
-int ast_say_phonetic_str_full(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd);
+SAY_EXTERN int (* ast_say_digit_str)(struct ast_channel *chan, const char *num, const char *ints, const char *lang) SAY_INIT(ast_say_digit_str);
+SAY_EXTERN int (* ast_say_digit_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_digit_str_full);
 
-int ast_say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+/*
+ * the generic 'say' routine, with the first chars in the string
+ * defining the format to use
+ */
+SAY_EXTERN int (* ast_say_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, const char *options, int audiofd, int ctrlfd) SAY_INIT(ast_say_full);
+SAY_EXTERN int (* ast_say_character_str)(struct ast_channel *chan, const char *num, const char *ints, const char *lang) SAY_INIT(ast_say_character_str);
+SAY_EXTERN int (* ast_say_character_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_character_str_full);
+SAY_EXTERN int (* ast_say_phonetic_str)(struct ast_channel *chan, const char *num, const char *ints, const char *lang) SAY_INIT(ast_say_phonetic_str);
+SAY_EXTERN int (* ast_say_phonetic_str_full)(struct ast_channel *chan, const char *num, const char *ints, const char *lang, int audiofd, int ctrlfd) SAY_INIT(ast_say_phonetic_str_full);
 
-int ast_say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+SAY_EXTERN int (* ast_say_datetime)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime);
+SAY_EXTERN int (* ast_say_time)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_time);
 
-int ast_say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+SAY_EXTERN int (* ast_say_date)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_date);
 
-int ast_say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+SAY_EXTERN int (* ast_say_datetime_from_now)(struct ast_channel *chan, time_t t, const char *ints, const char *lang) SAY_INIT(ast_say_datetime_from_now);
 
-int ast_say_date_with_format(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone);
+SAY_EXTERN int (* ast_say_date_with_format)(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone) SAY_INIT(ast_say_date_with_format);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: trunk/pbx.c
URL: http://svn.digium.com/view/asterisk/trunk/pbx.c?rev=14382&r1=14381&r2=14382&view=diff
==============================================================================
--- trunk/pbx.c (original)
+++ trunk/pbx.c Thu Mar 23 08:28:16 2006
@@ -51,6 +51,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/ast_expr.h"
 #include "asterisk/linkedlists.h"
+#define	SAY_STUBS	/* generate declarations and stubs for say methods */
 #include "asterisk/say.h"
 #include "asterisk/utils.h"
 #include "asterisk/causes.h"

Modified: trunk/say.c
URL: http://svn.digium.com/view/asterisk/trunk/say.c?rev=14382&r1=14381&r2=14382&view=diff
==============================================================================
--- trunk/say.c (original)
+++ trunk/say.c Thu Mar 23 08:28:16 2006
@@ -56,7 +56,8 @@
 /* Forward declaration */
 static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
 
-int ast_say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
+
+static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 {
 	const char *fn;
 	char fnbuf[256];
@@ -131,12 +132,12 @@
 	return res;
 }
 
-int ast_say_character_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
+static int say_character_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
 {
 	return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
 }
 
-int ast_say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
+static int say_phonetic_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 {
 	const char *fn;
 	char fnbuf[256];
@@ -210,12 +211,12 @@
 	return res;
 }
 
-int ast_say_phonetic_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
+static int say_phonetic_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
 {
 	return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
 }
 
-int ast_say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
+static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
 {
 	const char *fn;
 	char fnbuf[256];
@@ -261,12 +262,12 @@
 	return res;
 }
 
-int ast_say_digit_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
+static int say_digit_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
 {
 	return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
 }
 
-int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
+static int say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
 {
 	char fn2[256];
 
@@ -274,7 +275,7 @@
 	return ast_say_digit_str_full(chan, fn2, ints, lang, audiofd, ctrlfd);
 }
 
-int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
+static int say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang)
 {
 	return ast_say_digits_full(chan, num, ints, lang, -1, -1);
 }
@@ -413,7 +414,7 @@
 
 /*! \brief  ast_say_number_full: call language-specific functions */
 /* Called from AGI */
-int ast_say_number_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
+static int say_number_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 {
 	if (!strcasecmp(language,"en") ) {	/* English syntax */
 	   return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
@@ -456,7 +457,7 @@
 }
 
 /*! \brief  ast_say_number: call language-specific functions without file descriptors */
-int ast_say_number(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
+static int say_number(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
 {
 	return(ast_say_number_full(chan, num, ints, language, options, -1, -1));
 }
@@ -2273,7 +2274,7 @@
 
 /*! \brief  ast_say_enumeration_full: call language-specific functions */
 /* Called from AGI */
-int ast_say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
+static int say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
 {
 	if (!strcasecmp(language,"en") ) {	/* English syntax */
 	   return(ast_say_enumeration_full_en(chan, num, ints, language, audiofd, ctrlfd));
@@ -2288,7 +2289,7 @@
 }
 
 /*! \brief  ast_say_enumeration: call language-specific functions without file descriptors */
-int ast_say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
+static int say_enumeration(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
 {
 	return(ast_say_enumeration_full(chan, num, ints, language, options, -1, -1));
 }
@@ -2718,7 +2719,7 @@
 	return res;
 }
 
-int ast_say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
 		return(ast_say_date_en(chan, t, ints, lang));
@@ -2947,7 +2948,7 @@
 	return res;
 }
 
-int ast_say_date_with_format(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
+static int say_date_with_format(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
 {
 	/* If no format is given, use default english format */
 	if (format == NULL)
@@ -5164,7 +5165,7 @@
 	return res;
 }
 
-int ast_say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+static int say_time(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
 		return(ast_say_time_en(chan, t, ints, lang));
@@ -5353,7 +5354,7 @@
 	return res;
 }
 
-int ast_say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
 		return(ast_say_datetime_en(chan, t, ints, lang));
@@ -5632,7 +5633,7 @@
 	return res;
 }
 
-int ast_say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
 {
 	if (!strcasecmp(lang, "en") ) {	/* English syntax */
 		return(ast_say_datetime_from_now_en(chan, t, ints, lang));
@@ -6194,3 +6195,27 @@
 	}
 	return res;
 }
+
+/*
+ * remap the 'say' functions to use those in this file
+ */
+static void __attribute__((constructor)) __say_init(void)
+{
+	ast_say_number = say_number;
+	ast_say_number_full = say_number_full;
+	ast_say_enumeration = say_enumeration;
+	ast_say_enumeration_full = say_enumeration_full;
+	ast_say_digits = say_digits;
+	ast_say_digits_full = say_digits_full;
+	ast_say_digit_str = say_digit_str;
+	ast_say_digit_str_full = say_digit_str_full;
+	ast_say_character_str = say_character_str;
+	ast_say_character_str_full = say_character_str_full;
+	ast_say_phonetic_str = say_phonetic_str;
+	ast_say_phonetic_str_full = say_phonetic_str_full;
+	ast_say_datetime = say_datetime;
+	ast_say_time = say_time;
+	ast_say_date = say_date;
+	ast_say_datetime_from_now = say_datetime_from_now;
+	ast_say_date_with_format = say_date_with_format;
+}



More information about the asterisk-commits mailing list