diff options
| author | Eli Zaretskii | 2016-11-28 17:43:25 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-11-28 17:43:25 +0200 |
| commit | 5878abf87b6b3ead1367cbae5cc6b0743349f611 (patch) | |
| tree | 83fef8ba83ca1733c6a95e3201db9be45558ba07 /src | |
| parent | 46065291fa0807a10180b958285f5d375cf05914 (diff) | |
| download | emacs-5878abf87b6b3ead1367cbae5cc6b0743349f611.tar.gz emacs-5878abf87b6b3ead1367cbae5cc6b0743349f611.zip | |
Fix 'expand-file-name' during startup on MS-Windows
* src/w32.c (w32_init_file_name_codepage): New function, resets
file_name_codepage and w32_ansi_code_page to undo the values
recorded during dumping.
(codepage_for_filenames): Fix an embarrassing typo. Ignore the
cached value of file-name encoding if it is nil, i.e. not
initialized yet. Actually cache the last used file-name encoding
to avoid calling APIs when not necessary.
* src/w32.h (w32_init_file_name_codepage): Add prototype.
* src/w32term.c (syms_of_w32term): Set the value of
w32_unicode_filenames according to the OS version. This avoids
resetting it during startup, which then causes temacs to run with
the incorrect value.
* src/emacs.c (main): Call w32_init_file_name_codepage early
during the startup.
* src/fileio.c (Fexpand_file_name) [WINDOWSNT]: Update 'newdir'
after converting $HOME to a UTF-8 string, so that 'newdirlim' is
consistent with it. (Bug#25038)
* lisp/international/mule-cmds.el (set-locale-environment): Set
'default-file-name-coding-system' to the ANSI codepage even in
non-interactive sessions.
* lisp/files.el (directory-abbrev-alist, abbreviated-home-dir):
Doc fix.
(abbreviate-file-name): Decode 'abbreviated-home-dir' if it is a
unibyte string.
* doc/lispref/files.texi (Directory Names): Index
'directory-abbrev-alist'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs.c | 3 | ||||
| -rw-r--r-- | src/fileio.c | 8 | ||||
| -rw-r--r-- | src/w32.c | 18 | ||||
| -rw-r--r-- | src/w32.h | 1 | ||||
| -rw-r--r-- | src/w32term.c | 5 |
5 files changed, 28 insertions, 7 deletions
diff --git a/src/emacs.c b/src/emacs.c index ce30ae741b2..16cf6cc0e4d 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -716,6 +716,9 @@ main (int argc, char **argv) | |||
| 716 | to have non-stub implementations of APIs we need to convert file | 716 | to have non-stub implementations of APIs we need to convert file |
| 717 | names between UTF-8 and the system's ANSI codepage. */ | 717 | names between UTF-8 and the system's ANSI codepage. */ |
| 718 | maybe_load_unicows_dll (); | 718 | maybe_load_unicows_dll (); |
| 719 | /* Initialize the codepage for file names, needed to decode | ||
| 720 | non-ASCII file names during startup. */ | ||
| 721 | w32_init_file_name_codepage (); | ||
| 719 | #endif | 722 | #endif |
| 720 | /* This has to be done before module_init is called below, so that | 723 | /* This has to be done before module_init is called below, so that |
| 721 | the latter could use the thread ID of the main thread. */ | 724 | the latter could use the thread ID of the main thread. */ |
diff --git a/src/fileio.c b/src/fileio.c index c3b2be7c5f7..d94805f316b 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -1063,8 +1063,6 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1063 | if (!(newdir = egetenv ("HOME"))) | 1063 | if (!(newdir = egetenv ("HOME"))) |
| 1064 | newdir = newdirlim = ""; | 1064 | newdir = newdirlim = ""; |
| 1065 | nm++; | 1065 | nm++; |
| 1066 | /* `egetenv' may return a unibyte string, which will bite us since | ||
| 1067 | we expect the directory to be multibyte. */ | ||
| 1068 | #ifdef WINDOWSNT | 1066 | #ifdef WINDOWSNT |
| 1069 | if (newdir[0]) | 1067 | if (newdir[0]) |
| 1070 | { | 1068 | { |
| @@ -1072,11 +1070,14 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1072 | 1070 | ||
| 1073 | filename_from_ansi (newdir, newdir_utf8); | 1071 | filename_from_ansi (newdir, newdir_utf8); |
| 1074 | tem = make_unibyte_string (newdir_utf8, strlen (newdir_utf8)); | 1072 | tem = make_unibyte_string (newdir_utf8, strlen (newdir_utf8)); |
| 1073 | newdir = SSDATA (tem); | ||
| 1075 | } | 1074 | } |
| 1076 | else | 1075 | else |
| 1077 | #endif | 1076 | #endif |
| 1078 | tem = build_string (newdir); | 1077 | tem = build_string (newdir); |
| 1079 | newdirlim = newdir + SBYTES (tem); | 1078 | newdirlim = newdir + SBYTES (tem); |
| 1079 | /* `egetenv' may return a unibyte string, which will bite us | ||
| 1080 | if we expect the directory to be multibyte. */ | ||
| 1080 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1081 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1081 | { | 1082 | { |
| 1082 | hdir = DECODE_FILE (tem); | 1083 | hdir = DECODE_FILE (tem); |
| @@ -1105,8 +1106,7 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1105 | 1106 | ||
| 1106 | newdir = pw->pw_dir; | 1107 | newdir = pw->pw_dir; |
| 1107 | /* `getpwnam' may return a unibyte string, which will | 1108 | /* `getpwnam' may return a unibyte string, which will |
| 1108 | bite us since we expect the directory to be | 1109 | bite us when we expect the directory to be multibyte. */ |
| 1109 | multibyte. */ | ||
| 1110 | tem = make_unibyte_string (newdir, strlen (newdir)); | 1110 | tem = make_unibyte_string (newdir, strlen (newdir)); |
| 1111 | newdirlim = newdir + SBYTES (tem); | 1111 | newdirlim = newdir + SBYTES (tem); |
| 1112 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1112 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| @@ -1493,6 +1493,16 @@ w32_valid_pointer_p (void *p, int size) | |||
| 1493 | /* Current codepage for encoding file names. */ | 1493 | /* Current codepage for encoding file names. */ |
| 1494 | static int file_name_codepage; | 1494 | static int file_name_codepage; |
| 1495 | 1495 | ||
| 1496 | /* Initialize the codepage used for decoding file names. This is | ||
| 1497 | needed to undo the value recorded during dumping, which might not | ||
| 1498 | be correct when we run the dumped Emacs. */ | ||
| 1499 | void | ||
| 1500 | w32_init_file_name_codepage (void) | ||
| 1501 | { | ||
| 1502 | file_name_codepage = CP_ACP; | ||
| 1503 | w32_ansi_code_page = CP_ACP; | ||
| 1504 | } | ||
| 1505 | |||
| 1496 | /* Produce a Windows ANSI codepage suitable for encoding file names. | 1506 | /* Produce a Windows ANSI codepage suitable for encoding file names. |
| 1497 | Return the information about that codepage in CP_INFO. */ | 1507 | Return the information about that codepage in CP_INFO. */ |
| 1498 | int | 1508 | int |
| @@ -1509,12 +1519,13 @@ codepage_for_filenames (CPINFO *cp_info) | |||
| 1509 | if (NILP (current_encoding)) | 1519 | if (NILP (current_encoding)) |
| 1510 | current_encoding = Vdefault_file_name_coding_system; | 1520 | current_encoding = Vdefault_file_name_coding_system; |
| 1511 | 1521 | ||
| 1512 | if (!EQ (last_file_name_encoding, current_encoding)) | 1522 | if (!EQ (last_file_name_encoding, current_encoding) |
| 1523 | || NILP (last_file_name_encoding)) | ||
| 1513 | { | 1524 | { |
| 1514 | /* Default to the current ANSI codepage. */ | 1525 | /* Default to the current ANSI codepage. */ |
| 1515 | file_name_codepage = w32_ansi_code_page; | 1526 | file_name_codepage = w32_ansi_code_page; |
| 1516 | 1527 | ||
| 1517 | if (NILP (current_encoding)) | 1528 | if (!NILP (current_encoding)) |
| 1518 | { | 1529 | { |
| 1519 | char *cpname = SSDATA (SYMBOL_NAME (current_encoding)); | 1530 | char *cpname = SSDATA (SYMBOL_NAME (current_encoding)); |
| 1520 | char *cp = NULL, *end; | 1531 | char *cp = NULL, *end; |
| @@ -1543,6 +1554,9 @@ codepage_for_filenames (CPINFO *cp_info) | |||
| 1543 | if (!GetCPInfo (file_name_codepage, &cp)) | 1554 | if (!GetCPInfo (file_name_codepage, &cp)) |
| 1544 | emacs_abort (); | 1555 | emacs_abort (); |
| 1545 | } | 1556 | } |
| 1557 | |||
| 1558 | /* Cache the new value. */ | ||
| 1559 | last_file_name_encoding = current_encoding; | ||
| 1546 | } | 1560 | } |
| 1547 | if (cp_info) | 1561 | if (cp_info) |
| 1548 | *cp_info = cp; | 1562 | *cp_info = cp; |
| @@ -195,6 +195,7 @@ extern int filename_from_ansi (const char *, char *); | |||
| 195 | extern int filename_to_ansi (const char *, char *); | 195 | extern int filename_to_ansi (const char *, char *); |
| 196 | extern int filename_from_utf16 (const wchar_t *, char *); | 196 | extern int filename_from_utf16 (const wchar_t *, char *); |
| 197 | extern int filename_to_utf16 (const char *, wchar_t *); | 197 | extern int filename_to_utf16 (const char *, wchar_t *); |
| 198 | extern void w32_init_file_name_codepage (void); | ||
| 198 | extern int codepage_for_filenames (CPINFO *); | 199 | extern int codepage_for_filenames (CPINFO *); |
| 199 | extern Lisp_Object ansi_encode_filename (Lisp_Object); | 200 | extern Lisp_Object ansi_encode_filename (Lisp_Object); |
| 200 | extern int w32_copy_file (const char *, const char *, int, int, int); | 201 | extern int w32_copy_file (const char *, const char *, int, int, int); |
diff --git a/src/w32term.c b/src/w32term.c index 51743f8f94d..7b74ae03ad0 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -7157,7 +7157,10 @@ specified by `file-name-coding-system'. | |||
| 7157 | This variable is set to non-nil by default when Emacs runs on Windows | 7157 | This variable is set to non-nil by default when Emacs runs on Windows |
| 7158 | systems of the NT family, including W2K, XP, Vista, Windows 7 and | 7158 | systems of the NT family, including W2K, XP, Vista, Windows 7 and |
| 7159 | Windows 8. It is set to nil on Windows 9X. */); | 7159 | Windows 8. It is set to nil on Windows 9X. */); |
| 7160 | w32_unicode_filenames = 0; | 7160 | if (os_subtype == OS_9X) |
| 7161 | w32_unicode_filenames = 0; | ||
| 7162 | else | ||
| 7163 | w32_unicode_filenames = 1; | ||
| 7161 | 7164 | ||
| 7162 | 7165 | ||
| 7163 | /* FIXME: The following variable will be (hopefully) removed | 7166 | /* FIXME: The following variable will be (hopefully) removed |