Patch 8.0.0175
Problem:    Setting language in gvim on MS-Windows does not work when
            libintl.dll is dynamically linked with msvcrt.dll.
Solution:   Use putenv() from libintl as well. (Ken Takata, closes #1082)
Files:      src/mbyte.c, src/misc1.c, src/os_win32.c, src/proto/os_win32.pro,
            src/vim.h


*** ../vim-8.0.0174/src/mbyte.c 2016-12-03 16:40:44.432532400 +0100
--- src/mbyte.c 2017-01-12 21:39:35.536587643 +0100
***************
*** 4584,4630 ****
  #   endif
  
  /*
-  * Get the address of 'funcname' which is imported by 'hInst' DLL.
-  */
-     static void *
- get_iconv_import_func(HINSTANCE hInst, const char *funcname)
- {
-     PBYTE                     pImage = (PBYTE)hInst;
-     PIMAGE_DOS_HEADER         pDOS = (PIMAGE_DOS_HEADER)hInst;
-     PIMAGE_NT_HEADERS         pPE;
-     PIMAGE_IMPORT_DESCRIPTOR  pImpDesc;
-     PIMAGE_THUNK_DATA         pIAT;       /* Import Address Table */
-     PIMAGE_THUNK_DATA         pINT;       /* Import Name Table */
-     PIMAGE_IMPORT_BY_NAME     pImpName;
- 
-     if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
-       return NULL;
-     pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
-     if (pPE->Signature != IMAGE_NT_SIGNATURE)
-       return NULL;
-     pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
-           + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
-                                                           .VirtualAddress);
-     for (; pImpDesc->FirstThunk; ++pImpDesc)
-     {
-       if (!pImpDesc->OriginalFirstThunk)
-           continue;
-       pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
-       pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
-       for (; pIAT->u1.Function; ++pIAT, ++pINT)
-       {
-           if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
-               continue;
-           pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
-                                       + (UINT_PTR)(pINT->u1.AddressOfData));
-           if (strcmp((char *)pImpName->Name, funcname) == 0)
-               return (void *)pIAT->u1.Function;
-       }
-     }
-     return NULL;
- }
- 
- /*
   * Try opening the iconv.dll and return TRUE if iconv() can be used.
   */
      int
--- 4584,4589 ----
***************
*** 4671,4677 ****
      iconv_open        = (void *)GetProcAddress(hIconvDLL, "libiconv_open");
      iconv_close       = (void *)GetProcAddress(hIconvDLL, "libiconv_close");
      iconvctl  = (void *)GetProcAddress(hIconvDLL, "libiconvctl");
!     iconv_errno       = get_iconv_import_func(hIconvDLL, "_errno");
      if (iconv_errno == NULL)
        iconv_errno = (void *)GetProcAddress(hMsvcrtDLL, "_errno");
      if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
--- 4630,4636 ----
      iconv_open        = (void *)GetProcAddress(hIconvDLL, "libiconv_open");
      iconv_close       = (void *)GetProcAddress(hIconvDLL, "libiconv_close");
      iconvctl  = (void *)GetProcAddress(hIconvDLL, "libiconvctl");
!     iconv_errno       = get_dll_import_func(hIconvDLL, "_errno");
      if (iconv_errno == NULL)
        iconv_errno = (void *)GetProcAddress(hMsvcrtDLL, "_errno");
      if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
*** ../vim-8.0.0174/src/misc1.c 2017-01-07 15:39:36.397759526 +0100
--- src/misc1.c 2017-01-12 21:39:35.536587643 +0100
***************
*** 4455,4460 ****
--- 4455,4463 ----
      {
        sprintf((char *)envbuf, "%s=%s", name, val);
        putenv((char *)envbuf);
+ # ifdef libintl_putenv
+       libintl_putenv((char *)envbuf);
+ # endif
      }
  #endif
  #ifdef FEAT_GETTEXT
*** ../vim-8.0.0174/src/os_win32.c      2016-11-26 15:13:29.406218061 +0100
--- src/os_win32.c      2017-01-12 21:42:16.767329718 +0100
***************
*** 425,430 ****
--- 425,508 ----
      return dll;
  }
  
