consolidate API functions for saying numbers/digits/alpha/phonetic into less functions, using more efficient and clearer code (inspired by bug #4414)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5819 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Kevin P. Fleming 20 years ago
parent 6cb7849dcb
commit c0ff0e340b

@ -1126,8 +1126,6 @@ char ast_waitstream_full(struct ast_channel *c, const char *breakon, int audiofd
ast_frfree(fr); ast_frfree(fr);
} }
ast_sched_runq(c->sched); ast_sched_runq(c->sched);
} }
return (c->_softhangup ? -1 : 0); return (c->_softhangup ? -1 : 0);
} }

499
say.c

@ -39,377 +39,228 @@
/* Forward declaration */ /* Forward declaration */
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang); static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang);
int ast_say_digit_str(struct ast_channel *chan, const char *fn2, const char *ints, 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)
{ {
/* XXX Merge with full version? XXX */ const char *fn;
char fn[256] = ""; char fnbuf[256];
int num = 0;
int res = 0;
while(fn2[num] && !res) {
fn[0] = '\0';
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('-'):
snprintf(fn, sizeof(fn), "digits/minus");
break;
default:
if((fn2[num] >= '0') && (fn2[num] <= '9')){ /* Must be in {0-9} */
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
}
}
if(!ast_strlen_zero(fn)){ /* if length == 0, then skip this digit as it is invalid */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
ast_stopstream(chan);
}
num++;
}
return res;
}
int ast_say_character_str(struct ast_channel *chan, const char *fn2, const char *ints, const char *lang)
{
/* XXX Merge with full version? XXX */
char fn[256] = "";
char ltr; char ltr;
int num = 0; int num = 0;
int res = 0; int res = 0;
while(fn2[num] && !res) {
fn[0] = '\0';
switch (fn2[num]) {
case ('*'):
snprintf(fn, sizeof(fn), "digits/star");
break;
case ('#'):
snprintf(fn, sizeof(fn), "digits/pound");
break;
case ('0'):
case ('1'):
case ('2'):
case ('3'):
case ('4'):
case ('5'):
case ('6'):
case ('7'):
case ('8'):
case ('9'):
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
break;
case ('!'):
strncpy(fn, "letters/exclaimation-point", sizeof(fn));
break;
case ('@'):
strncpy(fn, "letters/at", sizeof(fn));
break;
case ('$'):
strncpy(fn, "letters/dollar", sizeof(fn));
break;
case ('-'):
strncpy(fn, "letters/dash", sizeof(fn));
break;
case ('.'):
strncpy(fn, "letters/dot", sizeof(fn));
break;
case ('='):
strncpy(fn, "letters/equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "letters/plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "letters/slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "letters/space", sizeof(fn));
break;
default:
ltr = fn2[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
snprintf(fn, sizeof(fn), "letters/%c", ltr);
}
if(!ast_strlen_zero(fn)) { /* if length == 0, then skip this digit as it is invalid */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
} ast_stopstream(chan);
num++;
}
return res;
}
int ast_say_phonetic_str(struct ast_channel *chan, const char *fn2, const char *ints, const char *lang) while (str[num]) {
{ fn = NULL;
/* XXX Merge with full version? XXX */ switch (str[num]) {
char fn[256] = ""; case ('*'):
char ltr; fn = "digits/star";
int num = 0; break;
int res = 0; case ('#'):
int temp; fn = "digits/pound";
int play; break;
char hex[3]; case ('!'):
/* while(fn2[num] && !res) { */ fn = "letters/exclaimation-point";
while(fn2[num]) { break;
play=1; case ('@'):
switch (fn2[num]) { fn = "letters/at";
case ('*'): break;
snprintf(fn, sizeof(fn), "digits/star"); case ('$'):
break; fn = "letters/dollar";
case ('#'): break;
snprintf(fn, sizeof(fn), "digits/pound"); case ('-'):
break; fn = "letters/dash";
case ('0'): break;
case ('1'): case ('.'):
case ('2'): fn = "letters/dot";
case ('3'): break;
case ('4'): case ('='):
case ('5'): fn = "letters/equals";
case ('6'): break;
case ('7'): case ('+'):
case ('8'): fn = "letters/plus";
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); break;
break; case ('/'):
case ('!'): fn = "letters/slash";
strncpy(fn, "letters/exclaimation-point", sizeof(fn)); break;
break; case (' '):
case ('@'): fn = "letters/space";
strncpy(fn, "letters/at", sizeof(fn)); break;
break; case ('0'):
case ('$'): case ('1'):
strncpy(fn, "letters/dollar", sizeof(fn)); case ('2'):
break; case ('3'):
case ('-'): case ('4'):
strncpy(fn, "letters/dash", sizeof(fn)); case ('5'):
break; case ('6'):
case ('.'): case ('7'):
strncpy(fn, "letters/dot", sizeof(fn)); case ('8'):
break; strcpy(fnbuf, "digits/X");
case ('='): fnbuf[7] = str[num];
strncpy(fn, "letters/equals", sizeof(fn)); fn = fnbuf;
break; break;
case ('+'): default: /* '9' falls here... */
strncpy(fn, "letters/plus", sizeof(fn)); ltr = str[num];
break; if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
case ('/'): strcpy(fnbuf, "letters/X");
strncpy(fn, "letters/slash", sizeof(fn)); fnbuf[8] = ltr;
break; fn = fnbuf;
case (' '):
strncpy(fn, "letters/space", sizeof(fn));
break;
case ('%'):
play=0;
/* check if we have 2 chars after the % */
if (strlen(fn2) > num+2)
{
hex[0]=fn2[num+1];
hex[1]=fn2[num+2];
hex[2]='\0';
if (sscanf(hex,"%x", &temp))
{ /* Hex to char convertion successfull */
num++;
if (temp==37)
{ /* If it is a percent, play it now */
strncpy(fn, "percent", sizeof(fn));
num++;
play=1;
}
/* check for invalid characters */
if ((temp<32) || (temp>126))
{
num++;
}
}
}
else
num++;
break;
default: /* '9' falls through to here, too */
ltr = tolower(fn2[num]);
snprintf(fn, sizeof(fn), "phonetic/%c_p", ltr);
}
if (play)
{
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
ast_stopstream(chan);
} }
num++;
}
return res;
}
int ast_say_digit_str_full(struct ast_channel *chan, const char *fn2, const char *ints, const char *lang, int audiofd, int ctrlfd)
{
char fn[256] = "";
int num = 0;
int res = 0;
while(fn2[num] && !res) {
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]);
res = ast_streamfile(chan, fn, lang); res = ast_streamfile(chan, fn, lang);
if (!res) if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan); ast_stopstream(chan);
num++; num++;
} }
return res; return res;
} }
int ast_say_character_str_full(struct ast_channel *chan, const char *fn2, const char *ints, const char *lang, int audiofd, int ctrlfd) int ast_say_character_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
{ {
char fn[256] = ""; 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)
{
const char *fn;
char fnbuf[256];
char ltr; char ltr;
int num = 0; int num = 0;
int res = 0; int res = 0;
while(fn2[num] && !res) {
switch (fn2[num]) { while (str[num]) {
case ('*'): fn = NULL;
snprintf(fn, sizeof(fn), "digits/star"); switch (str[num]) {
break; case ('*'):
case ('#'): fn = "digits/star";
snprintf(fn, sizeof(fn), "digits/pound"); break;
break; case ('#'):
case ('0'): fn = "digits/pound";
case ('1'): break;
case ('2'): case ('!'):
case ('3'): fn = "letters/exclaimation-point";
case ('4'): break;
case ('5'): case ('@'):
case ('6'): fn = "letters/at";
case ('7'): break;
case ('8'): case ('$'):
case ('9'): fn = "letters/dollar";
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); break;
break; case ('-'):
case ('!'): fn = "letters/dash";
strncpy(fn, "letters/exclaimation-point", sizeof(fn)); break;
break; case ('.'):
case ('@'): fn = "letters/dot";
strncpy(fn, "letters/at", sizeof(fn)); break;
break; case ('='):
case ('$'): fn = "letters/equals";
strncpy(fn, "letters/dollar", sizeof(fn)); break;
break; case ('+'):
case ('-'): fn = "letters/plus";
strncpy(fn, "letters/dash", sizeof(fn)); break;
break; case ('/'):
case ('.'): fn = "letters/slash";
strncpy(fn, "letters/dot", sizeof(fn)); break;
break; case (' '):
case ('='): fn = "letters/space";
strncpy(fn, "letters/equals", sizeof(fn)); break;
break; case ('0'):
case ('+'): case ('1'):
strncpy(fn, "letters/plus", sizeof(fn)); case ('2'):
break; case ('3'):
case ('/'): case ('4'):
strncpy(fn, "letters/slash", sizeof(fn)); case ('5'):
break; case ('6'):
case (' '): case ('7'):
strncpy(fn, "letters/space", sizeof(fn)); case ('8'):
break; strcpy(fnbuf, "digits/X");
default: fnbuf[7] = str[num];
ltr = fn2[num]; fn = fnbuf;
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */ break;
snprintf(fn, sizeof(fn), "letters/%c", ltr); default: /* '9' falls here... */
ltr = str[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
strcpy(fnbuf, "phonetic/X_p");
fnbuf[9] = ltr;
fn = fnbuf;
} }
/* snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); */
res = ast_streamfile(chan, fn, lang); res = ast_streamfile(chan, fn, lang);
if (!res) if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan); ast_stopstream(chan);
num++; num++;
} }
return res; return res;
} }
int ast_say_phonetic_str_full(struct ast_channel *chan, const char *fn2, const char *ints, const char *lang, int audiofd, int ctrlfd) int ast_say_phonetic_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
{ {
char fn[256] = ""; return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
char ltr; }
int ast_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];
int num = 0; int num = 0;
int res = 0; int res = 0;
while(fn2[num] && !res) {
switch (fn2[num]) { while (str[num]) {
case ('*'): fn = NULL;
snprintf(fn, sizeof(fn), "digits/star"); switch (str[num]) {
break; case ('*'):
case ('#'): fn = "digits/star";
snprintf(fn, sizeof(fn), "digits/pound"); break;
break; case ('#'):
case ('0'): fn = "digits/pound";
case ('1'): break;
case ('2'): case ('-'):
case ('3'): fn = "digits/minus";
case ('4'): break;
case ('5'): case '0':
case ('6'): case '1':
case ('7'): case '2':
case ('8'): case '3':
snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); case '4':
break; case '5':
case ('!'): case '6':
strncpy(fn, "letters/exclaimation-point", sizeof(fn)); case '7':
break; case '8':
case ('@'): case '9':
strncpy(fn, "letters/at", sizeof(fn)); strcpy(fnbuf, "digits/X");
break; fnbuf[7] = str[num];
case ('$'): fn = fnbuf;
strncpy(fn, "letters/dollar", sizeof(fn)); break;
break; }
case ('-'): if (fn) {
strncpy(fn, "letters/dash", sizeof(fn)); res = ast_streamfile(chan, fn, lang);
break; if (!res)
case ('.'): res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
strncpy(fn, "letters/dot", sizeof(fn)); ast_stopstream(chan);
break; }
case ('='):
strncpy(fn, "letters/equals", sizeof(fn));
break;
case ('+'):
strncpy(fn, "letters/plus", sizeof(fn));
break;
case ('/'):
strncpy(fn, "letters/slash", sizeof(fn));
break;
case (' '):
strncpy(fn, "letters/space", sizeof(fn));
break;
default: /* '9' falls here... */
ltr = fn2[num];
if ('A' <= ltr && ltr <= 'Z') ltr += 'a' - 'A'; /* file names are all lower-case */
snprintf(fn, sizeof(fn), "phonetic/%c", ltr);
}
/* snprintf(fn, sizeof(fn), "digits/%c", fn2[num]); */
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
ast_stopstream(chan);
num++; num++;
} }
return res; return res;
} }
int ast_say_digits(struct ast_channel *chan, int num, const char *ints, const char *lang) int ast_say_digit_str(struct ast_channel *chan, const char *str, const char *ints, const char *lang)
{ {
/* XXX Should I be merged with say_digits_full XXX */ return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
char fn2[256];
snprintf(fn2, sizeof(fn2), "%d", num);
return ast_say_digit_str(chan, fn2, ints, lang);
} }
int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd) int ast_say_digits_full(struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
{ {
char fn2[256]; char fn2[256];
snprintf(fn2, sizeof(fn2), "%d", num); snprintf(fn2, sizeof(fn2), "%d", num);
return ast_say_digit_str_full(chan, fn2, ints, lang, audiofd, ctrlfd); 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)
{
return ast_say_digits_full(chan, num, ints, lang, -1, -1);
}
/* Forward declarations */ /* Forward declarations */
/* Syntaxes supported, not really language codes. /* Syntaxes supported, not really language codes.
da - Danish da - Danish

Loading…
Cancel
Save