1 /*
2     getstring.c:
3 
4     Copyright (C) 1999 John ffitch
5     Jan 27 2005: replaced with new implementation by Istvan Varga
6     Dec 25 2007: added GNU gettext implementation as alternative -- John ffitch
7 
8     This file is part of Csound.
9 
10     The Csound Library is free software; you can redistribute it
11     and/or modify it under the terms of the GNU Lesser General Public
12     License as published by the Free Software Foundation; either
13     version 2.1 of the License, or (at your option) any later version.
14 
15     Csound is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU Lesser General Public License for more details.
19 
20     You should have received a copy of the GNU Lesser General Public
21     License along with Csound; if not, write to the Free Software
22     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23     02110-1301 USA
24 */
25 
26 #include "csoundCore.h"
27 #ifdef HAVE_STRTOD_L
28 static locale_t csound_c_locale = NULL;
29 #else
30 static char *csound_c_locale = NULL;
31 #endif
32 
33 #ifdef HAVE_DIRENT_H
34 #  include <sys/types.h>
35 #  include <dirent.h>
36 #  if 0 && defined(__MACH__)
37 typedef void* DIR;
38 DIR opendir(const char *);
39 struct dirent *readdir(DIR*);
40 int closedir(DIR*);
41 #  endif
42 #endif
43 
44 #include "namedins.h"
45 
46 #define CSSTRNGS_VERSION 0x2000
47 #include <locale.h>
48 #ifdef GNU_GETTEXT
49 #include <libintl.h>
50 #endif
51 
52 #ifndef GNU_GETTEXT
init_getstring(void * cs)53 void init_getstring(void *cs)
54 {
55    IGN(cs);
56 #ifndef HAVE_STRTOD_L
57     setlocale(LC_NUMERIC, "C");                   /* Ensure C syntax */
58     csound_c_locale = setlocale(LC_NUMERIC, "C"); /* and remwmber */
59 #else
60     if (csound_c_locale == NULL) {
61         csound_c_locale = newlocale (0, "C", NULL);
62     }
63 #endif
64 }
65 
csoundLocalizeString(const char * s)66 PUBLIC char *csoundLocalizeString(const char *s)
67 {
68     return (char*)s;
69 }
70 /* This stub is needed for backwards compatibility */
csoundSetLanguage(cslanguage_t lang_code)71 PUBLIC void csoundSetLanguage(cslanguage_t lang_code)
72 {
73   IGN(lang_code);
74     return;
75 }
76 #else
init_getstring(void * cs)77 void init_getstring(void *cs)
78 {
79   IGN(cs);
80 /*     s = csoundGetEnv(NULL, "CS_LANG"); */
81 /*     if (s == NULL)              /\* Default locale *\/ */
82 /*       setlocale (LC_MESSAGES, ""); */
83 /*     else  */
84 /*       setlocale (LC_MESSAGES, s);    /\* Set to particular value *\/ */
85 /*    textdomain("csound6"); */  /* This is not needed when using dgettext */
86     /* bind_textdomain_codeset("csound6", "UTF-8"); */
87 #if defined(CSOUND_TEXTDOMAIN)
88     bindtextdomain("csound6", CSOUND_TEXTDOMAIN);
89 #endif
90 #ifndef HAVE_STRTOD_L
91     setlocale(LC_NUMERIC, "C"); /* Ensure C syntax */
92 #else
93     if (csound_c_locale == NULL) {
94         csound_c_locale = newlocale (0, "C", NULL);
95     }
96 #endif
97 }
98 
csoundLocalizeString(const char * s)99 PUBLIC char *csoundLocalizeString(const char *s)
100 {
101     return dgettext("csound6", s);
102 }
103 
104 static const char *language_names[] = {"", /* Default */
105                             "af", /* CSLANGUAGE_AFRIKAANS */
106                             "sq", /* CSLANGUAGE_ALBANIAN */
107                             "ar", /* CSLANGUAGE_ARABIC */
108                             "hy", /* CSLANGUAGE_ARMENIAN */
109                             "as", /* CSLANGUAGE_ASSAMESE */
110                             "az", /* CSLANGUAGE_AZERI */
111                             "eu", /* CSLANGUAGE_BASQUE */
112                             "be", /* CSLANGUAGE_BELARUSIAN */
113                             "bn", /* CSLANGUAGE_BENGALI */
114                             "bg", /* CSLANGUAGE_BULGARIAN */
115                             "ca", /* CSLANGUAGE_CATALAN */
116                             "zh", /* CSLANGUAGE_CHINESE */
117                             "hr", /* CSLANGUAGE_CROATIAN */
118                             "cs", /* CSLANGUAGE_CZECH */
119                             "da", /* CSLANGUAGE_DANISH */
120                             "nl", /* CSLANGUAGE_DUTCH */
121                             "en_GB",
122                             "en_US",
123                             "et", /* CSLANGUAGE_ESTONIAN */
124                             "fo", /* CSLANGUAGE_FAEROESE */
125                             "fa", /* CSLANGUAGE_FARSI */
126                             "fi", /* CSLANGUAGE_FINNISH */
127                             "fr",
128                             "ka", /* CSLANGUAGE_GEORGIAN */
129                             "de",
130                             "el", /* CSLANGUAGE_GREEK */
131                             "gu", /* CSLANGUAGE_GUJARATI */
132                             "he", /* CSLANGUAGE_HEBREW */
133                             "hi", /* CSLANGUAGE_HINDI */
134                             "hu", /* CSLANGUAGE_HUNGARIAN */
135                             "is", /* CSLANGUAGE_ICELANDIC */
136                             "id", /* CSLANGUAGE_INDONESIAN */
137                             "it", /* CSLANGUAGE_ITALIAN */
138                             "ja", /* CSLANGUAGE_JAPANESE */
139                             "kn", /* CSLANGUAGE_KANNADA */
140                             "ks", /* CSLANGUAGE_KASHMIRI */
141                             "kk", /* CSLANGUAGE_KAZAK */
142                             "kok", /* CSLANGUAGE_KONKANI */
143                             "ko", /* CSLANGUAGE_KOREAN */
144                             "lv", /* CSLANGUAGE_LATVIAN */
145                             "lt", /* CSLANGUAGE_LITHUANIAN */
146                             "mk", /* CSLANGUAGE_MACEDONIAN */
147                             "ms", /* CSLANGUAGE_MALAY */
148                             "ml", /* CSLANGUAGE_MALAYALAM */
149                             "mni", /* CSLANGUAGE_MANIPURI */
150                             "mr", /* CSLANGUAGE_MARATHI */
151                             "ne", /* CSLANGUAGE_NEPALI */
152                             "no", /* CSLANGUAGE_NORWEGIAN */
153                             "or", /* CSLANGUAGE_ORIYA */
154                             "pl", /* CSLANGUAGE_POLISH */
155                             "pt", /* CSLANGUAGE_PORTUGUESE */
156                             "pa", /* CSLANGUAGE_PUNJABI */
157                             "ro",
158                             "ru", /* CSLANGUAGE_RUSSIAN */
159                             "sa", /* CSLANGUAGE_SANSKRIT */
160                             "sr", /* CSLANGUAGE_SERBIAN */
161                             "sd", /* CSLANGUAGE_SINDHI */
162                             "sk", /* CSLANGUAGE_SLOVAK */
163                             "sl", /* CSLANGUAGE_SLOVENIAN */
164                             "es",
165                             "sw", /* CSLANGUAGE_SWAHILI */
166                             "sv", /* CSLANGUAGE_SWEDISH */
167                             "ta", /* CSLANGUAGE_TAMIL */
168                             "tt", /* CSLANGUAGE_TATAR */
169                             "te", /* CSLANGUAGE_TELUGU */
170                             "th", /* CSLANGUAGE_THAI */
171                             "tr", /* CSLANGUAGE_TURKISH */
172                             "uk", /* CSLANGUAGE_UKRAINIAN */
173                             "ur", /* CSLANGUAGE_URDU */
174                             "uz", /* CSLANGUAGE_UZBEK */
175                             "vi", /* CSLANGUAGE_VIETNAMES */
176                             "es_CO", /* COLUMBIAN */
177   };
178 
csoundSetLanguage(cslanguage_t lang_code)179 PUBLIC void csoundSetLanguage(cslanguage_t lang_code)
180 {
181     const char *name;
182     if (lang_code == CSLANGUAGE_DEFAULT)
183       fprintf(stderr, "Localisation of messages is disabled, using "
184                       "default language.\n");
185     else {
186       fprintf(stderr, "Setting language of messages to %s ...\n",
187                       name=language_names[(int) lang_code]);
188       setlocale(LC_MESSAGES, name);
189     }
190     return;
191 }
192 
193 #endif
194 
cs_strtok_r(char * str,char * delim,char ** nextp)195 PUBLIC char* cs_strtok_r(char* str, char* delim, char** nextp) {
196 #ifdef HAVE_STRTOK_R
197     return strtok_r(str, delim, nextp);
198 #else
199     /*
200      * public domain strtok_r() by Charlie Gordon
201      *
202      *   from comp.lang.c  9/14/2007
203      *
204      *      http://groups.google.com/group/comp.lang.c/msg/2ab1ecbb86646684
205      *
206      *     (Declaration that it's public domain):
207      *      http://groups.google.com/group/comp.lang.c/msg/7c7b39328fefab9c
208      */
209     char *ret;
210     if (str == NULL)
211     {
212         str = *nextp;
213     }
214     str += strspn(str, delim);
215     if (*str == '\0')
216     {
217         return NULL;
218     }
219     ret = str;
220     str += strcspn(str, delim);
221     if (*str)
222     {
223         *str++ = '\0';
224     }
225     *nextp = str;
226     return ret;
227 #endif
228 }
229 
cs_strtod(char * nptr,char ** endptr)230 PUBLIC double cs_strtod(char* nptr, char** endptr) {
231 #ifdef HAVE_STRTOD_L
232     return strtod_l(nptr, endptr, csound_c_locale);
233 #else
234     return strtod(nptr, endptr);
235 #endif
236 }
237 
238 #if defined(HAVE_SPRINTF_L)
cs_sprintf(char * str,const char * format,...)239 PUBLIC int cs_sprintf(char *str, const char *format, ...)
240 {
241     // This is not thread-safe but no idea how to fix
242     va_list args;
243     int retVal;
244     va_start(args, format);
245     retVal = vsprintf_l(str,csound_c_locale,format,args);
246     va_end(args);
247     return retVal;
248 }
249 
cs_sscanf(char * str,const char * format,...)250 PUBLIC int cs_sscanf(char *str, const char *format, ...)
251 {
252     // This is not thread-safe but no idea how to fix
253     va_list args;
254     int retVal;
255     va_start(args, format);
256     retVal = vsscanf_l(str,csound_c_locale,format,args);
257     va_end(args);
258     return retVal;
259 }
260 #else
261 #if defined(HAVE__SPRINT_L)
cs_sprintf(char * str,const char * format,...)262 PUBLIC int cs_sprintf(char *str, const char *format, ...)
263 {
264     // This is not thread-safe but no idea how to fix
265     va_list args;
266     int retVal;
267     va_start(args, format);
268     retVal = __vsprintf_l(str,csound_c_locale,format,args);
269     va_end(args);
270     return retVal;
271 }
272 
cs_sscanf(char * str,const char * format,...)273 PUBLIC int cs_sscanf(char *str, const char *format, ...)
274 {
275     // This is not thread-safe but no idea how to fix
276     va_list args;
277     int retVal;
278     va_start(args, format);
279     retVal = __vsscanf_l(str,csound_c_locale,format,args);
280     va_end(args);
281     return retVal;
282 }
283 #else
cs_sprintf(char * str,const char * format,...)284 PUBLIC int cs_sprintf(char *str, const char *format, ...)
285 {
286     // This is not thread-safe but no idea how to fix
287     va_list args;
288     int retVal;
289     char *curlocale = setlocale(LC_NUMERIC, "C");
290     va_start(args, format);
291     retVal = vsprintf(str,format,args);
292     va_end(args);
293     setlocale(LC_NUMERIC, curlocale);
294     return retVal;
295 }
296 
cs_sscanf(char * str,const char * format,...)297 PUBLIC int cs_sscanf(char *str, const char *format, ...)
298 {
299     // This is not thread-safe but no idea how to fix
300     va_list args;
301     int retVal;
302     char *curlocale = setlocale(LC_NUMERIC, "C");
303     va_start(args, format);
304     retVal = vsscanf(str,format,args);
305     va_end(args);
306     setlocale(LC_NUMERIC, curlocale);
307     return retVal;
308 }
309 
310 #endif
311 #endif
312