diff --git a/src/data/file-name.c b/src/data/file-name.c index 9eeb4b1..cec17e7 100644 --- a/src/data/file-name.c +++ b/src/data/file-name.c @@ -28,6 +28,7 @@ #include "data/settings.h" #include "libpspp/hash-functions.h" +#include "libpspp/i18n.h" #include "libpspp/message.h" #include "libpspp/str.h" #include "libpspp/version.h" @@ -176,6 +177,46 @@ safety_violation (const char *fn) } #endif +static void +dump_str (const char *s, size_t len) +{ + int i; + for (i = 0; i < len; ++i) + printf ("%02X ", (unsigned char) s[i]); + + putchar ('\n'); +} + +static char * +utf8toutf16le (const char *fn, size_t len_fn) +{ + const char *fnp = fn; + size_t len_w_fn = len_fn * 2; + size_t len_w_fnp = len_fn * 2; + char *w_fn = xmalloc (len_w_fn); + char *w_fnp = w_fn; + size_t ret; + iconv_t conv = create_iconv ("UTF-16LE", UTF8); + + dump_str (fnp, len_fn); + + ret = iconv (conv, + &fnp, &len_fn, + &w_fn, &len_w_fn); + + if (ret == -1) + { + perror ("Could not convert"); + exit (1); + } + + printf ("Converted\n"); + dump_str (w_fnp, len_w_fnp); + printf ("Done\n"); + + return w_fnp; +} + /* File open routine that understands `-' as stdin/stdout and `|cmd' as a pipe to command `cmd'. Returns resultant FILE on success, NULL on failure. If NULL is returned then errno is set to a @@ -183,6 +224,7 @@ safety_violation (const char *fn) FILE * fn_open (const char *fn, const char *mode) { + const size_t len_fn = strlen (fn); assert (mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'a'); if (mode[0] == 'r') @@ -206,7 +248,7 @@ fn_open (const char *fn, const char *mode) return popen (&fn[1], mode[0] == 'r' ? "r" : "w"); } - else if (*fn && fn[strlen (fn) - 1] == '|') + else if (*fn && fn[len_fn - 1] == '|') { char *s; FILE *f; @@ -214,9 +256,9 @@ fn_open (const char *fn, const char *mode) if (settings_get_safer_mode ()) return safety_violation (fn); - s = xmalloca (strlen (fn)); - memcpy (s, fn, strlen (fn) - 1); - s[strlen (fn) - 1] = 0; + s = xmalloca (len_fn); + memcpy (s, fn, len_fn - 1); + s[len_fn - 1] = 0; f = popen (s, mode[0] == 'r' ? "r" : "w"); @@ -226,9 +268,12 @@ fn_open (const char *fn, const char *mode) } else #endif - return fopen (fn, mode); + + + return _wfopen (utf8toutf16le (fn, len_fn), utf8toutf16le(mode, strlen (mode))); } + /* Counterpart to fn_open that closes file F with name FN; returns 0 on success, EOF on failure. If EOF is returned, errno is set to a sensible value. */ diff --git a/src/libpspp/i18n.c b/src/libpspp/i18n.c index cdcf570..0411964 100644 --- a/src/libpspp/i18n.c +++ b/src/libpspp/i18n.c @@ -84,7 +84,7 @@ create_iconv__ (const char* tocode, const char* fromcode) return converter; } -static iconv_t +iconv_t create_iconv (const char* tocode, const char* fromcode) { struct converter *converter; diff --git a/src/libpspp/i18n.h b/src/libpspp/i18n.h index 6722b5c..4ac257d 100644 --- a/src/libpspp/i18n.h +++ b/src/libpspp/i18n.h @@ -19,6 +19,7 @@ #include #include +#include void i18n_done (void); void i18n_init (void); @@ -30,6 +31,8 @@ void i18n_init (void); UTF-8 or ISO-8859-1, but ASCII is adequate for our purposes. */ #define C_ENCODING "ASCII" +iconv_t create_iconv (const char* tocode, const char* fromcode); + struct pool; char recode_byte (const char *to, const char *from, char);