Merged revisions 57620 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r57620 | dhubbard | 2007-03-02 18:59:24 -0600 (Fri, 02 Mar 2007) | 1 line

submitted patch for Georgian language, issue 9010, submitted by Alexander Shaduri
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@57621 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Dwayne M. Hubbard 19 years ago
parent 746f3fcdb2
commit 26b4c4344a

@ -25,6 +25,8 @@
*
* \note 12-16-2004 : Support for Greek added by InAccess Networks (work funded by HOL, www.hol.gr) George Konstantoulakis <gkon@inaccessnetworks.com>
*
* \note 2007-02-08 : Support for Georgian added by Alexander Shaduri <ashaduri@gmail.com>,
* Next Generation Networks (NGN).
*/
#include "asterisk.h"
@ -274,6 +276,7 @@ static int say_digit_str_full(struct ast_channel *chan, const char *str, const c
\arg \b se - Swedish
\arg \b tw - Taiwanese / Chinese
\arg \b ru - Russian
\arg \b ge - Georgian
\par Gender:
For Some languages the numbers differ for gender and plural.
@ -328,6 +331,7 @@ static int ast_say_number_full_se(struct ast_channel *chan, int num, const char
static int ast_say_number_full_tw(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_ge(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
/* Forward declarations of language specific variants of ast_say_enumeration_full */
static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
@ -342,6 +346,7 @@ static int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints,
static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_with_format_en(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
static int ast_say_date_with_format_da(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone);
@ -364,6 +369,7 @@ static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints,
static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_de(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@ -373,10 +379,12 @@ static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *i
static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_from_now_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_from_now_fr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang)
{
@ -426,6 +434,8 @@ static int say_number_full(struct ast_channel *chan, int num, const char *ints,
return(ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd));
} else if (!strcasecmp(language, "ru") ) { /* Russian syntax */
return(ast_say_number_full_ru(chan, num, ints, language, options, audiofd, ctrlfd));
} else if (!strcasecmp(language, "ge") ) { /* Georgian syntax */
return(ast_say_number_full_ge(chan, num, ints, language, options, audiofd, ctrlfd));
}
/* Default to english */
@ -2724,6 +2734,8 @@ static int say_date(struct ast_channel *chan, time_t t, const char *ints, const
return(ast_say_date_pt(chan, t, ints, lang));
} else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
return(ast_say_date_gr(chan, t, ints, lang));
} else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
return(ast_say_date_ge(chan, t, ints, lang));
}
/* Default to English */
@ -5500,6 +5512,8 @@ static int say_time(struct ast_channel *chan, time_t t, const char *ints, const
return(ast_say_time_tw(chan, t, ints, lang));
} else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
return(ast_say_time_gr(chan, t, ints, lang));
} else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
return(ast_say_time_ge(chan, t, ints, lang));
}
/* Default to English */
@ -5719,6 +5733,8 @@ static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, co
return(ast_say_datetime_tw(chan, t, ints, lang));
} else if (!strcasecmp(lang, "gr") ) { /* Greek syntax */
return(ast_say_datetime_gr(chan, t, ints, lang));
} else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
return(ast_say_datetime_ge(chan, t, ints, lang));
}
/* Default to English */
@ -6002,6 +6018,8 @@ static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char
return(ast_say_datetime_from_now_fr(chan, t, ints, lang));
} else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "pt_BR")) { /* Portuguese syntax */
return(ast_say_datetime_from_now_pt(chan, t, ints, lang));
} else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */
return(ast_say_datetime_from_now_ge(chan, t, ints, lang));
}
/* Default to English */
@ -6572,6 +6590,377 @@ static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t time, co
return res;
}
/*********************************** Georgian Support ***************************************/
/*
Convert a number into a semi-localized string. Only for Georgian.
res must be of at least 256 bytes, preallocated.
The output corresponds to Georgian spoken numbers, so
it may be either converted to real words by applying a direct conversion
table, or played just by substituting the entities with played files.
Output may consist of the following tokens (separated by spaces):
0, minus.
1-9, 1_-9_. (erti, ori, sami, otxi, ... . erti, or, sam, otx, ...).
10-19.
20, 40, 60, 80, 20_, 40_, 60_, 80_. (oci, ormoci, ..., ocda, ormocda, ...).
100, 100_, 200, 200_, ..., 900, 900_. (asi, as, orasi, oras, ...).
1000, 1000_. (atasi, atas).
1000000, 1000000_. (milioni, milion).
1000000000, 1000000000_. (miliardi, miliard).
To be able to play the sounds, each of the above tokens needs
a corresponding sound file. (e.g. 200_.gsm).
*/
static char* ast_translate_number_ge(int num, char* res, int res_len)
{
char buf[256];
int digit = 0;
int remainder = 0;
if (num < 0) {
strncat(res, "minus ", res_len - strlen(res) - 1);
if ( num > INT_MIN ) {
num = -num;
} else {
num = 0;
}
}
/* directly read the numbers */
if (num <= 20 || num == 40 || num == 60 || num == 80 || num == 100) {
snprintf(buf, sizeof(buf), "%d", num);
strncat(res, buf, res_len - strlen(res) - 1);
return res;
}
if (num < 40) { /* ocda... */
strncat(res, "20_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(num - 20, res, res_len);
}
if (num < 60) { /* ormocda... */
strncat(res, "40_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(num - 40, res, res_len);
}
if (num < 80) { /* samocda... */
strncat(res, "60_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(num - 60, res, res_len);
}
if (num < 100) { /* otxmocda... */
strncat(res, "80_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(num - 80, res, res_len);
}
if (num < 1000) { /* as, oras, samas, ..., cxraas. asi, orasi, ..., cxraasi. */
remainder = num % 100;
digit = (num - remainder) / 100;
if (remainder == 0) {
snprintf(buf, sizeof(buf), "%d", num);
strncat(res, buf, res_len - strlen(res) - 1);
return res;
} else {
snprintf(buf, sizeof(buf), "%d_ ", digit*100);
strncat(res, buf, res_len - strlen(res) - 1);
return ast_translate_number_ge(remainder, res, res_len);
}
}
if (num == 1000) {
strncat(res, "1000", res_len - strlen(res) - 1);
return res;
}
if (num < 1000000) {
remainder = num % 1000;
digit = (num - remainder) / 1000;
if (remainder == 0) {
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000", res_len - strlen(res) - 1);
return res;
}
if (digit == 1) {
strncat(res, "1000_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(remainder, res, res_len);
}
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(remainder, res, res_len);
}
if (num == 1000000) {
strncat(res, "1 1000000", res_len - strlen(res) - 1);
return res;
}
if (num < 1000000000) {
remainder = num % 1000000;
digit = (num - remainder) / 1000000;
if (remainder == 0) {
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000000", res_len - strlen(res) - 1);
return res;
}
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000000_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(remainder, res, res_len);
}
if (num == 1000000000) {
strncat(res, "1 1000000000", res_len - strlen(res) - 1);
return res;
}
if (num > 1000000000) {
remainder = num % 1000000000;
digit = (num - remainder) / 1000000000;
if (remainder == 0) {
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000000000", res_len - strlen(res) - 1);
return res;
}
ast_translate_number_ge(digit, res, res_len);
strncat(res, " 1000000000_ ", res_len - strlen(res) - 1);
return ast_translate_number_ge(remainder, res, res_len);
}
return res;
}
/*! \brief ast_say_number_full_ge: Georgian syntax */
static int ast_say_number_full_ge(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
{
int res = 0;
char fn[512] = "";
if (!num)
return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
ast_translate_number_ge(num, fn, 512);
char* s = 0;
const char* remainder = fn;
while (res == 0 && (s = strstr(remainder, " "))) {
size_t len = s - remainder;
char* new_string = malloc(len + 1 + strlen("digits/"));
sprintf(new_string, "digits/");
strncat(new_string, remainder, len); /* we can't sprintf() it, it's not null-terminated. */
/* new_string[len + strlen("digits/")] = '\0'; */
if (!ast_streamfile(chan, new_string, language)) {
if ((audiofd > -1) && (ctrlfd > -1))
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
free(new_string);
remainder = s + 1; /* position just after the found space char. */
while(*remainder == ' ') /* skip multiple spaces */
remainder++;
}
/* the last chunk. */
if (res == 0 && *remainder) {
char* new_string = malloc(strlen(remainder) + 1 + strlen("digits/"));
sprintf(new_string, "digits/%s", remainder);
if (!ast_streamfile(chan, new_string, language)) {
if ((audiofd > -1) && (ctrlfd > -1))
res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
else
res = ast_waitstream(chan, ints);
}
ast_stopstream(chan);
free(new_string);
}
return res;
}
/*
Georgian support for date/time requires the following files (*.gsm):
mon-1, mon-2, ... (ianvari, tebervali, ...)
day-1, day-2, ... (orshabati, samshabati, ...)
saati_da
tsuti
tslis
*/
/* Georgian syntax. e.g. "oriatas xuti tslis 5 noemberi". */
static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
char fn[256];
int res = 0;
ast_localtime(&t,&tm,NULL);
if (!res)
res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
if (!res) {
snprintf(fn, sizeof(fn), "digits/tslis %d", tm.tm_wday);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
if (!res) {
res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
/* if (!res)
res = ast_waitstream(chan, ints);
*/
}
if (!res) {
snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
return res;
}
/* Georgian syntax. e.g. "otxi saati da eqvsi tsuti" */
static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
int res = 0;
localtime_r(&t,&tm);
res = ast_say_number(chan, tm.tm_hour, ints, lang, (char*)NULL);
if (!res) {
res = ast_streamfile(chan, "digits/saati_da", lang);
if (!res)
res = ast_waitstream(chan, ints);
}
if (tm.tm_min) {
if (!res) {
res = ast_say_number(chan, tm.tm_min, ints, lang, (char*)NULL);
if (!res) {
res = ast_streamfile(chan, "digits/tsuti", lang);
if (!res)
res = ast_waitstream(chan, ints);
}
}
}
return res;
}
/* Georgian syntax. Say date, then say time. */
static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
struct tm tm;
int res = 0;
localtime_r(&t,&tm);
res = ast_say_date(chan, t, ints, lang);
if (!res)
ast_say_time(chan, t, ints, lang);
return res;
}
/* Georgian syntax */
static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
{
int res=0;
time_t nowt;
int daydiff;
struct tm tm;
struct tm now;
char fn[256];
time(&nowt);
localtime_r(&t,&tm);
localtime_r(&nowt,&now);
daydiff = now.tm_yday - tm.tm_yday;
if ((daydiff < 0) || (daydiff > 6)) {
/* Day of month and month */
if (!res)
res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
if (!res) {
snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
} else if (daydiff) {
/* Just what day of the week */
if (!res) {
snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
res = ast_streamfile(chan, fn, lang);
if (!res)
res = ast_waitstream(chan, ints);
}
} /* Otherwise, it was today */
if (!res)
res = ast_say_time(chan, t, ints, lang);
return res;
}
/*
* remap the 'say' functions to use those in this file
*/

Loading…
Cancel
Save