summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.0894
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.0894')
-rw-r--r--data/vim/patches/8.1.0894453
1 files changed, 453 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.0894 b/data/vim/patches/8.1.0894
new file mode 100644
index 000000000..7112d6403
--- /dev/null
+++ b/data/vim/patches/8.1.0894
@@ -0,0 +1,453 @@
+To: vim_dev@googlegroups.com
+Subject: Patch 8.1.0894
+Fcc: outbox
+From: Bram Moolenaar <Bram@moolenaar.net>
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+------------
+
+Patch 8.1.0894
+Problem: MS-Windows: resolve() does not return a reparse point.
+Solution: Improve resolve(). (Yasuhiro Matsumoto, closes #3896)
+Files: runtime/doc/eval.txt, src/buffer.c, src/evalfunc.c,
+ src/os_mswin.c, src/proto/os_mswin.pro,
+ src/testdir/test_functions.vim
+
+
+*** ../vim-8.1.0893/runtime/doc/eval.txt 2019-02-08 12:46:03.584784210 +0100
+--- runtime/doc/eval.txt 2019-02-10 23:05:41.630790837 +0100
+***************
+*** 7330,7335 ****
+--- 7385,7393 ----
+ resolve({filename}) *resolve()* *E655*
+ On MS-Windows, when {filename} is a shortcut (a .lnk file),
+ returns the path the shortcut points to in a simplified form.
++ When {filename} is a symbolic link or junction point, return
++ the full path to the target. If the target of junction is
++ removed, return {filename}.
+ On Unix, repeat resolving symbolic links in all path
+ components of {filename} and return the simplified result.
+ To cope with link cycles, resolving of symbolic links is
+*** ../vim-8.1.0893/src/buffer.c 2019-02-05 21:23:00.600559169 +0100
+--- src/buffer.c 2019-02-10 23:05:41.630790837 +0100
+***************
+*** 4847,4853 ****
+ char_u *rfname;
+
+ // If the file name is a shortcut file, use the file it links to.
+! rfname = mch_resolve_shortcut(*ffname);
+ if (rfname != NULL)
+ {
+ vim_free(*ffname);
+--- 4847,4853 ----
+ char_u *rfname;
+
+ // If the file name is a shortcut file, use the file it links to.
+! rfname = mch_resolve_path(*ffname, FALSE);
+ if (rfname != NULL)
+ {
+ vim_free(*ffname);
+*** ../vim-8.1.0893/src/evalfunc.c 2019-02-10 22:58:58.976414779 +0100
+--- src/evalfunc.c 2019-02-10 23:05:41.630790837 +0100
+***************
+*** 9912,9918 ****
+ {
+ char_u *v = NULL;
+
+! v = mch_resolve_shortcut(p);
+ if (v != NULL)
+ rettv->vval.v_string = v;
+ else
+--- 9912,9918 ----
+ {
+ char_u *v = NULL;
+
+! v = mch_resolve_path(p, TRUE);
+ if (v != NULL)
+ rettv->vval.v_string = v;
+ else
+*** ../vim-8.1.0893/src/os_mswin.c 2019-01-24 16:38:58.272712472 +0100
+--- src/os_mswin.c 2019-02-10 23:12:31.960522594 +0100
+***************
+*** 1823,1835 ****
+ # include <shlobj.h>
+ # endif
+
+ /*
+ * When "fname" is the name of a shortcut (*.lnk) resolve the file it points
+ * to and return that name in allocated memory.
+ * Otherwise NULL is returned.
+ */
+! char_u *
+! mch_resolve_shortcut(char_u *fname)
+ {
+ HRESULT hr;
+ IShellLink *psl = NULL;
+--- 1823,2003 ----
+ # include <shlobj.h>
+ # endif
+
++ typedef enum _FILE_INFO_BY_HANDLE_CLASS_ {
++ FileBasicInfo_,
++ FileStandardInfo_,
++ FileNameInfo_,
++ FileRenameInfo_,
++ FileDispositionInfo_,
++ FileAllocationInfo_,
++ FileEndOfFileInfo_,
++ FileStreamInfo_,
++ FileCompressionInfo_,
++ FileAttributeTagInfo_,
++ FileIdBothDirectoryInfo_,
++ FileIdBothDirectoryRestartInfo_,
++ FileIoPriorityHintInfo_,
++ FileRemoteProtocolInfo_,
++ FileFullDirectoryInfo_,
++ FileFullDirectoryRestartInfo_,
++ FileStorageInfo_,
++ FileAlignmentInfo_,
++ FileIdInfo_,
++ FileIdExtdDirectoryInfo_,
++ FileIdExtdDirectoryRestartInfo_,
++ FileDispositionInfoEx_,
++ FileRenameInfoEx_,
++ MaximumFileInfoByHandleClass_
++ } FILE_INFO_BY_HANDLE_CLASS_;
++
++ typedef struct _FILE_NAME_INFO_ {
++ DWORD FileNameLength;
++ WCHAR FileName[1];
++ } FILE_NAME_INFO_;
++
++ typedef BOOL (WINAPI *pfnGetFileInformationByHandleEx)(
++ HANDLE hFile,
++ FILE_INFO_BY_HANDLE_CLASS_ FileInformationClass,
++ LPVOID lpFileInformation,
++ DWORD dwBufferSize);
++ static pfnGetFileInformationByHandleEx pGetFileInformationByHandleEx = NULL;
++
++ typedef BOOL (WINAPI *pfnGetVolumeInformationByHandleW)(
++ HANDLE hFile,
++ LPWSTR lpVolumeNameBuffer,
++ DWORD nVolumeNameSize,
++ LPDWORD lpVolumeSerialNumber,
++ LPDWORD lpMaximumComponentLength,
++ LPDWORD lpFileSystemFlags,
++ LPWSTR lpFileSystemNameBuffer,
++ DWORD nFileSystemNameSize);
++ static pfnGetVolumeInformationByHandleW pGetVolumeInformationByHandleW = NULL;
++
++ char_u *
++ resolve_reparse_point(char_u *fname)
++ {
++ HANDLE h = INVALID_HANDLE_VALUE;
++ DWORD size;
++ char_u *rfname = NULL;
++ FILE_NAME_INFO_ *nameinfo = NULL;
++ WCHAR buff[MAX_PATH], *volnames = NULL;
++ HANDLE hv;
++ DWORD snfile, snfind;
++ static BOOL loaded = FALSE;
++
++ if (pGetFileInformationByHandleEx == NULL ||
++ pGetVolumeInformationByHandleW == NULL)
++ {
++ HMODULE hmod = GetModuleHandle("kernel32.dll");
++
++ if (loaded == TRUE)
++ return NULL;
++ pGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx)
++ GetProcAddress(hmod, "GetFileInformationByHandleEx");
++ pGetVolumeInformationByHandleW = (pfnGetVolumeInformationByHandleW)
++ GetProcAddress(hmod, "GetVolumeInformationByHandleW");
++ loaded = TRUE;
++ if (pGetFileInformationByHandleEx == NULL ||
++ pGetVolumeInformationByHandleW == NULL)
++ return NULL;
++ }
++
++ if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
++ {
++ WCHAR *p;
++
++ p = enc_to_utf16(fname, NULL);
++ if (p == NULL)
++ goto fail;
++
++ if ((GetFileAttributesW(p) & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
++ {
++ vim_free(p);
++ goto fail;
++ }
++
++ h = CreateFileW(p, 0, 0, NULL, OPEN_EXISTING,
++ FILE_FLAG_BACKUP_SEMANTICS, NULL);
++ vim_free(p);
++ }
++ else
++ {
++ if ((GetFileAttributes((char*) fname) &
++ FILE_ATTRIBUTE_REPARSE_POINT) == 0)
++ goto fail;
++
++ h = CreateFile((char*) fname, 0, 0, NULL, OPEN_EXISTING,
++ FILE_FLAG_BACKUP_SEMANTICS, NULL);
++ }
++
++ if (h == INVALID_HANDLE_VALUE)
++ goto fail;
++
++ size = sizeof(FILE_NAME_INFO_) + sizeof(WCHAR) * (MAX_PATH - 1);
++ nameinfo = (FILE_NAME_INFO_*)alloc(size + sizeof(WCHAR));
++ if (nameinfo == NULL)
++ goto fail;
++
++ if (!pGetFileInformationByHandleEx(h, FileNameInfo_, nameinfo, size))
++ goto fail;
++
++ nameinfo->FileName[nameinfo->FileNameLength / sizeof(WCHAR)] = 0;
++
++ if (!pGetVolumeInformationByHandleW(
++ h, NULL, 0, &snfile, NULL, NULL, NULL, 0))
++ goto fail;
++
++ hv = FindFirstVolumeW(buff, MAX_PATH);
++ if (hv == INVALID_HANDLE_VALUE)
++ goto fail;
++
++ do {
++ GetVolumeInformationW(
++ buff, NULL, 0, &snfind, NULL, NULL, NULL, 0);
++ if (snfind == snfile)
++ break;
++ } while (FindNextVolumeW(hv, buff, MAX_PATH));
++
++ FindVolumeClose(hv);
++
++ if (snfind != snfile)
++ goto fail;
++
++ size = 0;
++ if (!GetVolumePathNamesForVolumeNameW(buff, NULL, 0, &size) &&
++ GetLastError() != ERROR_MORE_DATA)
++ goto fail;
++
++ volnames = (WCHAR*)alloc(size * sizeof(WCHAR));
++ if (!GetVolumePathNamesForVolumeNameW(buff, volnames, size,
++ &size))
++ goto fail;
++
++ wcscpy(buff, volnames);
++ if (nameinfo->FileName[0] == '\\')
++ wcscat(buff, nameinfo->FileName + 1);
++ else
++ wcscat(buff, nameinfo->FileName);
++ rfname = utf16_to_enc(buff, NULL);
++
++ fail:
++ if (h != INVALID_HANDLE_VALUE)
++ CloseHandle(h);
++ if (nameinfo != NULL)
++ vim_free(nameinfo);
++ if (volnames != NULL)
++ vim_free(volnames);
++
++ return rfname;
++ }
++
+ /*
+ * When "fname" is the name of a shortcut (*.lnk) resolve the file it points
+ * to and return that name in allocated memory.
+ * Otherwise NULL is returned.
+ */
+! static char_u *
+! resolve_shortcut(char_u *fname)
+ {
+ HRESULT hr;
+ IShellLink *psl = NULL;
+***************
+*** 1937,1942 ****
+--- 2105,2120 ----
+ CoUninitialize();
+ return rfname;
+ }
++
++ char_u *
++ mch_resolve_path(char_u *fname, int reparse_point)
++ {
++ char_u *path = resolve_shortcut(fname);
++
++ if (path == NULL && reparse_point)
++ path = resolve_reparse_point(fname);
++ return path;
++ }
+ #endif
+
+ #if (defined(FEAT_EVAL) && !defined(FEAT_GUI)) || defined(PROTO)
+*** ../vim-8.1.0893/src/proto/os_mswin.pro 2018-05-17 13:53:03.000000000 +0200
+--- src/proto/os_mswin.pro 2019-02-10 23:05:41.634790818 +0100
+***************
+*** 37,43 ****
+ void mch_print_set_font(int iBold, int iItalic, int iUnderline);
+ void mch_print_set_bg(long_u bgcol);
+ void mch_print_set_fg(long_u fgcol);
+! char_u *mch_resolve_shortcut(char_u *fname);
+ void win32_set_foreground(void);
+ void serverInitMessaging(void);
+ void serverSetName(char_u *name);
+--- 37,43 ----
+ void mch_print_set_font(int iBold, int iItalic, int iUnderline);
+ void mch_print_set_bg(long_u bgcol);
+ void mch_print_set_fg(long_u fgcol);
+! char_u *mch_resolve_path(char_u *fname, int reparse_point);
+ void win32_set_foreground(void);
+ void serverInitMessaging(void);
+ void serverSetName(char_u *name);
+*** ../vim-8.1.0893/src/testdir/test_functions.vim 2019-02-08 23:09:43.257123080 +0100
+--- src/testdir/test_functions.vim 2019-02-10 23:05:41.634790818 +0100
+***************
+*** 188,194 ****
+ call assert_fails('call strftime("%Y", [])', 'E745:')
+ endfunc
+
+! func Test_resolve()
+ if !has('unix')
+ return
+ endif
+--- 188,194 ----
+ call assert_fails('call strftime("%Y", [])', 'E745:')
+ endfunc
+
+! func Test_resolve_unix()
+ if !has('unix')
+ return
+ endif
+***************
+*** 234,239 ****
+--- 234,336 ----
+ call delete('Xlink1')
+ endfunc
+
++ func s:normalize_fname(fname)
++ let ret = substitute(a:fname, '\', '/', 'g')
++ let ret = substitute(ret, '//', '/', 'g')
++ let ret = tolower(ret)
++ endfunc
++
++ func Test_resolve_win32()
++ if !has('win32')
++ return
++ endif
++
++ " test for shortcut file
++ if executable('cscript')
++ new Xfile
++ wq
++ call writefile([
++ \ 'Set fs = CreateObject("Scripting.FileSystemObject")',
++ \ 'Set ws = WScript.CreateObject("WScript.Shell")',
++ \ 'Set shortcut = ws.CreateShortcut("Xlink.lnk")',
++ \ 'shortcut.TargetPath = fs.BuildPath(ws.CurrentDirectory, "Xfile")',
++ \ 'shortcut.Save'
++ \], 'link.vbs')
++ silent !cscript link.vbs
++ call delete('link.vbs')
++ call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink.lnk')))
++ call delete('Xfile')
++
++ call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink.lnk')))
++ call delete('Xlink.lnk')
++ else
++ echomsg 'skipped test for shortcut file'
++ endif
++
++ " remove files
++ call delete('Xlink')
++ call delete('Xdir', 'd')
++ call delete('Xfile')
++
++ " test for symbolic link to a file
++ new Xfile
++ wq
++ silent !mklink Xlink Xfile
++ if !v:shell_error
++ call assert_equal(s:normalize_fname(getcwd() . '\Xfile'), s:normalize_fname(resolve('./Xlink')))
++ call delete('Xlink')
++ else
++ echomsg 'skipped test for symbolic link to a file'
++ endif
++ call delete('Xfile')
++
++ " test for junction to a directory
++ call mkdir('Xdir')
++ silent !mklink /J Xlink Xdir
++ if !v:shell_error
++ call assert_equal(s:normalize_fname(getcwd() . '\Xdir'), s:normalize_fname(resolve(getcwd() . '/Xlink')))
++
++ call delete('Xdir', 'd')
++
++ " test for junction already removed
++ call assert_equal(s:normalize_fname(getcwd() . '\Xlink'), s:normalize_fname(resolve(getcwd() . '/Xlink')))
++ call delete('Xlink')
++ else
++ echomsg 'skipped test for junction to a directory'
++ call delete('Xdir', 'd')
++ endif
++
++ " test for symbolic link to a directory
++ call mkdir('Xdir')
++ silent !mklink /D Xlink Xdir
++ if !v:shell_error
++ call assert_equal(s:normalize_fname(getcwd() . '\Xdir'), s:normalize_fname(resolve(getcwd() . '/Xlink')))
++
++ call delete('Xdir', 'd')
++
++ " test for symbolic link already removed
++ call assert_equal(s:normalize_fname(getcwd() . '\Xlink'), s:normalize_fname(resolve(getcwd() . '/Xlink')))
++ call delete('Xlink')
++ else
++ echomsg 'skipped test for symbolic link to a directory'
++ call delete('Xdir', 'd')
++ endif
++
++ " test for buffer name
++ new Xfile
++ wq
++ silent !mklink Xlink Xfile
++ if !v:shell_error
++ edit Xlink
++ call assert_equal('Xlink', bufname('%'))
++ call delete('Xlink')
++ bw!
++ else
++ echomsg 'skipped test for buffer name'
++ endif
++ call delete('Xfile')
++ endfunc
++
+ func Test_simplify()
+ call assert_equal('', simplify(''))
+ call assert_equal('/', simplify('/'))
+*** ../vim-8.1.0893/src/version.c 2019-02-10 23:04:07.111243690 +0100
+--- src/version.c 2019-02-10 23:07:43.138163286 +0100
+***************
+*** 785,786 ****
+--- 785,788 ----
+ { /* Add new patch number below this line */
++ /**/
++ 894,
+ /**/
+
+--
+ERIC IDLE PLAYED: THE DEAD COLLECTOR, MR BINT (A VILLAGE NE'ER-DO -WELL VERY
+ KEEN ON BURNING WITCHES), SIR ROBIN, THE GUARD WHO DOESN'T
+ HICOUGH BUT TRIES TO GET THINGS STRAIGHT, CONCORDE (SIR
+ LAUNCELOT'S TRUSTY STEED), ROGER THE SHRUBBER (A SHRUBBER),
+ BROTHER MAYNARD
+ "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
+
+ /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
+/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
+\\\ an exciting new programming language -- http://www.Zimbu.org ///
+ \\\ help me help AIDS victims -- http://ICCF-Holland.org ///