diff options
author | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-01-16 18:41:35 +0000 |
---|---|---|
committer | tilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-01-16 18:41:35 +0000 |
commit | 04a98dd615ed71827af941ccca2617f5d4b36032 (patch) | |
tree | afaec45f1404ba87888045afdf3cdcaa459fcb25 /main/say.c | |
parent | caebf8461f9849f484eb5bbd649880e457c20e31 (diff) |
Fix the conjugation of Russian and Ukrainian languages.
(related to issue #12475)
Reported by: chappell
Patches:
vm_multilang.patch uploaded by chappell (license 8)
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@168828 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/say.c')
-rw-r--r-- | main/say.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/main/say.c b/main/say.c index 5903b4597..b6b973ccd 100644 --- a/main/say.c +++ b/main/say.c @@ -54,6 +54,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/lock.h" #include "asterisk/localtime.h" #include "asterisk/utils.h" +#include "asterisk/app.h" /* Forward declaration */ static int wait_file(struct ast_channel *chan, const char *ints, const char *file, const char *lang); @@ -7265,6 +7266,114 @@ static int ast_say_datetime_from_now_ge(struct ast_channel *chan, time_t t, cons return res; } +/* In English, we use the plural for everything but one. For example: + * 1 degree + * 2 degrees + * 5 degrees + * The filename for the plural form is generated by appending "s". Note that + * purpose is to generate a unique filename, not to implement irregular + * declensions. Thus: + * 1 man + * 2 mans (the "mans" soundfile will of course say "men") + */ +static const char *counted_noun_ending_en(int num) +{ + if (num == 1 || num == -1) { + return ""; + } else { + return "s"; + } +} + +/* Counting of objects in slavic languages such as Russian and Ukrainian the + * rules are more complicated. There are two plural forms used in counting. + * They are the genative singular which we represent with the suffix "x1" and + * the genative plural which we represent with the suffix "x2". The base names + * of the soundfiles remain in English. For example: + * 1 degree (soudfile says "gradus") + * 2 degreex1 (soundfile says "gradusa") + * 5 degreex2 (soundfile says "gradusov") + */ +static const char *counted_noun_ending_slavic(int num) +{ + if (num < 0) { + num *= -1; + } + num %= 100; /* never pay attention to more than two digits */ + if (num >= 20) { /* for numbers 20 and above, pay attention to only last digit */ + num %= 10; + } + if (num == 1) { /* singular */ + return ""; + } + if (num > 0 && num < 5) { /* 2--5 get genative singular */ + return "x1"; + } else { /* 5--19 get genative plural */ + return "x2"; + } +} + +int ast_say_counted_noun(struct ast_channel *chan, int num, const char noun[]) +{ + char *temp; + int temp_len; + const char *ending; + if (!strcasecmp(chan->language, "ru")) { /* Russian */ + ending = counted_noun_ending_slavic(num); + } else if(!strcasecmp(chan->language, "ua")) { /* Ukrainian */ + ending = counted_noun_ending_slavic(num); + } else if(!strcasecmp(chan->language, "ua")) { /* Polish */ + ending = counted_noun_ending_slavic(num); + } else { /* English and default */ + ending = counted_noun_ending_en(num); + } + temp = alloca((temp_len = (strlen(noun) + strlen(ending) + 1))); + snprintf(temp, temp_len, "%s%s", noun, ending); + return ast_play_and_wait(chan, temp); +} + +/* + * In slavic languages such as Russian and Ukrainian the rules for declining + * adjectives are simpler than those for nouns. When counting we use only + * the singular (to which we give no suffix) and the genative plural (which + * we represent by adding an "x"). Oh, an in the singular gender matters + * so we append the supplied gender suffix ("m", "f", "n"). + */ +static const char *counted_adjective_ending_ru(int num, const char gender[]) +{ + if (num < 0) { + num *= -1; + } + num %= 100; /* never pay attention to more than two digits */ + if (num >= 20) { /* at 20 and beyond only the last digit matters */ + num %= 10; + } + if (num == 1) { + return gender ? gender : ""; + } else { /* all other numbers get the genative plural */ + return "x"; + } +} + +int ast_say_counted_adjective(struct ast_channel *chan, int num, const char adjective[], const char gender[]) +{ + char *temp; + int temp_len; + const char *ending; + if (!strcasecmp(chan->language, "ru")) { /* Russian */ + ending = counted_adjective_ending_ru(num, gender); + } else if (!strcasecmp(chan->language, "ua")) { /* Ukrainian */ + ending = counted_adjective_ending_ru(num, gender); + } else if (!strcasecmp(chan->language, "pl")) { /* Polish */ + ending = counted_adjective_ending_ru(num, gender); + } else { /* English and default */ + ending = ""; + } + temp = alloca((temp_len = (strlen(adjective) + strlen(ending) + 1))); + snprintf(temp, temp_len, "%s%s", adjective, ending); + return ast_play_and_wait(chan, temp); +} + /* |