Merge remote-tracking branch 'origin/master' into YaSp
[scilab.git] / scilab / modules / localization / src / c / setgetlanguage.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2007-2008 - INRIA - Sylvestre LEDRU
4  * Copyright (C) 2007-2008 - INRIA - Allan CORNET
5  * Copyright (C) 2008 - Yung-Jang Lee
6  * Copyright (C) 2011 - 2011 - DIGITEO - Bruno JOFRET
7  *
8  * This file must be used under the terms of the CeCILL.
9  * This source file is licensed as described in the file COPYING, which
10  * you should have received as part of this distribution.  The terms
11  * are also available at
12  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
13  *
14  */
15
16 #include <wchar.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include "machine.h" /*  HAVE_LIBINTL_H &  HAVE_LOCALE_H */
21
22 #ifndef _MSC_VER
23 #ifdef __APPLE__
24 #include <locale.h>
25 #else
26  #ifdef HAVE_LIBINTL_H
27   #include <libintl.h>
28   #ifdef HAVE_LOCALE_H
29    #include <locale.h>
30   #else
31    #error "Cannot find locale.h despite that libintl.h is available"
32   #endif
33  #endif
34 #endif
35 #else
36     #include <locale.h>
37     #include <libintl.h>
38 #endif
39
40 #ifdef _MSC_VER
41 #include <windows.h>
42 #include "getLocaleInfo_Windows.h"
43 #endif
44 #ifdef __APPLE__
45 #include "getLocaleInfo_Apple.h"
46 #endif
47
48
49 #include "setgetlanguage.h"
50 #include "MALLOC.h"
51 #include "tableslanguages.h"
52 #include "defaultlanguage.h"
53 #include "scilabDefaults.h"
54 #include "charEncoding.h"
55 #include "../../../io/includes/setenvc.h"
56
57 /*--------------------------------------------------------------------------*/
58 //static wchar_t CURRENTLANGUAGESTRING[LengthAlphacode] = SCILABDEFAULTLANGUAGE;
59 static wchar_t CURRENTLANGUAGESTRING[LengthAlphacode] = L"en_US";
60 static int  CURRENTLANGUAGECODE = SCILABDEFAULTLANGUAGECODE;
61 /*--------------------------------------------------------------------------*/
62 static int FindLanguageCode(wchar_t *lang);
63 static BOOL setlanguagecode(wchar_t *lang);
64 static wchar_t *FindAlias(wchar_t *lang);
65 static wchar_t *GetLanguageFromAlias(wchar_t *langAlias);
66 /*--------------------------------------------------------------------------*/
67 BOOL setlanguage(wchar_t *lang)
68 {
69     if (lang)
70     {
71         if (LanguageIsOK(lang))
72         {
73             #ifndef _MSC_VER
74             if (needtochangelanguage(lang))
75             {
76             #endif
77                 /* Load the locale from the system */
78                 #if !defined(_MSC_VER) && !defined(__APPLE__)
79                 //for mbstowcs
80                 char *pstLang = wide_string_to_UTF8(lang);
81                 char *pstRet = setlocale(LC_CTYPE, pstLang);
82                 wchar_t *ret = (pstRet == NULL ? NULL : to_wide_string(pstRet));
83
84                 if (ret == NULL)
85                 {
86                     fprintf(stderr,
87                             "Warning: Localization issue. Failed to change the LC_CTYPE locale category. Does not support the locale '%ls' %ls %s.\nDid you install the system locales?\n",
88                             lang, ret, setlocale(LC_CTYPE, NULL));
89                 }
90
91                 //for gettext
92                 pstRet =  setlocale(LC_MESSAGES, pstLang);
93                 ret = (pstRet == NULL ? NULL : to_wide_string(pstRet));
94                 #else
95                 /* Load the user locale from the system */
96                 char *ret = getLocaleUserInfo();
97 #endif
98
99                 //                This stuff causes pb when locales have been compiled
100                 if (ret == NULL)
101                 {
102 #ifndef _MSC_VER
103                     fprintf(stderr, "Warning: Localization issue. Does not support the locale '%ls'\nReturned: %ls\nCurrent system locale: %s\nDid you install the system locales?\n", lang,
104                             ret, setlocale(LC_MESSAGES, NULL));
105 #else
106                     fprintf(stderr, "Warning: Localization issue. Cannot detect user locale.\n");
107 #endif
108                 }
109
110                 /* change language */
111                 if (wcscmp(lang, L"C") == 0 || ret == NULL || wcscmp(ret, L"C") == 0)
112                 {
113                     /* The lang is the default one... ie en_US */
114                     wcscpy(CURRENTLANGUAGESTRING,SCILABDEFAULTLANGUAGE);
115                 }
116                 else
117                 {
118                     if (wcscmp(lang, L"") == 0 && ret != NULL && wcscmp(ret,  L"") != 0 )
119                     {
120                         /* The requested language is the one of the system ...
121                          * which we don't really know which one is it
122                          * but if setlocale worked, we get it from the return
123                          */
124                         wcsncpy(CURRENTLANGUAGESTRING,ret,5); /* 5 is the number of char in fr_FR for example */
125                     }
126                     else
127                     {
128                         wcscpy(CURRENTLANGUAGESTRING,lang);
129                     }
130                 }
131                 #ifndef _MSC_VER
132                 setlanguagecode(CURRENTLANGUAGESTRING);
133                 #endif
134                 exportLocaleToSystem(CURRENTLANGUAGESTRING);
135                 return TRUE;
136             }
137         #ifndef _MSC_VER
138         }
139         #endif
140     }
141     return FALSE;
142 }
143 /*--------------------------------------------------------------------------*/
144 wchar_t *getlanguage(void)
145 {
146     return CURRENTLANGUAGESTRING;
147 }
148 /*--------------------------------------------------------------------------*/
149 int getcurrentlanguagecode(void)
150 {
151     return CURRENTLANGUAGECODE;
152 }
153 /*--------------------------------------------------------------------------*/
154 wchar_t *getlanguagefromcode(int code)
155 {
156     int i = 0;
157
158     for (i = 0 ; i < NumberLanguages ; i++)
159     {
160         if (LANGUAGE_COUNTRY_TAB[i].code == code)
161         {
162             return LANGUAGE_COUNTRY_TAB[i].alphacode;
163         }
164     }
165     return NULL;
166 }
167 /*--------------------------------------------------------------------------*/
168 int getcodefromlanguage(wchar_t *language)
169 {
170     return FindLanguageCode(language);
171 }
172 /*--------------------------------------------------------------------------*/
173 BOOL LanguageIsOK(wchar_t *lang)
174 {
175     int i=0;
176
177     if (wcslen(lang)==0)
178     {
179         /* Empty language declaration... it is the default
180         * language from the system */
181         return TRUE;
182     }
183
184     for (i = 0 ; i < NumberLanguages ; i++)
185     {
186         if (wcscmp(lang,LANGUAGE_COUNTRY_TAB[i].alphacode) == 0)
187         {
188             return TRUE;
189         }
190     }
191     return FALSE;
192 }
193 /*--------------------------------------------------------------------------*/
194 static int FindLanguageCode(wchar_t *lang)
195 {
196     int i=0;
197
198     for (i = 0 ; i < NumberLanguages ; i++)
199     {
200         if (wcscmp(lang,LANGUAGE_COUNTRY_TAB[i].alphacode) == 0)
201         {
202             return LANGUAGE_COUNTRY_TAB[i].code;
203         }
204     }
205     return -1;
206 }
207 /*--------------------------------------------------------------------------*/
208 static BOOL setlanguagecode(wchar_t *lang)
209 {
210     int tmpCode = FindLanguageCode(lang);
211
212     if (tmpCode>0)
213     {
214         CURRENTLANGUAGECODE = tmpCode;
215         return TRUE;
216     }
217     return FALSE;
218 }
219 /*--------------------------------------------------------------------------*/
220 static wchar_t *FindAlias(wchar_t *lang)
221 {
222     int i = 0;
223     for(i = 0 ; i < NumberLanguagesAlias ; i++)
224     {
225         if (wcscmp(LANGUAGE_LOCALE_ALIAS[i].alphacode, lang) == 0)
226         {
227           return LANGUAGE_LOCALE_ALIAS[i].alias;
228         }
229     }
230     return NULL;
231 }
232 /*--------------------------------------------------------------------------*/
233 static wchar_t *GetLanguageFromAlias(wchar_t *langAlias)
234 {
235     int i = 0;
236     for(i = 0 ; i < NumberLanguagesAlias ; i++)
237     {
238         if (wcscmp(LANGUAGE_LOCALE_ALIAS[i].alias,langAlias) == 0)
239         {
240             return LANGUAGE_LOCALE_ALIAS[i].alphacode;
241         }
242     }
243     return NULL;
244 }
245 /*--------------------------------------------------------------------------*/
246 wchar_t *getlanguagealias(void)
247 {
248     return FindAlias(CURRENTLANGUAGESTRING);
249 }
250 /*--------------------------------------------------------------------------*/
251 BOOL needtochangelanguage(wchar_t *language)
252 {
253   wchar_t *currentlanguage = getlanguage();
254
255   if (wcscmp(language, currentlanguage)) {
256     return TRUE;
257   }
258
259   return FALSE;
260 }
261 /*--------------------------------------------------------------------------*/
262 wchar_t *convertlanguagealias(wchar_t *strlanguage)
263 {
264     wchar_t *correctlanguage=NULL;
265
266     if ( (wcslen(strlanguage) == 2) || (wcscmp(strlanguage, L"en_US") == 0) ) /* If the user wants to change to en_US ... use the default locale */
267     {
268         correctlanguage=GetLanguageFromAlias(strlanguage);
269     }
270     else
271     {
272         if (wcscmp(strlanguage, L"eng") == 0) /* compatibility previous scilab */
273         {
274             correctlanguage=GetLanguageFromAlias(L"en");
275         }
276         else
277         {
278             if (wcslen(strlanguage) == 5 && strlanguage[2] == L'_')
279             { /* already xx_XX (fr_FR) */
280                 return strlanguage;
281             }
282         }
283     }
284     return correctlanguage;
285 }
286 /*--------------------------------------------------------------------------*/
287 /**
288  * Export the variable LC_XXXX to the system
289  *
290  * @param locale the locale (ex : fr_FR or en_US)
291  */
292 BOOL exportLocaleToSystem(wchar_t *locale){
293
294     if (locale==NULL)
295     {
296 #ifdef _MSC_VER
297         fprintf(stderr,"Localization: Haven't been able to find a suitable locale. Remains to default %s.\n", "LC_CTYPE");
298 #else
299         fprintf(stderr,"Localization: Haven't been able to find a suitable locale. Remains to default %d.\n", EXPORTENVLOCALE);
300 #endif
301         return FALSE;
302     }
303
304     /* It will put in the env something like LC_MESSAGES=fr_FR */
305     if ( !setenvcW(EXPORTENVLOCALESTR,locale))
306     {
307 #ifdef _MSC_VER
308         fprintf(stderr,"Localization: Failed to declare the system variable %s.\n", "LC_CTYPE");
309 #else
310         fprintf(stderr,"Localization: Failed to declare the system variable %d.\n", EXPORTENVLOCALE);
311 #endif
312         return FALSE;
313     }
314
315 #ifdef _MSC_VER
316 #ifdef USE_SAFE_GETTEXT_DLL
317     {
318         /* gettext is buggy on Windows */
319         /* We need to set a external environment variable to scilab env. */
320
321         wchar_t env[MAX_PATH];
322         swprintf(env, MAX_PATH, L"%ls=%ls", EXPORTENVLOCALESTR, locale);
323         gettext_putenv(wide_string_to_UTF8(env));
324     }
325 #endif
326 #else
327     /* Export LC_NUMERIC to the system to make sure that the rest of system
328        is using the english notation (Java, Tcl ...) */
329     setenvc("LC_NUMERIC",LCNUMERICVALUE);
330 #endif
331
332     return TRUE;
333 }
334 /*--------------------------------------------------------------------------*/