X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fgettext.c;h=f1b2f8a2713b109aa2912da3ddfd37e9c34fd179;hb=3892cdfd49dcf859d9cdcb504a3542843f408097;hp=fcd1f82e256ad30040bc3f1d91cb06a427b1dbb8;hpb=0e30ee7b09f0e29d0ce731417ec121c635d96bf8;p=citadel.git diff --git a/webcit/gettext.c b/webcit/gettext.c index fcd1f82e2..f1b2f8a27 100644 --- a/webcit/gettext.c +++ b/webcit/gettext.c @@ -1,5 +1,19 @@ /* - * $Id$ + * Copyright (c) 1996-2011 by the citadel.org team + * + * This program is open source software. You can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "webcit.h" @@ -10,16 +24,27 @@ /* actual supported locales */ const char *AvailLang[] = { "C", + "bg_BG", + "cs_CZ", "en_US", + "da_DK", "de_DE", - "it_IT", - "es_ES", + "el_GR", "en_GB", - "da_DK", + "es_ES", + "et_EE", + "fi_FI", "fr_FR", + "hu_HU", + "it_IT", "nl_NL", "pt_BR", - "hu_HU", + "ru_RU", + "zh_CN", + "he_IL", + "kk_KK", + "ro_RO", + "sl_SL", "" }; @@ -30,7 +55,7 @@ long nLocalesLoaded = 0; locale_t *wc_locales; /**< here we keep the parsed stuff */ #endif -/** Keep information about one locale */ +/* Keep information about one locale */ typedef struct _lang_pref{ char lang[16]; /**< the language locale string */ char region[16]; /**< the region locale string */ @@ -39,15 +64,15 @@ typedef struct _lang_pref{ int selectedlang; /**< is this the selected language? */ } LangStruct; -/* \brief parse browser locale header - * seems as most browsers just do a one after coma value even if more than 10 locales are available. Sample strings: +/* parse browser locale header + * + * seems as most browsers just do a one after comma value even if more than 10 locales are available. Sample strings: * opera: * Accept-Language: sq;q=1.0,de;q=0.9,as;q=0.8,ar;q=0.7,bn;q=0.6,zh-cn;q=0.5,kn;q=0.4,ch;q=0.3,fo;q=0.2,gn;q=0.1,ce;q=0.1,ie;q=0.1 * Firefox * Accept-Language: 'de-de,en-us;q=0.7,en;q=0.3' * Accept-Language: de,en-ph;q=0.8,en-us;q=0.5,de-at;q=0.3 * Accept-Language: de,en-us;q=0.9,it;q=0.9,de-de;q=0.8,en-ph;q=0.7,de-at;q=0.7,zh-cn;q=0.6,cy;q=0.5,ar-om;q=0.5,en-tt;q=0.4,xh;q=0.3,nl-be;q=0.3,cs;q=0.2,sv;q=0.1,tk;q=0.1 - * \param LocaleString the string from the browser http headers */ void httplang_to_locale(StrBuf *LocaleString, wcsession *sess) @@ -65,10 +90,10 @@ void httplang_to_locale(StrBuf *LocaleString, wcsession *sess) StrBuf *Buf = NULL; StrBuf *SBuf = NULL; - nParts=StrBufNum_tokens(LocaleString,','); - for (i=0; ((i 1) { int sbuflen, k; - StrBufExtract_token(SBuf,Buf, 1,'='); - sbuflen=StrLength(SBuf); - for (k=0; kpriority=StrTol(SBuf); + ls->priority = StrTol(SBuf); } else { - ls->priority=1000; + ls->priority = 1000; } + /** get the locale part */ - StrBufExtract_token(SBuf ,Buf, 0, ';'); + StrBufExtract_token(SBuf, Buf, 0, ';'); + /** get the lang part, which should be allways there */ - extract_token(&ls->lang[0], ChrPtr(SBuf), 0, '-', 16); + extract_token(&ls->lang[0], + ChrPtr(SBuf), + 0, '-', + sizeof(ls->lang)); + /** get the area code if any. */ - if (StrBufNum_tokens(SBuf,'-') > 1) { - extract_token(&ls->region[0],ChrPtr(SBuf),1,'-',16); + if (StrBufNum_tokens(SBuf, '-') > 1) { + extract_token(&ls->region[0], + ChrPtr(SBuf), + 1, '-', + sizeof(ls->region)); } else { /** no ara code? use lang code */ blen=strlen(&ls->lang[0]); - memcpy(&ls->region[0], ls->lang,blen); - ls->region[blen]='\0'; - } /** area codes are uppercase */ - blen=strlen(&ls->region[0]); - for (j=0; jregion[0], ls->lang, blen); + ls->region[blen] = '\0'; + } + + /* area codes are uppercase */ + blen = strlen(&ls->region[0]); + for (j = 0; j < blen; j++) { - int chars=toupper(ls->region[j]); - ls->region[j]=(char)chars;/** \todo ?! */ + int chars; + chars = toupper(ls->region[j]); + ls->region[j] = (char)chars;/** \todo ?! */ } - sprintf(&lbuf[0],"%s_%s",&ls->lang[0],&ls->region[0]); + snprintf(&lbuf[0], + sizeof(lbuf), + "%s_%s", + &ls->lang[0], + &ls->region[0]); /** check if we have this lang */ - ls->availability=1; - ls->selectedlang=-1; - for (j=0; javailability = 1; + ls->selectedlang = -1; + for (j = 0; j < nLocalesLoaded; j++) { int result; /** match against the LANG part */ - result=strcasecmp(&ls->lang[0], AvailLangLoaded[j]); - if ((result<0)&&(resultavailability)){ - ls->availability=result; - ls->selectedlang=j; + result = strcasecmp(&ls->lang[0], AvailLangLoaded[j]); + if ((result < 0) && (result < ls->availability)){ + ls->availability = result; + ls->selectedlang = j; } /** match against lang and locale */ - if (0==strcasecmp(&lbuf[0], AvailLangLoaded[j])){ - ls->availability=0; - ls->selectedlang=j; - j=nLocalesLoaded; + if (0 == strcasecmp(&lbuf[0], AvailLangLoaded[j])){ + ls->availability = 0; + ls->selectedlang = j; + j = nLocalesLoaded; } } } - prio=0; - av=-1000; - nBest=-1; - for (i=0; ((iavailability<=0)&& - (avavailability)&& - (priopriority)&& - (ls->selectedlang!=-1)) { - nBest=ls->selectedlang; - av=ls->availability; - prio=ls->priority; + prio = 0; + av = -1000; + nBest = -1; + for (i = 0; ((i < nParts) && (iavailability <= 0) && + (av < ls->availability) && + (prio < ls->priority) && + (ls->selectedlang != -1)) { + nBest = ls->selectedlang; + av = ls->availability; + prio = ls->priority; } } if (nBest == -1) { /** fall back to C */ nBest=0; } - sess->selected_language=nBest; - lprintf(9, "language found: %s\n", AvailLangLoaded[WC->selected_language]); + sess->selected_language = nBest; + syslog(9, "language found: %s\n", AvailLangLoaded[WC->selected_language]); FreeStrBuf(&Buf); FreeStrBuf(&SBuf); } -/** - * \brief show the language chooser on the login dialog +/* + * show the language chooser on the login dialog * depending on the browser locale change the sequence of the * language chooser. */ @@ -178,34 +219,33 @@ void tmplput_offer_languages(StrBuf *Target, WCTemplputParams *TP) if (nLocalesLoaded == 1) { - wprintf("

