diff options
-rw-r--r-- | include/language.h | 37 | ||||
-rw-r--r-- | include/services.h | 1 | ||||
-rwxr-xr-x | language/update.sh | 1 | ||||
-rw-r--r-- | src/language.cpp | 106 |
4 files changed, 119 insertions, 26 deletions
diff --git a/include/language.h b/include/language.h index 5d2e28bb5..9b91d49c9 100644 --- a/include/language.h +++ b/include/language.h @@ -55,13 +55,48 @@ namespace Language */ extern CoreExport const char *Translate(const NickCore *nc, const char *string); - /** Translatesa string to the given language. + /** Translates a string to the given language. * @param lang The language to translate to * @param string The string to translate * @return The translated string if found, else the original string. */ extern CoreExport const char *Translate(const char *lang, const char *string); + /** Translates a plural string to the default language. + * @param count The number of items the string is counting. + * @param singular The string to translate if there is one of \p count + * @param plural The string to translate if there is multiple of \p count + * @return The translated string if found, else the original string. + */ + extern CoreExport const char *Translate(int count, const char *singular, const char *plural); + + /** Translates a plural string to the language of the given user. + * @param u The user to translate the string for + * @param count The number of items the string is counting. + * @param singular The string to translate if there is one of \p count + * @param plural The string to translate if there is multiple of \p count + * @return The translated string if found, else the original string. + */ + extern CoreExport const char *Translate(User *u, int count, const char *singular, const char *plural); + + /** Translates a plural string to the language of the given account. + * @param nc The account to translate the string for + * @param count The number of items the string is counting. + * @param singular The string to translate if there is one of \p count + * @param plural The string to translate if there is multiple of \p count + * @return The translated string if count, else the original string + */ + extern CoreExport const char *Translate(const NickCore *nc, int count, const char *singular, const char *plural); + + /** Translates a plural string to the given language. + * @param lang The language to translate to + * @param count The number of items the string is counting. + * @param singular The string to translate if there is one of \p count + * @param plural The string to translate if there is multiple of \p count + * @return The translated string if found, else the original string. + */ + extern CoreExport const char *Translate(const char *lang, int count, const char *singular, const char *plural); + } // namespace Language /* Commonly used language strings */ diff --git a/include/services.h b/include/services.h index e8875daa5..ce5ce0296 100644 --- a/include/services.h +++ b/include/services.h @@ -40,6 +40,7 @@ #define BUFSIZE 1024 #define _(x) x +#define N_(x, y) x, y #ifndef _WIN32 # define DllExport __attribute__ ((visibility ("default"))) diff --git a/language/update.sh b/language/update.sh index 27a6a1ef8..421734838 100755 --- a/language/update.sh +++ b/language/update.sh @@ -30,6 +30,7 @@ find ../ \ --from-code=utf-8 \ --keyword \ --keyword=_ \ + --keyword=N_:1,2 \ {} + for f in *.po diff --git a/src/language.cpp b/src/language.cpp index bcade6ff1..912e4c80a 100644 --- a/src/language.cpp +++ b/src/language.cpp @@ -73,12 +73,67 @@ const char *Language::Translate(const NickCore *nc, const char *string) return Translate(nc ? nc->language.c_str() : "", string); } +const char *Language::Translate(int count, const char *singular, const char *plural) +{ + return Translate("", count, singular, plural); +} + +const char *Language::Translate(User *u, int count, const char *singular, const char *plural) +{ + if (u && u->IsIdentified()) + return Translate(u->Account(), count, singular, plural); + else + return Translate("", count, singular, plural); +} + +const char *Language::Translate(const NickCore *nc, int count, const char *singular, const char *plural) +{ + return Translate(nc ? nc->language.c_str() : "", count, singular, plural); +} + #if HAVE_LOCALIZATION #if defined(__GLIBC__) && defined(__USE_GNU_GETTEXT) extern "C" int _nl_msg_cat_cntr; #endif +namespace +{ + void PreTranslate(const char* lang) + { +#if defined(__GLIBC__) && defined(__USE_GNU_GETTEXT) + ++_nl_msg_cat_cntr; +#endif + +#ifdef _WIN32 + SetThreadLocale(MAKELCID(MAKELANGID(WindowsGetLanguage(lang), SUBLANG_DEFAULT), SORT_DEFAULT)); +#else + /* First, set LANG and LANGUAGE env variables. + * Some systems (Debian) don't care about this, so we must setlocale LC_ALL as well. + * BUT if this call fails because the LANGUAGE env variable is set, setlocale resets + * the locale to "C", which short circuits gettext and causes it to fail on systems that + * use the LANGUAGE env variable. We must reset the locale to en_US (or, anything not + * C or POSIX) then. + */ + setenv("LANG", lang, 1); + setenv("LANGUAGE", lang, 1); + if (setlocale(LC_ALL, lang) == NULL) + setlocale(LC_ALL, "en_US"); +#endif + } + + void PostTranslate() + { +#ifdef _WIN32 + SetThreadLocale(MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT)); +#else + unsetenv("LANGUAGE"); + unsetenv("LANG"); + setlocale(LC_ALL, ""); +#endif + } +} + const char *Language::Translate(const char *lang, const char *string) { if (!string || !*string) @@ -87,36 +142,31 @@ const char *Language::Translate(const char *lang, const char *string) if (!lang || !*lang) lang = Config->DefLanguage.c_str(); -#if defined(__GLIBC__) && defined(__USE_GNU_GETTEXT) - ++_nl_msg_cat_cntr; -#endif + PreTranslate(lang); -#ifdef _WIN32 - SetThreadLocale(MAKELCID(MAKELANGID(WindowsGetLanguage(lang), SUBLANG_DEFAULT), SORT_DEFAULT)); -#else - /* First, set LANG and LANGUAGE env variables. - * Some systems (Debian) don't care about this, so we must setlocale LC_ALL as well. - * BUT if this call fails because the LANGUAGE env variable is set, setlocale resets - * the locale to "C", which short circuits gettext and causes it to fail on systems that - * use the LANGUAGE env variable. We must reset the locale to en_US (or, anything not - * C or POSIX) then. - */ - setenv("LANG", lang, 1); - setenv("LANGUAGE", lang, 1); - if (setlocale(LC_ALL, lang) == NULL) - setlocale(LC_ALL, "en_US"); -#endif const char *translated_string = dgettext("anope", string); for (unsigned i = 0; translated_string == string && i < Domains.size(); ++i) translated_string = dgettext(Domains[i].c_str(), string); -#ifdef _WIN32 - SetThreadLocale(MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), SORT_DEFAULT)); -#else - unsetenv("LANGUAGE"); - unsetenv("LANG"); - setlocale(LC_ALL, ""); -#endif + PostTranslate(); + return translated_string; +} + +const char *Language::Translate(const char *lang, int count, const char *singular, const char *plural) +{ + if (!singular || !*singular || !plural || !*plural) + return ""; + + if (!lang || !*lang) + lang = Config->DefLanguage.c_str(); + + PreTranslate(lang); + + const char *translated_string = dngettext("anope", singular, plural, count); + for (unsigned i = 0; (translated_string == singular || translated_string == plural) && i < Domains.size(); ++i) + translated_string = dngettext(Domains[i].c_str(), singular, plural, count); + + PostTranslate(); return translated_string; } #else @@ -124,4 +174,10 @@ const char *Language::Translate(const char *lang, const char *string) { return string != NULL ? string : ""; } +const char *Language::Translate(const char *lang, int count, const char *singular, const char *plural) +{ + return Language::Translate("", count == 1 ? singular : plural); +} #endif + + |