From 6ee4509abf626f26ef56527ca0269614285a8404 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 25 Jan 2013 16:34:26 +0200 Subject: [PATCH] Support MS-Windows file names encoded in multibyte encodings. src/w32.c (w32_get_long_filename, init_environment, readlink): Support file names encoded in DBCS codepages. --- src/ChangeLog | 5 +++++ src/w32.c | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e9c4fe0c50e..2294a473f53 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2013-01-25 Eli Zaretskii + + * w32.c (w32_get_long_filename, init_environment, readlink): + Support file names encoded in DBCS codepages. + 2013-01-23 Eli Zaretskii * w32.c (max_filename_mbslen): New function. diff --git a/src/w32.c b/src/w32.c index 51e304af1e9..98ec573f553 100644 --- a/src/w32.c +++ b/src/w32.c @@ -37,7 +37,7 @@ along with GNU Emacs. If not, see . */ /* must include CRT headers *before* config.h */ #include -#include /* for _mbspbrk and _mbslwr */ +#include /* for _mbspbrk, _mbslwr, _mbsrchr, ... */ #undef access #undef chdir @@ -1573,7 +1573,7 @@ w32_get_long_filename (char * name, char * buf, int size) while (p != NULL && *p) { q = p; - p = strchr (q, '\\'); + p = _mbschr (q, '\\'); if (p) *p = '\0'; len = get_long_basename (full, o, size); if (len > 0) @@ -1800,16 +1800,16 @@ init_environment (char ** argv) if (!GetModuleFileName (NULL, modname, MAX_PATH)) emacs_abort (); - if ((p = strrchr (modname, '\\')) == NULL) + if ((p = _mbsrchr (modname, '\\')) == NULL) emacs_abort (); *p = 0; - if ((p = strrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) + if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) { char buf[SET_ENV_BUF_SIZE]; *p = 0; - for (p = modname; *p; p++) + for (p = modname; *p; p = CharNext (p)) if (*p == '\\') *p = '/'; _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); @@ -1824,17 +1824,17 @@ init_environment (char ** argv) || xstrcasecmp (p, "\\AMD64") == 0)) { *p = 0; - p = strrchr (modname, '\\'); + p = _mbsrchr (modname, '\\'); if (p != NULL) { *p = 0; - p = strrchr (modname, '\\'); + p = _mbsrchr (modname, '\\'); if (p && xstrcasecmp (p, "\\src") == 0) { char buf[SET_ENV_BUF_SIZE]; *p = 0; - for (p = modname; *p; p++) + for (p = modname; *p; p = CharNext (p)) if (*p == '\\') *p = '/'; _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); @@ -4340,18 +4340,34 @@ readlink (const char *name, char *buf, size_t buf_size) else { size_t size_to_copy = buf_size; - BYTE *p = lname; + BYTE *p = lname, *p2; BYTE *pend = p + lname_len; + int dbcs_p = max_filename_mbslen () > 1; /* Normalize like dostounix_filename does, but we don't want to assume that lname is null-terminated. */ - if (*p && p[1] == ':' && *p >= 'A' && *p <= 'Z') - *p += 'a' - 'A'; + if (dbcs_p) + p2 = CharNextExA (w32_ansi_code_page, p, 0); + else + p2 = p + 1; + if (*p && *p2 == ':' && *p >= 'A' && *p <= 'Z') + { + *p += 'a' - 'A'; + p += 2; + } while (p <= pend) { if (*p == '\\') *p = '/'; - ++p; + if (dbcs_p) + { + p = CharNextExA (w32_ansi_code_page, p, 0); + /* CharNextExA doesn't advance at null character. */ + if (!*p) + break; + } + else + ++p; } /* Testing for null-terminated LNAME is paranoia: WideCharToMultiByte should always return a -- 2.11.4.GIT