--- say.c 2004-04-20 23:38:19.080968208 +0200 +++ say_lang.c 2004-04-20 23:34:05.441527264 +0200 @@ -27,6 +27,9 @@ #define DIGITS_DIR AST_SOUNDS "/digits/" +/* 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 */ @@ -84,22 +87,78 @@ 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 + it - Italian +*/ + +int ast_say_number_full_en(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd); +int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd); +int ast_say_number_full_da(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd); +int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd); +int ast_say_number_full_it(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd); + +int ast_say_number_fr(struct ast_channel *chan, int num, char *ints, char *language); +int ast_say_number_da(struct ast_channel *chan, int num, char *ints, char *language); +int ast_say_number_en(struct ast_channel *chan, int num, char *ints, char *language); +int ast_say_number_pt(struct ast_channel *chan, int num, char *ints, char *language); +int ast_say_number_it(struct ast_channel *chan, int num, char *ints, char *language); + +/* ast_say_number_full: call language-specific functions */ int ast_say_number_full(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd) { + if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) { + return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd)); + } + /* French */ + if (!strcasecmp(language, "fr") ) { + return(ast_say_number_full_fr(chan, num, ints, language, audiofd, ctrlfd)); + } + if (!strcasecmp(language, "da") ) { + return(ast_say_number_full_da(chan, num, ints, language, audiofd, ctrlfd)); + } + if (!strcasecmp(language, "it") ) { + return(ast_say_number_full_it(chan, num, ints, language, audiofd, ctrlfd)); + } + + /* Default to english */ + return(ast_say_number_full_en(chan, num, ints, language, audiofd, ctrlfd)); +} + +int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language) +{ + if (!strcasecmp(language, "no") || !strcasecmp(language,"se") || !strcasecmp(language,"en") ) { + return(ast_say_number_en(chan, num, ints, language)); + } + /* French */ + if (!strcasecmp(language, "fr")) { + return(ast_say_number_fr(chan, num, ints, language)); + } + if (!strcasecmp(language, "da")) { + return(ast_say_number_da(chan, num, ints, language)); + } + if (!strcasecmp(language, "it")) { + return(ast_say_number_it(chan, num, ints, language)); + } + + /* Default to english */ + return(ast_say_number_en(chan, num, ints, language)); +} + +/* ast_say_number_full_en: English syntax */ +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; @@ -118,14 +177,14 @@ 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; @@ -144,12 +203,11 @@ ast_stopstream(chan); } - } } return res; } -int ast_say_number(struct ast_channel *chan, int num, char *ints, char *language) +int ast_say_number_en(struct ast_channel *chan, int num, char *ints, char *language) { /* XXX Should I be merged with ast_say_number_full XXX */ int res = 0; @@ -157,12 +215,7 @@ 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)) { + while(!res && (num || playh)) { if (playh) { snprintf(fn, sizeof(fn), "digits/hundred"); playh = 0; @@ -181,14 +234,14 @@ num -= ((num / 100) * 100); } else { if (num < 1000000) { - res = ast_say_number(chan, num / 1000, ints, language); + res = ast_say_number_en(chan, num / 1000, ints, language); if (res) return res; num = num % 1000; snprintf(fn, sizeof(fn), "digits/thousand"); } else { if (num < 1000000000) { - res = ast_say_number(chan, num / 1000000, ints, language); + res = ast_say_number_en(chan, num / 1000000, ints, language); if (res) return res; num = num % 1000000; @@ -207,10 +260,839 @@ ast_stopstream(chan); } - } } return res; } + + +/* ast_say_number_full_fr: French syntax */ +int ast_say_number_full_fr(struct ast_channel *chan, int num, char *ints, char *language, int audiofd, int ctrlfd) +{ + int res = 0; + int playh = 0; + int playa = 0; /* For french */ + char fn[256] = ""; + if (!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) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream(chan, ints); + ast_stopstream(chan); + } + } + return res; +} + +int ast_say_number_fr(struct ast_channel *chan, int num, char *ints, char *language) +{ + /* XXX Should I be merged with ast_say_number_full XXX */ + int res = 0; + int playh = 0; + int playa = 0; + char fn[256] = ""; + if (!num) + return ast_say_digits(chan, 0,ints, language); + + 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_fr(chan, num / 1000, ints, language); + if (res) return res; + snprintf(fn, sizeof(fn), "digits/thousand"); + num = num % 1000; + } else + if (num < 1000000000) { + res = ast_say_number_fr(chan, num / 1000000, ints, language); + 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) { + res = ast_streamfile(chan, fn, language); + if (!res) + 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: "millions", "and" and "1-and" through "9-and" + */ +int ast_say_number_full_da(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 Danish 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) { + 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 < 1000000000) { + int millions = num / 1000000; + res = ast_say_number_full_da(chan, millions, ints, language,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 < 100) + playa++; + } + } + if (!res) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); + ast_stopstream(chan); + } + + } + return res; +} + +/* Danish */ +int ast_say_number_da(struct ast_channel *chan, int num, char *ints, char *language) +{ + /* XXX Should I be merged with ast_say_number_full XXX */ + int res = 0; + int playh = 0; + int playa = 0; + char fn[256] = ""; + if (!num) + return ast_say_digits(chan, 0,ints, language); + while(!res && (num || playh || playa )) { + /* The grammer for Danish 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) { + snprintf(fn, sizeof(fn), "digits/%d", (num / 100)); + playh++; + num -= ((num / 100) * 100); + } else { + if (num < 1000000) { + res = ast_say_number_da(chan, num / 1000, ints, language); + 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_da(chan, millions, ints, language); + 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 < 100) + playa++; + } + } + + if (!res) { + res = ast_streamfile(chan, fn, language); + if (!res) + 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" */ +int ast_say_number_full_pt(struct ast_channel *chan, int num, char *ints, char *language, 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); + + /* This hack will be removed and replaced with a new option to ast_say_number* functions */ + /* Use negative numbers to force feminine */ + + if (num < 0) { /* Feminin */ + mf = -1; + num = -num; + } + + 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, 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, 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) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream(chan, ints); + ast_stopstream(chan); + } + } + return res; +} + +/*This is really french, not done yet */ +int ast_say_number_pt(struct ast_channel *chan, int num, char *ints, char *language) +{ + /* XXX Should I be merged with ast_say_number_full XXX */ + int res = 0; + int playh = 0; + int playa = 0; + char fn[256] = ""; + if (!num) + return ast_say_digits(chan, 0,ints, language); + + 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_fr(chan, num / 1000, ints, language); + if (res) return res; + snprintf(fn, sizeof(fn), "digits/thousand"); + num = num % 1000; + } else + if (num < 1000000000) { + res = ast_say_number_fr(chan, num / 1000000, ints, language); + 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) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream(chan, ints); + ast_stopstream(chan); + } + + } + return res; +} + +/* italian */ +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) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); + ast_stopstream(chan); + } + } + return res; +} + +int ast_say_number_it(struct ast_channel *chan, int num, char *ints, char *language) +{ + /* XXX Should I be merged with ast_say_number_full_it XXX */ + int res = 0; + int playh = 0; + int tempnum = 0; + char fn[256] = ""; + + if (!num) + return ast_say_digits(chan, 0,ints, language); + + /* + 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(chan, num / 1000, ints, language); + 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(chan, num / 1000000, ints, language); + 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) { + res = ast_streamfile(chan, fn, language); + if (!res) + res = ast_waitstream(chan, ints); + ast_stopstream(chan); + } + } /* end while */ + return res; +} +/* end of italian */ + int ast_say_date(struct ast_channel *chan, time_t t, char *ints, char *lang) { struct tm tm;