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.1.229 < prev    next >
Encoding:
Internet Message Format  |  2002-10-14  |  8.0 KB

  1. To: vim-dev@vim.org
  2. Subject: Patch 6.1.229
  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.1.229
  11. Problem:    Win32: Conversion to/from often used codepages requires the iconv
  12.         library, which is not always available.
  13. Solution:   Use standard MS-Windows functions for the conversion when
  14.         possible. (mostly by Glenn Maynard)
  15.         Also fixes missing declaration for patch 6.1.220.
  16. Files:        src/fileio.c
  17.  
  18.  
  19. *** ../vim61.228/src/fileio.c    Sun Oct 13 20:08:14 2002
  20. --- src/fileio.c    Tue Oct 15 20:35:02 2002
  21. ***************
  22. *** 78,83 ****
  23. --- 78,88 ----
  24.   # define FIO_UCS2    0x04    /* convert UCS-2 */
  25.   # define FIO_UCS4    0x08    /* convert UCS-4 */
  26.   # define FIO_UTF16    0x10    /* convert UTF-16 */
  27. + # ifdef WIN3264
  28. + #  define FIO_CODEPAGE    0x20    /* convert MS-Windows codepage */
  29. + #  define FIO_PUT_CP(x) (((x) & 0xffff) << 16)    /* put codepage in top word */
  30. + #  define FIO_GET_CP(x)    (((x)>>16) & 0xffff)    /* get codepage from top word */
  31. + # endif
  32.   # define FIO_ENDIAN_L    0x80    /* little endian */
  33.   # define FIO_ENCRYPTED    0x1000    /* encrypt written bytes */
  34.   # define FIO_NOCONVERT    0x2000    /* skip encoding conversion */
  35. ***************
  36. *** 125,131 ****
  37. --- 130,140 ----
  38.   static int get_fio_flags __ARGS((char_u *ptr));
  39.   static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags));
  40.   static int make_bom __ARGS((char_u *buf, char_u *name));
  41. + # ifdef WIN3264
  42. + static int get_win_fio_flags __ARGS((char_u *ptr));
  43. + # endif
  44.   #endif
  45. + static int move_lines __ARGS((buf_T *frombuf, buf_T *tobuf));
  46.   
  47.   static linenr_T    write_no_eol_lnum = 0;    /* non-zero lnum when last line of
  48.                          next binary write should not have
  49. ***************
  50. *** 851,856 ****
  51. --- 861,874 ----
  52.       else if (enc_utf8 || STRCMP(p_enc, "latin1") == 0)
  53.           fio_flags = get_fio_flags(fenc);
  54.   
  55. + # ifdef WIN3264
  56. +     /*
  57. +      * Conversion from an MS-Windows codepage to UTF-8 is handled here.
  58. +      */
  59. +     if (fio_flags == 0 && enc_utf8)
  60. +         fio_flags = get_win_fio_flags(fenc);
  61. + # endif
  62.   # ifdef USE_ICONV
  63.       /*
  64.        * Try using iconv() if we can't convert internally.
  65. ***************
  66. *** 1007,1012 ****
  67. --- 1025,1034 ----
  68.               size = (size * 2 / 3) & ~3;
  69.           else if (fio_flags == FIO_UCSBOM)
  70.               size = size / ICONV_MULT;    /* worst case */
  71. + # ifdef WIN3264
  72. +         else if (fio_flags & FIO_CODEPAGE)
  73. +             size = size / ICONV_MULT;    /* also worst case */
  74. + # endif
  75.   #endif
  76.   
  77.   #ifdef FEAT_MBYTE
  78. ***************
  79. *** 1213,1218 ****
  80. --- 1235,1301 ----
  81.           }
  82.   # endif
  83.   
  84. + # ifdef WIN3264
  85. +         if (fio_flags & FIO_CODEPAGE)
  86. +         {
  87. +         /*
  88. +          * Conversion from an MS-Windows codepage to UTF-8, using
  89. +          * standard MS-Windows functions.
  90. +          */
  91. +         char_u    *ucsp;
  92. +         size_t    from_size;
  93. +         int    needed;
  94. +         char_u    *p;
  95. +         int    u8c;
  96. +         /*
  97. +          * We can't tell if the last byte of an MBCS string is valid
  98. +          * and MultiByteToWideChar() returns zero if it isn't.
  99. +          * Try the whole string, and if that fails, bump the last byte
  100. +          * into conv_rest and try again.
  101. +          */
  102. +         from_size = size;
  103. +         needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  104. +                    MB_ERR_INVALID_CHARS, (LPCSTR)ptr, from_size,
  105. +                                      NULL, 0);
  106. +         if (needed == 0)
  107. +         {
  108. +             conv_rest[0] = ptr[from_size - 1];
  109. +             conv_restlen = 1;
  110. +             --from_size;
  111. +             needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  112. +                    MB_ERR_INVALID_CHARS, (LPCSTR)ptr, from_size,
  113. +                                      NULL, 0);
  114. +         }
  115. +         /* If there really is a conversion error, try using another
  116. +          * conversion. */
  117. +         if (needed == 0)
  118. +             goto rewind_retry;
  119. +         /* Put the result of conversion to UCS-2 at the end of the
  120. +          * buffer, then convert from UCS-2 to UTF-8 into the start of
  121. +          * the buffer.  If there is not enough space just fail, there
  122. +          * is probably something wrong. */
  123. +         ucsp = ptr + real_size - (needed * sizeof(WCHAR));
  124. +         if (ucsp < ptr + size)
  125. +             goto rewind_retry;
  126. +         needed = MultiByteToWideChar(FIO_GET_CP(fio_flags),
  127. +                         MB_ERR_INVALID_CHARS, (LPCSTR)ptr,
  128. +                          from_size, (LPWSTR)ucsp, needed);
  129. +         /* Now go from UCS-2 to UTF-8. */
  130. +         p = ptr;
  131. +         for (; needed > 0; --needed)
  132. +         {
  133. +             u8c = *ucsp++;
  134. +             u8c += (*ucsp++ << 8);
  135. +             p += utf_char2bytes(u8c, p);
  136. +         }
  137. +         size = p - ptr;
  138. +         }
  139. +         else
  140. + # endif
  141.           if (fio_flags != 0)
  142.           {
  143.           int    u8c;
  144. ***************
  145. *** 3146,3151 ****
  146. --- 3229,3248 ----
  147.       }
  148.       }
  149.   
  150. + # ifdef WIN3264
  151. +     if (converted && wb_flags == 0 && get_win_fio_flags(fenc))
  152. +     {
  153. +     wb_flags = get_win_fio_flags(fenc);
  154. +     /* Convert UTF-8 -> UCS-2 and UCS-2 -> DBCS.  Worst-case * 4: */
  155. +     write_info.bw_conv_buflen = bufsize * 4;
  156. +     write_info.bw_conv_buf
  157. +                 = lalloc((long_u)write_info.bw_conv_buflen, TRUE);
  158. +     if (write_info.bw_conv_buf == NULL)
  159. +         end = 0;
  160. +     }
  161. + # endif
  162.   # if defined(FEAT_EVAL) || defined(USE_ICONV)
  163.       if (converted && wb_flags == 0)
  164.       {
  165. ***************
  166. *** 4126,4131 ****
  167. --- 4223,4291 ----
  168.           }
  169.       }
  170.   
  171. + # ifdef WIN3264
  172. +     else if (flags & FIO_CODEPAGE)
  173. +     {
  174. +         /*
  175. +          * Convert UTF-8 to UCS-2 and then to MS-Windows codepage.
  176. +          */
  177. +         char_u    *from;
  178. +         size_t    fromlen;
  179. +         char_u    *to;
  180. +         int        u8c;
  181. +         BOOL    bad = FALSE;
  182. +         if (ip->bw_restlen > 0)
  183. +         {
  184. +         /* Need to concatenate the remainder of the previous call and
  185. +          * the bytes of the current call.  Use the end of the
  186. +          * conversion buffer for this. */
  187. +         fromlen = len + ip->bw_restlen;
  188. +         from = ip->bw_conv_buf + ip->bw_conv_buflen - fromlen;
  189. +         mch_memmove(from, ip->bw_rest, (size_t)ip->bw_restlen);
  190. +         mch_memmove(from + ip->bw_restlen, buf, (size_t)len);
  191. +         }
  192. +         else
  193. +         {
  194. +         from = buf;
  195. +         fromlen = len;
  196. +         }
  197. +         /* Convert from UTF-8 to UCS-2, to the start of the buffer.
  198. +          * The buffer has been allocated to be big enough. */
  199. +         to = ip->bw_conv_buf;
  200. +         while (fromlen > 0)
  201. +         {
  202. +         n = utf_ptr2len_check_len(from, fromlen);
  203. +         if (n > (int)fromlen)
  204. +             break;
  205. +         u8c = utf_ptr2char(from);
  206. +         *to++ = (u8c & 0xff);
  207. +         *to++ = (u8c >> 8);
  208. +         fromlen -= n;
  209. +         from += n;
  210. +         }
  211. +         /* copy remainder to ip->bw_rest[] to be used for the next call. */
  212. +         mch_memmove(ip->bw_rest, from, fromlen);
  213. +         ip->bw_restlen = fromlen;
  214. +         /* Convert from UCS-2 to the codepage, using the remainder of the
  215. +          * conversion buffer.  If the conversion uses the default
  216. +          * character "0", the data doesn't fit in this encoding, so fail. */
  217. +         fromlen = to - ip->bw_conv_buf;
  218. +         len = WideCharToMultiByte(FIO_GET_CP(flags), 0,
  219. +             (LPCWSTR)ip->bw_conv_buf, (int)fromlen / sizeof(WCHAR),
  220. +             (LPSTR)to, ip->bw_conv_buflen - fromlen, 0, &bad);
  221. +         if (bad)
  222. +         {
  223. +         ip->bw_conv_error = TRUE;
  224. +         return FAIL;
  225. +         }
  226. +         buf = to;
  227. +     }
  228. + # endif
  229.   # ifdef USE_ICONV
  230.       if (ip->bw_iconv_fd != (iconv_t)-1)
  231.       {
  232. ***************
  233. *** 4364,4369 ****
  234. --- 4524,4544 ----
  235.       /* must be ENC_DBCS, requires iconv() */
  236.       return 0;
  237.   }
  238. + #ifdef WIN3264
  239. + /*
  240. +  * Check "ptr" for a MS-Windows codepage name and return the FIO_ flags needed
  241. +  * for the conversion MS-Windows can do for us.
  242. +  */
  243. +     static int
  244. + get_win_fio_flags(ptr)
  245. +     char_u    *ptr;
  246. + {
  247. +     if (ptr[0] == 'c' && ptr[1] == 'p' && isdigit(ptr[2]))
  248. +     return FIO_PUT_CP(atoi(ptr + 2)) | FIO_CODEPAGE;
  249. +     return 0;
  250. + }
  251. + #endif
  252.   
  253.   /*
  254.    * Check for a Unicode BOM (Byte Order Mark) at the start of p[size].
  255. *** ../vim61.228/src/version.c    Tue Oct 15 21:05:16 2002
  256. --- src/version.c    Tue Oct 15 21:09:55 2002
  257. ***************
  258. *** 608,609 ****
  259. --- 608,611 ----
  260.   {   /* Add new patch number below this line */
  261. + /**/
  262. +     229,
  263.   /**/
  264.  
  265. -- 
  266. hundred-and-one symptoms of being an internet addict:
  267. 235. You start naming your kids Pascal, COBOL, Algol and Fortran.
  268.  
  269.  ///  Bram Moolenaar -- Bram@moolenaar.net -- http://www.moolenaar.net  \\\
  270. ///          Creator of Vim - Vi IMproved -- http://www.vim.org          \\\
  271. \\\           Project leader for A-A-P -- http://www.a-a-p.org           ///
  272.  \\\ Lord Of The Rings helps Uganda - http://iccf-holland.org/lotr.html ///
  273.