home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 6.2.456 < prev    next >
Encoding:
Internet Message Format  |  2004-04-05  |  24.1 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.2.456 (extra)
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=ISO-8859-1
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 6.2.456 (extra)
  11. Problem:    Win32: Editing a file by its Unicode name (dropping it on Vim or
  12.         using the file selection dialog) doesn't work. (Yakov Lerner, Alex
  13.         Jakushev)
  14. Solution:   Use wide character functions when file names are involved and
  15.         convert from/to 'encoding' where needed.
  16. Files:        src/gui_w48.c, src/macros.h, src/memfile.c, src/memline.c,
  17.         src/os_mswin.c, src/os_win32.c
  18.  
  19.  
  20. *** ../vim-6.2.455/src/gui_w48.c    Tue Mar 30 22:11:17 2004
  21. --- src/gui_w48.c    Tue Mar 30 22:09:17 2004
  22. ***************
  23. *** 288,295 ****
  24.   
  25.   #ifdef FEAT_BEVAL
  26.   /* balloon-eval WM_NOTIFY_HANDLER */
  27. ! void Handle_WM_Notify __ARGS((HWND hwnd, LPNMHDR pnmh));
  28. ! void TrackUserActivity __ARGS((UINT uMsg));
  29.   #endif
  30.   
  31.   /*
  32. --- 288,295 ----
  33.   
  34.   #ifdef FEAT_BEVAL
  35.   /* balloon-eval WM_NOTIFY_HANDLER */
  36. ! static void Handle_WM_Notify __ARGS((HWND hwnd, LPNMHDR pnmh));
  37. ! static void TrackUserActivity __ARGS((UINT uMsg));
  38.   #endif
  39.   
  40.   /*
  41. ***************
  42. *** 2628,2635 ****
  43.       char_u  *icon)
  44.   {
  45.   #ifdef FEAT_MBYTE
  46. !     if (title != NULL && has_mbyte
  47. !               && (enc_codepage == 0 || enc_codepage != (int)GetACP()))
  48.       {
  49.       WCHAR    *wbuf;
  50.   
  51. --- 2628,2634 ----
  52.       char_u  *icon)
  53.   {
  54.   #ifdef FEAT_MBYTE
  55. !     if (title != NULL && enc_codepage != (int)GetACP())
  56.       {
  57.       WCHAR    *wbuf;
  58.   
  59. ***************
  60. *** 2715,2734 ****
  61.    * the \t and \n delimeters with \0.
  62.    * Returns the converted string in allocated memory.
  63.    */
  64.       static char_u *
  65.   convert_filter(char_u *s)
  66.   {
  67.       char_u    *res;
  68.       unsigned    s_len = (unsigned)STRLEN(s);
  69.       unsigned    i;
  70.   
  71.       res = alloc(s_len + 3);
  72.       if (res != NULL)
  73.       {
  74. -     STRCPY(res, s);
  75.       for (i = 0; i < s_len; ++i)
  76. !         if ((res[i] == '\t') || (res[i] == '\n'))
  77.           res[i] = '\0';
  78.       /* Add two extra NULs to make sure it's properly terminated. */
  79.       res[s_len + 1] = NUL;
  80.       res[s_len + 2] = NUL;
  81. --- 2714,2747 ----
  82.    * the \t and \n delimeters with \0.
  83.    * Returns the converted string in allocated memory.
  84.    */
  85. + # ifdef FEAT_MBYTE
  86. +     static WCHAR *
  87. + # else
  88.       static char_u *
  89. + # endif
  90.   convert_filter(char_u *s)
  91.   {
  92. + # ifdef FEAT_MBYTE
  93. +     WCHAR    *res;
  94. + # else
  95.       char_u    *res;
  96. + # endif
  97.       unsigned    s_len = (unsigned)STRLEN(s);
  98.       unsigned    i;
  99.   
  100. + # ifdef FEAT_MBYTE
  101. +     res = (WCHAR *)alloc((s_len + 3) * 2);
  102. + # else
  103.       res = alloc(s_len + 3);
  104. + # endif
  105.       if (res != NULL)
  106.       {
  107.       for (i = 0; i < s_len; ++i)
  108. !         if (s[i] == '\t' || s[i] == '\n')
  109.           res[i] = '\0';
  110. +         else
  111. +         res[i] = s[i];
  112. +     res[s_len] = NUL;
  113.       /* Add two extra NULs to make sure it's properly terminated. */
  114.       res[s_len + 1] = NUL;
  115.       res[s_len + 2] = NUL;
  116. ***************
  117. *** 2755,2799 ****
  118.       char_u *initdir,
  119.       char_u *filter)
  120.   {
  121.       OPENFILENAME    fileStruct;
  122. !     char_u        fileBuf[MAXPATHL], *p;
  123. !     char_u        dirBuf[MAXPATHL];
  124.   
  125.       if (dflt == NULL)
  126. !     fileBuf[0] = '\0';
  127.       else
  128.       {
  129.       STRNCPY(fileBuf, dflt, MAXPATHL - 1);
  130.       fileBuf[MAXPATHL - 1] = NUL;
  131.       }
  132.   
  133.       /* Convert the filter to Windows format. */
  134. !     filter = convert_filter(filter);
  135.   
  136.       memset(&fileStruct, 0, sizeof(OPENFILENAME));
  137. !     fileStruct.lStructSize = sizeof(OPENFILENAME);
  138. !     fileStruct.lpstrFilter = filter;
  139. !     fileStruct.lpstrFile = fileBuf;
  140. !     fileStruct.nMaxFile = MAXPATHL;
  141.       fileStruct.lpstrTitle = title;
  142.       fileStruct.lpstrDefExt = ext;
  143.       fileStruct.hwndOwner = s_hwnd;        /* main Vim window is owner*/
  144.       /* has an initial dir been specified? */
  145.       if (initdir != NULL && *initdir != NUL)
  146.       {
  147.       /* Must have backslashes here, no matter what 'shellslash' says */
  148. -     STRNCPY(dirBuf, initdir, MAXPATHL - 1);
  149. -     dirBuf[MAXPATHL - 1] = NUL;
  150. -     for (p = dirBuf; *p != NUL; ++p)
  151. -     {
  152. -         if (*p == '/')
  153. -         *p = '\\';
  154.   #ifdef FEAT_MBYTE
  155. !         if (has_mbyte)
  156. !         p += (*mb_ptr2len_check)(p) - 1;
  157. ! #endif
  158.       }
  159. !     fileStruct.lpstrInitialDir = dirBuf;
  160.       }
  161.   
  162.       /*
  163. --- 2768,2865 ----
  164.       char_u *initdir,
  165.       char_u *filter)
  166.   {
  167. + #ifdef FEAT_MBYTE
  168. +     /* We always use the wide function.  This means enc_to_ucs2() must work,
  169. +      * otherwise it fails miserably! */
  170. +     OPENFILENAMEW    fileStruct;
  171. +     WCHAR        fileBuf[MAXPATHL];
  172. +     WCHAR        *wp;
  173. +     int            i;
  174. +     WCHAR        *titlep = NULL;
  175. +     WCHAR        *extp = NULL;
  176. +     WCHAR        *initdirp = NULL;
  177. +     WCHAR        *filterp;
  178. + #else
  179.       OPENFILENAME    fileStruct;
  180. !     char_u        fileBuf[MAXPATHL];
  181. !     char_u        *initdirp = NULL;
  182. !     char_u        *filterp;
  183. ! #endif
  184. !     char_u        *p;
  185.   
  186.       if (dflt == NULL)
  187. !     fileBuf[0] = NUL;
  188.       else
  189.       {
  190. + #ifdef FEAT_MBYTE
  191. +     wp = enc_to_ucs2(dflt, NULL);
  192. +     if (wp == NULL)
  193. +         fileBuf[0] = NUL;
  194. +     else
  195. +     {
  196. +         for (i = 0; wp[i] != NUL && i < MAXPATHL - 1; ++i)
  197. +         fileBuf[i] = wp[i];
  198. +         fileBuf[i] = NUL;
  199. +         vim_free(wp);
  200. +     }
  201. + #else
  202.       STRNCPY(fileBuf, dflt, MAXPATHL - 1);
  203.       fileBuf[MAXPATHL - 1] = NUL;
  204. + #endif
  205.       }
  206.   
  207.       /* Convert the filter to Windows format. */
  208. !     filterp = convert_filter(filter);
  209.   
  210.       memset(&fileStruct, 0, sizeof(OPENFILENAME));
  211. ! #ifdef OPENFILENAME_SIZE_VERSION_400
  212. !     /* be compatible with Windows NT 4.0 */
  213. !     /* TODO: what when using OPENFILENAMEW??? */
  214. !     fileStruct.lStructSize = sizeof(OPENFILENAME_SIZE_VERSION_400);
  215. ! #else
  216. !     fileStruct.lStructSize = sizeof(fileStruct);
  217. ! #endif
  218. ! #ifdef FEAT_MBYTE
  219. !     if (title != NULL)
  220. !     titlep = enc_to_ucs2(title, NULL);
  221. !     fileStruct.lpstrTitle = titlep;
  222. ! #else
  223.       fileStruct.lpstrTitle = title;
  224. + #endif
  225. + #ifdef FEAT_MBYTE
  226. +     if (ext != NULL)
  227. +     extp = enc_to_ucs2(ext, NULL);
  228. +     fileStruct.lpstrDefExt = extp;
  229. + #else
  230.       fileStruct.lpstrDefExt = ext;
  231. + #endif
  232. +     fileStruct.lpstrFile = fileBuf;
  233. +     fileStruct.nMaxFile = MAXPATHL;
  234. +     fileStruct.lpstrFilter = filterp;
  235.       fileStruct.hwndOwner = s_hwnd;        /* main Vim window is owner*/
  236.       /* has an initial dir been specified? */
  237.       if (initdir != NULL && *initdir != NUL)
  238.       {
  239.       /* Must have backslashes here, no matter what 'shellslash' says */
  240.   #ifdef FEAT_MBYTE
  241. !     initdirp = enc_to_ucs2(initdir, NULL);
  242. !     if (initdirp != NULL)
  243. !     {
  244. !         for (wp = initdirp; *wp != NUL; ++wp)
  245. !         if (*wp == '/')
  246. !             *wp = '\\';
  247.       }
  248. ! #else
  249. !     initdirp = vim_strsave(initdir);
  250. !     if (initdirp != NULL)
  251. !         for (p = initdirp; *p != NUL; ++p)
  252. !         if (*p == '/')
  253. !             *p = '\\';
  254. ! #endif
  255. !     fileStruct.lpstrInitialDir = initdirp;
  256.       }
  257.   
  258.       /*
  259. ***************
  260. *** 2811,2832 ****
  261.   #endif
  262.       if (saving)
  263.       {
  264.       if (!GetSaveFileName(&fileStruct))
  265.           return NULL;
  266.       }
  267.       else
  268.       {
  269.       if (!GetOpenFileName(&fileStruct))
  270.           return NULL;
  271.       }
  272.   
  273. !     vim_free(filter);
  274.   
  275.       /* Shorten the file name if possible */
  276.       mch_dirname(IObuff, IOSIZE);
  277. !     p = shorten_fname(fileBuf, IObuff);
  278.       if (p == NULL)
  279. !     p = fileBuf;
  280.       return vim_strsave(p);
  281.   }
  282.   #endif /* FEAT_BROWSE */
  283. --- 2877,2922 ----
  284.   #endif
  285.       if (saving)
  286.       {
  287. + #ifdef FEAT_MBYTE
  288. +     if (!GetSaveFileNameW(&fileStruct))
  289. + #else
  290.       if (!GetSaveFileName(&fileStruct))
  291. + #endif
  292.           return NULL;
  293.       }
  294.       else
  295.       {
  296. + #ifdef FEAT_MBYTE
  297. +     if (!GetOpenFileNameW(&fileStruct))
  298. + #else
  299.       if (!GetOpenFileName(&fileStruct))
  300. + #endif
  301.           return NULL;
  302.       }
  303.   
  304. !     vim_free(filterp);
  305. !     vim_free(initdirp);
  306. ! #ifdef FEAT_MBYTE
  307. !     vim_free(titlep);
  308. !     vim_free(extp);
  309. ! #endif
  310. ! #ifdef FEAT_MBYTE
  311. !     /* Convert from UCS2 to 'encoding'. */
  312. !     p = ucs2_to_enc(fileBuf, NULL);
  313. !     if (p != NULL)        /* when out of memory we get garbage... */
  314. !     STRCPY(fileBuf, p);
  315. !     vim_free(p);
  316. ! #endif
  317. !     /* Give focus back to main window (when using MDI). */
  318. !     SetFocus(s_hwnd);
  319.   
  320.       /* Shorten the file name if possible */
  321.       mch_dirname(IObuff, IOSIZE);
  322. !     p = shorten_fname((char_u *)fileBuf, IObuff);
  323.       if (p == NULL)
  324. !     p = (char_u *)fileBuf;
  325.       return vim_strsave(p);
  326.   }
  327.   #endif /* FEAT_BROWSE */
  328. ***************
  329. *** 2844,2851 ****
  330.   # define BUFPATHLEN MAXPATHL
  331.   # define DRAGQVAL 0xFFFF
  332.   #endif
  333.       char    szFile[BUFPATHLEN];
  334. !     UINT    cFiles = DragQueryFile(hDrop, DRAGQVAL, szFile, BUFPATHLEN);
  335.       UINT    i;
  336.       char_u  **fnames;
  337.       POINT   pt;
  338. --- 2934,2945 ----
  339.   # define BUFPATHLEN MAXPATHL
  340.   # define DRAGQVAL 0xFFFF
  341.   #endif
  342. + #ifdef FEAT_MBYTE
  343. +     WCHAR    szFile[BUFPATHLEN];
  344. + #else
  345.       char    szFile[BUFPATHLEN];
  346. ! #endif
  347. !     UINT    cFiles = DragQueryFile(hDrop, DRAGQVAL, NULL, 0);
  348.       UINT    i;
  349.       char_u  **fnames;
  350.       POINT   pt;
  351. ***************
  352. *** 2866,2873 ****
  353. --- 2960,2972 ----
  354.       if (fnames != NULL)
  355.       for (i = 0; i < cFiles; ++i)
  356.       {
  357. + #ifdef FEAT_MBYTE
  358. +         DragQueryFileW(hDrop, i, szFile, BUFPATHLEN);
  359. +         fnames[i] = ucs2_to_enc(szFile, NULL);
  360. + #else
  361.           DragQueryFile(hDrop, i, szFile, BUFPATHLEN);
  362.           fnames[i] = vim_strsave(szFile);
  363. + #endif
  364.       }
  365.   
  366.       DragFinish(hDrop);
  367. *** ../vim-6.2.455/src/macros.h    Sun Jan 25 20:28:03 2004
  368. --- src/macros.h    Tue Mar 16 14:54:11 2004
  369. ***************
  370. *** 149,155 ****
  371.   # ifndef WIN32
  372.   #   define mch_access(n, p)    access((n), (p))
  373.   # endif
  374. ! # define mch_fopen(n, p)    fopen((n), (p))
  375.   # define mch_fstat(n, p)    fstat((n), (p))
  376.   # define mch_lstat(n, p)    lstat((n), (p))
  377.   # ifdef MSWIN    /* has it's own mch_stat() function */
  378. --- 149,157 ----
  379.   # ifndef WIN32
  380.   #   define mch_access(n, p)    access((n), (p))
  381.   # endif
  382. ! # if !(defined(FEAT_MBYTE) && defined(WIN3264))
  383. ! #  define mch_fopen(n, p)    fopen((n), (p))
  384. ! # endif
  385.   # define mch_fstat(n, p)    fstat((n), (p))
  386.   # define mch_lstat(n, p)    lstat((n), (p))
  387.   # ifdef MSWIN    /* has it's own mch_stat() function */
  388. ***************
  389. *** 177,183 ****
  390.    */
  391.   #  define mch_open(n, m, p)    open(vms_fixfilename(n), (m), (p))
  392.   # else
  393. ! #  define mch_open(n, m, p)    open((n), (m), (p))
  394.   # endif
  395.   #endif
  396.   
  397. --- 179,198 ----
  398.    */
  399.   #  define mch_open(n, m, p)    open(vms_fixfilename(n), (m), (p))
  400.   # else
  401. ! #  if !(defined(FEAT_MBYTE) && defined(WIN3264))
  402. ! #   define mch_open(n, m, p)    open((n), (m), (p))
  403. ! #  endif
  404. ! # endif
  405. ! #endif
  406. ! /* mch_open_rw(): invoke mch_open() with third argument for user R/W. */
  407. ! #if defined(UNIX) || defined(VMS)  /* open in rw------- mode */
  408. ! # define mch_open_rw(n, f)    mch_open((n), (f), (mode_t)0600)
  409. ! #else
  410. ! # if defined(MSDOS) || defined(MSWIN) || defined(OS2)  /* open read/write */
  411. ! #  define mch_open_rw(n, f)    mch_open((n), (f), S_IREAD | S_IWRITE)
  412. ! # else
  413. ! #  define mch_open_rw(n, f)    mch_open((n), (f), 0)
  414.   # endif
  415.   #endif
  416.   
  417. *** ../vim-6.2.455/src/memfile.c    Sun Oct 12 17:25:14 2003
  418. --- src/memfile.c    Mon Mar 15 22:28:37 2004
  419. ***************
  420. *** 1268,1298 ****
  421.       }
  422.       else
  423.   #endif
  424. !     /*
  425. !      * try to open the file
  426. !      */
  427. !     mfp->mf_fd = open(
  428. ! #ifdef VMS
  429. !         vms_fixfilename(mfp->mf_fname),
  430. ! #else
  431. !         (char *)mfp->mf_fname,
  432. ! #endif
  433. !         flags | O_EXTRA
  434.   #ifdef WIN32
  435.       /* Prevent handle inheritance that cause problems with Cscope
  436.        * (swap file may not be deleted if cscope connection was open after
  437. !      * the file)
  438. !      */
  439. !         |O_NOINHERIT
  440. ! #endif
  441. ! #if defined(UNIX) || defined(RISCOS) || defined(VMS)
  442. !             , (mode_t)0600        /* open in rw------- mode */
  443. ! #endif
  444. ! #if defined(MSDOS) || defined(MSWIN) || defined(__EMX__)
  445. !             , S_IREAD | S_IWRITE    /* open read/write */
  446.   #endif
  447. !             );
  448.   
  449.       /*
  450.        * If the file cannot be opened, use memory only
  451. --- 1268,1286 ----
  452.       }
  453.       else
  454.   #endif
  455. !     {
  456. !     /*
  457. !      * try to open the file
  458. !      */
  459. !     flags |= O_EXTRA;
  460.   #ifdef WIN32
  461.       /* Prevent handle inheritance that cause problems with Cscope
  462.        * (swap file may not be deleted if cscope connection was open after
  463. !      * the file) */
  464. !     flags |= O_NOINHERIT;
  465.   #endif
  466. !     mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags);
  467. !     }
  468.   
  469.       /*
  470.        * If the file cannot be opened, use memory only
  471. *** ../vim-6.2.455/src/memline.c    Sun Jan 25 19:45:13 2004
  472. --- src/memline.c    Mon Mar 15 22:29:48 2004
  473. ***************
  474. *** 3468,3487 ****
  475.               f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
  476.               if (f1 < 0)
  477.               {
  478. !             f1 = open(
  479. ! #ifdef VMS
  480. !                 vms_fixfilename((char *)fname),
  481. ! #else
  482. !                 (char *)fname,
  483. ! #endif
  484. !                 O_RDWR|O_CREAT|O_EXCL|O_EXTRA
  485. ! #if defined(UNIX) || defined(VMS)  /* open in rw------- mode */
  486. !                                   , (mode_t)0600
  487. ! #endif
  488. ! #if defined(MSDOS) || defined(MSWIN) || defined(OS2)  /* open read/write */
  489. !                             , S_IREAD | S_IWRITE
  490. ! #endif
  491. !                                         );
  492.   #if defined(OS2)
  493.               if (f1 < 0 && errno == ENOENT)
  494.                   same = TRUE;
  495. --- 3468,3475 ----
  496.               f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0);
  497.               if (f1 < 0)
  498.               {
  499. !             f1 = mch_open_rw((char *)fname,
  500. !                            O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
  501.   #if defined(OS2)
  502.               if (f1 < 0 && errno == ENOENT)
  503.                   same = TRUE;
  504. ***************
  505. *** 3493,3512 ****
  506.               f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
  507.               if (f2 < 0)
  508.               {
  509. !                 f2 = open(
  510. ! #ifdef VMS
  511. !                     vms_fixfilename((char *)fname2),
  512. ! #else
  513. !                     (char *)fname2,
  514. ! #endif
  515. !                     O_RDWR|O_CREAT|O_EXCL|O_EXTRA
  516. ! #if defined(UNIX) || defined(VMS)  /* open in rw------- mode */
  517. !                                   , (mode_t)0600
  518. ! #endif
  519. ! #if defined(MSDOS) || defined(MSWIN) || defined(OS2)  /* open read/write */
  520. !                             , S_IREAD | S_IWRITE
  521. ! #endif
  522. !                                         );
  523.                   created2 = TRUE;
  524.               }
  525.               if (f2 >= 0)
  526. --- 3481,3488 ----
  527.               f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0);
  528.               if (f2 < 0)
  529.               {
  530. !                 f2 = mch_open_rw((char *)fname2,
  531. !                            O_RDWR|O_CREAT|O_EXCL|O_EXTRA);
  532.                   created2 = TRUE;
  533.               }
  534.               if (f2 >= 0)
  535. *** ../vim-6.2.455/src/os_mswin.c    Fri Apr  2 11:36:09 2004
  536. --- src/os_mswin.c    Thu Apr  1 22:43:35 2004
  537. ***************
  538. *** 450,455 ****
  539. --- 450,469 ----
  540.       --p;
  541.       if (p > buf && (*p == '\\' || *p == '/') && p[-1] != ':')
  542.       *p = NUL;
  543. + #ifdef FEAT_MBYTE
  544. +     if ((int)GetACP() != enc_codepage)
  545. +     {
  546. +     WCHAR    *wp = enc_to_ucs2(buf, NULL);
  547. +     int    n;
  548. +     if (wp != NULL)
  549. +     {
  550. +         n = _wstat(wp, (struct _stat *)stp);
  551. +         vim_free(wp);
  552. +         return n;
  553. +     }
  554. +     }
  555. + #endif
  556.       return stat(buf, stp);
  557.   }
  558.   
  559. *** ../vim-6.2.455/src/os_win32.c    Tue Mar 23 21:23:28 2004
  560. --- src/os_win32.c    Tue Apr  6 21:25:50 2004
  561. ***************
  562. *** 2361,2366 ****
  563. --- 2361,2380 ----
  564.   mch_getperm(
  565.       char_u *name)
  566.   {
  567. + #ifdef FEAT_MBYTE
  568. +     if ((int)GetACP() != enc_codepage)
  569. +     {
  570. +     WCHAR    *p = enc_to_ucs2(name, NULL);
  571. +     long    n;
  572. +     if (p != NULL)
  573. +     {
  574. +         n = (long)GetFileAttributesW(p);
  575. +         vim_free(p);
  576. +         return n;
  577. +     }
  578. +     }
  579. + #endif
  580.       return (long)GetFileAttributes((char *)name);
  581.   }
  582.   
  583. ***************
  584. *** 2374,2379 ****
  585. --- 2388,2407 ----
  586.       long perm)
  587.   {
  588.       perm |= FILE_ATTRIBUTE_ARCHIVE;    /* file has changed, set archive bit */
  589. + #ifdef FEAT_MBYTE
  590. +     if ((int)GetACP() != enc_codepage)
  591. +     {
  592. +     WCHAR    *p = enc_to_ucs2(name, NULL);
  593. +     long    n;
  594. +     if (p != NULL)
  595. +     {
  596. +         n = (long)SetFileAttributesW(p, perm);
  597. +         vim_free(p);
  598. +         return n ? OK : FAIL;
  599. +     }
  600. +     }
  601. + #endif
  602.       return SetFileAttributes((char *)name, perm) ? OK : FAIL;
  603.   }
  604.   
  605. ***************
  606. *** 2383,2396 ****
  607.       void
  608.   mch_hide(char_u *name)
  609.   {
  610. !     int    perm;
  611.   
  612. !     perm = GetFileAttributes((char *)name);
  613.       if (perm >= 0)
  614.       {
  615.       perm |= FILE_ATTRIBUTE_HIDDEN;
  616. !     SetFileAttributes((char *)name, perm);
  617.       }
  618.   }
  619.   
  620.   /*
  621. --- 2411,2443 ----
  622.       void
  623.   mch_hide(char_u *name)
  624.   {
  625. !     int        perm;
  626. ! #ifdef FEAT_MBYTE
  627. !     WCHAR    *p = NULL;
  628. !     if ((int)GetACP() != enc_codepage)
  629. !     p = enc_to_ucs2(name, NULL);
  630. ! #endif
  631.   
  632. ! #ifdef FEAT_MBYTE
  633. !     if (p != NULL)
  634. !     perm = GetFileAttributesW(p);
  635. !     else
  636. ! #endif
  637. !     perm = GetFileAttributes((char *)name);
  638.       if (perm >= 0)
  639.       {
  640.       perm |= FILE_ATTRIBUTE_HIDDEN;
  641. ! #ifdef FEAT_MBYTE
  642. !     if (p != NULL)
  643. !         SetFileAttributesW(p, perm);
  644. !     else
  645. ! #endif
  646. !         SetFileAttributes((char *)name, perm);
  647.       }
  648. + #ifdef FEAT_MBYTE
  649. +     vim_free(p);
  650. + #endif
  651.   }
  652.   
  653.   /*
  654. ***************
  655. *** 3959,3964 ****
  656. --- 4006,4027 ----
  657.       int
  658.   mch_remove(char_u *name)
  659.   {
  660. + #ifdef FEAT_MBYTE
  661. +     WCHAR    *wn = NULL;
  662. +     int        n;
  663. +     if ((int)GetACP() != enc_codepage)
  664. +     {
  665. +     wn = enc_to_ucs2(name, NULL);
  666. +     if (wn != NULL)
  667. +     {
  668. +         SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL);
  669. +         n = DeleteFileW(wn) ? 0 : -1;
  670. +         vim_free(wn);
  671. +         return n;
  672. +     }
  673. +     }
  674. + #endif
  675.       SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL);
  676.       return DeleteFile(name) ? 0 : -1;
  677.   }
  678. ***************
  679. *** 3995,4000 ****
  680. --- 4058,4122 ----
  681.       return (long_u) (ms.dwAvailPhys + ms.dwAvailPageFile);
  682.   }
  683.   
  684. + #ifdef FEAT_MBYTE
  685. + /*
  686. +  * Same code as below, but with wide functions and no comments.
  687. +  * Return 0 for success, non-zero for failure.
  688. +  */
  689. +     int
  690. + mch_wrename(WCHAR *wold, WCHAR *wnew)
  691. + {
  692. +     WCHAR    *p;
  693. +     int        i;
  694. +     WCHAR    szTempFile[_MAX_PATH + 1];
  695. +     WCHAR    szNewPath[_MAX_PATH + 1];
  696. +     HANDLE    hf;
  697. +     if (!mch_windows95())
  698. +     {
  699. +     p = wold;
  700. +     for (i = 0; wold[i] != NUL; ++i)
  701. +         if ((wold[i] == '/' || wold[i] == '\\' || wold[i] == ':')
  702. +             && wold[i + 1] != 0)
  703. +         p = wold + i + 1;
  704. +     if ((int)(wold + i - p) < 8 || p[6] != '~')
  705. +         return (MoveFileW(wold, wnew) == 0);
  706. +     }
  707. +     if (GetFullPathNameW(wnew, _MAX_PATH, szNewPath, &p) == 0 || p == NULL)
  708. +     return -1;
  709. +     *p = NUL;
  710. +     if (GetTempFileNameW(szNewPath, L"VIM", 0, szTempFile) == 0)
  711. +     return -2;
  712. +     if (!DeleteFileW(szTempFile))
  713. +     return -3;
  714. +     if (!MoveFileW(wold, szTempFile))
  715. +     return -4;
  716. +     if ((hf = CreateFileW(wold, GENERIC_WRITE, 0, NULL, CREATE_NEW,
  717. +             FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
  718. +     return -5;
  719. +     if (!CloseHandle(hf))
  720. +     return -6;
  721. +     if (!MoveFileW(szTempFile, wnew))
  722. +     {
  723. +     (void)MoveFileW(szTempFile, wold);
  724. +     return -7;
  725. +     }
  726. +     DeleteFileW(szTempFile);
  727. +     if (!DeleteFileW(wold))
  728. +     return -8;
  729. +     return 0;
  730. + }
  731. + #endif
  732.   
  733.   /*
  734.    * mch_rename() works around a bug in rename (aka MoveFile) in
  735. ***************
  736. *** 4024,4029 ****
  737. --- 4146,4171 ----
  738.       char    szNewPath[_MAX_PATH+1];
  739.       char    *pszFilePart;
  740.       HANDLE    hf;
  741. + #ifdef FEAT_MBYTE
  742. +     WCHAR    *wold = NULL;
  743. +     WCHAR    *wnew = NULL;
  744. +     int        retval = 0;
  745. +     if ((int)GetACP() != enc_codepage)
  746. +     {
  747. +     wold = enc_to_ucs2((char_u *)pszOldFile, NULL);
  748. +     wnew = enc_to_ucs2((char_u *)pszNewFile, NULL);
  749. +     if (wold != NULL && wnew != NULL)
  750. +     {
  751. +         retval = mch_wrename(wold, wnew);
  752. +         vim_free(wold);
  753. +         vim_free(wnew);
  754. +         return retval;
  755. +     }
  756. +     vim_free(wold);
  757. +     vim_free(wnew);
  758. +     }
  759. + #endif
  760.   
  761.       /*
  762.        * No need to play tricks if not running Windows 95, unless the file name
  763. ***************
  764. *** 4116,4147 ****
  765.       int
  766.   mch_access(char *n, int p)
  767.   {
  768. !     HANDLE  hFile;
  769. !     DWORD am;
  770.   
  771.       if (mch_isdir(n))
  772.       {
  773.       char TempName[_MAX_PATH + 16] = "";
  774.   
  775.       if (p & R_OK)
  776.       {
  777.           /* Read check is performed by seeing if we can do a find file on
  778. !          * the directory for any file
  779. !          */
  780. !         char *pch;
  781. !         WIN32_FIND_DATA d;
  782.   
  783. !         STRNCPY(TempName, n, _MAX_PATH);
  784. !         pch = TempName + STRLEN(TempName) - 1;
  785. !         if (*pch != '\\' && *pch != '/')
  786. !         *pch++ = '\\';
  787. !         *pch++ = '*';
  788. !         *pch = NUL;
  789. !         hFile = FindFirstFile(TempName, &d);
  790. !         if (hFile == INVALID_HANDLE_VALUE)
  791. !         return -1;
  792. !         (void)FindClose(hFile);
  793.       }
  794.   
  795.       if (p & W_OK)
  796. --- 4258,4320 ----
  797.       int
  798.   mch_access(char *n, int p)
  799.   {
  800. !     HANDLE    hFile;
  801. !     DWORD    am;
  802. !     int        retval = -1;        /* default: fail */
  803. ! #ifdef FEAT_MBYTE
  804. !     WCHAR    *wn = NULL;
  805. !     if ((int)GetACP() != enc_codepage)
  806. !     wn = enc_to_ucs2(n, NULL);
  807. ! #endif
  808.   
  809.       if (mch_isdir(n))
  810.       {
  811.       char TempName[_MAX_PATH + 16] = "";
  812. + #ifdef FEAT_MBYTE
  813. +     WCHAR TempNameW[_MAX_PATH + 16] = L"";
  814. + #endif
  815.   
  816.       if (p & R_OK)
  817.       {
  818.           /* Read check is performed by seeing if we can do a find file on
  819. !          * the directory for any file. */
  820. ! #ifdef FEAT_MBYTE
  821. !         if (wn != NULL)
  822. !         {
  823. !         int            i;
  824. !         WIN32_FIND_DATAW    d;
  825.   
  826. !         for (i = 0; i < _MAX_PATH && wn[i] != 0; ++i)
  827. !             TempNameW[i] = wn[i];
  828. !         if (TempNameW[i - 1] != '\\' && TempNameW[i - 1] != '/')
  829. !             TempNameW[i++] = '\\';
  830. !         TempNameW[i++] = '*';
  831. !         TempNameW[i++] = 0;
  832. !         hFile = FindFirstFileW(TempNameW, &d);
  833. !         if (hFile == INVALID_HANDLE_VALUE)
  834. !             goto getout;
  835. !         (void)FindClose(hFile);
  836. !         }
  837. !         else
  838. ! #endif
  839. !         {
  840. !         char            *pch;
  841. !         WIN32_FIND_DATA        d;
  842. !         STRNCPY(TempName, n, _MAX_PATH);
  843. !         pch = TempName + STRLEN(TempName) - 1;
  844. !         if (*pch != '\\' && *pch != '/')
  845. !             *++pch = '\\';
  846. !         *++pch = '*';
  847. !         *++pch = NUL;
  848. !         hFile = FindFirstFile(TempName, &d);
  849. !         if (hFile == INVALID_HANDLE_VALUE)
  850. !             goto getout;
  851. !         (void)FindClose(hFile);
  852. !         }
  853.       }
  854.   
  855.       if (p & W_OK)
  856. ***************
  857. *** 4149,4176 ****
  858.           /* Trying to create a temporary file in the directory should catch
  859.            * directories on read-only network shares.  However, in
  860.            * directories whose ACL allows writes but denies deletes will end
  861. !          * up keeping the temporary file :-(
  862. !          */
  863. !         if (!GetTempFileName(n, "VIM", 0, TempName))
  864. !         return -1;
  865. !         mch_remove((char_u *)TempName);
  866.       }
  867.       }
  868.       else
  869.       {
  870.       /* Trying to open the file for the required access does ACL, read-only
  871. !      * network share, and file attribute checks.
  872. !      */
  873.       am = ((p & W_OK) ? GENERIC_WRITE : 0)
  874.           | ((p & R_OK) ? GENERIC_READ : 0);
  875. !     hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL);
  876.       if (hFile == INVALID_HANDLE_VALUE)
  877. !         return -1;
  878.       CloseHandle(hFile);
  879.       }
  880. !     return 0;
  881.   }
  882.   
  883.   /*
  884.    * SUB STREAM:
  885.    *
  886. --- 4322,4419 ----
  887.           /* Trying to create a temporary file in the directory should catch
  888.            * directories on read-only network shares.  However, in
  889.            * directories whose ACL allows writes but denies deletes will end
  890. !          * up keeping the temporary file :-(. */
  891. ! #ifdef FEAT_MBYTE
  892. !         if (wn != NULL)
  893. !         {
  894. !         if (!GetTempFileNameW(wn, L"VIM", 0, TempNameW))
  895. !             goto getout;
  896. !         DeleteFileW(TempNameW);
  897. !         }
  898. !         else
  899. ! #endif
  900. !         {
  901. !         if (!GetTempFileName(n, "VIM", 0, TempName))
  902. !             goto getout;
  903. !         mch_remove((char_u *)TempName);
  904. !         }
  905.       }
  906.       }
  907.       else
  908.       {
  909.       /* Trying to open the file for the required access does ACL, read-only
  910. !      * network share, and file attribute checks.  */
  911.       am = ((p & W_OK) ? GENERIC_WRITE : 0)
  912.           | ((p & R_OK) ? GENERIC_READ : 0);
  913. ! #ifdef FEAT_MBYTE
  914. !     if (wn != NULL)
  915. !         hFile = CreateFileW(wn, am, 0, NULL, OPEN_EXISTING, 0, NULL);
  916. !     else
  917. ! #endif
  918. !         hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL);
  919.       if (hFile == INVALID_HANDLE_VALUE)
  920. !         goto getout;
  921.       CloseHandle(hFile);
  922.       }
  923. !     retval = 0;        /* success */
  924. ! getout:
  925. ! #ifdef FEAT_MBYTE
  926. !     vim_free(wn);
  927. ! #endif
  928. !     return retval;
  929.   }
  930.   
  931. + #if defined(FEAT_MBYTE) || defined(PROTO)
  932. + /*
  933. +  * Version of open() that may use ucs2 file name.
  934. +  */
  935. +     int
  936. + mch_open(char *name, int flags, int mode)
  937. + {
  938. +     WCHAR    *wn;
  939. +     int        f;
  940. +     if ((int)GetACP() != enc_codepage)
  941. +     {
  942. +     wn = enc_to_ucs2(name, NULL);
  943. +     if (wn != NULL)
  944. +     {
  945. +         f = _wopen(wn, flags, mode);
  946. +         vim_free(wn);
  947. +         return f;
  948. +     }
  949. +     }
  950. +     return open(name, flags, mode);
  951. + }
  952. + /*
  953. +  * Version of fopen() that may use ucs2 file name.
  954. +  */
  955. +     FILE *
  956. + mch_fopen(char *name, char *mode)
  957. + {
  958. +     WCHAR    *wn, *wm;
  959. +     FILE    *f;
  960. +     if ((int)GetACP() != enc_codepage)
  961. +     {
  962. +     wn = enc_to_ucs2(name, NULL);
  963. +     wm = enc_to_ucs2(mode, NULL);
  964. +     if (wn != NULL && wm != NULL)
  965. +     {
  966. +         f = _wfopen(wn, wm);
  967. +         return f;
  968. +     }
  969. +     vim_free(wn);
  970. +     vim_free(wm);
  971. +     }
  972. +     return fopen(name, mode);
  973. + }
  974. + #endif
  975.   /*
  976.    * SUB STREAM:
  977.    *
  978. *** ../vim-6.2.455/src/version.c    Tue Apr  6 20:19:26 2004
  979. --- src/version.c    Tue Apr  6 21:28:09 2004
  980. ***************
  981. *** 639,640 ****
  982. --- 639,642 ----
  983.   {   /* Add new patch number below this line */
  984. + /**/
  985. +     456,
  986.   /**/
  987.  
  988. -- 
  989. "Intelligence has much less practical application than you'd think."
  990.           -- Scott Adams, Dilbert.
  991.  
  992.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  993. ///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  994. \\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
  995.  \\\  Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///
  996.