From 0d8dfc45e363ea341b1c960a1b9f01dab9dfded0 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 25 Aug 2013 17:01:42 +0200 Subject: [PATCH 01/18] updated for version 7.4.008 Problem: New regexp engine can't be interrupted. Solution: Check for CTRL-C pressed. (Yasuhiro Matsumoto) --- src/regexp.c | 4 ++-- src/regexp_nfa.c | 6 ++++++ src/version.c | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/regexp.c b/src/regexp.c index 06bbb4a540..df884e25bd 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -4311,8 +4311,8 @@ regmatch(scan) */ for (;;) { - /* Some patterns may cause a long time to match, even though they are not - * illegal. E.g., "\([a-z]\+\)\+Q". Allow breaking them with CTRL-C. */ + /* Some patterns may take a long time to match, e.g., "\([a-z]\+\)\+Q". + * Allow interrupting them with CTRL-C. */ fast_breakcheck(); #ifdef DEBUG diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 57539f4e53..5288eb6d3f 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -5089,6 +5089,12 @@ nfa_regmatch(prog, start, submatch, m) return FALSE; } #endif + /* Some patterns may take a long time to match, especially when using + * recursive_regmatch(). Allow interrupting them with CTRL-C. */ + fast_breakcheck(); + if (got_int) + return FALSE; + nfa_match = FALSE; /* Allocate memory for the lists of nodes. */ diff --git a/src/version.c b/src/version.c index d34ed63ddf..22fc9b961b 100644 --- a/src/version.c +++ b/src/version.c @@ -727,6 +727,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 8, /**/ 7, /**/ From 335193bd5a9d7589e71eb7c1b06576f31719e2e2 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 25 Aug 2013 17:01:42 +0200 Subject: [PATCH 02/18] Added tag v7-4-008 for changeset b04bdb2c5fce --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index e3f2e100fa..bdd5d543ef 100644 --- a/.hgtags +++ b/.hgtags @@ -2730,3 +2730,4 @@ f6247eaf4e1d556f782321890d725663f74babe6 v7-4-004 3640cf4c0d4b6e5687bb7a31678fab70c88ed94b v7-4-005 2374a05efe20287d55bd824689a41becc7662505 v7-4-006 4fe1dfc7014e57b4beb5a01c9e94357265d19a92 v7-4-007 +b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 From cbeea0f01b5354f5e2830c38861b32cbd3e540bc Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 25 Aug 2013 17:46:08 +0200 Subject: [PATCH 03/18] updated for version 7.4.009 Problem: When a file was not decrypted (yet), writing it may destroy the contents. Solution: Mark the file as readonly until decryption was done. (Christian Brabandt) --- src/fileio.c | 7 +++++++ src/version.c | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/fileio.c b/src/fileio.c index b48a83a3cd..010d933a12 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2926,9 +2926,14 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, fname, did_ask) int *did_ask; /* flag: whether already asked for key */ { int method = crypt_method_from_magic((char *)ptr, *sizep); + int b_p_ro = curbuf->b_p_ro; if (method >= 0) { + /* Mark the buffer as read-only until the decryption has taken place. + * Avoids accidentally overwriting the file with garbage. */ + curbuf->b_p_ro = TRUE; + set_crypt_method(curbuf, method); if (method > 0) (void)blowfish_self_test(); @@ -2977,6 +2982,8 @@ check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile, fname, did_ask) *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len; mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len, (size_t)*sizep); + /* Restore the read-only flag. */ + curbuf->b_p_ro = b_p_ro; } } /* When starting to edit a new file which does not have encryption, clear diff --git a/src/version.c b/src/version.c index 22fc9b961b..9b5343e9d6 100644 --- a/src/version.c +++ b/src/version.c @@ -727,6 +727,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 9, /**/ 8, /**/ From 3283d2bbe4786eba8636f17596265eaefa9f91a2 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 25 Aug 2013 17:46:08 +0200 Subject: [PATCH 04/18] Added tag v7-4-009 for changeset 8b5d80861c5e --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index bdd5d543ef..fa8fadb41b 100644 --- a/.hgtags +++ b/.hgtags @@ -2731,3 +2731,4 @@ f6247eaf4e1d556f782321890d725663f74babe6 v7-4-004 2374a05efe20287d55bd824689a41becc7662505 v7-4-006 4fe1dfc7014e57b4beb5a01c9e94357265d19a92 v7-4-007 b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 +8b5d80861c5e0403ea9f54ddddce2752a463c8a5 v7-4-009 From 35a70f5453ed712bd1e8e756e2583867ec57d02a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:00:08 +0200 Subject: [PATCH 05/18] updated for version 7.4.010 Problem: Crash with invalid argument to mkdir(). Solution: Check for empty string. (lcd47) --- src/eval.c | 25 +++++++++++++++---------- src/version.c | 2 ++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/eval.c b/src/eval.c index 58317d29bd..73844800c4 100644 --- a/src/eval.c +++ b/src/eval.c @@ -14292,18 +14292,23 @@ f_mkdir(argvars, rettv) return; dir = get_tv_string_buf(&argvars[0], buf); - if (*gettail(dir) == NUL) - /* remove trailing slashes */ - *gettail_sep(dir) = NUL; - - if (argvars[1].v_type != VAR_UNKNOWN) + if (*dir == NUL) + rettv->vval.v_number = FAIL; + else { - if (argvars[2].v_type != VAR_UNKNOWN) - prot = get_tv_number_chk(&argvars[2], NULL); - if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) - mkdir_recurse(dir, prot); + if (*gettail(dir) == NUL) + /* remove trailing slashes */ + *gettail_sep(dir) = NUL; + + if (argvars[1].v_type != VAR_UNKNOWN) + { + if (argvars[2].v_type != VAR_UNKNOWN) + prot = get_tv_number_chk(&argvars[2], NULL); + if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) + mkdir_recurse(dir, prot); + } + rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); } - rettv->vval.v_number = prot == -1 ? FAIL : vim_mkdir_emsg(dir, prot); } #endif diff --git a/src/version.c b/src/version.c index 9b5343e9d6..61694a4672 100644 --- a/src/version.c +++ b/src/version.c @@ -727,6 +727,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 10, /**/ 9, /**/ From 581b7aaaf902831e6d4aa926e6590642b7020010 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:00:09 +0200 Subject: [PATCH 06/18] Added tag v7-4-010 for changeset bb358cc41d92 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index fa8fadb41b..cc216d98b0 100644 --- a/.hgtags +++ b/.hgtags @@ -2732,3 +2732,4 @@ f6247eaf4e1d556f782321890d725663f74babe6 v7-4-004 4fe1dfc7014e57b4beb5a01c9e94357265d19a92 v7-4-007 b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 8b5d80861c5e0403ea9f54ddddce2752a463c8a5 v7-4-009 +bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 From cabbc20d8762b4d8ab14d39a6a6582f227df63dc Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:35:44 +0200 Subject: [PATCH 07/18] updated for version 7.4.011 Problem: Cannot find out if "acl" and "xpm" features are supported. Solution: Add "acl" and "xpm" to the list of features. (Ken Takata) --- src/eval.c | 10 +++++++++- src/version.c | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index 73844800c4..807efe25f3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12135,6 +12135,9 @@ f_has(argvars, rettv) #ifndef CASE_INSENSITIVE_FILENAME "fname_case", #endif +#ifdef HAVE_ACL + "acl", +#endif #ifdef FEAT_ARABIC "arabic", #endif @@ -12538,7 +12541,12 @@ f_has(argvars, rettv) "xfontset", #endif #ifdef FEAT_XPM_W32 - "xpm_w32", + "xpm", + "xpm_w32", /* for backward compatibility */ +#else +# if defined(HAVE_XPM) + "xpm", +# endif #endif #ifdef USE_XSMP "xsmp", diff --git a/src/version.c b/src/version.c index 61694a4672..3e530040d9 100644 --- a/src/version.c +++ b/src/version.c @@ -60,6 +60,11 @@ static void version_msg __ARGS((char *s)); static char *(features[]) = { +#ifdef HAVE_ACL + "+acl", +#else + "-acl", +#endif #ifdef AMIGA /* only for Amiga systems */ # ifdef FEAT_ARP "+ARP", @@ -721,12 +726,20 @@ static char *(features[]) = # else "-xpm_w32", # endif +#else +# ifdef HAVE_XPM + "+xpm", +# else + "-xpm", +# endif #endif NULL }; static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 11, /**/ 10, /**/ From 9eb60f358e945f72f15d73c58648a697b58f4d97 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:35:45 +0200 Subject: [PATCH 08/18] Added tag v7-4-011 for changeset 54e66395831c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index cc216d98b0..ba0ff42a25 100644 --- a/.hgtags +++ b/.hgtags @@ -2733,3 +2733,4 @@ f6247eaf4e1d556f782321890d725663f74babe6 v7-4-004 b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 8b5d80861c5e0403ea9f54ddddce2752a463c8a5 v7-4-009 bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 +54e66395831c1a58b4a9804e7884e505842157e8 v7-4-011 From 554e2eab3229f8fafac484eb3ba24117f8c0df1f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:44:19 +0200 Subject: [PATCH 09/18] updated for version 7.4.012 Problem: MS-Windows: resolving shortcut does not work properly with multi-byte characters. Solution: Use wide system functions. (Ken Takata) --- src/os_mswin.c | 68 ++++++++++++++++++++++++++++++++++++++++++++------ src/version.c | 2 ++ 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/os_mswin.c b/src/os_mswin.c index 96d3448c33..77f5599176 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -1761,9 +1761,13 @@ mch_resolve_shortcut(char_u *fname) IPersistFile *ppf = NULL; OLECHAR wsz[MAX_PATH]; WIN32_FIND_DATA ffd; // we get those free of charge - TCHAR buf[MAX_PATH]; // could have simply reused 'wsz'... + CHAR buf[MAX_PATH]; // could have simply reused 'wsz'... char_u *rfname = NULL; int len; +# ifdef FEAT_MBYTE + IShellLinkW *pslw = NULL; + WIN32_FIND_DATAW ffdw; // we get those free of charge +# endif /* Check if the file name ends in ".lnk". Avoid calling * CoCreateInstance(), it's quite slow. */ @@ -1775,18 +1779,62 @@ mch_resolve_shortcut(char_u *fname) CoInitialize(NULL); +# ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + // create a link manager object and request its interface + hr = CoCreateInstance( + &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, (void**)&pslw); + if (hr == S_OK) + { + WCHAR *p = enc_to_utf16(fname, NULL); + + if (p != NULL) + { + // Get a pointer to the IPersistFile interface. + hr = pslw->lpVtbl->QueryInterface( + pslw, &IID_IPersistFile, (void**)&ppf); + if (hr != S_OK) + goto shortcut_errorw; + + // "load" the name and resolve the link + hr = ppf->lpVtbl->Load(ppf, p, STGM_READ); + if (hr != S_OK) + goto shortcut_errorw; +# if 0 // This makes Vim wait a long time if the target does not exist. + hr = pslw->lpVtbl->Resolve(pslw, NULL, SLR_NO_UI); + if (hr != S_OK) + goto shortcut_errorw; +# endif + + // Get the path to the link target. + ZeroMemory(wsz, MAX_PATH * sizeof(WCHAR)); + hr = pslw->lpVtbl->GetPath(pslw, wsz, MAX_PATH, &ffdw, 0); + if (hr == S_OK && wsz[0] != NUL) + rfname = utf16_to_enc(wsz, NULL); + +shortcut_errorw: + vim_free(p); + if (hr == S_OK) + goto shortcut_end; + } + } + /* Retry with non-wide function (for Windows 98). */ + } +# endif // create a link manager object and request its interface hr = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (void**)&psl); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; // Get a pointer to the IPersistFile interface. hr = psl->lpVtbl->QueryInterface( psl, &IID_IPersistFile, (void**)&ppf); if (hr != S_OK) - goto shortcut_error; + goto shortcut_end; // full path string must be in Unicode. MultiByteToWideChar(CP_ACP, 0, fname, -1, wsz, MAX_PATH); @@ -1794,12 +1842,12 @@ mch_resolve_shortcut(char_u *fname) // "load" the name and resolve the link hr = ppf->lpVtbl->Load(ppf, wsz, STGM_READ); if (hr != S_OK) - goto shortcut_error; -#if 0 // This makes Vim wait a long time if the target doesn't exist. + goto shortcut_end; +# if 0 // This makes Vim wait a long time if the target doesn't exist. hr = psl->lpVtbl->Resolve(psl, NULL, SLR_NO_UI); if (hr != S_OK) - goto shortcut_error; -#endif + goto shortcut_end; +# endif // Get the path to the link target. ZeroMemory(buf, MAX_PATH); @@ -1807,12 +1855,16 @@ mch_resolve_shortcut(char_u *fname) if (hr == S_OK && buf[0] != NUL) rfname = vim_strsave(buf); -shortcut_error: +shortcut_end: // Release all interface pointers (both belong to the same object) if (ppf != NULL) ppf->lpVtbl->Release(ppf); if (psl != NULL) psl->lpVtbl->Release(psl); +# ifdef FEAT_MBYTE + if (pslw != NULL) + pslw->lpVtbl->Release(pslw); +# endif CoUninitialize(); return rfname; diff --git a/src/version.c b/src/version.c index 3e530040d9..8eee3e95cc 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 12, /**/ 11, /**/ From d7d89c9cadb3acc24311241b9077e2688b89b116 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:44:19 +0200 Subject: [PATCH 10/18] Added tag v7-4-012 for changeset 8e28c23e482c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index ba0ff42a25..dcad050964 100644 --- a/.hgtags +++ b/.hgtags @@ -2734,3 +2734,4 @@ b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 8b5d80861c5e0403ea9f54ddddce2752a463c8a5 v7-4-009 bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 54e66395831c1a58b4a9804e7884e505842157e8 v7-4-011 +8e28c23e482c5b3c8296d8022271822886793456 v7-4-012 From be17bc2cc21ba025f181f628a04b35b2a0d4da31 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:51:18 +0200 Subject: [PATCH 11/18] updated for version 7.4.013 Problem: File name buffer too small for utf-8. Solution: Use character count instead of byte count. (Ken Takata) --- src/os_mswin.c | 18 ++++++++++++++++-- src/version.c | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/os_mswin.c b/src/os_mswin.c index 77f5599176..67b7960978 100644 --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -456,7 +456,14 @@ mch_FullName( int mch_isFullName(char_u *fname) { +#ifdef FEAT_MBYTE + /* WinNT and later can use _MAX_PATH wide characters for a pathname, which + * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is + * UTF-8. */ + char szName[_MAX_PATH * 3 + 1]; +#else char szName[_MAX_PATH + 1]; +#endif /* A name like "d:/foo" and "//server/share" is absolute */ if ((fname[0] && fname[1] == ':' && (fname[2] == '/' || fname[2] == '\\')) @@ -464,7 +471,7 @@ mch_isFullName(char_u *fname) return TRUE; /* A name that can't be made absolute probably isn't absolute. */ - if (mch_FullName(fname, szName, _MAX_PATH, FALSE) == FAIL) + if (mch_FullName(fname, szName, sizeof(szName) - 1, FALSE) == FAIL) return FALSE; return pathcmp(fname, szName, -1) == 0; @@ -498,10 +505,17 @@ slash_adjust(p) int vim_stat(const char *name, struct stat *stp) { +#ifdef FEAT_MBYTE + /* WinNT and later can use _MAX_PATH wide characters for a pathname, which + * means that the maximum pathname is _MAX_PATH * 3 bytes when 'enc' is + * UTF-8. */ + char buf[_MAX_PATH * 3 + 1]; +#else char buf[_MAX_PATH + 1]; +#endif char *p; - vim_strncpy((char_u *)buf, (char_u *)name, _MAX_PATH); + vim_strncpy((char_u *)buf, (char_u *)name, sizeof(buf) - 1); p = buf + strlen(buf); if (p > buf) mb_ptr_back(buf, p); diff --git a/src/version.c b/src/version.c index 8eee3e95cc..13ff1ca522 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 13, /**/ 12, /**/ From 5dcb84635faaee99c7917c2a24894b6de700f476 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 16:51:19 +0200 Subject: [PATCH 12/18] Added tag v7-4-013 for changeset 07737d3aa817 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index dcad050964..aebea90928 100644 --- a/.hgtags +++ b/.hgtags @@ -2735,3 +2735,4 @@ b04bdb2c5fce70a278d26c477debb65a388da0ca v7-4-008 bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 54e66395831c1a58b4a9804e7884e505842157e8 v7-4-011 8e28c23e482c5b3c8296d8022271822886793456 v7-4-012 +07737d3aa81725672796cbc9a010d63414ab6fea v7-4-013 From c643a48c398ef60a30a13ae7127bce7e96af14f4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:07:01 +0200 Subject: [PATCH 13/18] updated for version 7.4.014 Problem: MS-Windows: check for writing to device does not work. Solution: Fix #ifdefs. (Ken Takata) --- src/fileio.c | 17 ++++++++--------- src/version.c | 2 ++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index 010d933a12..233990bf50 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -428,13 +428,13 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) } } -#ifdef UNIX - /* - * On Unix it is possible to read a directory, so we have to - * check for it before the mch_open(). - */ if (!read_stdin && !read_buffer) { +#ifdef UNIX + /* + * On Unix it is possible to read a directory, so we have to + * check for it before the mch_open(). + */ perm = mch_getperm(fname); if (perm >= 0 && !S_ISREG(perm) /* not a regular file ... */ # ifdef S_ISFIFO @@ -457,8 +457,8 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) msg_scroll = msg_save; return FAIL; } - -# if defined(MSDOS) || defined(MSWIN) || defined(OS2) +#endif +#if defined(MSDOS) || defined(MSWIN) || defined(OS2) /* * MS-Windows allows opening a device, but we will probably get stuck * trying to read it. @@ -470,9 +470,8 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) msg_scroll = msg_save; return FAIL; } -# endif - } #endif + } /* Set default or forced 'fileformat' and 'binary'. */ set_file_options(set_options, eap); diff --git a/src/version.c b/src/version.c index 13ff1ca522..e8b935966a 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 14, /**/ 13, /**/ From a573223877eb367cdccb7251cb920ceda0d9b570 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:07:02 +0200 Subject: [PATCH 14/18] Added tag v7-4-014 for changeset 9801d06e7b4c --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index aebea90928..407c322bb3 100644 --- a/.hgtags +++ b/.hgtags @@ -2736,3 +2736,4 @@ bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 54e66395831c1a58b4a9804e7884e505842157e8 v7-4-011 8e28c23e482c5b3c8296d8022271822886793456 v7-4-012 07737d3aa81725672796cbc9a010d63414ab6fea v7-4-013 +9801d06e7b4ccdcd02cf40bee34eaaada0ca0409 v7-4-014 From aa8c48fe550502552965d12b87e6278def5ce575 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:11:33 +0200 Subject: [PATCH 15/18] updated for version 7.4.015 Problem: MS-Windows: Detecting node type does not work for multi-byte characters. Solution: Use wide character function when needed. (Ken Takata) --- src/os_win32.c | 44 +++++++++++++++++++++++++++++++++++++------- src/version.c | 2 ++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/os_win32.c b/src/os_win32.c index 4013353cf3..33a72565aa 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -3107,6 +3107,9 @@ mch_nodetype(char_u *name) { HANDLE hFile; int type; +#ifdef FEAT_MBYTE + WCHAR *wn = NULL; +#endif /* We can't open a file with a name "\\.\con" or "\\.\prn" and trying to * read from it later will cause Vim to hang. Thus return NODE_WRITABLE @@ -3114,14 +3117,41 @@ mch_nodetype(char_u *name) if (STRNCMP(name, "\\\\.\\", 4) == 0) return NODE_WRITABLE; - hFile = CreateFile(name, /* file name */ - GENERIC_WRITE, /* access mode */ - 0, /* share mode */ - NULL, /* security descriptor */ - OPEN_EXISTING, /* creation disposition */ - 0, /* file attributes */ - NULL); /* handle to template file */ +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + wn = enc_to_utf16(name, NULL); + if (wn != NULL) + { + hFile = CreateFileW(wn, /* file name */ + GENERIC_WRITE, /* access mode */ + 0, /* share mode */ + NULL, /* security descriptor */ + OPEN_EXISTING, /* creation disposition */ + 0, /* file attributes */ + NULL); /* handle to template file */ + if (hFile == INVALID_HANDLE_VALUE + && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + { + /* Retry with non-wide function (for Windows 98). */ + vim_free(wn); + wn = NULL; + } + } + } + if (wn == NULL) +#endif + hFile = CreateFile(name, /* file name */ + GENERIC_WRITE, /* access mode */ + 0, /* share mode */ + NULL, /* security descriptor */ + OPEN_EXISTING, /* creation disposition */ + 0, /* file attributes */ + NULL); /* handle to template file */ +#ifdef FEAT_MBYTE + vim_free(wn); +#endif if (hFile == INVALID_HANDLE_VALUE) return NODE_NORMAL; diff --git a/src/version.c b/src/version.c index e8b935966a..fb14593310 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 15, /**/ 14, /**/ From abfb2163cbe0f1d75b5fd3f212fbed27e91efdaf Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:11:33 +0200 Subject: [PATCH 16/18] Added tag v7-4-015 for changeset a7478f9f2551 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 407c322bb3..093942cc30 100644 --- a/.hgtags +++ b/.hgtags @@ -2737,3 +2737,4 @@ bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 8e28c23e482c5b3c8296d8022271822886793456 v7-4-012 07737d3aa81725672796cbc9a010d63414ab6fea v7-4-013 9801d06e7b4ccdcd02cf40bee34eaaada0ca0409 v7-4-014 +a7478f9f2551e95bff138cd658f7a86ced804ab1 v7-4-015 From 4ff15ba7b69c8bd8c348e0dc47ff7e9335484187 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:29:16 +0200 Subject: [PATCH 17/18] updated for version 7.4.016 Problem: MS-Windows: File name completion doesn't work properly with Chinese characters. (Yue Wu) Solution: Add fname_casew(). (Ken Takata) --- src/os_win32.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++- src/version.c | 2 + 2 files changed, 152 insertions(+), 1 deletion(-) diff --git a/src/os_win32.c b/src/os_win32.c index 33a72565aa..f36dfb3db9 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -2500,9 +2500,125 @@ mch_check_win( } +#ifdef FEAT_MBYTE +/* + * fname_casew(): Wide version of fname_case(). Set the case of the file name, + * if it already exists. When "len" is > 0, also expand short to long + * filenames. + * Return FAIL if wide functions are not available, OK otherwise. + * NOTE: much of this is identical to fname_case(), keep in sync! + */ + static int +fname_casew( + WCHAR *name, + int len) +{ + WCHAR szTrueName[_MAX_PATH + 2]; + WCHAR szTrueNameTemp[_MAX_PATH + 2]; + WCHAR *ptrue, *ptruePrev; + WCHAR *porig, *porigPrev; + int flen; + WIN32_FIND_DATAW fb; + HANDLE hFind; + int c; + int slen; + + flen = (int)wcslen(name); + if (flen > _MAX_PATH) + return OK; + + /* slash_adjust(name) not needed, already adjusted by fname_case(). */ + + /* Build the new name in szTrueName[] one component at a time. */ + porig = name; + ptrue = szTrueName; + + if (iswalpha(porig[0]) && porig[1] == L':') + { + /* copy leading drive letter */ + *ptrue++ = *porig++; + *ptrue++ = *porig++; + *ptrue = NUL; /* in case nothing follows */ + } + + while (*porig != NUL) + { + /* copy \ characters */ + while (*porig == psepc) + *ptrue++ = *porig++; + + ptruePrev = ptrue; + porigPrev = porig; + while (*porig != NUL && *porig != psepc) + { + *ptrue++ = *porig++; + } + *ptrue = NUL; + + /* To avoid a slow failure append "\*" when searching a directory, + * server or network share. */ + wcscpy(szTrueNameTemp, szTrueName); + slen = (int)wcslen(szTrueNameTemp); + if (*porig == psepc && slen + 2 < _MAX_PATH) + wcscpy(szTrueNameTemp + slen, L"\\*"); + + /* Skip "", "." and "..". */ + if (ptrue > ptruePrev + && (ptruePrev[0] != L'.' + || (ptruePrev[1] != NUL + && (ptruePrev[1] != L'.' || ptruePrev[2] != NUL))) + && (hFind = FindFirstFileW(szTrueNameTemp, &fb)) + != INVALID_HANDLE_VALUE) + { + c = *porig; + *porig = NUL; + + /* Only use the match when it's the same name (ignoring case) or + * expansion is allowed and there is a match with the short name + * and there is enough room. */ + if (_wcsicoll(porigPrev, fb.cFileName) == 0 + || (len > 0 + && (_wcsicoll(porigPrev, fb.cAlternateFileName) == 0 + && (int)(ptruePrev - szTrueName) + + (int)wcslen(fb.cFileName) < len))) + { + wcscpy(ptruePrev, fb.cFileName); + + /* Look for exact match and prefer it if found. Must be a + * long name, otherwise there would be only one match. */ + while (FindNextFileW(hFind, &fb)) + { + if (*fb.cAlternateFileName != NUL + && (wcscoll(porigPrev, fb.cFileName) == 0 + || (len > 0 + && (_wcsicoll(porigPrev, + fb.cAlternateFileName) == 0 + && (int)(ptruePrev - szTrueName) + + (int)wcslen(fb.cFileName) < len)))) + { + wcscpy(ptruePrev, fb.cFileName); + break; + } + } + } + FindClose(hFind); + *porig = c; + ptrue = ptruePrev + wcslen(ptruePrev); + } + else if (hFind == INVALID_HANDLE_VALUE + && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + return FAIL; + } + + wcscpy(name, szTrueName); + return OK; +} +#endif + /* * fname_case(): Set the case of the file name, if it already exists. * When "len" is > 0, also expand short to long filenames. + * NOTE: much of this is identical to fname_casew(), keep in sync! */ void fname_case( @@ -2520,11 +2636,44 @@ fname_case( int slen; flen = (int)STRLEN(name); - if (flen == 0 || flen > _MAX_PATH) + if (flen == 0) return; slash_adjust(name); +#ifdef FEAT_MBYTE + if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { + WCHAR *p = enc_to_utf16(name, NULL); + + if (p != NULL) + { + char_u *q; + WCHAR buf[_MAX_PATH + 2]; + + wcscpy(buf, p); + vim_free(p); + + if (fname_casew(buf, (len > 0) ? _MAX_PATH : 0) == OK) + { + q = utf16_to_enc(buf, NULL); + if (q != NULL) + { + vim_strncpy(name, q, (len > 0) ? len - 1 : flen); + vim_free(q); + return; + } + } + } + /* Retry with non-wide function (for Windows 98). */ + } +#endif + + /* If 'enc' is utf-8, flen can be larger than _MAX_PATH. + * So we should check this after calling wide function. */ + if (flen > _MAX_PATH) + return; + /* Build the new name in szTrueName[] one component at a time. */ porig = name; ptrue = szTrueName; diff --git a/src/version.c b/src/version.c index fb14593310..ce71dff777 100644 --- a/src/version.c +++ b/src/version.c @@ -738,6 +738,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 16, /**/ 15, /**/ From 3fd86dc03a4929c9146b739fff16314b9e760b4f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Aug 2013 17:29:16 +0200 Subject: [PATCH 18/18] Added tag v7-4-016 for changeset 8d5cd0ec3e71 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 093942cc30..d112ae08aa 100644 --- a/.hgtags +++ b/.hgtags @@ -2738,3 +2738,4 @@ bb358cc41d920983629ace62bcf26decbf06cab4 v7-4-010 07737d3aa81725672796cbc9a010d63414ab6fea v7-4-013 9801d06e7b4ccdcd02cf40bee34eaaada0ca0409 v7-4-014 a7478f9f2551e95bff138cd658f7a86ced804ab1 v7-4-015 +8d5cd0ec3e7183a289f9bac41d3981307cdc1fac v7-4-016