1 /******************************************************************************
2  *  Warmux is a convivial mass murder game.
3  *  Copyright (C) 2001-2011 Warmux Team.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18  ******************************************************************************
19  * Function used to format string.
20  * Eg. : Format("Hello %s", "world") returns "Hello World".
21  *****************************************************************************/
22 
23 #include <WARMUX_i18n.h>
24 #include <WARMUX_error.h>
25 #include <string>
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 
30 #ifdef USE_FRIBIDI
31 # include <fribidi/fribidi.h>
32 # include <cstring>
33 
34 FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON;
35 FriBidiChar unicode_buffer[2048];
36 char buffer[2048];
37 
localization(const char * message)38 char* localization(const char * message) {
39   char* string = gettext(message);
40   int l        = strlen(string);
41   int l_u      = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, string, l, unicode_buffer);
42 
43   fribidi_log2vis(unicode_buffer, l_u, &pbase_dir, unicode_buffer, NULL, NULL, NULL);
44   fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, unicode_buffer, l_u, (char *)buffer);
45   return buffer;
46 }
47 #endif /* USE_FRIBIDI */
48 
49 #define BUFFER_SIZE   512
50 
Format(const char * format,...)51 std::string Format(const char *format, ...)
52 {
53   char buffer[BUFFER_SIZE];
54   va_list argp;
55   std::string result;
56 
57   va_start(argp, format);
58   int size = vsnprintf(buffer, BUFFER_SIZE, format, argp);
59   va_end(argp);
60 
61   //if (size < 0)
62   //  Error("Error formating string...");
63 
64   if (size < BUFFER_SIZE) {
65     result = std::string(buffer);
66   } else {
67     char *bigBuffer = (char *)malloc((size + 1) * sizeof(char));
68     if (bigBuffer == NULL)
69       Error("Out of memory !");
70 
71     // We need to redo va_start/va_end before calling vsnprintf
72     // with same arguments else the va_list may be already modified
73     va_start(argp, format);
74     size = vsnprintf(bigBuffer, size + 1, format, argp);
75     va_end(argp);
76 
77     if(size < 0)
78       Error( "Error formating string...");
79 
80     result = std::string(bigBuffer);
81     free(bigBuffer);
82   }
83 
84   return result;
85 }
86 
87 #ifdef ENABLE_NLS
I18N_SetDir(const std::string & dir)88 static void I18N_SetDir(const std::string &dir)
89 {
90   printf("o Bind text domain to: %s\n"
91          "o Codeset: %s\n"
92          "o Text domain: %s\n",
93          bindtextdomain(PACKAGE, dir.c_str()), bind_textdomain_codeset(PACKAGE, "UTF-8"), textdomain(PACKAGE));
94 }
95 
InitI18N(const std::string & dir,const std::string & default_language)96 void InitI18N(const std::string &dir, const std::string &default_language)
97 {
98 #ifdef ANDROID
99   // Yes this is a leak
100   static char *def = NULL;
101 
102   if (!def) {
103     const char *lang = getenv("LANG");
104     if (lang) {
105       def = (char*)malloc(strlen(lang)+1);
106       strcpy(def, lang);
107     } else {
108       def = (char*)malloc(1);
109       def[0] = 0;
110     }
111   }
112 
113   if (default_language == "")
114     setenv("LANG", def, 1);
115   else
116     setenv("LANG", default_language.c_str(), 1);
117 
118   // setlocale always return NULL
119   printf("o Locale: %s\n", getenv("LANG"));
120 #else
121   const char *locale = setlocale(LC_ALL, "");
122 
123   if (!locale) {
124     fprintf(stderr, "Couldn't set locale!\n");
125     return;
126   }
127   printf("o Locale: %s\n", default_language.c_str());
128 
129 # ifdef _WIN32
130   std::string variable = "LANGUAGE=";
131   variable += default_language;
132   _putenv(variable.c_str());
133 # else
134   setenv("LANGUAGE", default_language.c_str(), 1);
135 # endif
136 #endif
137 
138   I18N_SetDir(dir);
139 }
140 #endif
141