%s

", AvailLangLoaded[0]); + wc_printf("

%s

", AvailLangLoaded[0]); return; } - wprintf("\n"); for (i=0; i < nLocalesLoaded; ++i) { #ifndef HAVE_USELOCALE if (strcmp(AvailLangLoaded[i], Lang) == 0) #endif - wprintf("\n", + wc_printf("\n", ((WC->selected_language == i) ? "selected" : ""), AvailLangLoaded[i], AvailLangLoaded[i] ); } - wprintf("\n"); + wc_printf("\n"); } -/** - * \brief Set the selected language for this session. - * \param lang the locale to set. +/* + * Set the selected language for this session. */ void set_selected_language(const char *lang) { #ifdef HAVE_USELOCALE int i; - for (i=0; iselected_language = i; } @@ -213,8 +253,8 @@ void set_selected_language(const char *lang) { #endif } -/** - * \brief Activate the selected language for this session. +/* + * Activate the selected language for this session. */ void go_selected_language(void) { #ifdef HAVE_USELOCALE @@ -230,8 +270,8 @@ void go_selected_language(void) { #endif } -/** - * \brief Deactivate the selected language for this session. +/* + * Deactivate the selected language for this session. */ void stop_selected_language(void) { #ifdef HAVE_USELOCALE @@ -244,16 +284,14 @@ void stop_selected_language(void) { locale_t Empty_Locale; #endif -/** - * \brief Create a locale_t for each available language +/* + * Create a locale_t for each available language */ void initialize_locales(void) { int nLocales; int i; char buf[32]; char *language = NULL; - char *locale; - nLocales = 0; while (!IsEmptyStr(AvailLang[nLocales])) @@ -261,7 +299,7 @@ void initialize_locales(void) { language = getenv("WEBCIT_LANG"); if ((language) && (!IsEmptyStr(language)) && (strcmp(language, "UNLIMITED") != 0)) { - lprintf(9, "Nailing locale to %s\n", language); + syslog(9, "Nailing locale to %s\n", language); } else language = NULL; @@ -293,20 +331,21 @@ void initialize_locales(void) { (((i > 0) && (wc_locales[0] != NULL)) ? wc_locales[0] : Empty_Locale) ); if (wc_locales[nLocalesLoaded] == NULL) { - lprintf(1, "Error configuring locale for "LOCALEDIR"locale/%s: %s\n", + syslog(1, "locale for "LOCALEDIR"locale/%s: %s; disabled\n", buf, strerror(errno) ); } else { - lprintf(3, "Configured available locale: %s\n", buf); + syslog(3, "Found locale: %s\n", buf); AvailLangLoaded[nLocalesLoaded] = AvailLang[i]; nLocalesLoaded++; } #else - if (language != NULL) { + if ((language != NULL) && (strcmp(language, AvailLang[i]) == 0)) { setenv("LANG", buf, 1); AvailLangLoaded[nLocalesLoaded] = AvailLang[i]; + setlocale(LC_MESSAGES, AvailLang[i]); nLocalesLoaded++; } else if (nLocalesLoaded == 0) { @@ -317,7 +356,7 @@ void initialize_locales(void) { #endif } if ((language != NULL) && (nLocalesLoaded == 0)) { - lprintf(1, "Your selected locale [%s] isn't available on your system. falling back to C\n", language); + syslog(1, "Your selected locale [%s] isn't available on your system. falling back to C\n", language); #ifdef HAVE_USELOCALE wc_locales[0] = newlocale( (LC_MESSAGES_MASK|LC_TIME_MASK), @@ -330,17 +369,13 @@ void initialize_locales(void) { AvailLangLoaded[0] = AvailLang[0]; nLocalesLoaded = 1; } -#ifndef HAVE_USELOCALE - - -#endif #ifdef ENABLE_NLS - locale = setlocale(LC_ALL, ""); + /*locale = */setlocale(LC_ALL, ""); - lprintf(9, "Message catalog directory: %s\n", bindtextdomain("webcit", LOCALEDIR"/locale")); - lprintf(9, "Text domain: %s\n", textdomain("webcit")); - lprintf(9, "Text domain Charset: %s\n", bind_textdomain_codeset("webcit","UTF8")); + syslog(9, "Message catalog directory: %s\n", bindtextdomain("webcit", LOCALEDIR"/locale")); + syslog(9, "Text domain: %s\n", textdomain("webcit")); + syslog(9, "Text domain Charset: %s\n", bind_textdomain_codeset("webcit","UTF8")); #endif } @@ -357,32 +392,35 @@ ServerShutdownModule_GETTEXT freelocale(wc_locales[i]); } free(wc_locales); - free(AvailLangLoaded); #endif + free(AvailLangLoaded); } #else /* ENABLE_NLS */ -const char *AvailLang[NUM_LANGS] = { - "C"}; +const char *AvailLang[] = { + "C", ""}; -/** \brief dummy for non NLS enabled systems */ +/* dummy for non NLS enabled systems */ void tmplput_offer_languages(StrBuf *Target, WCTemplputParams *TP) { - wprintf("English (US)"); + wc_printf("English (US)"); } -/** \brief dummy for non NLS enabled systems */ -void set_selected_language(char *lang) { +/* dummy for non NLS enabled systems */ +void set_selected_language(const char *lang) { } -/** \brief dummy for non NLS enabled systems */ +/* dummy for non NLS enabled systems */ void go_selected_language(void) { } -/** \brief dummy for non NLS enabled systems */ +/* dummy for non NLS enabled systems */ void stop_selected_language(void) { } +void initialize_locales(void) { +} + #endif /* ENABLE_NLS */ @@ -408,12 +446,24 @@ const char *get_selected_language(void) { #endif } + +void Header_HandleAcceptLanguage(StrBuf *Line, ParsedHttpHdrs *hdr) +{ + hdr->HR.browser_language = Line; +} + + void InitModule_GETTEXT (void) { initialize_locales(); - RegisterNamespace("LANG:SELECT", 0, 0, tmplput_offer_languages, CTX_NONE); + + RegisterHeaderHandler(HKEY("ACCEPT-LANGUAGE"), + Header_HandleAcceptLanguage); + + RegisterNamespace("LANG:SELECT", 0, 0, + tmplput_offer_languages, NULL, CTX_NONE); } @@ -422,15 +472,11 @@ SessionNewModule_GETTEXT (wcsession *sess) { #ifdef ENABLE_NLS - OneHttpHeader *vLine = NULL; - - if ( (sess->Hdr->HTTPHeaders != NULL) - && GetHash(sess->Hdr->HTTPHeaders, HKEY("ACCEPT-LANGUAGE"), (void *)&vLine) - && (vLine != NULL) - && (vLine->Val != NULL) + if ( (sess != NULL) + && (!sess->Hdr->HR.Static) + && (sess->Hdr->HR.browser_language != NULL) ) { - StrBuf *accept_language = vLine->Val; - httplang_to_locale(accept_language, sess); + httplang_to_locale(sess->Hdr->HR.browser_language, sess); } #endif }