(svn r3966) -Fix: [OSX and some linux] [ 1157244 ] Can't save game if name contains german umlauts
authorbjarni
Sat, 18 Mar 2006 15:55:24 +0000
changeset 3260 ed19f95eb4f7
parent 3259 ce30772897f8
child 3261 e17a3e96f11e
(svn r3966) -Fix: [OSX and some linux] [ 1157244 ] Can't save game if name contains german umlauts
now it saves correctly, but the load window still display some chars wrong (fix by ln-)
Makefile
saveload.c
screenshot.c
unix.c
--- a/Makefile	Sat Mar 18 14:35:54 2006 +0000
+++ b/Makefile	Sat Mar 18 15:55:24 2006 +0000
@@ -485,6 +485,10 @@
 endif
 endif
 
+ifdef OSX
+LIBS += -liconv
+endif
+
 # enables/disables assert()
 ifdef DISABLE_ASSERTS
 CFLAGS += -DNDEBUG
--- a/saveload.c	Sat Mar 18 14:35:54 2006 +0000
+++ b/saveload.c	Sat Mar 18 15:55:24 2006 +0000
@@ -1314,6 +1314,12 @@
 extern void BeforeSaveGame(void);
 extern bool LoadOldSaveGame(const char *file);
 
+#ifdef UNIX
+extern const char *convert_to_fs_charset(const char *filename);
+#else
+#define convert_to_fs_charset(str) (str)
+#endif // UNIX
+
 /** Small helper function to close the to be loaded savegame an signal error */
 static inline SaveOrLoadResult AbortSaveLoad(void)
 {
@@ -1418,7 +1424,6 @@
 	save_thread = NULL;
 }
 
-
 /**
  * Main Save or Load function where the high-level saveload functions are
  * handled. It opens the savegame, selects format and checks versions
@@ -1449,7 +1454,11 @@
 		return SL_OK;
 	}
 
-	_sl.fh = fopen(filename, (mode == SL_SAVE) ? "wb" : "rb");
+	if(mode == SL_SAVE) {
+		_sl.fh = fopen(convert_to_fs_charset(filename), "wb");
+	} else {
+		_sl.fh = fopen(filename, "rb");
+	}
 	if (_sl.fh == NULL) {
 		DEBUG(misc, 0) ("[Sl] Cannot open savegame for saving/loading.");
 		return SL_ERROR;
--- a/screenshot.c	Sat Mar 18 14:35:54 2006 +0000
+++ b/screenshot.c	Sat Mar 18 15:55:24 2006 +0000
@@ -12,6 +12,12 @@
 #include "screenshot.h"
 #include "variables.h"
 
+#ifdef UNIX
+extern const char *convert_to_fs_charset(const char *filename);
+#else
+#define convert_to_fs_charset(str) (str)
+#endif // UNIX
+
 char _screenshot_format_name[8];
 uint _num_screenshot_formats;
 uint _cur_screenshot_format;
@@ -73,7 +79,7 @@
 	if (pixelformat != 8)
 		return false;
 
-	f = fopen(name, "wb");
+	f = fopen(convert_to_fs_charset(name), "wb");
 	if (f == NULL) return false;
 
 	// each scanline must be aligned on a 32bit boundary
@@ -177,7 +183,7 @@
 	if (pixelformat != 8)
 		return false;
 
-	f = fopen(name, "wb");
+	f = fopen(convert_to_fs_charset(name), "wb");
 	if (f == NULL) return false;
 
 	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (char *)name, png_my_error, png_my_warning);
@@ -288,7 +294,7 @@
 	if (pixelformat != 8 || w == 0)
 		return false;
 
-	f = fopen(name, "wb");
+	f = fopen(convert_to_fs_charset(name), "wb");
 	if (f == NULL) return false;
 
 	memset(&pcx, 0, sizeof(pcx));
--- a/unix.c	Sat Mar 18 14:35:54 2006 +0000
+++ b/unix.c	Sat Mar 18 15:55:24 2006 +0000
@@ -49,6 +49,8 @@
 	#endif
 #endif
 
+#include <iconv.h>
+#include <locale.h>
 static char *_fios_path;
 static char *_fios_save_path;
 static char *_fios_scn_path;
@@ -604,3 +606,56 @@
 	}
 	#endif // __AMIGA__
 }
+
+bool guessUTF8(void)
+{
+#if defined(__linux__)
+	const char *lang = getenv("LANG");
+	if(lang != NULL && strstr(lang, "UTF-8") != NULL)
+		return true;
+	else
+		return false;
+#elif defined(__APPLE__)
+	return true;
+#else
+	return false;
+#endif
+
+}
+
+/* FYI: This is not thread-safe.
+Assumptions:
+	- the 'from' charset is ISO-8859-15
+	- the 'to' charset is either the same, or UTF-8
+*/
+const char *convert_to_fs_charset(const char *filename)
+{
+	static char statout[1024], statin[1024];
+	static iconv_t convd;
+	static bool alreadyInited;
+	char *outbuf = statout;
+	const char *inbuf = statin;
+	size_t inlen = strlen(filename), outlen = 1023;
+	size_t retval = 0;
+	if(inbuf == NULL)
+		inbuf = statin;
+
+	if(guessUTF8() == false)
+		return filename;
+	setlocale(LC_ALL, "C-UTF-8");
+	strcpy(statout, filename);
+	strcpy(statin, filename);
+	inbuf = strrchr(statin, '/');
+	outbuf = strrchr(statout, '/');
+	if(alreadyInited == false)
+	{
+		convd = iconv_open("UTF-8", "ISO-8859-15");
+		if(convd == (iconv_t)(-1))
+			return filename;
+		alreadyInited = true;
+	}
+	retval = iconv(convd, NULL, NULL, NULL, NULL);
+	inlen = iconv(convd, &inbuf, &inlen, &outbuf, &outlen);
+	// FIX: invalid characters will abort conversion, but they shouldn't occur?
+	return statout;
+}