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