mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-02 19:16:15 +00:00
func_sayfiles: Retrieve say file names
Up until now, all of the logic used to translate arguments to the Say applications has been directly coupled to playback, preventing other modules from using this logic. This refactors code in say.c and adds a SAYFILES function that can be used to retrieve the file names that would be played. These can then be used in other applications or for other purposes. Additionally, a SayMoney application and a SayOrdinal application are added. Both SayOrdinal and SayNumber are also expanded to support integers greater than one billion. ASTERISK-29531 Change-Id: If9718c89353b8e153d84add3cc4637b79585db19
This commit is contained in:
committed by
George Joseph
parent
698604a064
commit
11516e4b8e
501
main/say.c
501
main/say.c
@@ -29,6 +29,8 @@
|
||||
* Next Generation Networks (NGN).
|
||||
* \note 2007-03-20 : Support for Thai added by Dome C. <dome@tel.co.th>,
|
||||
* IP Crossing Co., Ltd.
|
||||
* \note 2021-07-26 : Refactoring to separate string buildup and playback
|
||||
* by Naveen Albert <asterisk@phreaknet.org>
|
||||
*/
|
||||
|
||||
/*** MODULEINFO
|
||||
@@ -58,9 +60,7 @@
|
||||
/* Forward declaration */
|
||||
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
|
||||
|
||||
|
||||
static int say_character_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
|
||||
{
|
||||
struct ast_str* ast_get_character_str(const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity) {
|
||||
const char *fn;
|
||||
char fnbuf[10], asciibuf[20] = "letters/ascii";
|
||||
char ltr;
|
||||
@@ -69,6 +69,12 @@ static int say_character_str_full(struct ast_channel *chan, const char *str, con
|
||||
int upper = 0;
|
||||
int lower = 0;
|
||||
|
||||
struct ast_str *filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
while (str[num] && !res) {
|
||||
fn = NULL;
|
||||
switch (str[num]) {
|
||||
@@ -154,14 +160,7 @@ static int say_character_str_full(struct ast_channel *chan, const char *str, con
|
||||
}
|
||||
if ((fn && ast_fileexists(fn, NULL, lang) > 0) ||
|
||||
(snprintf(asciibuf + 13, sizeof(asciibuf) - 13, "%d", str[num]) > 0 && ast_fileexists(asciibuf, NULL, lang) > 0 && (fn = asciibuf))) {
|
||||
res = ast_streamfile(chan, fn, lang);
|
||||
if (!res) {
|
||||
if ((audiofd > -1) && (ctrlfd > -1))
|
||||
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
|
||||
else
|
||||
res = ast_waitstream(chan, ints);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
|
||||
}
|
||||
if (upper || lower) {
|
||||
continue;
|
||||
@@ -169,18 +168,56 @@ static int say_character_str_full(struct ast_channel *chan, const char *str, con
|
||||
num++;
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
static int say_filenames(struct ast_channel *chan, const char *ints, const char *lang, int audiofd, int ctrlfd, struct ast_str *filenames)
|
||||
{
|
||||
int res = 0;
|
||||
char *files;
|
||||
const char *fn;
|
||||
|
||||
if (!filenames) {
|
||||
return -1;
|
||||
}
|
||||
files = ast_str_buffer(filenames);
|
||||
|
||||
while ((fn = strsep(&files, "&"))) {
|
||||
res = ast_streamfile(chan, fn, lang);
|
||||
if (!res) {
|
||||
if ((audiofd > -1) && (ctrlfd > -1))
|
||||
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
|
||||
else
|
||||
res = ast_waitstream(chan, ints);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
}
|
||||
|
||||
ast_free(filenames);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int say_phonetic_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, enum ast_say_case_sensitivity sensitivity, int audiofd, int ctrlfd)
|
||||
{
|
||||
struct ast_str *filenames = ast_get_character_str(str, lang, sensitivity);
|
||||
return say_filenames(chan, ints, lang, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
struct ast_str* ast_get_phonetic_str(const char *str, const char *lang)
|
||||
{
|
||||
const char *fn;
|
||||
char fnbuf[256];
|
||||
char ltr;
|
||||
int num = 0;
|
||||
int res = 0;
|
||||
|
||||
while (str[num] && !res) {
|
||||
struct ast_str *filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
while (str[num]) {
|
||||
fn = NULL;
|
||||
switch (str[num]) {
|
||||
case ('*'):
|
||||
@@ -237,29 +274,33 @@ static int say_phonetic_str_full(struct ast_channel *chan, const char *str, cons
|
||||
fn = fnbuf;
|
||||
}
|
||||
if (fn && ast_fileexists(fn, NULL, lang) > 0) {
|
||||
res = ast_streamfile(chan, fn, lang);
|
||||
if (!res) {
|
||||
if ((audiofd > -1) && (ctrlfd > -1))
|
||||
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
|
||||
else
|
||||
res = ast_waitstream(chan, ints);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
|
||||
}
|
||||
num++;
|
||||
}
|
||||
|
||||
return res;
|
||||
return filenames;
|
||||
}
|
||||
|
||||
static int say_digit_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)
|
||||
{
|
||||
struct ast_str *filenames = ast_get_phonetic_str(str, lang);
|
||||
return say_filenames(chan, ints, lang, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
struct ast_str* ast_get_digit_str(const char *str, const char *lang)
|
||||
{
|
||||
const char *fn;
|
||||
char fnbuf[256];
|
||||
int num = 0;
|
||||
int res = 0;
|
||||
|
||||
while (str[num] && !res) {
|
||||
struct ast_str *filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
while (str[num]) {
|
||||
fn = NULL;
|
||||
switch (str[num]) {
|
||||
case ('*'):
|
||||
@@ -287,19 +328,340 @@ static int say_digit_str_full(struct ast_channel *chan, const char *str, const c
|
||||
break;
|
||||
}
|
||||
if (fn && ast_fileexists(fn, NULL, lang) > 0) {
|
||||
res = ast_streamfile(chan, fn, lang);
|
||||
if (!res) {
|
||||
if ((audiofd > -1) && (ctrlfd > -1))
|
||||
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
|
||||
else
|
||||
res = ast_waitstream(chan, ints);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
ast_str_append(&filenames, 0, (num == 0 ? "%s" : "&%s"), fn);
|
||||
}
|
||||
num++;
|
||||
}
|
||||
|
||||
return res;
|
||||
return filenames;
|
||||
}
|
||||
|
||||
static int say_digit_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
|
||||
{
|
||||
struct ast_str *filenames = ast_get_digit_str(str, lang);
|
||||
return say_filenames(chan, ints, lang, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
static struct ast_str* ast_get_money_en_dollars_str(const char *str, const char *lang)
|
||||
{
|
||||
const char *fnr;
|
||||
|
||||
double dollars = 0;
|
||||
int amt, cents;
|
||||
struct ast_str *fnrecurse = NULL;
|
||||
|
||||
struct ast_str *filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
if (sscanf(str, "%30lf", &dollars) != 1) {
|
||||
amt = 0;
|
||||
} else { /* convert everything to cents */
|
||||
amt = dollars * 100;
|
||||
}
|
||||
|
||||
/* Just the cents after the dollar decimal point */
|
||||
cents = amt - (((int) dollars) * 100);
|
||||
ast_debug(1, "Cents is %d, amount is %d\n", cents, amt);
|
||||
|
||||
if (amt >= 100) {
|
||||
fnrecurse = ast_get_number_str((amt / 100), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_WARNING, "Couldn't get string for dollars\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, "%s", fnr);
|
||||
}
|
||||
|
||||
/* If this is it, end on a down pitch, otherwise up pitch */
|
||||
if (amt < 200) {
|
||||
ast_str_append(&filenames, 0, "&%s", (cents > 0) ? "letters/dollar_" : "letters/dollar");
|
||||
} else {
|
||||
ast_str_append(&filenames, 0, "&%s", "dollars");
|
||||
}
|
||||
|
||||
/* If dollars and cents, add "and" in the middle */
|
||||
if (cents > 0) {
|
||||
ast_str_append(&filenames, 0, "&%s", "and");
|
||||
}
|
||||
}
|
||||
|
||||
if (cents > 0) {
|
||||
fnrecurse = ast_get_number_str(cents, lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for cents\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (amt < 100 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
ast_str_append(&filenames, 0, "&%s", (cents == 1) ? "cent" : "cents");
|
||||
} else if (amt == 0) {
|
||||
fnrecurse = ast_get_digit_str("0", lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for cents\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, "%s", fnr);
|
||||
}
|
||||
ast_str_append(&filenames, 0, "&%s", "cents");
|
||||
}
|
||||
|
||||
if (fnrecurse) {
|
||||
ast_free(fnrecurse);
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
/*! \brief ast_get_money_str: call language-specific functions */
|
||||
struct ast_str* ast_get_money_str(const char *str, const char *lang)
|
||||
{
|
||||
if (!strncasecmp(lang, "en", 2)) { /* English syntax */
|
||||
return ast_get_money_en_dollars_str(str, lang);
|
||||
}
|
||||
|
||||
ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to US Dollars\n", lang);
|
||||
/* Default to english */
|
||||
return ast_get_money_en_dollars_str(str, lang);
|
||||
}
|
||||
|
||||
static int say_money_str_full(struct ast_channel *chan, const char *str, const char *ints, const char *lang, int audiofd, int ctrlfd)
|
||||
{
|
||||
struct ast_str *filenames = ast_get_money_str(str, lang);
|
||||
return say_filenames(chan, ints, lang, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
static struct ast_str* get_number_str_en(int num, const char *lang)
|
||||
{
|
||||
const char *fnr;
|
||||
int loops = 0;
|
||||
|
||||
int res = 0;
|
||||
int playh = 0;
|
||||
char fn[256] = "";
|
||||
|
||||
struct ast_str *filenames;
|
||||
|
||||
if (!num) {
|
||||
return ast_get_digit_str("0", lang);
|
||||
}
|
||||
|
||||
filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
while (!res && (num || playh)) {
|
||||
if (num < 0) {
|
||||
ast_copy_string(fn, "digits/minus", sizeof(fn));
|
||||
if ( num > INT_MIN ) {
|
||||
num = -num;
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
} else if (playh) {
|
||||
ast_copy_string(fn, "digits/hundred", sizeof(fn));
|
||||
playh = 0;
|
||||
} else if (num < 20) {
|
||||
snprintf(fn, sizeof(fn), "digits/%d", num);
|
||||
num = 0;
|
||||
} else if (num < 100) {
|
||||
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
|
||||
num %= 10;
|
||||
} else {
|
||||
if (num < 1000){
|
||||
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
|
||||
playh++;
|
||||
num %= 100;
|
||||
} else {
|
||||
struct ast_str *fnrecurse = NULL;
|
||||
if (num < 1000000) { /* 1,000,000 */
|
||||
fnrecurse = get_number_str_en((num / 1000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000;
|
||||
snprintf(fn, sizeof(fn), "&digits/thousand");
|
||||
} else {
|
||||
if (num < 1000000000) { /* 1,000,000,000 */
|
||||
fnrecurse = get_number_str_en((num / 1000000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000000;
|
||||
ast_copy_string(fn, "&digits/million", sizeof(fn));
|
||||
} else {
|
||||
if (num < INT_MAX) {
|
||||
fnrecurse = get_number_str_en((num / 1000000000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000000000;
|
||||
ast_copy_string(fn, "&digits/billion", sizeof(fn));
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Number '%d' is too big for me\n", num);
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fnrecurse) {
|
||||
ast_free(fnrecurse);
|
||||
}
|
||||
/* we already decided whether or not to add an &, don't add another one immediately */
|
||||
loops = 0;
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fn);
|
||||
loops++;
|
||||
}
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
/*! \brief ast_get_number_str: call language-specific functions */
|
||||
struct ast_str* ast_get_number_str(int num, const char *lang)
|
||||
{
|
||||
if (!strncasecmp(lang, "en", 2)) { /* English syntax */
|
||||
return get_number_str_en(num, lang);
|
||||
}
|
||||
|
||||
ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
|
||||
/* Default to english */
|
||||
return get_number_str_en(num, lang);
|
||||
}
|
||||
|
||||
static struct ast_str* get_ordinal_str_en(int num, const char *lang)
|
||||
{
|
||||
const char *fnr;
|
||||
int loops = 0;
|
||||
|
||||
int res = 0;
|
||||
int playh = 0;
|
||||
char fn[256] = "";
|
||||
|
||||
struct ast_str *filenames;
|
||||
|
||||
if (!num) {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
filenames = ast_str_create(20);
|
||||
if (!filenames) {
|
||||
return NULL;
|
||||
}
|
||||
ast_str_reset(filenames);
|
||||
|
||||
while (!res && (num || playh)) {
|
||||
if (num < 0) {
|
||||
ast_copy_string(fn, "digits/minus", sizeof(fn));
|
||||
if ( num > INT_MIN ) {
|
||||
num = -num;
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
} else if (playh) {
|
||||
ast_copy_string(fn, (num % 100 == 0) ? "digits/h-hundred" : "digits/hundred", sizeof(fn));
|
||||
playh = 0;
|
||||
} else if (num < 20) {
|
||||
if (num > 0) {
|
||||
snprintf(fn, sizeof(fn), "digits/h-%d", num);
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Unsupported ordinal number: %d\n", num);
|
||||
}
|
||||
num = 0;
|
||||
} else if (num < 100) {
|
||||
int base = (num / 10) * 10;
|
||||
if (base != num) {
|
||||
snprintf(fn, sizeof(fn), "digits/%d", base);
|
||||
} else {
|
||||
snprintf(fn, sizeof(fn), "digits/h-%d", base);
|
||||
}
|
||||
num %= 10;
|
||||
} else {
|
||||
if (num < 1000){
|
||||
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
|
||||
playh++;
|
||||
num %= 100;
|
||||
} else {
|
||||
struct ast_str *fnrecurse = NULL;
|
||||
if (num < 1000000) { /* 1,000,000 */
|
||||
fnrecurse = get_number_str_en((num / 1000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000;
|
||||
snprintf(fn, sizeof(fn), (num % 1000 == 0) ? "&digits/h-thousand" : "&digits/thousand");
|
||||
} else {
|
||||
if (num < 1000000000) { /* 1,000,000,000 */
|
||||
fnrecurse = get_number_str_en((num / 1000000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000000;
|
||||
ast_copy_string(fn, (num % 1000000 == 0) ? "&digits/h-million" : "&digits/million", sizeof(fn));
|
||||
} else {
|
||||
if (num < INT_MAX) {
|
||||
fnrecurse = get_number_str_en((num / 1000000000), lang);
|
||||
if (!fnrecurse) {
|
||||
ast_log(LOG_ERROR, "Couldn't get string for num\n");
|
||||
} else {
|
||||
fnr = ast_str_buffer(fnrecurse);
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fnr);
|
||||
}
|
||||
num %= 1000000000;
|
||||
ast_copy_string(fn, (num % 1000000000 == 0) ? "&digits/h-billion" : "&digits/billion", sizeof(fn));
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "Number '%d' is too big for me\n", num);
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fnrecurse) {
|
||||
ast_free(fnrecurse);
|
||||
}
|
||||
/* we already decided whether or not to add an &, don't add another one immediately */
|
||||
loops = 0;
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
ast_str_append(&filenames, 0, (loops == 0 ? "%s" : "&%s"), fn);
|
||||
loops++;
|
||||
}
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
/*! \brief ast_get_ordinal_str: call language-specific functions */
|
||||
struct ast_str* ast_get_ordinal_str(int num, const char *lang)
|
||||
{
|
||||
if (!strncasecmp(lang, "en", 2)) { /* English syntax */
|
||||
return get_ordinal_str_en(num, lang);
|
||||
}
|
||||
|
||||
ast_log(LOG_WARNING, "Language %s not currently supported, defaulting to English\n", lang);
|
||||
/* Default to english */
|
||||
return get_ordinal_str_en(num, lang);
|
||||
}
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -564,66 +926,15 @@ static int say_number_full(struct ast_channel *chan, int num, const char *ints,
|
||||
\note 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, const char *ints, const 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);
|
||||
struct ast_str *filenames = ast_get_number_str(num, language);
|
||||
return say_filenames(chan, ints, language, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
while (!res && (num || playh)) {
|
||||
if (num < 0) {
|
||||
ast_copy_string(fn, "digits/minus", sizeof(fn));
|
||||
if ( num > INT_MIN ) {
|
||||
num = -num;
|
||||
} else {
|
||||
num = 0;
|
||||
}
|
||||
} else if (playh) {
|
||||
ast_copy_string(fn, "digits/hundred", sizeof(fn));
|
||||
playh = 0;
|
||||
} else if (num < 20) {
|
||||
snprintf(fn, sizeof(fn), "digits/%d", num);
|
||||
num = 0;
|
||||
} else if (num < 100) {
|
||||
snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
|
||||
num %= 10;
|
||||
} else {
|
||||
if (num < 1000){
|
||||
snprintf(fn, sizeof(fn), "digits/%d", (num/100));
|
||||
playh++;
|
||||
num %= 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 %= 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 %= 1000000;
|
||||
ast_copy_string(fn, "digits/million", sizeof(fn));
|
||||
} else {
|
||||
ast_debug(1, "Number '%d' is too big for me\n", num);
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!res) {
|
||||
if (!ast_streamfile(chan, fn, language)) {
|
||||
if ((audiofd > -1) && (ctrlfd > -1))
|
||||
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
|
||||
else
|
||||
res = ast_waitstream(chan, ints);
|
||||
}
|
||||
ast_stopstream(chan);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
/*! \brief say_ordinal_full */
|
||||
static int say_ordinal_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
|
||||
{
|
||||
struct ast_str *filenames = ast_get_ordinal_str(num, language);
|
||||
return say_filenames(chan, ints, language, audiofd, ctrlfd, filenames);
|
||||
}
|
||||
|
||||
static int exp10_int(int power)
|
||||
@@ -9482,8 +9793,10 @@ int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adje
|
||||
static void __attribute__((constructor)) __say_init(void)
|
||||
{
|
||||
ast_say_number_full = say_number_full;
|
||||
ast_say_ordinal_full = say_ordinal_full;
|
||||
ast_say_enumeration_full = say_enumeration_full;
|
||||
ast_say_digit_str_full = say_digit_str_full;
|
||||
ast_say_money_str_full = say_money_str_full;
|
||||
ast_say_character_str_full = say_character_str_full;
|
||||
ast_say_phonetic_str_full = say_phonetic_str_full;
|
||||
ast_say_datetime = say_datetime;
|
||||
|
Reference in New Issue
Block a user