+ #if defined(DYNAMIC_ICONV) || defined(DYNAMIC_GETTEXT) || defined(PROTO)
+ /*
+  * Get related information about 'funcname' which is imported by 'hInst'.
+  * If 'info' is 0, return the function address.
+  * If 'info' is 1, return the module name which the function is imported from.
+  */
+     static void *
+ get_imported_func_info(HINSTANCE hInst, const char *funcname, int info)
+ {
+     PBYTE                     pImage = (PBYTE)hInst;
+     PIMAGE_DOS_HEADER         pDOS = (PIMAGE_DOS_HEADER)hInst;
+     PIMAGE_NT_HEADERS         pPE;
+     PIMAGE_IMPORT_DESCRIPTOR  pImpDesc;
+     PIMAGE_THUNK_DATA         pIAT;       /* Import Address Table */
+     PIMAGE_THUNK_DATA         pINT;       /* Import Name Table */
+     PIMAGE_IMPORT_BY_NAME     pImpName;
+ 
+     if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
+       return NULL;
+     pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
+     if (pPE->Signature != IMAGE_NT_SIGNATURE)
+       return NULL;
+     pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
+           + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
+                                                           .VirtualAddress);
+     for (; pImpDesc->FirstThunk; ++pImpDesc)
+     {
+       if (!pImpDesc->OriginalFirstThunk)
+           continue;
+       pIAT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->FirstThunk);
+       pINT = (PIMAGE_THUNK_DATA)(pImage + pImpDesc->OriginalFirstThunk);
+       for (; pIAT->u1.Function; ++pIAT, ++pINT)
+       {
+           if (IMAGE_SNAP_BY_ORDINAL(pINT->u1.Ordinal))
+               continue;
+           pImpName = (PIMAGE_IMPORT_BY_NAME)(pImage
+                                       + (UINT_PTR)(pINT->u1.AddressOfData));
+           if (strcmp((char *)pImpName->Name, funcname) == 0)
+           {
+               switch (info)
+               {
+                   case 0:
+                       return (void *)pIAT->u1.Function;
+                   case 1:
+                       return (void *)(pImage + pImpDesc->Name);
+                   default:
+                       return NULL;
+               }
+           }
+       }
+     }
+     return NULL;
+ }
+ 
+ /*
+  * Get the module handle which 'funcname' in 'hInst' is imported from.
+  */
+     HINSTANCE
+ find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname)
+ {
+     char    *modulename;
+ 
+     modulename = (char *)get_imported_func_info(hInst, funcname, 1);
+     if (modulename != NULL)
+       return GetModuleHandleA(modulename);
+     return NULL;
+ }
+ 
+ /*
+  * Get the address of 'funcname' which is imported by 'hInst' DLL.
+  */
+     void *
+ get_dll_import_func(HINSTANCE hInst, const char *funcname)
+ {
+     return get_imported_func_info(hInst, funcname, 0);
+ }
+ #endif
+ 
  #if defined(DYNAMIC_GETTEXT) || defined(PROTO)
  # ifndef GETTEXT_DLL
  #  define GETTEXT_DLL "libintl.dll"
***************
*** 436,441 ****
--- 514,520 ----
  static char *null_libintl_textdomain(const char *);
  static char *null_libintl_bindtextdomain(const char *, const char *);
  static char *null_libintl_bind_textdomain_codeset(const char *, const char *);
+ static int null_libintl_putenv(const char *);
  
  static HINSTANCE hLibintlDLL = NULL;
  char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
***************
*** 446,451 ****
--- 525,531 ----
                                                = null_libintl_bindtextdomain;
  char *(*dyn_libintl_bind_textdomain_codeset)(const char *, const char *)
                                       = null_libintl_bind_textdomain_codeset;
+ int (*dyn_libintl_putenv)(const char *) = null_libintl_putenv;
  
      int
  dyn_libintl_init(void)
***************
*** 463,468 ****
--- 543,549 ----
        {"bindtextdomain", (FARPROC*)&dyn_libintl_bindtextdomain},
        {NULL, NULL}
      };
+     HINSTANCE hmsvcrt;
  
      /* No need to initialize twice. */
      if (hLibintlDLL)
***************
*** 507,512 ****
--- 588,600 ----
        dyn_libintl_bind_textdomain_codeset =
                                         null_libintl_bind_textdomain_codeset;
  
+     /* _putenv() function for the libintl.dll is optional. */
+     hmsvcrt = find_imported_module_by_funcname(hLibintlDLL, "getenv");
+     if (hmsvcrt != NULL)
+       dyn_libintl_putenv = (void *)GetProcAddress(hmsvcrt, "_putenv");
+     if (dyn_libintl_putenv == NULL || dyn_libintl_putenv == putenv)
+       dyn_libintl_putenv = null_libintl_putenv;
+ 
      return 1;
  }
  
***************
*** 521,526 ****
--- 609,615 ----
      dyn_libintl_textdomain    = null_libintl_textdomain;
      dyn_libintl_bindtextdomain        = null_libintl_bindtextdomain;
      dyn_libintl_bind_textdomain_codeset = 
