W32CE fix.
[gnupg.git] / common / utf8conv.c
1 /* utf8conf.c -  UTF8 character set conversion
2  * Copyright (C) 1994, 1998, 1999, 2000, 2001, 2003, 2006,
3  *               2008, 2010  Free Software Foundation, Inc.
4  *
5  * This file is part of JNLIB.
6  *
7  * JNLIB is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * JNLIB is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include <ctype.h>
26 #ifdef HAVE_LANGINFO_CODESET
27 #include <langinfo.h>
28 #endif
29 #include <errno.h>
30 #ifndef HAVE_W32_SYSTEM
31 # include <iconv.h>
32 #endif
33
34 #include "libjnlib-config.h"
35 #include "stringhelp.h"
36 #include "dynload.h"
37 #include "utf8conv.h"
38
39 #ifndef MB_LEN_MAX
40 #define MB_LEN_MAX 16
41 #endif
42
43 static const char *active_charset_name = "iso-8859-1";
44 static int no_translation;     /* Set to true if we let simply pass through. */
45 static int use_iconv;          /* iconv comversion fucntions required. */
46
47
48 /* Under W32 we dlopen the iconv dll and don't require any iconv
49    related headers at all.  However we need to define some stuff.  */
50 #ifdef HAVE_W32_SYSTEM
51 typedef void *iconv_t;
52 #ifndef ICONV_CONST
53 #define ICONV_CONST
54 #endif
55 static iconv_t (* __stdcall iconv_open) (const char *tocode,
56                                          const char *fromcode);
57 static size_t  (* __stdcall iconv) (iconv_t cd,
58                                     char **inbuf, size_t *inbytesleft,
59                                     char **outbuf, size_t *outbytesleft);
60 static int     (* __stdcall iconv_close) (iconv_t cd);
61
62 static int 
63 load_libiconv (void)
64 {
65 #ifdef HAVE_W32CE_SYSTEM
66   return -1; /* FIXME No libiconv yet - Need to investigate whether it
67                 is at all required.  */
68 #else
69   static int done;
70   
71   if (!done)
72     {
73       void *handle;
74
75       done = 1; /* Do it right now because we might get called recursivly
76                    through gettext.  */
77     
78       handle = dlopen ("iconv.dll", RTLD_LAZY);
79       if (handle)
80         {
81           iconv_open  = dlsym (handle, "libiconv_open");
82           if (iconv_open)
83             iconv = dlsym (handle, "libiconv");
84           if (iconv)    
85             iconv_close = dlsym (handle, "libiconv_close");
86         }
87       if (!handle || !iconv_close)
88         {
89           log_info (_("error loading `%s': %s\n"),
90                      "iconv.dll",  dlerror ());
91           log_info (_("please see %s for more information\n"),
92                     "http://www.gnupg.org/download/iconv.html");
93           iconv_open = NULL;
94           iconv = NULL;
95           iconv_close = NULL;
96           if (handle)
97             dlclose (handle);
98         }
99     }
100   return iconv_open? 0: -1;
101 #endif
102 }    
103 #endif /*HAVE_W32_SYSTEM*/
104
105
106 /* Error handler for iconv failures. This is needed to not clutter the
107    output with repeated diagnostics about a missing conversion. */
108 static void
109 handle_iconv_error (const char *to, const char *from, int use_fallback)
110 {
111   if (errno == EINVAL)
112     {
113       static int shown1, shown2;
114       int x;
115
116       if (to && !strcmp (to, "utf-8"))
117         {
118           x = shown1;
119           shown1 = 1;
120         }
121       else
122         {
123           x = shown2;
124           shown2 = 1;
125         }
126
127       if (!x)
128         log_info (_("conversion from `%s' to `%s' not available\n"),
129                   from, to);
130     }
131   else
132     {
133       static int shown;
134
135       if (!shown)
136         log_info (_("iconv_open failed: %s\n"), strerror (errno));
137       shown = 1;
138     }
139
140   if (use_fallback)
141     {
142       /* To avoid further error messages we fallback to Latin-1 for the
143          native encoding.  This is justified as one can expect that on a
144          utf-8 enabled system nl_langinfo() will work and thus we won't
145          never get to here.  Thus Latin-1 seems to be a reasonable
146          default.  */
147       active_charset_name = "iso-8859-1";
148       no_translation = 0;
149       use_iconv = 0;
150     }
151 }
152
153
154
155 int
156 set_native_charset (const char *newset)
157 {
158   const char *full_newset;
159
160   if (!newset) 
161     {
162 #ifdef HAVE_W32_SYSTEM
163       static char codepage[30];
164       unsigned int cpno;
165       const char *aliases;
166       
167       /* We are a console program thus we need to use the
168          GetConsoleOutputCP function and not the the GetACP which
169          would give the codepage for a GUI program.  Note this is not
170          a bulletproof detection because GetConsoleCP might return a
171          different one for console input.  Not sure how to cope with
172          that.  If the console Code page is not known we fall back to
173          the system code page.  */
174 #ifndef HAVE_W32CE_SYSTEM
175       cpno = GetConsoleOutputCP ();
176       if (!cpno)
177 #endif
178         cpno = GetACP ();
179       sprintf (codepage, "CP%u", cpno );
180       /* Resolve alias.  We use a long string string and not the usual
181          array to optimize if the code is taken to a DSO.  Taken from
182          libiconv 1.9.2. */
183       newset = codepage;
184       for (aliases = ("CP936"   "\0" "GBK" "\0"
185                       "CP1361"  "\0" "JOHAB" "\0"
186                       "CP20127" "\0" "ASCII" "\0"
187                       "CP20866" "\0" "KOI8-R" "\0"
188                       "CP21866" "\0" "KOI8-RU" "\0"
189                       "CP28591" "\0" "ISO-8859-1" "\0"
190                       "CP28592" "\0" "ISO-8859-2" "\0"
191                       "CP28593" "\0" "ISO-8859-3" "\0"
192                       "CP28594" "\0" "ISO-8859-4" "\0"
193                       "CP28595" "\0" "ISO-8859-5" "\0"
194                       "CP28596" "\0" "ISO-8859-6" "\0"
195                       "CP28597" "\0" "ISO-8859-7" "\0"
196                       "CP28598" "\0" "ISO-8859-8" "\0"
197                       "CP28599" "\0" "ISO-8859-9" "\0"
198                       "CP28605" "\0" "ISO-8859-15" "\0"
199                       "CP65001" "\0" "UTF-8" "\0");
200            *aliases;
201            aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
202         {
203           if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1]))
204             {
205               newset = aliases + strlen (aliases) + 1;
206               break;
207             }
208         }
209
210 #else /*!HAVE_W32_SYSTEM*/
211       
212 #ifdef HAVE_LANGINFO_CODESET
213       newset = nl_langinfo (CODESET);
214 #else /*!HAVE_LANGINFO_CODESET*/
215       /* Try to get the used charset from environment variables.  */
216       static char codepage[30];
217       const char *lc, *dot, *mod;
218
219       strcpy (codepage, "iso-8859-1");
220       lc = getenv ("LC_ALL");
221       if (!lc || !*lc)
222         {
223           lc = getenv ("LC_CTYPE");
224           if (!lc || !*lc)
225             lc = getenv ("LANG");
226         }
227       if (lc && *lc)
228         {
229           dot = strchr (lc, '.');
230           if (dot)
231             {
232               mod = strchr (++dot, '@');
233               if (!mod)
234                 mod = dot + strlen (dot);
235               if (mod - dot < sizeof codepage && dot != mod) 
236                 {
237                   memcpy (codepage, dot, mod - dot);
238                   codepage [mod - dot] = 0;
239                 }
240             }
241         }
242       newset = codepage;
243 #endif /*!HAVE_LANGINFO_CODESET*/
244 #endif /*!HAVE_W32_SYSTEM*/
245     }
246
247   full_newset = newset;
248   if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3))
249     {
250       newset += 3;
251       if (*newset == '-' || *newset == '_')
252         newset++;
253     }
254
255   /* Note that we silently assume that plain ASCII is actually meant
256      as Latin-1.  This makes sense because many Unix system don't have
257      their locale set up properly and thus would get annoying error
258      messages and we have to handle all the "bug" reports. Latin-1 has
259      always been the character set used for 8 bit characters on Unix
260      systems. */
261   if ( !*newset
262        || !ascii_strcasecmp (newset, "8859-1" )
263        || !ascii_strcasecmp (newset, "646" )
264        || !ascii_strcasecmp (newset, "ASCII" )
265        || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" )
266        )
267     {
268       active_charset_name = "iso-8859-1";
269       no_translation = 0;
270       use_iconv = 0;
271     }
272   else if ( !ascii_strcasecmp (newset, "utf8" )
273             || !ascii_strcasecmp(newset, "utf-8") )
274     {
275       active_charset_name = "utf-8";
276       no_translation = 1;
277       use_iconv = 0;
278     }
279   else
280     {
281       iconv_t cd;
282       
283 #ifdef HAVE_W32_SYSTEM
284       if (load_libiconv ())
285         return -1;
286 #endif /*HAVE_W32_SYSTEM*/      
287
288       cd = iconv_open (full_newset, "utf-8");
289       if (cd == (iconv_t)-1) 
290         {
291           handle_iconv_error (full_newset, "utf-8", 0);
292           return -1;
293         }
294       iconv_close (cd);
295       cd = iconv_open ("utf-8", full_newset);
296       if (cd == (iconv_t)-1) 
297         {
298           handle_iconv_error ("utf-8", full_newset, 0);
299           return -1;
300         }
301       iconv_close (cd);
302       active_charset_name = full_newset;
303       no_translation = 0;
304       use_iconv = 1;
305     }
306   return 0;
307 }
308
309 const char *
310 get_native_charset ()
311 {
312   return active_charset_name;
313 }
314
315 /* Return true if the native charset is utf-8.  */
316 int 
317 is_native_utf8 (void)
318 {
319   return no_translation;
320 }
321
322
323 /* Convert string, which is in native encoding to UTF8 and return a
324    new allocated UTF-8 string.  This function terminates the process
325    on memory shortage.  */
326 char *
327 native_to_utf8 (const char *orig_string)
328 {
329   const unsigned char *string = (const unsigned char *)orig_string;
330   const unsigned char *s;
331   char *buffer;
332   unsigned char *p;
333   size_t length = 0;
334
335   if (no_translation)
336     {
337       /* Already utf-8 encoded. */
338       buffer = jnlib_xstrdup (orig_string);
339     }
340   else if (!use_iconv)
341     {
342       /* For Latin-1 we can avoid the iconv overhead. */
343       for (s = string; *s; s++)
344         {
345           length++;
346           if (*s & 0x80)
347             length++;
348         }
349       buffer = jnlib_xmalloc (length + 1);
350       for (p = (unsigned char *)buffer, s = string; *s; s++)
351         {
352           if ( (*s & 0x80 ))
353             {
354               *p++ = 0xc0 | ((*s >> 6) & 3);
355               *p++ = 0x80 | (*s & 0x3f);
356             }
357           else
358             *p++ = *s;
359         }
360       *p = 0;
361     }
362   else
363     { 
364       /* Need to use iconv.  */
365       iconv_t cd;
366       const char *inptr;
367       char *outptr;
368       size_t inbytes, outbytes;
369      
370       cd = iconv_open ("utf-8", active_charset_name);
371       if (cd == (iconv_t)-1)
372         {
373           handle_iconv_error ("utf-8", active_charset_name, 1);
374           return native_to_utf8 (string);
375         }
376
377       for (s=string; *s; s++ ) 
378         {
379           length++;
380           if ((*s & 0x80))
381             length += 5; /* We may need up to 6 bytes for the utf8 output. */
382         }
383       buffer = jnlib_xmalloc (length + 1);
384       
385       inptr = string;
386       inbytes = strlen (string);
387       outptr = buffer;
388       outbytes = length;
389       if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
390                   &outptr, &outbytes) == (size_t)-1)
391         {
392           static int shown;
393
394           if (!shown)
395             log_info (_("conversion from `%s' to `%s' failed: %s\n"),
396                       active_charset_name, "utf-8", strerror (errno));
397           shown = 1;
398           /* We don't do any conversion at all but use the strings as is. */
399           strcpy (buffer, string);
400         }
401       else /* Success.  */
402         {
403           *outptr = 0;
404           /* We could realloc the buffer now but I doubt that it makes
405              much sense given that it will get freed anyway soon
406              after.  */
407         }
408       iconv_close (cd);
409     }
410   return buffer;
411 }
412
413
414
415 static char *
416 do_utf8_to_native (const char *string, size_t length, int delim,
417                    int with_iconv)
418 {
419   int nleft;
420   int i;
421   unsigned char encbuf[8];
422   int encidx;
423   const unsigned char *s;
424   size_t n;
425   char *buffer = NULL;
426   char *p = NULL;
427   unsigned long val = 0;
428   size_t slen;
429   int resync = 0;
430
431   /* First pass (p==NULL): count the extended utf-8 characters.  */
432   /* Second pass (p!=NULL): create string.  */
433   for (;;)
434     {
435       for (slen = length, nleft = encidx = 0, n = 0,
436              s = (const unsigned char *)string;
437            slen;
438            s++, slen--)
439         {
440           if (resync)
441             {
442               if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)))
443                 {
444                   /* Still invalid. */
445                   if (p)
446                     {
447                       sprintf (p, "\\x%02x", *s);
448                       p += 4;
449                     }
450                   n += 4;
451                   continue;
452                 }
453               resync = 0;
454             }
455           if (!nleft)
456             {
457               if (!(*s & 0x80))
458                 {       
459                   /* Plain ascii. */
460                   if ( delim != -1
461                        && (*s < 0x20 || *s == 0x7f || *s == delim 
462                            || (delim && *s == '\\')))
463                     {
464                       n++;
465                       if (p)
466                         *p++ = '\\';
467                       switch (*s)
468                         {
469                         case '\n': n++; if ( p ) *p++ = 'n'; break;
470                         case '\r': n++; if ( p ) *p++ = 'r'; break;
471                         case '\f': n++; if ( p ) *p++ = 'f'; break;
472                         case '\v': n++; if ( p ) *p++ = 'v'; break;
473                         case '\b': n++; if ( p ) *p++ = 'b'; break;
474                         case    0: n++; if ( p ) *p++ = '0'; break;
475                         default:
476                           n += 3;
477                           if (p)
478                             {
479                               sprintf (p, "x%02x", *s);
480                               p += 3;
481                             }
482                           break;
483                         }
484                     }
485                   else
486                     {
487                       if (p)
488                         *p++ = *s;
489                       n++;
490                     }
491                 }
492               else if ((*s & 0xe0) == 0xc0) /* 110x xxxx */
493                 {
494                   val = *s & 0x1f;
495                   nleft = 1;
496                   encidx = 0;
497                   encbuf[encidx++] = *s;
498                 }
499               else if ((*s & 0xf0) == 0xe0) /* 1110 xxxx */
500                 {       
501                   val = *s & 0x0f;
502                   nleft = 2;
503                   encidx = 0;
504                   encbuf[encidx++] = *s;
505                 }
506               else if ((*s & 0xf8) == 0xf0) /* 1111 0xxx */
507                 {       
508                   val = *s & 0x07;
509                   nleft = 3;
510                   encidx = 0;
511                   encbuf[encidx++] = *s;
512                 }
513               else if ((*s & 0xfc) == 0xf8) /* 1111 10xx */
514                 {       
515                   val = *s & 0x03;
516                   nleft = 4;
517                   encidx = 0;
518                   encbuf[encidx++] = *s;
519                 }
520               else if ((*s & 0xfe) == 0xfc) /* 1111 110x */
521                 {               
522                   val = *s & 0x01;
523                   nleft = 5;
524                   encidx = 0;
525                   encbuf[encidx++] = *s;
526                 }
527               else /* Invalid encoding: print as \xNN. */
528                 {               
529                   if (p)
530                     {
531                       sprintf (p, "\\x%02x", *s);
532                       p += 4;
533                     }
534                   n += 4;
535                   resync = 1;
536                 }
537             }
538           else if (*s < 0x80 || *s >= 0xc0) /* Invalid utf-8 */
539             {
540               if (p)
541                 {
542                   for (i = 0; i < encidx; i++)
543                     {
544                       sprintf (p, "\\x%02x", encbuf[i]);
545                       p += 4;
546                     }
547                   sprintf (p, "\\x%02x", *s);
548                   p += 4;
549                 }
550               n += 4 + 4 * encidx;
551               nleft = 0;
552               encidx = 0;
553               resync = 1;
554             }
555           else
556             {
557               encbuf[encidx++] = *s;
558               val <<= 6;
559               val |= *s & 0x3f;
560               if (!--nleft)  /* Ready. */
561                 { 
562                   if (no_translation)
563                     {
564                       if (p)
565                         {
566                           for (i = 0; i < encidx; i++)
567                             *p++ = encbuf[i];
568                         }
569                       n += encidx;
570                       encidx = 0;
571                     }
572                   else if (with_iconv)
573                     {
574                       /* Our strategy for using iconv is a bit strange
575                          but it better keeps compatibility with
576                          previous versions in regard to how invalid
577                          encodings are displayed.  What we do is to
578                          keep the utf-8 as is and have the real
579                          translation step then at the end.  Yes, I
580                          know that this is ugly.  However we are short
581                          of the 1.4 release and for this branch we
582                          should not mess too much around with iconv
583                          things.  One reason for this is that we don't
584                          know enough about non-GNU iconv
585                          implementation and want to minimize the risk
586                          of breaking the code on too many platforms.  */
587                         if ( p )
588                           {
589                             for (i=0; i < encidx; i++ )
590                               *p++ = encbuf[i];
591                           }
592                         n += encidx;
593                         encidx = 0;
594                     }
595                   else  /* Latin-1 case. */
596                     {
597                       if (val >= 0x80 && val < 256)
598                         {
599                           /* We can simply print this character */
600                           n++;  
601                           if (p)
602                             *p++ = val;
603                         }
604                       else
605                         {       
606                           /* We do not have a translation: print utf8. */
607                           if (p)
608                             {
609                               for (i = 0; i < encidx; i++)
610                                 {
611                                   sprintf (p, "\\x%02x", encbuf[i]);
612                                   p += 4;
613                                 }
614                             }
615                           n += encidx * 4;
616                           encidx = 0;
617                         }
618                     }
619                 }
620
621             }
622         }
623       if (!buffer)
624         {
625           /* Allocate the buffer after the first pass. */
626           buffer = p = jnlib_xmalloc (n + 1);
627         }
628       else if (with_iconv)
629         {
630           /* Note: See above for comments.  */
631           iconv_t cd;
632           const char *inptr;
633           char *outbuf, *outptr;
634           size_t inbytes, outbytes;
635           
636           *p = 0;  /* Terminate the buffer. */
637
638           cd = iconv_open (active_charset_name, "utf-8");
639           if (cd == (iconv_t)-1)
640             {
641               handle_iconv_error (active_charset_name, "utf-8", 1);
642               jnlib_free (buffer);
643               return utf8_to_native (string, length, delim);
644             }
645
646           /* Allocate a new buffer large enough to hold all possible
647              encodings. */
648           n = p - buffer + 1;
649           inbytes = n - 1;;
650           inptr = buffer;
651           outbytes = n * MB_LEN_MAX;
652           if (outbytes / MB_LEN_MAX != n) 
653             BUG (); /* Actually an overflow. */
654           outbuf = outptr = jnlib_xmalloc (outbytes);
655           if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
656                       &outptr, &outbytes) == (size_t)-1) 
657             {
658               static int shown;
659               
660               if (!shown)
661                 log_info (_("conversion from `%s' to `%s' failed: %s\n"),
662                           "utf-8", active_charset_name, strerror (errno));
663               shown = 1;
664               /* Didn't worked out.  Try again but without iconv.  */
665               jnlib_free (buffer);
666               buffer = NULL;
667               jnlib_free (outbuf);
668               outbuf = do_utf8_to_native (string, length, delim, 0);
669             }
670             else /* Success.  */
671               { 
672                 *outptr = 0; /* Make sure it is a string. */
673                 /* We could realloc the buffer now but I doubt that it
674                    makes much sense given that it will get freed
675                    anyway soon after.  */
676                 jnlib_free (buffer);
677               }
678           iconv_close (cd);
679           return outbuf;
680         }
681       else /* Not using iconv. */
682         {
683           *p = 0; /* Make sure it is a string. */
684           return buffer;
685         }
686     }
687 }
688
689 /* Convert string, which is in UTF-8 to native encoding.  Replace
690    illegal encodings by some "\xnn" and quote all control
691    characters. A character with value DELIM will always be quoted, it
692    must be a vanilla ASCII character.  A DELIM value of -1 is special:
693    it disables all quoting of control characters.  This function
694    terminates the process on memory shortage.  */
695 char *
696 utf8_to_native (const char *string, size_t length, int delim)
697 {
698   return do_utf8_to_native (string, length, delim, use_iconv);
699 }
700
701
702
703
704 /* Wrapper function for iconv_open, required for W32 as we dlopen that
705    library on that system.  */
706 jnlib_iconv_t 
707 jnlib_iconv_open (const char *tocode, const char *fromcode)
708 {
709 #ifdef HAVE_W32_SYSTEM
710   if (load_libiconv ())
711     return (jnlib_iconv_t)(-1);
712 #endif /*HAVE_W32_SYSTEM*/      
713
714   return (jnlib_iconv_t)iconv_open (tocode, fromcode);
715 }
716
717
718 /* Wrapper function for iconv, required for W32 as we dlopen that
719    library on that system.  */
720 size_t
721 jnlib_iconv (jnlib_iconv_t cd,
722              const char **inbuf, size_t *inbytesleft,
723              char **outbuf, size_t *outbytesleft)
724 {
725
726 #ifdef HAVE_W32_SYSTEM
727   if (load_libiconv ())
728     return 0;
729 #endif /*HAVE_W32_SYSTEM*/      
730
731   return iconv ((iconv_t)cd, (char**)inbuf, inbytesleft, outbuf, outbytesleft);
732 }
733
734 /* Wrapper function for iconv_close, required for W32 as we dlopen that
735    library on that system.  */
736 int
737 jnlib_iconv_close (jnlib_iconv_t cd)
738 {
739 #ifdef HAVE_W32_SYSTEM
740   if (load_libiconv ())
741     return 0;
742 #endif /*HAVE_W32_SYSTEM*/      
743
744   return iconv_close ((iconv_t)cd);
745 }
746
747
748 #ifdef HAVE_W32_SYSTEM
749 /* Return a malloced string encoded in UTF-8 from the wide char input
750    string STRING.  Caller must free this value.  Returns NULL and sets
751    ERRNO on failure.  Calling this function with STRING set to NULL is
752    not defined.  */
753 char *
754 wchar_to_utf8 (const wchar_t *string)
755 {
756   int n;
757   char *result;
758
759   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
760   if (n < 0)
761     {
762       jnlib_set_errno (EINVAL);
763       return NULL;
764     }
765
766   result = jnlib_malloc (n+1);
767   if (!result)
768     return NULL;
769
770   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
771   if (n < 0)
772     {
773       jnlib_free (result);
774       jnlib_set_errno (EINVAL);
775       result = NULL;
776     }
777   return result;
778 }
779
780
781 /* Return a malloced wide char string from an UTF-8 encoded input
782    string STRING.  Caller must free this value.  Returns NULL and sets
783    ERRNO on failure.  Calling this function with STRING set to NULL is
784    not defined.  */
785 wchar_t *
786 utf8_to_wchar (const char *string)
787 {
788   int n;
789   size_t nbytes;
790   wchar_t *result;
791
792   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
793   if (n < 0)
794     {
795       jnlib_set_errno (EINVAL);
796       return NULL;
797     }
798
799   nbytes = (size_t)(n+1) * sizeof(*result);
800   if (nbytes / sizeof(*result) != (n+1)) 
801     {
802       jnlib_set_errno (ENOMEM);
803       return NULL;
804     }
805   result = malloc (nbytes);
806   if (!result)
807     return NULL;
808
809   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
810   if (n < 0)
811     {
812       free (result);
813       jnlib_set_errno (EINVAL);
814       result = NULL;
815     }
816   return result;
817 }
818 #endif /*HAVE_W32_SYSTEM*/