diff options
| author | Eli Zaretskii | 2013-11-02 15:03:32 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2013-11-02 15:03:32 +0200 |
| commit | 1fd201bb1d720d0c5ab727a3972363778eef834f (patch) | |
| tree | 508abf22dbb91d24309869bc42a93e814f9fbcd6 /src | |
| parent | 5c4a19a90f803ed46629c2bdc1ac3d3563caa738 (diff) | |
| download | emacs-1fd201bb1d720d0c5ab727a3972363778eef834f.tar.gz emacs-1fd201bb1d720d0c5ab727a3972363778eef834f.zip | |
Adapted dostounix_filename. w32-short/long-filename work with wide APIs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs.c | 19 | ||||
| -rw-r--r-- | src/fileio.c | 20 | ||||
| -rw-r--r-- | src/filelock.c | 2 | ||||
| -rw-r--r-- | src/msdos.c | 6 | ||||
| -rw-r--r-- | src/msdos.h | 2 | ||||
| -rw-r--r-- | src/termcap.c | 2 | ||||
| -rw-r--r-- | src/unexw32.c | 10 | ||||
| -rw-r--r-- | src/w32.c | 202 | ||||
| -rw-r--r-- | src/w32.h | 7 | ||||
| -rw-r--r-- | src/w32fns.c | 4 | ||||
| -rw-r--r-- | src/w32proc.c | 14 |
11 files changed, 131 insertions, 157 deletions
diff --git a/src/emacs.c b/src/emacs.c index 06b8d290cae..a58829e8918 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -2153,9 +2153,15 @@ decode_env_path (const char *evarname, const char *defalt) | |||
| 2153 | Lisp_Object lpath, element, tem; | 2153 | Lisp_Object lpath, element, tem; |
| 2154 | #ifdef WINDOWSNT | 2154 | #ifdef WINDOWSNT |
| 2155 | bool defaulted = 0; | 2155 | bool defaulted = 0; |
| 2156 | const char *emacs_dir = egetenv ("emacs_dir"); | ||
| 2157 | static const char *emacs_dir_env = "%emacs_dir%/"; | 2156 | static const char *emacs_dir_env = "%emacs_dir%/"; |
| 2158 | const size_t emacs_dir_len = strlen (emacs_dir_env); | 2157 | const size_t emacs_dir_len = strlen (emacs_dir_env); |
| 2158 | const char *edir = egetenv ("emacs_dir"); | ||
| 2159 | char emacs_dir[MAX_UTF8_PATH]; | ||
| 2160 | |||
| 2161 | /* egetenv looks in process-environment, which holds the variables | ||
| 2162 | in their original system-locale encoding. We need emacs_dir to | ||
| 2163 | be in UTF-8. */ | ||
| 2164 | filename_from_ansi (edir, emacs_dir); | ||
| 2159 | #endif | 2165 | #endif |
| 2160 | 2166 | ||
| 2161 | /* It's okay to use getenv here, because this function is only used | 2167 | /* It's okay to use getenv here, because this function is only used |
| @@ -2176,9 +2182,16 @@ decode_env_path (const char *evarname, const char *defalt) | |||
| 2176 | /* Ensure values from the environment use the proper directory separator. */ | 2182 | /* Ensure values from the environment use the proper directory separator. */ |
| 2177 | if (path) | 2183 | if (path) |
| 2178 | { | 2184 | { |
| 2179 | char *path_copy = alloca (strlen (path) + 1); | 2185 | char *path_copy; |
| 2186 | |||
| 2187 | #ifdef WINDOWSNT | ||
| 2188 | path_copy = alloca (MAX_UTF8_PATH); | ||
| 2189 | filename_from_ansi (path, path_copy); | ||
| 2190 | #else /* MSDOS */ | ||
| 2191 | path_copy = alloca (strlen (path) + 1); | ||
| 2180 | strcpy (path_copy, path); | 2192 | strcpy (path_copy, path); |
| 2181 | dostounix_filename (path_copy, 0); | 2193 | #endif |
| 2194 | dostounix_filename (path_copy); | ||
| 2182 | path = path_copy; | 2195 | path = path_copy; |
| 2183 | } | 2196 | } |
| 2184 | #endif | 2197 | #endif |
diff --git a/src/fileio.c b/src/fileio.c index dc6d80932c4..eeaa736290c 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -459,7 +459,8 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 459 | strcat (res, "/"); | 459 | strcat (res, "/"); |
| 460 | beg = res; | 460 | beg = res; |
| 461 | p = beg + strlen (beg); | 461 | p = beg + strlen (beg); |
| 462 | dostounix_filename (beg, 0); | 462 | dostounix_filename (beg); |
| 463 | /* FIXME: Figure out the multibyte vs unibyte stuff here. */ | ||
| 463 | tem_fn = make_specified_string (beg, -1, p - beg, | 464 | tem_fn = make_specified_string (beg, -1, p - beg, |
| 464 | STRING_MULTIBYTE (filename)); | 465 | STRING_MULTIBYTE (filename)); |
| 465 | } | 466 | } |
| @@ -470,7 +471,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 470 | else if (STRING_MULTIBYTE (filename)) | 471 | else if (STRING_MULTIBYTE (filename)) |
| 471 | { | 472 | { |
| 472 | tem_fn = make_specified_string (beg, -1, p - beg, 1); | 473 | tem_fn = make_specified_string (beg, -1, p - beg, 1); |
| 473 | dostounix_filename (SSDATA (tem_fn), 1); | 474 | dostounix_filename (SSDATA (tem_fn)); |
| 474 | #ifdef WINDOWSNT | 475 | #ifdef WINDOWSNT |
| 475 | if (!NILP (Vw32_downcase_file_names)) | 476 | if (!NILP (Vw32_downcase_file_names)) |
| 476 | tem_fn = Fdowncase (tem_fn); | 477 | tem_fn = Fdowncase (tem_fn); |
| @@ -478,7 +479,7 @@ Given a Unix syntax file name, returns a string ending in slash. */) | |||
| 478 | } | 479 | } |
| 479 | else | 480 | else |
| 480 | { | 481 | { |
| 481 | dostounix_filename (beg, 0); | 482 | dostounix_filename (beg); |
| 482 | tem_fn = make_specified_string (beg, -1, p - beg, 0); | 483 | tem_fn = make_specified_string (beg, -1, p - beg, 0); |
| 483 | } | 484 | } |
| 484 | return tem_fn; | 485 | return tem_fn; |
| @@ -582,7 +583,7 @@ file_name_as_directory (char *dst, const char *src, ptrdiff_t srclen, | |||
| 582 | dst[srclen++] = DIRECTORY_SEP; | 583 | dst[srclen++] = DIRECTORY_SEP; |
| 583 | dst[srclen] = 0; | 584 | dst[srclen] = 0; |
| 584 | #ifdef DOS_NT | 585 | #ifdef DOS_NT |
| 585 | dostounix_filename (dst, multibyte); | 586 | dostounix_filename (dst); |
| 586 | #endif | 587 | #endif |
| 587 | return srclen; | 588 | return srclen; |
| 588 | } | 589 | } |
| @@ -651,7 +652,7 @@ directory_file_name (char *dst, char *src, ptrdiff_t srclen, bool multibyte) | |||
| 651 | memcpy (dst, src, srclen); | 652 | memcpy (dst, src, srclen); |
| 652 | dst[srclen] = 0; | 653 | dst[srclen] = 0; |
| 653 | #ifdef DOS_NT | 654 | #ifdef DOS_NT |
| 654 | dostounix_filename (dst, multibyte); | 655 | dostounix_filename (dst); |
| 655 | #endif | 656 | #endif |
| 656 | return srclen; | 657 | return srclen; |
| 657 | } | 658 | } |
| @@ -1082,7 +1083,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1082 | #ifdef DOS_NT | 1083 | #ifdef DOS_NT |
| 1083 | /* Make sure directories are all separated with /, but | 1084 | /* Make sure directories are all separated with /, but |
| 1084 | avoid allocation of a new string when not required. */ | 1085 | avoid allocation of a new string when not required. */ |
| 1085 | dostounix_filename (nm, multibyte); | 1086 | /* FIXME: Figure out multibyte and downcase here. */ |
| 1087 | dostounix_filename (nm); | ||
| 1086 | #ifdef WINDOWSNT | 1088 | #ifdef WINDOWSNT |
| 1087 | if (IS_DIRECTORY_SEP (nm[1])) | 1089 | if (IS_DIRECTORY_SEP (nm[1])) |
| 1088 | { | 1090 | { |
| @@ -1465,7 +1467,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) | |||
| 1465 | target[1] = ':'; | 1467 | target[1] = ':'; |
| 1466 | } | 1468 | } |
| 1467 | result = make_specified_string (target, -1, o - target, multibyte); | 1469 | result = make_specified_string (target, -1, o - target, multibyte); |
| 1468 | dostounix_filename (SSDATA (result), multibyte); | 1470 | /* FIXME: Figure out the multibyte and downcase here. */ |
| 1471 | dostounix_filename (SSDATA (result)); | ||
| 1469 | #ifdef WINDOWSNT | 1472 | #ifdef WINDOWSNT |
| 1470 | if (!NILP (Vw32_downcase_file_names)) | 1473 | if (!NILP (Vw32_downcase_file_names)) |
| 1471 | result = Fdowncase (result); | 1474 | result = Fdowncase (result); |
| @@ -1749,7 +1752,8 @@ those `/' is discarded. */) | |||
| 1749 | nm = xlispstrdupa (filename); | 1752 | nm = xlispstrdupa (filename); |
| 1750 | 1753 | ||
| 1751 | #ifdef DOS_NT | 1754 | #ifdef DOS_NT |
| 1752 | dostounix_filename (nm, multibyte); | 1755 | /* FIXME: Figure out multibyte and downcase. */ |
| 1756 | dostounix_filename (nm); | ||
| 1753 | substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); | 1757 | substituted = (memcmp (nm, SDATA (filename), SBYTES (filename)) != 0); |
| 1754 | #endif | 1758 | #endif |
| 1755 | endp = nm + SBYTES (filename); | 1759 | endp = nm + SBYTES (filename); |
diff --git a/src/filelock.c b/src/filelock.c index 2f53047f526..82ffd5d172b 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -689,7 +689,7 @@ lock_file (Lisp_Object fn) | |||
| 689 | /* Ensure we have only '/' separators, to avoid problems with | 689 | /* Ensure we have only '/' separators, to avoid problems with |
| 690 | looking (inside fill_in_lock_file_name) for backslashes in file | 690 | looking (inside fill_in_lock_file_name) for backslashes in file |
| 691 | names encoded by some DBCS codepage. */ | 691 | names encoded by some DBCS codepage. */ |
| 692 | dostounix_filename (SSDATA (fn), 1); | 692 | dostounix_filename (SSDATA (fn)); |
| 693 | #endif | 693 | #endif |
| 694 | encoded_fn = ENCODE_FILE (fn); | 694 | encoded_fn = ENCODE_FILE (fn); |
| 695 | 695 | ||
diff --git a/src/msdos.c b/src/msdos.c index 2ba7a16a443..cb4f8c3df89 100644 --- a/src/msdos.c +++ b/src/msdos.c | |||
| @@ -3295,7 +3295,7 @@ void msdos_downcase_filename (unsigned char *); | |||
| 3295 | /* Destructively turn backslashes into slashes. */ | 3295 | /* Destructively turn backslashes into slashes. */ |
| 3296 | 3296 | ||
| 3297 | void | 3297 | void |
| 3298 | dostounix_filename (char *p, int ignore) | 3298 | dostounix_filename (char *p) |
| 3299 | { | 3299 | { |
| 3300 | msdos_downcase_filename (p); | 3300 | msdos_downcase_filename (p); |
| 3301 | 3301 | ||
| @@ -3559,7 +3559,7 @@ init_environment (int argc, char **argv, int skip_args) | |||
| 3559 | if (!s) s = "c:/command.com"; | 3559 | if (!s) s = "c:/command.com"; |
| 3560 | t = alloca (strlen (s) + 1); | 3560 | t = alloca (strlen (s) + 1); |
| 3561 | strcpy (t, s); | 3561 | strcpy (t, s); |
| 3562 | dostounix_filename (t, 0); | 3562 | dostounix_filename (t); |
| 3563 | setenv ("SHELL", t, 0); | 3563 | setenv ("SHELL", t, 0); |
| 3564 | 3564 | ||
| 3565 | /* PATH is also downcased and backslashes mirrored. */ | 3565 | /* PATH is also downcased and backslashes mirrored. */ |
| @@ -3569,7 +3569,7 @@ init_environment (int argc, char **argv, int skip_args) | |||
| 3569 | /* Current directory is always considered part of MsDos's path but it is | 3569 | /* Current directory is always considered part of MsDos's path but it is |
| 3570 | not normally mentioned. Now it is. */ | 3570 | not normally mentioned. Now it is. */ |
| 3571 | strcat (strcpy (t, ".;"), s); | 3571 | strcat (strcpy (t, ".;"), s); |
| 3572 | dostounix_filename (t, 0); /* Not a single file name, but this should work. */ | 3572 | dostounix_filename (t); /* Not a single file name, but this should work. */ |
| 3573 | setenv ("PATH", t, 1); | 3573 | setenv ("PATH", t, 1); |
| 3574 | 3574 | ||
| 3575 | /* In some sense all dos users have root privileges, so... */ | 3575 | /* In some sense all dos users have root privileges, so... */ |
diff --git a/src/msdos.h b/src/msdos.h index 27090324b44..11d7eb5c3e1 100644 --- a/src/msdos.h +++ b/src/msdos.h | |||
| @@ -29,7 +29,7 @@ void dos_set_window_size (int *, int *); | |||
| 29 | 29 | ||
| 30 | int getdefdir (int, char*); | 30 | int getdefdir (int, char*); |
| 31 | void unixtodos_filename (char *); | 31 | void unixtodos_filename (char *); |
| 32 | void dostounix_filename (char *, int); | 32 | void dostounix_filename (char *); |
| 33 | char *rootrelativepath (char *); | 33 | char *rootrelativepath (char *); |
| 34 | void init_environment (int, char **, int); | 34 | void init_environment (int, char **, int); |
| 35 | void internal_terminal_init (void); | 35 | void internal_terminal_init (void); |
diff --git a/src/termcap.c b/src/termcap.c index aa225d9b3b1..f0819266318 100644 --- a/src/termcap.c +++ b/src/termcap.c | |||
| @@ -393,7 +393,7 @@ tgetent (char *bp, const char *name) | |||
| 393 | if (termcap_name && (*termcap_name == '\\' | 393 | if (termcap_name && (*termcap_name == '\\' |
| 394 | || *termcap_name == '/' | 394 | || *termcap_name == '/' |
| 395 | || termcap_name[1] == ':')) | 395 | || termcap_name[1] == ':')) |
| 396 | dostounix_filename (termcap_name, 0); | 396 | dostounix_filename (termcap_name); |
| 397 | #endif | 397 | #endif |
| 398 | 398 | ||
| 399 | filep = termcap_name && valid_filename_p (termcap_name); | 399 | filep = termcap_name && valid_filename_p (termcap_name); |
diff --git a/src/unexw32.c b/src/unexw32.c index a01ac799592..5320ec1e371 100644 --- a/src/unexw32.c +++ b/src/unexw32.c | |||
| @@ -728,9 +728,15 @@ unexec (const char *new_name, const char *old_name) | |||
| 728 | char *q; | 728 | char *q; |
| 729 | 729 | ||
| 730 | /* Ignore old_name, and get our actual location from the OS. */ | 730 | /* Ignore old_name, and get our actual location from the OS. */ |
| 731 | if (!GetModuleFileName (NULL, in_filename, MAX_PATH)) | 731 | if (!GetModuleFileNameA (NULL, in_filename, MAX_PATH)) |
| 732 | abort (); | 732 | abort (); |
| 733 | dostounix_filename (in_filename, 0); | 733 | |
| 734 | /* Can't use dostounix_filename here, since that needs its file name | ||
| 735 | argument encoded in UTF-8. */ | ||
| 736 | for (p = in_filename; *p; p = CharNextA (p)) | ||
| 737 | if (*p == '\\') | ||
| 738 | *p = '/'; | ||
| 739 | |||
| 734 | strcpy (out_filename, in_filename); | 740 | strcpy (out_filename, in_filename); |
| 735 | 741 | ||
| 736 | /* Change the base of the output filename to match the requested name. */ | 742 | /* Change the base of the output filename to match the requested name. */ |
| @@ -1336,7 +1336,7 @@ filename_to_ansi (const char *fn_in, char *fn_out) | |||
| 1336 | return -1; | 1336 | return -1; |
| 1337 | } | 1337 | } |
| 1338 | 1338 | ||
| 1339 | static int | 1339 | int |
| 1340 | filename_from_ansi (const char *fn_in, char *fn_out) | 1340 | filename_from_ansi (const char *fn_in, char *fn_out) |
| 1341 | { | 1341 | { |
| 1342 | wchar_t fn_utf16[MAXPATHLEN]; | 1342 | wchar_t fn_utf16[MAXPATHLEN]; |
| @@ -1799,31 +1799,20 @@ max_filename_mbslen (void) | |||
| 1799 | return cp_info.MaxCharSize; | 1799 | return cp_info.MaxCharSize; |
| 1800 | } | 1800 | } |
| 1801 | 1801 | ||
| 1802 | /* Normalize filename by converting all path separators to | 1802 | /* Normalize filename by converting in-place all of its path |
| 1803 | the specified separator. Also conditionally convert upper | 1803 | separators to the separator specified by PATH_SEP. */ |
| 1804 | case path name components to lower case. */ | ||
| 1805 | 1804 | ||
| 1806 | static void | 1805 | static void |
| 1807 | normalize_filename (register char *fp, char path_sep, int multibyte) | 1806 | normalize_filename (register char *fp, char path_sep) |
| 1808 | { | 1807 | { |
| 1809 | char sep; | 1808 | char *p2; |
| 1810 | char *elem, *p2; | ||
| 1811 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 1812 | |||
| 1813 | /* Multibyte file names are in the Emacs internal representation, so | ||
| 1814 | we can traverse them by bytes with no problems. */ | ||
| 1815 | if (multibyte) | ||
| 1816 | dbcs_p = 0; | ||
| 1817 | 1809 | ||
| 1818 | /* Always lower-case drive letters a-z, even if the filesystem | 1810 | /* Always lower-case drive letters a-z, even if the filesystem |
| 1819 | preserves case in filenames. | 1811 | preserves case in filenames. |
| 1820 | This is so filenames can be compared by string comparison | 1812 | This is so filenames can be compared by string comparison |
| 1821 | functions that are case-sensitive. Even case-preserving filesystems | 1813 | functions that are case-sensitive. Even case-preserving filesystems |
| 1822 | do not distinguish case in drive letters. */ | 1814 | do not distinguish case in drive letters. */ |
| 1823 | if (dbcs_p) | 1815 | p2 = fp + 1; |
| 1824 | p2 = CharNextExA (file_name_codepage, fp, 0); | ||
| 1825 | else | ||
| 1826 | p2 = fp + 1; | ||
| 1827 | 1816 | ||
| 1828 | if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z') | 1817 | if (*p2 == ':' && *fp >= 'A' && *fp <= 'Z') |
| 1829 | { | 1818 | { |
| @@ -1831,68 +1820,26 @@ normalize_filename (register char *fp, char path_sep, int multibyte) | |||
| 1831 | fp += 2; | 1820 | fp += 2; |
| 1832 | } | 1821 | } |
| 1833 | 1822 | ||
| 1834 | if (multibyte || NILP (Vw32_downcase_file_names)) | 1823 | while (*fp) |
| 1835 | { | 1824 | { |
| 1836 | while (*fp) | 1825 | if (*fp == '/' || *fp == '\\') |
| 1837 | { | 1826 | *fp = path_sep; |
| 1838 | if (*fp == '/' || *fp == '\\') | 1827 | fp++; |
| 1839 | *fp = path_sep; | ||
| 1840 | if (!dbcs_p) | ||
| 1841 | fp++; | ||
| 1842 | else | ||
| 1843 | fp = CharNextExA (file_name_codepage, fp, 0); | ||
| 1844 | } | ||
| 1845 | return; | ||
| 1846 | } | 1828 | } |
| 1847 | |||
| 1848 | sep = path_sep; /* convert to this path separator */ | ||
| 1849 | elem = fp; /* start of current path element */ | ||
| 1850 | |||
| 1851 | do { | ||
| 1852 | if (*fp >= 'a' && *fp <= 'z') | ||
| 1853 | elem = 0; /* don't convert this element */ | ||
| 1854 | |||
| 1855 | if (*fp == 0 || *fp == ':') | ||
| 1856 | { | ||
| 1857 | sep = *fp; /* restore current separator (or 0) */ | ||
| 1858 | *fp = '/'; /* after conversion of this element */ | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | if (*fp == '/' || *fp == '\\') | ||
| 1862 | { | ||
| 1863 | if (elem && elem != fp) | ||
| 1864 | { | ||
| 1865 | *fp = 0; /* temporary end of string */ | ||
| 1866 | _mbslwr (elem); /* while we convert to lower case */ | ||
| 1867 | } | ||
| 1868 | *fp = sep; /* convert (or restore) path separator */ | ||
| 1869 | elem = fp + 1; /* next element starts after separator */ | ||
| 1870 | sep = path_sep; | ||
| 1871 | } | ||
| 1872 | if (*fp) | ||
| 1873 | { | ||
| 1874 | if (!dbcs_p) | ||
| 1875 | fp++; | ||
| 1876 | else | ||
| 1877 | fp = CharNextExA (file_name_codepage, fp, 0); | ||
| 1878 | } | ||
| 1879 | } while (*fp); | ||
| 1880 | } | 1829 | } |
| 1881 | 1830 | ||
| 1882 | /* Destructively turn backslashes into slashes. MULTIBYTE non-zero | 1831 | /* Destructively turn backslashes into slashes. */ |
| 1883 | means the file name is a multibyte string in Emacs's internal | ||
| 1884 | representation. */ | ||
| 1885 | void | 1832 | void |
| 1886 | dostounix_filename (register char *p, int multibyte) | 1833 | dostounix_filename (register char *p) |
| 1887 | { | 1834 | { |
| 1888 | normalize_filename (p, '/', multibyte); | 1835 | normalize_filename (p, '/'); |
| 1889 | } | 1836 | } |
| 1890 | 1837 | ||
| 1891 | /* Destructively turn slashes into backslashes. */ | 1838 | /* Destructively turn slashes into backslashes. */ |
| 1892 | void | 1839 | void |
| 1893 | unixtodos_filename (register char *p) | 1840 | unixtodos_filename (register char *p) |
| 1894 | { | 1841 | { |
| 1895 | normalize_filename (p, '\\', 0); | 1842 | normalize_filename (p, '\\'); |
| 1896 | } | 1843 | } |
| 1897 | 1844 | ||
| 1898 | /* Remove all CR's that are followed by a LF. | 1845 | /* Remove all CR's that are followed by a LF. |
| @@ -1943,17 +1890,13 @@ parse_root (char * name, char ** pPath) | |||
| 1943 | else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) | 1890 | else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) |
| 1944 | { | 1891 | { |
| 1945 | int slashes = 2; | 1892 | int slashes = 2; |
| 1946 | int dbcs_p = max_filename_mbslen () > 1; | ||
| 1947 | 1893 | ||
| 1948 | name += 2; | 1894 | name += 2; |
| 1949 | do | 1895 | do |
| 1950 | { | 1896 | { |
| 1951 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) | 1897 | if (IS_DIRECTORY_SEP (*name) && --slashes == 0) |
| 1952 | break; | 1898 | break; |
| 1953 | if (dbcs_p) | 1899 | name++; |
| 1954 | name = CharNextExA (file_name_codepage, name, 0); | ||
| 1955 | else | ||
| 1956 | name++; | ||
| 1957 | } | 1900 | } |
| 1958 | while ( *name ); | 1901 | while ( *name ); |
| 1959 | if (IS_DIRECTORY_SEP (name[0])) | 1902 | if (IS_DIRECTORY_SEP (name[0])) |
| @@ -1970,23 +1913,44 @@ parse_root (char * name, char ** pPath) | |||
| 1970 | static int | 1913 | static int |
| 1971 | get_long_basename (char * name, char * buf, int size) | 1914 | get_long_basename (char * name, char * buf, int size) |
| 1972 | { | 1915 | { |
| 1973 | WIN32_FIND_DATA find_data; | ||
| 1974 | HANDLE dir_handle; | 1916 | HANDLE dir_handle; |
| 1917 | char fname_utf8[MAX_UTF8_PATH]; | ||
| 1975 | int len = 0; | 1918 | int len = 0; |
| 1919 | int cstatus; | ||
| 1976 | 1920 | ||
| 1977 | /* must be valid filename, no wild cards or other invalid characters */ | 1921 | /* Must be valid filename, no wild cards or other invalid characters. */ |
| 1978 | if (_mbspbrk (name, "*?|<>\"")) | 1922 | if (strpbrk (name, "*?|<>\"")) |
| 1979 | return 0; | 1923 | return 0; |
| 1980 | 1924 | ||
| 1981 | dir_handle = FindFirstFile (name, &find_data); | 1925 | if (w32_unicode_filenames) |
| 1982 | if (dir_handle != INVALID_HANDLE_VALUE) | ||
| 1983 | { | 1926 | { |
| 1984 | if ((len = strlen (find_data.cFileName)) < size) | 1927 | wchar_t fname_utf16[MAX_PATH]; |
| 1985 | memcpy (buf, find_data.cFileName, len + 1); | 1928 | WIN32_FIND_DATAW find_data_wide; |
| 1986 | else | 1929 | |
| 1987 | len = 0; | 1930 | filename_to_utf16 (name, fname_utf16); |
| 1988 | FindClose (dir_handle); | 1931 | dir_handle = FindFirstFileW (fname_utf16, &find_data_wide); |
| 1932 | if (dir_handle != INVALID_HANDLE_VALUE) | ||
| 1933 | cstatus = filename_from_utf16 (find_data_wide.cFileName, fname_utf8); | ||
| 1934 | } | ||
| 1935 | else | ||
| 1936 | { | ||
| 1937 | char fname_ansi[MAX_PATH]; | ||
| 1938 | WIN32_FIND_DATAA find_data_ansi; | ||
| 1939 | |||
| 1940 | filename_to_ansi (name, fname_ansi); | ||
| 1941 | dir_handle = FindFirstFileA (fname_ansi, &find_data_ansi); | ||
| 1942 | if (dir_handle != INVALID_HANDLE_VALUE) | ||
| 1943 | cstatus = filename_from_ansi (find_data_ansi.cFileName, fname_utf8); | ||
| 1989 | } | 1944 | } |
| 1945 | |||
| 1946 | if (cstatus == 0 && (len = strlen (fname_utf8)) < size) | ||
| 1947 | memcpy (buf, fname_utf8, len + 1); | ||
| 1948 | else | ||
| 1949 | len = 0; | ||
| 1950 | |||
| 1951 | if (dir_handle != INVALID_HANDLE_VALUE) | ||
| 1952 | FindClose (dir_handle); | ||
| 1953 | |||
| 1990 | return len; | 1954 | return len; |
| 1991 | } | 1955 | } |
| 1992 | 1956 | ||
| @@ -1997,11 +1961,11 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 1997 | char * o = buf; | 1961 | char * o = buf; |
| 1998 | char * p; | 1962 | char * p; |
| 1999 | char * q; | 1963 | char * q; |
| 2000 | char full[ MAX_PATH ]; | 1964 | char full[ MAX_UTF8_PATH ]; |
| 2001 | int len; | 1965 | int len; |
| 2002 | 1966 | ||
| 2003 | len = strlen (name); | 1967 | len = strlen (name); |
| 2004 | if (len >= MAX_PATH) | 1968 | if (len >= MAX_UTF8_PATH) |
| 2005 | return FALSE; | 1969 | return FALSE; |
| 2006 | 1970 | ||
| 2007 | /* Use local copy for destructive modification. */ | 1971 | /* Use local copy for destructive modification. */ |
| @@ -2018,7 +1982,7 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 2018 | while (p != NULL && *p) | 1982 | while (p != NULL && *p) |
| 2019 | { | 1983 | { |
| 2020 | q = p; | 1984 | q = p; |
| 2021 | p = _mbschr (q, '\\'); | 1985 | p = strchr (q, '\\'); |
| 2022 | if (p) *p = '\0'; | 1986 | if (p) *p = '\0'; |
| 2023 | len = get_long_basename (full, o, size); | 1987 | len = get_long_basename (full, o, size); |
| 2024 | if (len > 0) | 1988 | if (len > 0) |
| @@ -2042,6 +2006,29 @@ w32_get_long_filename (char * name, char * buf, int size) | |||
| 2042 | return TRUE; | 2006 | return TRUE; |
| 2043 | } | 2007 | } |
| 2044 | 2008 | ||
| 2009 | unsigned int | ||
| 2010 | w32_get_short_filename (char * name, char * buf, int size) | ||
| 2011 | { | ||
| 2012 | if (w32_unicode_filenames) | ||
| 2013 | { | ||
| 2014 | wchar_t name_utf16[MAX_PATH], short_name[MAX_PATH]; | ||
| 2015 | unsigned int retval; | ||
| 2016 | |||
| 2017 | filename_to_utf16 (name, name_utf16); | ||
| 2018 | retval = GetShortPathNameW (name_utf16, short_name, size); | ||
| 2019 | if (retval && retval < size) | ||
| 2020 | filename_from_utf16 (short_name, buf); | ||
| 2021 | return retval; | ||
| 2022 | } | ||
| 2023 | else | ||
| 2024 | { | ||
| 2025 | char name_ansi[MAX_PATH]; | ||
| 2026 | |||
| 2027 | filename_to_ansi (name, name_ansi); | ||
| 2028 | return GetShortPathNameA (name_ansi, buf, size); | ||
| 2029 | } | ||
| 2030 | } | ||
| 2031 | |||
| 2045 | static int | 2032 | static int |
| 2046 | is_unc_volume (const char *filename) | 2033 | is_unc_volume (const char *filename) |
| 2047 | { | 2034 | { |
| @@ -2506,7 +2493,7 @@ emacs_root_dir (void) | |||
| 2506 | emacs_abort (); | 2493 | emacs_abort (); |
| 2507 | strcpy (root_dir, p); | 2494 | strcpy (root_dir, p); |
| 2508 | root_dir[parse_root (root_dir, NULL)] = '\0'; | 2495 | root_dir[parse_root (root_dir, NULL)] = '\0'; |
| 2509 | dostounix_filename (root_dir, 0); | 2496 | dostounix_filename (root_dir); |
| 2510 | return root_dir; | 2497 | return root_dir; |
| 2511 | } | 2498 | } |
| 2512 | 2499 | ||
| @@ -3937,49 +3924,6 @@ convert_from_time_t (time_t time, FILETIME * pft) | |||
| 3937 | pft->dwLowDateTime = tmp.LowPart; | 3924 | pft->dwLowDateTime = tmp.LowPart; |
| 3938 | } | 3925 | } |
| 3939 | 3926 | ||
| 3940 | #if 0 | ||
| 3941 | /* No reason to keep this; faking inode values either by hashing or even | ||
| 3942 | using the file index from GetInformationByHandle, is not perfect and | ||
| 3943 | so by default Emacs doesn't use the inode values on Windows. | ||
| 3944 | Instead, we now determine file-truename correctly (except for | ||
| 3945 | possible drive aliasing etc). */ | ||
| 3946 | |||
| 3947 | /* Modified version of "PJW" algorithm (see the "Dragon" compiler book). */ | ||
| 3948 | static unsigned | ||
| 3949 | hashval (const unsigned char * str) | ||
| 3950 | { | ||
| 3951 | unsigned h = 0; | ||
| 3952 | while (*str) | ||
| 3953 | { | ||
| 3954 | h = (h << 4) + *str++; | ||
| 3955 | h ^= (h >> 28); | ||
| 3956 | } | ||
| 3957 | return h; | ||
| 3958 | } | ||
| 3959 | |||
| 3960 | /* Return the hash value of the canonical pathname, excluding the | ||
| 3961 | drive/UNC header, to get a hopefully unique inode number. */ | ||
| 3962 | static DWORD | ||
| 3963 | generate_inode_val (const char * name) | ||
| 3964 | { | ||
| 3965 | char fullname[ MAX_PATH ]; | ||
| 3966 | char * p; | ||
| 3967 | unsigned hash; | ||
| 3968 | |||
| 3969 | /* Get the truly canonical filename, if it exists. (Note: this | ||
| 3970 | doesn't resolve aliasing due to subst commands, or recognize hard | ||
| 3971 | links. */ | ||
| 3972 | if (!w32_get_long_filename ((char *)name, fullname, MAX_PATH)) | ||
| 3973 | emacs_abort (); | ||
| 3974 | |||
| 3975 | parse_root (fullname, &p); | ||
| 3976 | /* Normal W32 filesystems are still case insensitive. */ | ||
| 3977 | _strlwr (p); | ||
| 3978 | return hashval (p); | ||
| 3979 | } | ||
| 3980 | |||
| 3981 | #endif | ||
| 3982 | |||
| 3983 | static PSECURITY_DESCRIPTOR | 3927 | static PSECURITY_DESCRIPTOR |
| 3984 | get_file_security_desc_by_handle (HANDLE h) | 3928 | get_file_security_desc_by_handle (HANDLE h) |
| 3985 | { | 3929 | { |
| @@ -152,6 +152,9 @@ extern int w32_valid_pointer_p (void *, int); | |||
| 152 | /* Get long (aka "true") form of file name, if it exists. */ | 152 | /* Get long (aka "true") form of file name, if it exists. */ |
| 153 | extern BOOL w32_get_long_filename (char * name, char * buf, int size); | 153 | extern BOOL w32_get_long_filename (char * name, char * buf, int size); |
| 154 | 154 | ||
| 155 | /* Get the short (a.k.a. "8+3") form of a file name. */ | ||
| 156 | extern unsigned int w32_get_short_filename (char *, char *, int); | ||
| 157 | |||
| 155 | /* Prepare our standard handles for proper inheritance by child processes. */ | 158 | /* Prepare our standard handles for proper inheritance by child processes. */ |
| 156 | extern void prepare_standard_handles (int in, int out, | 159 | extern void prepare_standard_handles (int in, int out, |
| 157 | int err, HANDLE handles[4]); | 160 | int err, HANDLE handles[4]); |
| @@ -181,8 +184,10 @@ extern void init_environment (char **); | |||
| 181 | extern void check_windows_init_file (void); | 184 | extern void check_windows_init_file (void); |
| 182 | extern void syms_of_ntproc (void); | 185 | extern void syms_of_ntproc (void); |
| 183 | extern void syms_of_ntterm (void); | 186 | extern void syms_of_ntterm (void); |
| 184 | extern void dostounix_filename (register char *, int); | 187 | extern void dostounix_filename (register char *); |
| 185 | extern void unixtodos_filename (register char *); | 188 | extern void unixtodos_filename (register char *); |
| 189 | extern int filename_from_ansi (const char *, char *); | ||
| 190 | |||
| 186 | extern BOOL init_winsock (int load_now); | 191 | extern BOOL init_winsock (int load_now); |
| 187 | extern void srandom (int); | 192 | extern void srandom (int); |
| 188 | extern int random (void); | 193 | extern int random (void); |
diff --git a/src/w32fns.c b/src/w32fns.c index c98c84c8542..3e60d68023b 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -6466,8 +6466,8 @@ Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */) | |||
| 6466 | #ifdef NTGUI_UNICODE | 6466 | #ifdef NTGUI_UNICODE |
| 6467 | filename = from_unicode_buffer (filename_buf); | 6467 | filename = from_unicode_buffer (filename_buf); |
| 6468 | #else /* !NTGUI_UNICODE */ | 6468 | #else /* !NTGUI_UNICODE */ |
| 6469 | dostounix_filename (filename_buf, 0); | 6469 | filename = DECODE_FILE (build_unibyte_string (filename_buf)); |
| 6470 | filename = DECODE_FILE (build_string (filename_buf)); | 6470 | dostounix_filename (SSDATA (filename)); |
| 6471 | #endif /* NTGUI_UNICODE */ | 6471 | #endif /* NTGUI_UNICODE */ |
| 6472 | 6472 | ||
| 6473 | #ifdef CYGWIN | 6473 | #ifdef CYGWIN |
diff --git a/src/w32proc.c b/src/w32proc.c index ea16f26a0ee..89748267bc6 100644 --- a/src/w32proc.c +++ b/src/w32proc.c | |||
| @@ -2647,10 +2647,11 @@ All path elements in FILENAME are converted to their short names. */) | |||
| 2647 | filename = Fexpand_file_name (filename, Qnil); | 2647 | filename = Fexpand_file_name (filename, Qnil); |
| 2648 | 2648 | ||
| 2649 | /* luckily, this returns the short version of each element in the path. */ | 2649 | /* luckily, this returns the short version of each element in the path. */ |
| 2650 | if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname, MAX_PATH) == 0) | 2650 | if (w32_get_short_filename (SDATA (ENCODE_FILE (filename)), |
| 2651 | shortname, MAX_PATH) == 0) | ||
| 2651 | return Qnil; | 2652 | return Qnil; |
| 2652 | 2653 | ||
| 2653 | dostounix_filename (shortname, 0); | 2654 | dostounix_filename (shortname); |
| 2654 | 2655 | ||
| 2655 | /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ | 2656 | /* No need to DECODE_FILE, because 8.3 names are pure ASCII. */ |
| 2656 | return build_string (shortname); | 2657 | return build_string (shortname); |
| @@ -2664,7 +2665,7 @@ If FILENAME does not exist, return nil. | |||
| 2664 | All path elements in FILENAME are converted to their long names. */) | 2665 | All path elements in FILENAME are converted to their long names. */) |
| 2665 | (Lisp_Object filename) | 2666 | (Lisp_Object filename) |
| 2666 | { | 2667 | { |
| 2667 | char longname[ MAX_PATH ]; | 2668 | char longname[ MAX_UTF8_PATH ]; |
| 2668 | int drive_only = 0; | 2669 | int drive_only = 0; |
| 2669 | 2670 | ||
| 2670 | CHECK_STRING (filename); | 2671 | CHECK_STRING (filename); |
| @@ -2676,10 +2677,11 @@ All path elements in FILENAME are converted to their long names. */) | |||
| 2676 | /* first expand it. */ | 2677 | /* first expand it. */ |
| 2677 | filename = Fexpand_file_name (filename, Qnil); | 2678 | filename = Fexpand_file_name (filename, Qnil); |
| 2678 | 2679 | ||
| 2679 | if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, MAX_PATH)) | 2680 | if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)), longname, |
| 2681 | MAX_UTF8_PATH)) | ||
| 2680 | return Qnil; | 2682 | return Qnil; |
| 2681 | 2683 | ||
| 2682 | dostounix_filename (longname, 0); | 2684 | dostounix_filename (longname); |
| 2683 | 2685 | ||
| 2684 | /* If we were passed only a drive, make sure that a slash is not appended | 2686 | /* If we were passed only a drive, make sure that a slash is not appended |
| 2685 | for consistency with directories. Allow for drive mapping via SUBST | 2687 | for consistency with directories. Allow for drive mapping via SUBST |
| @@ -2687,7 +2689,7 @@ All path elements in FILENAME are converted to their long names. */) | |||
| 2687 | if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3]) | 2689 | if (drive_only && longname[1] == ':' && longname[2] == '/' && !longname[3]) |
| 2688 | longname[2] = '\0'; | 2690 | longname[2] = '\0'; |
| 2689 | 2691 | ||
| 2690 | return DECODE_FILE (build_string (longname)); | 2692 | return DECODE_FILE (build_unibyte_string (longname)); |
| 2691 | } | 2693 | } |
| 2692 | 2694 | ||
| 2693 | DEFUN ("w32-set-process-priority", Fw32_set_process_priority, | 2695 | DEFUN ("w32-set-process-priority", Fw32_set_process_priority, |