null_libintl_bind_textdomain_codeset;
+     dyn_libintl_putenv                = null_libintl_putenv;
  }
  
  /*ARGSUSED*/
***************
*** 562,567 ****
--- 651,663 ----
      return NULL;
  }
  
+ /*ARGSUSED*/
+     int
+ null_libintl_putenv(const char *envstring)
+ {
+     return 0;
+ }
+ 
  #endif /* DYNAMIC_GETTEXT */
  
  /* This symbol is not defined in older versions of the SDK or Visual C++ */
***************
*** 4781,4812 ****
  #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
      static HANDLE
  job_io_file_open(
!         char_u *fname,
!         DWORD dwDesiredAccess,
!         DWORD dwShareMode,
!         LPSECURITY_ATTRIBUTES lpSecurityAttributes,
!         DWORD dwCreationDisposition,
!         DWORD dwFlagsAndAttributes)
  {
      HANDLE h;
  # ifdef FEAT_MBYTE
      WCHAR *wn = NULL;
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
      {
!         wn = enc_to_utf16(fname, NULL);
!         if (wn != NULL)
!         {
!             h = CreateFileW(wn, dwDesiredAccess, dwShareMode,
!                      lpSecurityAttributes, dwCreationDisposition,
!                      dwFlagsAndAttributes, NULL);
!             vim_free(wn);
!         }
      }
      if (wn == NULL)
  # endif
!         h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode,
!                      lpSecurityAttributes, dwCreationDisposition,
!                      dwFlagsAndAttributes, NULL);
      return h;
  }
  
--- 4877,4908 ----
  #if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
      static HANDLE
  job_io_file_open(
!       char_u *fname,
!       DWORD dwDesiredAccess,
!       DWORD dwShareMode,
!       LPSECURITY_ATTRIBUTES lpSecurityAttributes,
!       DWORD dwCreationDisposition,
!       DWORD dwFlagsAndAttributes)
  {
      HANDLE h;
  # ifdef FEAT_MBYTE
      WCHAR *wn = NULL;
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
      {
!       wn = enc_to_utf16(fname, NULL);
!       if (wn != NULL)
!       {
!           h = CreateFileW(wn, dwDesiredAccess, dwShareMode,
!                   lpSecurityAttributes, dwCreationDisposition,
!                   dwFlagsAndAttributes, NULL);
!           vim_free(wn);
!       }
      }
      if (wn == NULL)
  # endif
!       h = CreateFile((LPCSTR)fname, dwDesiredAccess, dwShareMode,
!               lpSecurityAttributes, dwCreationDisposition,
!               dwFlagsAndAttributes, NULL);
      return h;
  }
  
*** ../vim-8.0.0174/src/proto/os_win32.pro      2016-10-15 18:36:45.353910276 
+0200
--- src/proto/os_win32.pro      2017-01-12 21:39:35.540587611 +0100
***************
*** 1,5 ****
--- 1,7 ----
  /* os_win32.c */
  HINSTANCE vimLoadLib(char *name);
+ HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char 
*funcname);
+ void *get_dll_import_func(HINSTANCE hInst, const char *funcname);
  int dyn_libintl_init(void);
  void dyn_libintl_end(void);
  void PlatformId(void);
*** ../vim-8.0.0174/src/vim.h   2016-12-03 16:40:44.432532400 +0100
--- src/vim.h   2017-01-12 21:39:35.540587611 +0100
***************
*** 574,579 ****
--- 574,580 ----
  extern char *(*dyn_libintl_bindtextdomain)(const char *domainname, const char 
*dirname);
  extern char *(*dyn_libintl_bind_textdomain_codeset)(const char *domainname, 
const char *codeset);
  extern char *(*dyn_libintl_textdomain)(const char *domainname);
+ extern int (*dyn_libintl_putenv)(const char *envstring);
  #endif
  
  
***************
*** 592,597 ****
--- 593,599 ----
  #   define HAVE_BIND_TEXTDOMAIN_CODESET 1
  #  endif
  #  define textdomain(domain) (*dyn_libintl_textdomain)(domain)
+ #  define libintl_putenv(envstring) (*dyn_libintl_putenv)(envstring)
  # else
  #  include <libintl.h>
  #  define _(x) gettext((char *)(x))
*** ../vim-8.0.0174/src/version.c       2017-01-12 20:28:22.454078272 +0100
--- src/version.c       2017-01-12 21:39:20.840702285 +0100
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     175,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
257. Your "hundred-and-one" lists include well over 101 items, since you
     automatically interpret all numbers in hexadecimal notation.
     (hex 101 = decimal 257)

 /// Bram Moolenaar -- b...@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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui