From: Eli Zaretskii Date: Sat, 19 Oct 2013 18:17:01 +0000 (+0300) Subject: Start; wrote conversion from UTF-8 to UTF-16 and ANSI. X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~446^2~49 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=03d58cca817e8a21414c84696387813687c75261;p=emacs.git Start; wrote conversion from UTF-8 to UTF-16 and ANSI. --- diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index e27ae4daf4f..6ecafe46d7a 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h @@ -152,6 +152,9 @@ extern char *getenv (); #define MAXPATHLEN _MAX_PATH #endif +/* This is used to hold UTF-8 encoded file names. */ +#define MAX_UTF8_PATH (MAXPATHLEN * 4) + #ifdef HAVE_NTGUI # ifndef HAVE_WINDOW_SYSTEM # define HAVE_WINDOW_SYSTEM 1 diff --git a/src/w32.c b/src/w32.c index 2c157d11769..511cec15d5f 100644 --- a/src/w32.c +++ b/src/w32.c @@ -300,6 +300,8 @@ static BOOL g_b_init_is_valid_security_descriptor; static BOOL g_b_init_set_file_security; static BOOL g_b_init_get_adapters_info; +int w32_unicode_filenames; + /* BEGIN: Wrapper functions around OpenProcessToken and other functions in advapi32.dll that are only @@ -1182,7 +1184,83 @@ w32_valid_pointer_p (void *p, int size) return -1; } -static char startup_dir[MAXPATHLEN]; + + +/* Converting file names from UTF-8 to either UTF-16 or the system + ANSI codepage. */ +static int +filename_to_utf16 (const char *fn_in, wchar_t *fn_out) +{ + int result = MultiByteToWideChar (CP_UTF8, 0, fn_in, -1, fn_out, MAX_PATH); + + if (!result) + { + DWORD err = GetLastError (); + + switch (err) + { + case ERROR_INVALID_FLAGS: + case ERROR_INVALID_PARAMETER: + errno = EINVAL; + break; + case ERROR_INSUFFICIENT_BUFFER: + case ERROR_NO_UNICODE_TRANSLATION: + default: + errno = ENOENT; + break; + } + return -1; + } + return 0; +} + +static int +filename_from_utf16 (const wchar_t *fn_in, char *fn_out) +{ + return -1; +} + +static int +filename_to_ansi (const char *fn_in, char *fn_out) +{ + wchar_t fn_utf16[MAXPATHLEN]; + + if (filename_to_utf16 (fn_in, fn_utf16) == 0) + { + int result = WideCharToMultiByte (CP_ACP, 0, fn_utf16, -1, + fn_out, MAX_UTF8_PATH, NULL, NULL); + + if (!result) + { + DWORD err = GetLastError (); + + switch (err) + { + case ERROR_INVALID_FLAGS: + case ERROR_INVALID_PARAMETER: + errno = EINVAL; + break; + case ERROR_INSUFFICIENT_BUFFER: + case ERROR_NO_UNICODE_TRANSLATION: + default: + errno = ENOENT; + break; + } + return -1; + } + return 0; + } +} + +static int +filename_from_ansi (const char *fn_in, char *fn_out) +{ + return -1; +} + + + +static char startup_dir[MAX_UTF8_PATH]; /* Get the current working directory. */ char * @@ -3334,7 +3412,25 @@ faccessat (int dirfd, const char * path, int mode, int flags) int sys_chdir (const char * path) { - return _chdir (map_w32_filename (path, NULL)); + /* FIXME: Temporary. Also, figure out what to do with + map_w32_filename, as the original code did this: + _chdir(map_w32_filename (path, NULL)). */ + if (w32_unicode_filenames) + { + wchar_t newdir[MAXPATHLEN]; + + if (filename_to_utf16 (path, newdir) == 0) + return _wchdir (newdir); + return -1; + } + else + { + char newdir[MAXPATHLEN]; + + if (filename_to_ansi (path, newdir) == 0) + return _chdir (path); + return -1; + } } int @@ -8040,6 +8136,14 @@ globals_of_w32 (void) /* Reset, in case it has some value inherited from dump time. */ w32_stat_get_owner_group = 0; + + /* If w32_unicode_filenames is non-zero, we will be using Unicode + (a.k.a. "wide") APIs to invoke functions that accept file + names. */ + if (is_windows_9x ()) + w32_unicode_filenames = 0; + else + w32_unicode_filenames = 1; } /* For make-serial-process */