aboutsummaryrefslogtreecommitdiffstats
path: root/say.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-29 02:30:14 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-04-29 02:30:14 +0000
commitea132fd13c83ef62851e74a5afa441960a0cca30 (patch)
tree30fe504429e2388014832e4f050836d223fc2b59 /say.c
parentfefa0442a5925353c6c06c1e7ebcb4126a66a746 (diff)
Add support for French, Danish, Portuguese, Spanish, Italian, and Dutch numbers
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@2809 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'say.c')
-rwxr-xr-xsay.c875
1 files changed, 798 insertions, 77 deletions
diff --git a/say.c b/say.c
index 46ef8c01f..68f01dafa 100755
--- a/say.c
+++ b/say.c
@@ -25,6 +25,10 @@
#include "asterisk.h"
#include <stdio.h>
+
+/* Forward declaration */
+static int wait_file(struct ast_channel *chan, char *ints, char *file, char *lang);
+
int ast_say_digit_str(struct ast_channel *chan, char *fn2, char *ints, char *lang)
{
/* XXX Merge with full version? XXX */
@@ -87,22 +91,95 @@ int ast_say_digits_full(struct ast_channel *chan, int num, char *ints, char *lan
return ast_say_digit_str_full(chan, fn2, ints, lang, audiofd, ctrlfd);
}
+/* Forward declarations */
+/* Syntaxes supported, not really language codes.
+ en - English, Swedish, Norwegian
+ fr - French
+ da - Danish (maybe German - please check)
+ pt - Portuguese
+ es - Spanish
+ it - Italian
+ nl - Dutch
+
+ For portuguese, we're using an option to saynumber() to indicate if the gender is male of female
+ This should also be implemented in _full version, really.
+
+ OEJ 2004-04-25
+*/
+
+static int ast_say_number_full_en(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_de(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_da(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd);
+static int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd);
+static int ast_say_number_full_it(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_es(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_nl(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd);
+
+/*--- ast_say_number_full: call language-specific functions */
+/* Called from AGI */
int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
+ char *options=(char *) NULL; /* While waiting for a general hack for agi */
+
+ if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) {
+ return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "fr") ) { /* French syntax */
+ return(ast_say_number_full_fr(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "de") ) { /* German syntax */
+ return(ast_say_number_full_de(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "da") ) { /* Danish syntax */
+ return(ast_say_number_full_da(chan, num, ints, language, options, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "it") ) { /* Italian syntax */
+ return(ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "pt") ) { /* Portuguese syntax */
+ return(ast_say_number_full_pt(chan, num, ints, language, options, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "es") ) { /* Spanish syntax */
+ return(ast_say_number_full_es(chan, num, ints, language, audiofd, ctrlfd));
+ } else if (!strcasecmp(language, "nl") ) { /* Spanish syntax */
+ return(ast_say_number_full_nl(chan, num, ints, language, audiofd, ctrlfd));
+ }
+
+ /* Default to english */
+ return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd));
+}
+
+/*--- ast_say_number: call language-specific functions without file descriptors */
+int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language, char *options)
+{
+ if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) {
+ return(ast_say_number_full_en(chan, num, ints, language, -1, -1));
+ }
+ /* French */
+ if (!strcasecmp(language, "fr")) { /* French syntax */
+ return(ast_say_number_full_fr(chan, num, ints, language, -1, -1));
+ } else if (!strcasecmp(language, "da")) { /* Danish syntax */
+ return(ast_say_number_full_da(chan, num, ints, language, options, -1, -1));
+ } else if (!strcasecmp(language, "it")) { /* Italian syntax */
+ return(ast_say_number_full_it(chan, num, ints, language, -1, -1));
+ } else if (!strcasecmp(language, "pt")) { /* Portuguese syntax */
+ return(ast_say_number_full_pt(chan, num, ints, language, options, -1, -1));
+ } else if (!strcasecmp(language, "nl")) { /* Spanish syntax */
+ return(ast_say_number_full_nl(chan, num, ints, language, -1, -1));
+ } else if (!strcasecmp(language, "es")) { /* Spanish syntax */
+ return(ast_say_number_full_es(chan, num, ints, language, -1, -1));
+ }
+
+ /* Default to english */
+ return(ast_say_number_full_en(chan, num, ints, language, NULL, NULL));
+}
+
+/*--- ast_say_number_full_en: English syntax */
+/* This is the default syntax, if no other syntax defined in this file is used */
+static int ast_say_number_full_en(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
int res = 0;
int playh = 0;
char fn[256] = "";
if (!num)
return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
- if (0) {
- /* XXX Only works for english XXX */
- } else {
- /* Use english numbers if a given language is supported. */
- /* As a special case, Norwegian has the same numerical grammar
- as English */
- if (strcasecmp(language, "no"))
- language = "en";
- while(!res && (num || playh)) {
+
+ while(!res && (num || playh)) {
if (playh) {
snprintf(fn, sizeof(fn), "digits/hundred");
playh = 0;
@@ -121,14 +198,14 @@ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lan
num -= ((num / 100) * 100);
} else {
if (num < 1000000) { /* 1,000,000 */
- res = ast_say_number_full(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000;
snprintf(fn, sizeof(fn), "digits/thousand");
} else {
if (num < 1000000000) { /* 1,000,000,000 */
- res = ast_say_number_full(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
if (res)
return res;
num = num % 1000000;
@@ -140,80 +217,723 @@ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *lan
}
}
}
- if (!res) {
- res = ast_streamfile(chan, fn, language);
- if (!res)
- res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
- ast_stopstream(chan);
- }
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
- }
}
return res;
}
-int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language)
+
+/*--- ast_say_number_full_fr: French syntax */
+static int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
{
- /* XXX Should I be merged with ast_say_number_full XXX */
int res = 0;
int playh = 0;
+ int playa = 0; /* For french */
char fn[256] = "";
if (!num)
- return ast_say_digits(chan, 0,ints, language);
- if (0) {
- /* XXX Only works for english XXX */
- } else {
- /* Use english numbers */
- language = "en";
- while(!res && (num || playh)) {
- if (playh) {
- snprintf(fn, sizeof(fn), "digits/hundred");
- playh = 0;
- } else
- if (num < 20) {
- snprintf(fn, sizeof(fn), "digits/%d", num);
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+ while(!res && (num || playh || playa)) {
+ if (playh) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ playh = 0;
+ } else
+ if (playa) {
+ snprintf(fn, sizeof(fn), "digits/et");
+ playa = 0;
+ } else
+ if (num < 21) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 70) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
+ if ((num % 10) == 1) playa++;
+ num = num % 10;
+ } else
+ if (num < 80) {
+ snprintf(fn, sizeof(fn), "digits/60");
+ if ((num % 10) == 1) playa++;
+ num = num - 60;
+ } else
+ if (num < 100) {
+ snprintf(fn, sizeof(fn), "digits/80");
+ num = num - 80;
+ } else
+ if (num < 200) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ num = num - 100;
+ } else
+ if (num < 1000) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num/100));
+ playh++;
+ num = num % 100;
+ } else
+ if (num < 2000) {
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ num = num - 1000;
+ } else
+ if (num < 1000000) {
+ res = ast_say_number_full_fr(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ if (res) return res;
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ num = num % 1000;
+ } else
+ if (num < 1000000000) {
+ res = ast_say_number_full_fr(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ if (res) return res;
+ snprintf(fn, sizeof(fn), "digits/million");
+ num = num % 1000000;
+ } else {
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
+
+
+ }
+ return res;
+}
+
+/*--- ast_say_number_full_da: Danish syntax */
+/* New files:
+ In addition to English, the following sounds are required: "1N", "millions", "and" and "1-and" through "9-and"
+ */
+static int ast_say_number_full_da(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ int playa = 0;
+ int cn = 1; /* +1 = Commune; -1 = Neutrum */
+ char fn[256] = "";
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+
+ if (options && !strncasecmp(options, "n",1)) cn = -1;
+
+ while(!res && (num || playh || playa )) {
+ /* The grammer for Danish numbers is the same as for English except
+ * for the following:
+ * - 1 exists in both commune ("en", file "1N") and neutrum ("et", file "1")
+ * - numbers 20 through 99 are said in reverse order, i.e. 21 is
+ * "one-and twenty" and 68 is "eight-and sixty".
+ * - "million" is different in singular and plural form
+ * - numbers > 1000 with zero as the third digit from last have an
+ * "and" before the last two digits, i.e. 2034 is "two thousand and
+ * four-and thirty" and 1000012 is "one million and twelve".
+ */
+ if (playh) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ playh = 0;
+ } else
+ if (playa) {
+ snprintf(fn, sizeof(fn), "digits/and");
+ playa = 0;
+ } else
+ if (num == 1 && cn == -1) {
+ snprintf(fn, sizeof(fn), "digits/1N");
num = 0;
- } else
- if (num < 100) {
- snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
- num -= ((num / 10) * 10);
- } else {
- if (num < 1000){
- snprintf(fn, sizeof(fn), "digits/%d", (num/100));
- playh++;
- num -= ((num / 100) * 100);
- } else {
- if (num < 1000000) {
- res = ast_say_number(chan, num / 1000, ints, language);
- if (res)
- return res;
- num = num % 1000;
- snprintf(fn, sizeof(fn), "digits/thousand");
+ } else
+ if (num < 20) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ int ones = num % 10;
+ if (ones) {
+ snprintf(fn, sizeof(fn), "digits/%d-and", ones);
+ num -= ones;
+ } else {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ }
+ } else {
+ if (num < 1000) {
+ int hundreds = num / 100;
+ if (hundreds == 1)
+ snprintf(fn, sizeof(fn), "digits/1N");
+ else
+ snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
+
+ playh++;
+ num -= 100 * hundreds;
+ if (num)
+ playa++;
+
+ } else {
+ if (num < 1000000) {
+ res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num % 1000;
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ } else {
+ if (num < 1000000000) {
+ int millions = num / 1000000;
+ res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
+ if (res)
+ return res;
+ if (millions == 1)
+ snprintf(fn, sizeof(fn), "digits/million");
+ else
+ snprintf(fn, sizeof(fn), "digits/millions");
+ num = num % 1000000;
} else {
- if (num < 1000000000) {
- res = ast_say_number(chan, num / 1000000, ints, language);
- if (res)
- return res;
- num = num % 1000000;
- snprintf(fn, sizeof(fn), "digits/million");
- } else {
- ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
- res = -1;
- }
- }
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ if (num && num < 100)
+ playa++;
+ }
+ }
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
}
+ ast_stopstream(chan);
+
}
+
+ }
+ return res;
+}
+
+/*--- ast_say_number_full_de: German syntax */
+/* New files:
+ In addition to English, the following sounds are required: "millions", "and" and "1-and" through "9-and"
+ */
+static int ast_say_number_full_de(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ int playa = 0;
+ char fn[256] = "";
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+
+ while(!res && (num || playh || playa )) {
+ /* The grammer for German numbers is the same as for English except
+ * for the following:
+ * - numbers 20 through 99 are said in reverse order, i.e. 21 is
+ * "one-and twenty" and 68 is "eight-and sixty".
+ * - "million" is different in singular and plural form
+ * - numbers > 1000 with zero as the third digit from last have an
+ * "and" before the last two digits, i.e. 2034 is "two thousand and
+ * four-and thirty" and 1000012 is "one million and twelve".
+ */
+ if (playh) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ playh = 0;
+ } else
+ if (playa) {
+ snprintf(fn, sizeof(fn), "digits/and");
+ playa = 0;
+ } else
+ if (num < 20) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ int ones = num % 10;
+ if (ones) {
+ snprintf(fn, sizeof(fn), "digits/%d-and", ones);
+ num -= ones;
+ } else {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ }
+ } else {
+ if (num < 1000) {
+ int hundreds = num / 100;
+ if (hundreds == 1)
+ snprintf(fn, sizeof(fn), "digits/1N");
+ else
+ snprintf(fn, sizeof(fn), "digits/%d", (num / 100));
+
+ playh++;
+ num -= 100 * hundreds;
+ if (num)
+ playa++;
+
+ } else {
+ if (num < 1000000) {
+ res = ast_say_number_full_da(chan, num / 1000, ints, language, "n", audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num % 1000;
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ } else {
+ if (num < 1000000000) {
+ int millions = num / 1000000;
+ res = ast_say_number_full_da(chan, millions, ints, language, "c", audiofd, ctrlfd);
+ if (res)
+ return res;
+ if (millions == 1)
+ snprintf(fn, sizeof(fn), "digits/million");
+ else
+ snprintf(fn, sizeof(fn), "digits/millions");
+ num = num % 1000000;
+ } else {
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ if (num && num < 100)
+ playa++;
+ }
+ }
if (!res) {
- res = ast_streamfile(chan, fn, language);
- if (!res)
- res = ast_waitstream(chan, ints);
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
ast_stopstream(chan);
+
}
- }
}
return res;
}
+
+/*------------ Portuguese ----------------------*/
+/* ast_say_number_full_pt: Portuguese syntax */
+/* For feminin all sound files end with F */
+/* 100E for 100+ something */
+/* What is "pt-e" */
+static int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, char *options, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ int mf = 1; /* +1 = Masculin; -1 = Feminin */
+
+ char fn[256] = "";
+
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+
+ if (options && !strncasecmp(options, "f",1)) mf = -1;
+
+ while(!res && num ) {
+
+ if (num < 20) {
+ if ((num == 1 || num == 2) && (mf < 0))
+ snprintf(fn, sizeof(fn), "digits/%dF", num);
+ else
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10);
+ if (num % 10)
+ playh = 1;
+ num = num % 10;
+ } else
+ if (num < 1000) {
+ if (num == 100)
+ snprintf(fn, sizeof(fn), "digits/100");
+ else if (num < 200)
+ snprintf(fn, sizeof(fn), "digits/100E");
+ else {
+ if (mf < 0 && num > 199)
+ snprintf(fn, sizeof(fn), "digits/%dF", (num / 100) * 100);
+ else
+ snprintf(fn, sizeof(fn), "digits/%d", (num / 100) * 100);
+ if (num % 100)
+ playh = 1;
+ }
+ num = num % 100;
+ } else
+ if (num < 1000000) {
+ if (num > 1999) {
+ res = ast_say_number_full_pt(chan, (num / 1000) * mf, ints, language, options, audiofd, ctrlfd);
+ if (res)
+ return res;
+ }
+ snprintf(fn, sizeof(fn), "digits/1000");
+ if ((num % 1000) && ((num % 1000) < 100 || !(num % 100)))
+ playh = 1;
+ num = num % 1000;
+ } else
+ if (num < 1000000000) {
+ res = ast_say_number_full_pt(chan, (num / 1000000), ints, language, options, audiofd, ctrlfd );
+ if (res)
+ return res;
+
+ if (num < 2000000)
+ snprintf(fn, sizeof(fn), "digits/1000000");
+ else
+ snprintf(fn, sizeof(fn), "digits/1000000S");
+
+ if ((num % 1000000) &&
+ // no thousands
+ ((!((num / 1000) % 1000) && ((num % 1000) < 100 || !(num % 100))) ||
+ // no hundreds and below
+ (!(num % 1000) && (((num / 1000) % 1000) < 100 || !((num / 1000) % 100))) ) )
+ playh = 1;
+ num = num % 1000000;
+ }
+ if (!res && playh) {
+ res = wait_file(chan, ints, "digits/pt-e", language);
+ ast_stopstream(chan);
+ playh = 0;
+ }
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
+
+ }
+ return res;
+}
+
+
+/*--- ast_say_number_full_it: italian */
+static int ast_say_number_full_it(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ int tempnum = 0;
+ char fn[256] = "";
+
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+
+ /*
+ Italian support
+
+ Like english, numbers till 20 are a single 'word', and other
+ compound, but with exceptions.
+ For example 21 is not twenty-one, but is a single word in it.
+ Idem for 28 (ie when a the 2nd part of a compund number
+ starts with a wovel)
+
+ There're exceptions also for hundred, thounsand and million.
+ In english 100 = one hundred, 200 is two hundred.
+ In italian 100 = cento , like to say hundred (without one),
+ 200 and more are like english.
+
+ Same apply for thousand:
+ 1000 is one thousand in en, 2000 is two thousand.
+ In it we have 1000 = mille , 2000 = 2 mila
+
+ For million(s) we use the plural, if more than one
+ Also, one million is abbreviated in it, like on-million,
+ or 'un milione', not 'uno milione'.
+ So the right file is provided.
+ */
+
+ while(!res && (num || playh)) {
+ if (playh) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ playh = 0;
+ } else
+ if (num < 20) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 21) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 28) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 31) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 38) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 41) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 48) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 51) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 58) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 61) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 68) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 71) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 78) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 81) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 88) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 91) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num == 98) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
+ num -= ((num / 10) * 10);
+ } else {
+ if (num < 1000){
+ if ((num / 100) > 1) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num/100));
+ playh++;
+ }
+ else {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ }
+ num -= ((num / 100) * 100);
+ } else {
+ if (num < 1000000) { /* 1,000,000 */
+ if ((num/1000) > 1)
+ res = ast_say_number_full(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ tempnum = num;
+ num = num % 1000;
+ if ((tempnum / 1000) < 2)
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ else /* for 1000 it says mille, for >1000 (eg 2000) says mila */
+ snprintf(fn, sizeof(fn), "digits/thousands");
+ } else {
+ if (num < 1000000000) { /* 1,000,000,000 */
+ if ((num / 1000000) > 1)
+ res = ast_say_number_full(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ tempnum = num;
+ num = num % 1000000;
+ if ((tempnum / 1000000) < 2)
+ snprintf(fn, sizeof(fn), "digits/million");
+ else
+ snprintf(fn, sizeof(fn), "digits/millions");
+ } else {
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ }
+ }
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
+ }
+ return res;
+}
+
+
+/*--- ast_say_number_full_es: spanish syntax */
+/* New files:
+ Requires a few new audios:
+ 21.gsm thru 29.gsm, cien.gsm, mil.gsm, millon.gsm, millones.gsm, 100.gsm, 200.gsm, 300.gsm, 400.gsm, 500.gsm, 600.gsm, 700.gsm, 800.gsm, 900.gsm, y.gsm
+ */
+static int ast_say_number_full_es(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playa = 0;
+ char fn[256] = "";
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+ while (!res && num) {
+ if (playa) {
+ snprintf(fn, sizeof(fn), "digits/y");
+ playa = 0;
+ } else
+ if (num < 31) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num/10)*10);
+ num -= ((num/10)*10);
+ if (num)
+ playa++;
+ } else
+ if (num == 100) {
+ snprintf(fn, sizeof(fn), "digits/cien");
+ num = 0;
+ } else {
+ if (num < 1000) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num/100)*100);
+ num -= ((num/100)*100);
+ } else {
+ if (num < 1000000) {
+ res = ast_say_number_full_es(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num % 1000;
+ snprintf(fn, sizeof(fn), "digits/mil");
+ } else {
+ if (num < 2147483640) {
+ res = ast_say_number_full_es(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ if ((num/1000000) == 1) {
+ snprintf(fn, sizeof(fn), "digits/millon");
+ } else {
+ snprintf(fn, sizeof(fn), "digits/millones");
+ }
+ num = num % 1000000;
+ } else {
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ }
+ }
+
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
+
+ }
+ return res;
+}
+
+/*--- ast_say_number_full_nl: dutch syntax */
+/* New files: ???
+ */
+static int ast_say_number_full_nl(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ int units = 0;
+ char fn[256] = "";
+ if (!num)
+ return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+ while (!res && (num || playh )) {
+ if (playh) {
+ snprintf(fn, sizeof(fn), "digits/hundred");
+ playh = 0;
+ } else
+ if (num < 20) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else
+ if (num < 100) {
+ units = num % 10;
+ if (units > 0) {
+ res = ast_say_number_full_nl(chan, units, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num - units;
+ snprintf(fn, sizeof(fn), "digits/nl-en");
+ } else {
+ snprintf(fn, sizeof(fn), "digits/%d", num - units);
+ num = 0;
+ }
+ } else {
+ if (num < 1000){
+ snprintf(fn, sizeof(fn), "digits/%d", (num/100));
+ playh++;
+ num -= ((num / 100) * 100);
+ } else {
+ if (num < 1000000) { /* 1,000,000 */
+ res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num % 1000;
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ } else {
+ if (num < 1000000000) { /* 1,000,000,000 */
+ res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num = num % 1000000;
+ snprintf(fn, sizeof(fn), "digits/million");
+ } else {
+ ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ }
+ }
+
+ if (!res) {
+ if(!ast_streamfile(chan, fn, language)) {
+ if (audiofd && ctrlfd)
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+
+ }
+
+ }
+ return res;
+}
+
+
int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang)
{
struct tm tm;
@@ -233,12 +953,13 @@ int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang)
res = ast_waitstream(chan, ints);
}
if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang);
+ res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+ /* Should portuguese add a gender here? Defaults to masculin */
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
+ res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
return res;
}
@@ -548,21 +1269,21 @@ int ast_say_time(struct ast_channel *chan, time_t t, char *ints, char *lang)
pm = 1;
}
if (!res)
- res = ast_say_number(chan, hour, ints, lang);
+ res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
if (tm.tm_min > 9) {
if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang);
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else if (tm.tm_min) {
if (!res)
- res = ast_streamfile(chan, "digits/oh", lang);
+ res = ast_streamfile(chan, "digits/oh", lang); /* This is very english ! */
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang);
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else {
if (!res)
- res = ast_streamfile(chan, "digits/oclock", lang);
+ res = ast_streamfile(chan, "digits/oclock", lang); /* This is very english ! */
if (!res)
res = ast_waitstream(chan, ints);
}
@@ -598,7 +1319,7 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
res = ast_waitstream(chan, ints);
}
if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang);
+ res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
hour = tm.tm_hour;
if (!hour)
@@ -610,18 +1331,18 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
pm = 1;
}
if (!res)
- res = ast_say_number(chan, hour, ints, lang);
+ res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
if (tm.tm_min > 9) {
if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang);
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else if (tm.tm_min) {
if (!res)
res = ast_streamfile(chan, "digits/oh", lang);
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
- res = ast_say_number(chan, tm.tm_min, ints, lang);
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
} else {
if (!res)
res = ast_streamfile(chan, "digits/oclock", lang);
@@ -638,7 +1359,7 @@ int ast_say_datetime(struct ast_channel *chan, time_t t, char *ints, char *lang)
if (!res)
res = ast_waitstream(chan, ints);
if (!res)
- res = ast_say_number(chan, tm.tm_year + 1900, ints, lang);
+ res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
return res;
}
@@ -665,7 +1386,7 @@ int ast_say_datetime_from_now(struct ast_channel *chan, time_t t, char *ints, ch
res = ast_waitstream(chan, ints);
}
if (!res)
- res = ast_say_number(chan, tm.tm_mday, ints, lang);
+ res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
} else if (daydiff) {
/* Just what day of the week */