src/unix.cpp
changeset 9130 f6d1fc1e8815
parent 9111 48ce04029fe4
child 9470 08424e2e79e4
equal deleted inserted replaced
9129:a7b713cb0422 9130:f6d1fc1e8815
   103 
   103 
   104 bool FiosIsHiddenFile(const struct dirent *ent)
   104 bool FiosIsHiddenFile(const struct dirent *ent)
   105 {
   105 {
   106 	return ent->d_name[0] == '.';
   106 	return ent->d_name[0] == '.';
   107 }
   107 }
       
   108 
       
   109 #ifdef WITH_ICONV
       
   110 
       
   111 #include <iconv.h>
       
   112 #include <errno.h>
       
   113 #include "debug.h"
       
   114 #include "string_func.h"
       
   115 
       
   116 const char *GetCurrentLocale(const char *param);
       
   117 
       
   118 #define INTERNALCODE "UTF-8"
       
   119 
       
   120 /** Try and try to decipher the current locale from environmental
       
   121  * variables. MacOSX is hardcoded, other OS's are dynamic. If no suitable
       
   122  * locale can be found, don't do any conversion "" */
       
   123 static const char *GetLocalCode()
       
   124 {
       
   125 #if defined(__APPLE__)
       
   126 	return "UTF-8-MAC";
       
   127 #else
       
   128 	/* Strip locale (eg en_US.UTF-8) to only have UTF-8 */
       
   129 	const char *locale = GetCurrentLocale("LC_CTYPE");
       
   130 	if (locale != NULL) locale = strchr(locale, '.');
       
   131 
       
   132 	return (locale == NULL) ? "" : locale + 1;
       
   133 #endif
       
   134 }
       
   135 
       
   136 /** FYI: This is not thread-safe.
       
   137  * convert between locales, which from and which to is set in the calling
       
   138  * functions OTTD2FS() and FS2OTTD(). You should NOT use this function directly
       
   139  * NOTE: iconv was added in OSX 10.3. 10.2.x will still have the invalid char
       
   140  * issues. There aren't any easy fix for this */
       
   141 static const char *convert_tofrom_fs(iconv_t convd, const char *name)
       
   142 {
       
   143 	static char buf[1024];
       
   144 	/* Work around buggy iconv implementation where inbuf is wrongly typed as
       
   145 	 * non-const. Correct implementation is at
       
   146 	 * http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html */
       
   147 #ifdef HAVE_BROKEN_ICONV
       
   148 	char *inbuf = (char*)name;
       
   149 #else
       
   150 	const char *inbuf = name;
       
   151 #endif
       
   152 
       
   153 	char *outbuf  = buf;
       
   154 	size_t outlen = sizeof(buf) - 1;
       
   155 	size_t inlen  = strlen(name);
       
   156 
       
   157 	ttd_strlcpy(outbuf, name, sizeof(buf));
       
   158 
       
   159 	iconv(convd, NULL, NULL, NULL, NULL);
       
   160 	if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
       
   161 		DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
       
   162 	}
       
   163 
       
   164 	*outbuf = '\0';
       
   165 	/* FIX: invalid characters will abort conversion, but they shouldn't occur? */
       
   166 	return buf;
       
   167 }
       
   168 
       
   169 /** Convert from OpenTTD's encoding to that of the local environment
       
   170  * @param name pointer to a valid string that will be converted
       
   171  * @return pointer to a new stringbuffer that contains the converted string */
       
   172 const char *OTTD2FS(const char *name)
       
   173 {
       
   174 	static iconv_t convd = (iconv_t)(-1);
       
   175 
       
   176 	if (convd == (iconv_t)(-1)) {
       
   177 		const char *env = GetLocalCode();
       
   178 		convd = iconv_open(env, INTERNALCODE);
       
   179 		if (convd == (iconv_t)(-1)) {
       
   180 			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
       
   181 			return name;
       
   182 		}
       
   183 	}
       
   184 
       
   185 	return convert_tofrom_fs(convd, name);
       
   186 }
       
   187 
       
   188 /** Convert to OpenTTD's encoding from that of the local environment
       
   189  * @param name pointer to a valid string that will be converted
       
   190  * @return pointer to a new stringbuffer that contains the converted string */
       
   191 const char *FS2OTTD(const char *name)
       
   192 {
       
   193 	static iconv_t convd = (iconv_t)(-1);
       
   194 
       
   195 	if (convd == (iconv_t)(-1)) {
       
   196 		const char *env = GetLocalCode();
       
   197 		convd = iconv_open(INTERNALCODE, env);
       
   198 		if (convd == (iconv_t)(-1)) {
       
   199 			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
       
   200 			return name;
       
   201 		}
       
   202 	}
       
   203 
       
   204 	return convert_tofrom_fs(convd, name);
       
   205 }
       
   206 
       
   207 #else
       
   208 const char *FS2OTTD(const char *name) {return name;}
       
   209 const char *OTTD2FS(const char *name) {return name;}
       
   210 #endif /* WITH_ICONV */
   108 
   211 
   109 void ShowInfo(const char *str)
   212 void ShowInfo(const char *str)
   110 {
   213 {
   111 	fprintf(stderr, "%s\n", str);
   214 	fprintf(stderr, "%s\n", str);
   112 }
   215 }
   196 	}
   299 	}
   197 	#else
   300 	#else
   198 		usleep(milliseconds * 1000);
   301 		usleep(milliseconds * 1000);
   199 	#endif
   302 	#endif
   200 }
   303 }
   201 
       
   202 #ifdef WITH_ICONV
       
   203 
       
   204 #include <iconv.h>
       
   205 #include <errno.h>
       
   206 #include "debug.h"
       
   207 #include "string_func.h"
       
   208 
       
   209 const char *GetCurrentLocale(const char *param);
       
   210 
       
   211 #define INTERNALCODE "UTF-8"
       
   212 
       
   213 /** Try and try to decipher the current locale from environmental
       
   214  * variables. MacOSX is hardcoded, other OS's are dynamic. If no suitable
       
   215  * locale can be found, don't do any conversion "" */
       
   216 static const char *GetLocalCode()
       
   217 {
       
   218 #if defined(__APPLE__)
       
   219 	return "UTF-8-MAC";
       
   220 #else
       
   221 	/* Strip locale (eg en_US.UTF-8) to only have UTF-8 */
       
   222 	const char *locale = GetCurrentLocale("LC_CTYPE");
       
   223 	if (locale != NULL) locale = strchr(locale, '.');
       
   224 
       
   225 	return (locale == NULL) ? "" : locale + 1;
       
   226 #endif
       
   227 }
       
   228 
       
   229 /** FYI: This is not thread-safe.
       
   230  * convert between locales, which from and which to is set in the calling
       
   231  * functions OTTD2FS() and FS2OTTD(). You should NOT use this function directly
       
   232  * NOTE: iconv was added in OSX 10.3. 10.2.x will still have the invalid char
       
   233  * issues. There aren't any easy fix for this */
       
   234 static const char *convert_tofrom_fs(iconv_t convd, const char *name)
       
   235 {
       
   236 	static char buf[1024];
       
   237 	/* Work around buggy iconv implementation where inbuf is wrongly typed as
       
   238 	 * non-const. Correct implementation is at
       
   239 	 * http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html */
       
   240 #ifdef HAVE_BROKEN_ICONV
       
   241 	char *inbuf = (char*)name;
       
   242 #else
       
   243 	const char *inbuf = name;
       
   244 #endif
       
   245 
       
   246 	char *outbuf  = buf;
       
   247 	size_t outlen = sizeof(buf) - 1;
       
   248 	size_t inlen  = strlen(name);
       
   249 
       
   250 	ttd_strlcpy(outbuf, name, sizeof(buf));
       
   251 
       
   252 	iconv(convd, NULL, NULL, NULL, NULL);
       
   253 	if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
       
   254 		DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
       
   255 	}
       
   256 
       
   257 	*outbuf = '\0';
       
   258 	/* FIX: invalid characters will abort conversion, but they shouldn't occur? */
       
   259 	return buf;
       
   260 }
       
   261 
       
   262 /** Convert from OpenTTD's encoding to that of the local environment
       
   263  * @param name pointer to a valid string that will be converted
       
   264  * @return pointer to a new stringbuffer that contains the converted string */
       
   265 const char *OTTD2FS(const char *name)
       
   266 {
       
   267 	static iconv_t convd = (iconv_t)(-1);
       
   268 
       
   269 	if (convd == (iconv_t)(-1)) {
       
   270 		const char *env = GetLocalCode();
       
   271 		convd = iconv_open(env, INTERNALCODE);
       
   272 		if (convd == (iconv_t)(-1)) {
       
   273 			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", INTERNALCODE, env);
       
   274 			return name;
       
   275 		}
       
   276 	}
       
   277 
       
   278 	return convert_tofrom_fs(convd, name);
       
   279 }
       
   280 
       
   281 /** Convert to OpenTTD's encoding from that of the local environment
       
   282  * @param name pointer to a valid string that will be converted
       
   283  * @return pointer to a new stringbuffer that contains the converted string */
       
   284 const char *FS2OTTD(const char *name)
       
   285 {
       
   286 	static iconv_t convd = (iconv_t)(-1);
       
   287 
       
   288 	if (convd == (iconv_t)(-1)) {
       
   289 		const char *env = GetLocalCode();
       
   290 		convd = iconv_open(INTERNALCODE, env);
       
   291 		if (convd == (iconv_t)(-1)) {
       
   292 			DEBUG(misc, 0, "[iconv] conversion from codeset '%s' to '%s' unsupported", env, INTERNALCODE);
       
   293 			return name;
       
   294 		}
       
   295 	}
       
   296 
       
   297 	return convert_tofrom_fs(convd, name);
       
   298 }
       
   299 
       
   300 #else
       
   301 const char *FS2OTTD(const char *name) {return name;}
       
   302 const char *OTTD2FS(const char *name) {return name;}
       
   303 #endif /* WITH_ICONV */