From a06ab7b648e0da0cb1f0af92b1a5bf9627c02e4f Mon Sep 17 00:00:00 2001 From: Tilghman Lesher Date: Wed, 18 Jun 2008 22:17:17 +0000 Subject: [PATCH] Merged revisions 123769 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r123769 | tilghman | 2008-06-18 17:08:30 -0500 (Wed, 18 Jun 2008) | 8 lines Add support for saying numbers in Hebrew. (closes issue #11662) Reported by: greenfieldtech Patches: say.c.patch-12042008 uploaded by greenfieldtech (license 369) Hebrew-Sounds.ods uploaded by greenfieldtech (with signficant changes to the spreadsheet by me) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@123770 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- doc/lang/hebrew.ods | Bin 0 -> 23290 bytes main/say.c | 572 +++++++++++++++++++++++++++++++++----------- 2 files changed, 429 insertions(+), 143 deletions(-) create mode 100644 doc/lang/hebrew.ods diff --git a/doc/lang/hebrew.ods b/doc/lang/hebrew.ods new file mode 100644 index 0000000000000000000000000000000000000000..f8b0f54df5a785250c843fd3461520f2d16d5cbc GIT binary patch literal 23290 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 JIMlm7`WHBpidp~w literal 0 HcmV?d00001 diff --git a/main/say.c b/main/say.c index 9a8e7d5360..46538b0622 100644 --- a/main/say.c +++ b/main/say.c @@ -353,6 +353,7 @@ static int ast_say_number_full_th(struct ast_channel *chan, int num, const char static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd); static int ast_say_enumeration_full_da(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd); static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd); +static int ast_say_enumeration_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd); /* Forward declarations of ast_say_date, ast_say_datetime and ast_say_time functions */ static int ast_say_date_en(struct ast_channel *chan, time_t t, const char *ints, const char *lang); @@ -365,6 +366,7 @@ static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, static int ast_say_date_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang); +static int ast_say_date_he(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); @@ -391,6 +393,7 @@ static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, static int ast_say_time_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang); +static int ast_say_time_he(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); @@ -403,11 +406,13 @@ static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *i static int ast_say_datetime_ge(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang); static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang); +static int ast_say_datetime_he(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 ast_say_datetime_from_now_he(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) { @@ -1180,147 +1185,169 @@ static int ast_say_number_full_fr(struct ast_channel *chan, int num, const char -/*! \brief ast_say_number_full_he: Hebrew syntax */ -/* Extra sounds needed: - 1F: feminin 'one' - ve: 'and' - 1hundred: 1 hundred - 2hundred: 2 hundreds - 2thousands: 2 thousand - thousands: plural of 'thousand' - 3sF 'Smichut forms (female) - 4sF - 5sF - 6sF - 7sF - 8sF - 9sF - 3s 'Smichut' forms (male) - 4s - 5s - 6s - 7s - 9s - 10s - 11s - 12s - 13s - 14s - 15s - 16s - 17s - 18s - 19s - -TODO: 've' should sometimed be 'hu': -* before 'shtaym' (2, F) -* before 'shnaym' (2, M) -* before 'shlosha' (3, M) -* before 'shmone' (8, M) -* before 'shlosim' (30) -* before 'shmonim' (80) - -What about: -'sheva' (7, F)? -'tesha' (9, F)? -*/ +/* Hebrew syntax */ +/* Check doc/lang/hebrew-digits.txt for information about the various + * recordings required to make this translation work properly */ #define SAY_NUM_BUF_SIZE 256 -static int ast_say_number_full_he(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_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd) { int res = 0; - int state = 0; /* no need to save anything */ - int mf = 1; /* +1 = Masculin; -1 = Feminin */ + int state = 0; /* no need to save anything */ + int mf = -1; /* +1 = Masculin; -1 = Feminin */ + int tmpnum = 0; + char fn[SAY_NUM_BUF_SIZE] = ""; - ast_debug(3, "ast_say_digits_full: started. " - "num: %d, options=\"%s\"\n", - num, options - ); - if (!num) + + ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options); + + if (!num) { return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd); - - if (options && !strncasecmp(options, "f", 1)) - mf = -1; + } + if (options && !strncasecmp(options, "m", 1)) { + mf = 1; + } + ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d\n", num, state, options, mf); /* Do we have work to do? */ - while (!res && (num || (state>0) )) { + while (!res && (num || (state > 0))) { /* first type of work: play a second sound. In this loop - * we can only play one sound file at a time. Thus playing - * a second one requires repeating the loop just for the + * we can only play one sound file at a time. Thus playing + * a second one requires repeating the loop just for the * second file. The variable 'state' remembers where we were. * state==0 is the normal mode and it means that we continue * to check if the number num has yet anything left. */ - ast_debug(3, "ast_say_digits_full: num: %d, " - "state=%d, options=\"%s\", mf=%d\n", - num, state, options, mf - ); + ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, state=%d, options=\"%s\", mf=%d, tmpnum=%d\n", num, state, options, mf, tmpnum); + if (state == 1) { - ast_copy_string(fn, "digits/hundred", sizeof(fn)); state = 0; } else if (state == 2) { - ast_copy_string(fn, "digits/ve", sizeof(fn)); + if ((num >= 11) && (num < 21)) { + if (mf < 0) { + snprintf(fn, sizeof(fn), "digits/ve"); + } else { + snprintf(fn, sizeof(fn), "digits/uu"); + } + } else { + switch (num) { + case 1: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 2: + snprintf(fn, sizeof(fn), "digits/uu"); + break; + case 3: + if (mf < 0) { + snprintf(fn, sizeof(fn), "digits/ve"); + } else { + snprintf(fn, sizeof(fn), "digits/uu"); + } + break; + case 4: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 5: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 6: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 7: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 8: + snprintf(fn, sizeof(fn), "digits/uu"); + break; + case 9: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + case 10: + snprintf(fn, sizeof(fn), "digits/ve"); + break; + } + } state = 0; } else if (state == 3) { - ast_copy_string(fn, "digits/thousands", sizeof(fn)); - state=0; - } else if (num < 21) { - if (mf < 0) - snprintf(fn, sizeof(fn), "digits/%dF", num); - else + snprintf(fn, sizeof(fn), "digits/1k"); + state = 0; + } else if (num < 0) { + snprintf(fn, sizeof(fn), "digits/minus"); + num = (-1) * num; + } else if (num < 20) { + if (mf < 0) { snprintf(fn, sizeof(fn), "digits/%d", num); + } else { + snprintf(fn, sizeof(fn), "digits/%dm", num); + } num = 0; - } else if (num < 100) { + } else if ((num < 100) && (num >= 20)) { snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10); num = num % 10; - if (num > 0) state = 2; - } else if (num < 200) { - ast_copy_string(fn, "digits/1hundred", sizeof(fn)); - num = num - 100; - state = 2; - } else if (num < 300) { - ast_copy_string(fn, "digits/2hundred", sizeof(fn)); - num = num - 200; - state = 2; - } else if (num < 1000) { - snprintf(fn, sizeof(fn), "digits/%d", (num / 100)); - state = 1; - num = num % 100; - } else if (num < 2000) { - ast_copy_string(fn, "digits/thousand", sizeof(fn)); - num = num - 1000; - } else if (num < 3000) { - ast_copy_string(fn, "digits/2thousand", sizeof(fn)); - num = num - 2000; - if (num > 0) + if (num > 0) { + state = 2; + } + } else if ((num >= 100) && (num < 1000)) { + tmpnum = num / 100; + snprintf(fn, sizeof(fn), "digits/%d00", tmpnum); + num = num - (tmpnum * 100); + if ((num > 0) && (num < 11)) { + state = 2; + } + } else if ((num >= 1000) && (num < 10000)) { + tmpnum = num / 1000; + snprintf(fn, sizeof(fn), "digits/%dk", tmpnum); + num = num - (tmpnum * 1000); + if ((num > 0) && (num < 11)) { state = 2; + } } else if (num < 20000) { - snprintf(fn, sizeof(fn), "digits/%ds", (num / 1000)); + snprintf(fn, sizeof(fn), "digits/%dm", (num / 1000)); num = num % 1000; state = 3; } else if (num < 1000000) { - res = ast_say_number_full_he(chan, num / 1000, ints, language, options, audiofd, ctrlfd); - if (res) + res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd); + if (res) { return res; - ast_copy_string(fn, "digits/thousand", sizeof(fn)); + } + snprintf(fn, sizeof(fn), "digits/1k"); num = num % 1000; - } else if (num < 1000000000) { - res = ast_say_number_full_he(chan, num / 1000000, ints, language, options, audiofd, ctrlfd); - if (res) + if ((num > 0) && (num < 11)) { + state = 2; + } + } else if (num < 2000000) { + snprintf(fn, sizeof(fn), "digits/million"); + num = num % 1000000; + if ((num > 0) && (num < 11)) { + state = 2; + } + } else if (num < 3000000) { + snprintf(fn, sizeof(fn), "digits/twomillion"); + num = num - 2000000; + if ((num > 0) && (num < 11)) { + state = 2; + } + } else if (num < 1000000000) { + res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd); + if (res) { return res; - ast_copy_string(fn, "digits/million", sizeof(fn)); + } + snprintf(fn, sizeof(fn), "digits/million"); num = num % 1000000; + if ((num > 0) && (num < 11)) { + state = 2; + } } else { ast_debug(1, "Number '%d' is too big for me\n", num); res = -1; } + tmpnum = 0; if (!res) { if (!ast_streamfile(chan, fn, language)) { - if ((audiofd > -1) && (ctrlfd > -1)) + if ((audiofd > -1) && (ctrlfd > -1)) { res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); - else + } else { res = ast_waitstream(chan, ints); + } } ast_stopstream(chan); } @@ -2461,6 +2488,8 @@ static int say_enumeration_full(struct ast_channel *chan, int num, const char *i return(ast_say_enumeration_full_da(chan, num, ints, language, options, audiofd, ctrlfd)); } else if (!strcasecmp(language, "de") ) { /* German syntax */ return(ast_say_enumeration_full_de(chan, num, ints, language, options, audiofd, ctrlfd)); + } else if (!strcasecmp(language, "he")) { /* Hebrew syntax */ + return (ast_say_enumeration_full_he(chan, num, ints, language, options, audiofd, ctrlfd)); } /* Default to english */ @@ -2892,6 +2921,94 @@ static int ast_say_enumeration_full_de(struct ast_channel *chan, int num, const return res; } +static int ast_say_enumeration_full_he(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd) +{ + int res = 0; + char fn[256] = ""; + int mf = -1; /* +1 = Masculin; -1 = Feminin */ + ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: started. num: %d, options=\"%s\"\n", num, options); + + if (options && !strncasecmp(options, "m", 1)) { + mf = -1; + } + + ast_verbose(VERBOSE_PREFIX_3 "ast_say_digits_full: num: %d, options=\"%s\", mf=%d\n", num, options, mf); + + while (!res && num) { + if (num < 0) { + snprintf(fn, sizeof(fn), "digits/minus"); /* kind of senseless for enumerations, but our best effort for error checking */ + if (num > INT_MIN) { + num = -num; + } else { + num = 0; + } + } else if (num < 21) { + if (mf < 0) { + if (num < 10) { + snprintf(fn, sizeof(fn), "digits/f-0%d", num); + } else { + snprintf(fn, sizeof(fn), "digits/f-%d", num); + } + } else { + if (num < 10) { + snprintf(fn, sizeof(fn), "digits/m-0%d", num); + } else { + snprintf(fn, sizeof(fn), "digits/m-%d", num); + } + } + num = 0; + } else if ((num < 100) && num >= 20) { + snprintf(fn, sizeof(fn), "digits/%d", (num / 10) * 10); + num = num % 10; + } else if ((num >= 100) && (num < 1000)) { + int tmpnum = num / 100; + snprintf(fn, sizeof(fn), "digits/%d00", tmpnum); + num = num - (tmpnum * 100); + } else if ((num >= 1000) && (num < 10000)) { + int tmpnum = num / 1000; + snprintf(fn, sizeof(fn), "digits/%dk", tmpnum); + num = num - (tmpnum * 1000); + } else if (num < 20000) { + snprintf(fn, sizeof(fn), "digits/m-%d", (num / 1000)); + num = num % 1000; + } else if (num < 1000000) { + res = ast_say_number_full_he(chan, num / 1000, ints, language, "m", audiofd, ctrlfd); + if (res) { + return res; + } + snprintf(fn, sizeof(fn), "digits/1k"); + num = num % 1000; + } else if (num < 2000000) { + snprintf(fn, sizeof(fn), "digits/1m"); + num = num % 1000000; + } else if (num < 3000000) { + snprintf(fn, sizeof(fn), "digits/2m"); + num = num - 2000000; + } else if (num < 1000000000) { + res = ast_say_number_full_he(chan, num / 1000000, ints, language, "m", audiofd, ctrlfd); + if (res) { + return res; + } + snprintf(fn, sizeof(fn), "digits/1m"); + 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 > -1) && (ctrlfd > -1)) { + res = ast_waitstream_full(chan, ints, audiofd, ctrlfd); + } else { + res = ast_waitstream(chan, ints); + } + } + ast_stopstream(chan); + } + } + return res; +} + static int say_date(struct ast_channel *chan, time_t t, const char *ints, const char *lang) { if (!strcasecmp(lang, "en") ) { /* English syntax */ @@ -2914,6 +3031,8 @@ static int say_date(struct ast_channel *chan, time_t t, const char *ints, const return(ast_say_date_th(chan, t, ints, lang)); } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */ return(ast_say_date_ge(chan, t, ints, lang)); + } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */ + return (ast_say_date_he(chan, t, ints, lang)); } /* Default to English */ @@ -3201,6 +3320,40 @@ int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const return res; } +/* Hebrew syntax */ +int ast_say_date_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang) +{ + struct timeval tv = { t, 0 }; + struct ast_tm tm; + char fn[256]; + int res = 0; + ast_localtime(&tv, &tm, NULL); + 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); + } + } + 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); + } + } + if (!res) { + res = ast_say_number(chan, tm.tm_mday, ints, lang, "m"); + } + if (!res) { + res = ast_waitstream(chan, ints); + } + if (!res) { + res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "m"); + } + return res; +} + static int say_date_with_format(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone) { if (!strcasecmp(lang, "en") ) { /* English syntax */ @@ -3210,17 +3363,17 @@ static int say_date_with_format(struct ast_channel *chan, time_t time, const cha } else if (!strcasecmp(lang, "de") ) { /* German syntax */ return(ast_say_date_with_format_de(chan, time, ints, lang, format, timezone)); } else if (!strcasecmp(lang, "es") || !strcasecmp(lang, "mx")) { /* Spanish syntax */ - return(ast_say_date_with_format_es(chan, time, ints, lang, format, timezone)); - } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */ - return(ast_say_date_with_format_he(chan, time, ints, lang, format, timezone)); - } else if (!strcasecmp(lang, "fr") ) { /* French syntax */ - return(ast_say_date_with_format_fr(chan, time, ints, lang, format, timezone)); - } else if (!strcasecmp(lang, "it") ) { /* Italian syntax */ - return(ast_say_date_with_format_it(chan, time, ints, lang, format, timezone)); - } else if (!strcasecmp(lang, "nl") ) { /* Dutch syntax */ - return(ast_say_date_with_format_nl(chan, time, ints, lang, format, timezone)); - } else if (!strcasecmp(lang, "pl") ) { /* Polish syntax */ - return(ast_say_date_with_format_pl(chan, time, ints, lang, format, timezone)); + return (ast_say_date_with_format_es(chan, time, ints, lang, format, timezone)); + } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */ + return (ast_say_date_with_format_he(chan, time, ints, lang, format, timezone)); + } else if (!strcasecmp(lang, "fr")) { /* French syntax */ + return (ast_say_date_with_format_fr(chan, time, ints, lang, format, timezone)); + } else if (!strcasecmp(lang, "it")) { /* Italian syntax */ + return (ast_say_date_with_format_it(chan, time, ints, lang, format, timezone)); + } else if (!strcasecmp(lang, "nl")) { /* Dutch syntax */ + return (ast_say_date_with_format_nl(chan, time, ints, lang, format, timezone)); + } else if (!strcasecmp(lang, "pl")) { /* Polish syntax */ + return (ast_say_date_with_format_pl(chan, time, ints, lang, format, timezone)); } else if (!strcasecmp(lang, "pt") || !strcasecmp(lang, "pt_BR")) { /* Portuguese syntax */ return(ast_say_date_with_format_pt(chan, time, ints, lang, format, timezone)); } else if (!strcasecmp(lang, "tw") || !strcasecmp(lang, "zh") ) { /* Taiwanese / Chinese syntax */ @@ -4067,26 +4220,25 @@ int ast_say_date_with_format_th(struct ast_channel *chan, time_t time, const cha * * The numbers of 3000--19000 are not handled well **/ #define IL_DATE_STR "AdBY" -#define IL_TIME_STR "IMp" +#define IL_TIME_STR "HM" /* NOTE: In Hebrew we do not support 12 hours, only 24. No AM or PM exists in the Hebrew language */ #define IL_DATE_STR_FULL IL_DATE_STR " 'digits/at' " IL_TIME_STR -int ast_say_date_with_format_he(struct ast_channel *chan, time_t time, - const char *ints, const char *lang, const char *format, - const char *timezone) +int ast_say_date_with_format_he(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone) { /* TODO: This whole function is cut&paste from * ast_say_date_with_format_en . Is that considered acceptable? **/ struct timeval tv = { time, 0 }; struct ast_tm tm; - int res=0, offset, sndoffset; + int res = 0, offset, sndoffset; char sndfile[256], nextmsg[256]; - if (!format) + if (!format) { format = IL_DATE_STR_FULL; + } ast_localtime(&tv, &tm, timezone); - for (offset=0 ; format[offset] != '\0' ; offset++) { + for (offset = 0; format[offset] != '\0'; offset++) { ast_debug(1, "Parsing %c (offset %d) in %s\n", format[offset], offset, format); switch (format[offset]) { /* NOTE: if you add more options here, please try to be consistent with strftime(3) */ @@ -4113,43 +4265,32 @@ int ast_say_date_with_format_he(struct ast_channel *chan, time_t time, break; case 'd': case 'e': /* Day of the month */ + /* I'm not sure exactly what the parameters + * audiofd and ctrlfd to + * ast_say_number_full_he mean, but it seems + * safe to pass -1 there. + * + * At least in one of the pathes :-( + */ res = ast_say_number_full_he(chan, tm.tm_mday, ints, lang, "m", -1, -1); break; case 'Y': /* Year */ res = ast_say_number_full_he(chan, tm.tm_year + 1900, ints, lang, "f", -1, -1); break; case 'I': - case 'l': /* 12-Hour */ - { - int hour = tm.tm_hour; - hour = hour % 12; - if (hour == 0) - hour = 12; - - res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1); - } - break; + case 'l': /* 12-Hour -> we do not support 12 hour based langauges in Hebrew */ case 'H': case 'k': /* 24-Hour */ - /* With 'H' there is an 'oh' after a single- - * digit hour */ - if ((format[offset] == 'H') && (tm.tm_hour < 10) && (tm.tm_hour > 0)) { /* e.g. oh-eight */ - res = wait_file(chan, ints, "digits/oh", lang); - } - res = ast_say_number_full_he(chan, tm.tm_hour, ints, lang, "f", -1, -1); break; case 'M': /* Minute */ + if (tm.tm_min >= 0 && tm.tm_min <= 9) /* say a leading zero if needed */ + res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1); res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1); break; case 'P': case 'p': - /* AM/PM */ - if (tm.tm_hour > 11) - ast_copy_string(nextmsg, "digits/p-m", sizeof(nextmsg)); - else - ast_copy_string(nextmsg, "digits/a-m", sizeof(nextmsg)); - res = wait_file(chan, ints, nextmsg, lang); + /* AM/PM - There is no AM/PM in Hebrew... */ break; case 'Q': /* Shorthand for "Today", "Yesterday", or "date" */ @@ -5843,6 +5984,8 @@ static int say_time(struct ast_channel *chan, time_t t, const char *ints, const return(ast_say_time_th(chan, t, ints, lang)); } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */ return(ast_say_time_ge(chan, t, ints, lang)); + } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */ + return (ast_say_time_he(chan, t, ints, lang)); } /* Default to English */ @@ -6099,6 +6242,41 @@ int ast_say_time_tw(struct ast_channel *chan, time_t t, const char *ints, const return res; } +/* Hebrew syntax */ +int ast_say_time_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang) +{ + struct timeval tv = { t, 0 }; + struct ast_tm tm; + int res = 0; + int hour; + + ast_localtime(&tv, &tm, NULL); + hour = tm.tm_hour; + if (!hour) + hour = 12; + + if (!res) + res = ast_say_number_full_he(chan, hour, ints, lang, "f", -1, -1); + + if (tm.tm_min > 9) { + if (!res) + res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1); + } else if (tm.tm_min) { + if (!res) { /* say a leading zero if needed */ + res = ast_say_number_full_he(chan, 0, ints, lang, "f", -1, -1); + } + if (!res) + res = ast_waitstream(chan, ints); + if (!res) + res = ast_say_number_full_he(chan, tm.tm_min, ints, lang, "f", -1, -1); + } else { + if (!res) + res = ast_waitstream(chan, ints); + } + if (!res) + res = ast_waitstream(chan, ints); + return res; +} static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, const char *lang) { if (!strcasecmp(lang, "en") ) { /* English syntax */ @@ -6123,6 +6301,8 @@ static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, co return(ast_say_datetime_th(chan, t, ints, lang)); } else if (!strcasecmp(lang, "ge") ) { /* Georgian syntax */ return(ast_say_datetime_ge(chan, t, ints, lang)); + } else if (!strcasecmp(lang, "he")) { /* Hebrew syntax */ + return (ast_say_datetime_he(chan, t, ints, lang)); } /* Default to English */ @@ -6469,6 +6649,71 @@ int ast_say_datetime_tw(struct ast_channel *chan, time_t t, const char *ints, co return res; } +/* Hebrew syntax */ +int ast_say_datetime_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang) +{ + struct timeval tv = { t, 0 }; + struct ast_tm tm; + char fn[256]; + int res = 0; + int hour; + + ast_localtime(&tv, &tm, NULL); + 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); + } + } + 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); + } + } + if (!res) { + res = ast_say_number(chan, tm.tm_mday, ints, lang, "f"); + } + + hour = tm.tm_hour; + if (!hour) { + hour = 12; + } + + if (!res) { + res = ast_say_number(chan, hour, ints, lang, "f"); + } + + if (tm.tm_min > 9) { + if (!res) { + res = ast_say_number(chan, tm.tm_min, ints, lang, "f"); + } + } else if (tm.tm_min) { + if (!res) { + /* say a leading zero if needed */ + res = ast_say_number(chan, 0, ints, lang, "f"); + } + if (!res) { + res = ast_waitstream(chan, ints); + } + if (!res) { + res = ast_say_number(chan, tm.tm_min, ints, lang, "f"); + } + } else { + if (!res) { + res = ast_waitstream(chan, ints); + } + } + if (!res) { + res = ast_waitstream(chan, ints); + } + if (!res) { + res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, "f"); + } + return res; +} static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char *ints, const char *lang) { if (!strcasecmp(lang, "en") ) { /* English syntax */ @@ -6479,6 +6724,8 @@ static int say_datetime_from_now(struct ast_channel *chan, time_t t, const char 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)); + } else if (!strcasecmp(lang, "he")) { /* Georgian syntax */ + return (ast_say_datetime_from_now_he(chan, t, ints, lang)); } /* Default to English */ @@ -6611,6 +6858,45 @@ int ast_say_datetime_from_now_pt(struct ast_channel *chan, time_t t, const char return res; } +/* Hebrew syntax */ +int ast_say_datetime_from_now_he(struct ast_channel *chan, time_t t, const char *ints, const char *lang) +{ + int res = 0; + struct timeval nowt = ast_tvnow(), tv = { t, 0 }; + int daydiff; + struct ast_tm tm; + struct ast_tm now; + char fn[256]; + + ast_localtime(&tv, &tm, NULL); + ast_localtime(&nowt, &now, NULL); + daydiff = now.tm_yday - tm.tm_yday; + if ((daydiff < 0) || (daydiff > 6)) { + /* Day of month and month */ + 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); + } + if (!res) { + res = ast_say_number(chan, tm.tm_mday, ints, lang, "f"); + } + } 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; +} /*********************************** GREEK SUPPORT ***************************************/