1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 /*  Wide char wrapper for strtold
7  *  Revision history:
8  *  6 Nov 2002	Initial version.
9  *  25 Aug 2006  Don't use strtold internal functions.
10  *
11  *  Contributor:   Danny Smith <dannysmith@users.sourceforege.net>
12  */
13 
14  /* This routine has been placed in the public domain.*/
15 
16 #ifndef WIN32_LEAN_AND_MEAN
17 #define WIN32_LEAN_AND_MEAN
18 #endif
19 #include <windows.h>
20 #include <locale.h>
21 #include <wchar.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <mbstring.h>
25 
26 #include "mb_wc_common.h"
27 
wcstold(const wchar_t * __restrict__ wcs,wchar_t ** __restrict__ wcse)28 long double wcstold (const wchar_t * __restrict__ wcs, wchar_t ** __restrict__ wcse)
29 {
30   char * cs;
31   char * cse;
32   unsigned int i;
33   long double ret;
34   const unsigned int cp = ___lc_codepage_func();
35 
36   /* Allocate enough room for (possibly) mb chars */
37   cs = (char *) malloc ((wcslen(wcs)+1) * MB_CUR_MAX);
38 
39   if (cp == 0) /* C locale */
40     {
41       for (i = 0; (wcs[i] != 0) && wcs[i] <= 255; i++)
42         cs[i] = (char) wcs[i];
43       cs[i]  = '\0';
44     }
45   else
46     {
47       int nbytes = -1;
48       int mb_len = 0;
49       /* loop through till we hit null or invalid character */
50       for (i = 0; (wcs[i] != 0) && (nbytes != 0); i++)
51 	{
52 	  nbytes = WideCharToMultiByte(cp, WC_COMPOSITECHECK | WC_SEPCHARS,
53 				       wcs + i, 1, cs + mb_len, MB_CUR_MAX,
54 				       NULL, NULL);
55 	  mb_len += nbytes;
56 	}
57       cs[mb_len] = '\0';
58     }
59 
60   ret =  strtold (cs, &cse);
61 
62   if (wcse)
63     {
64       /* Make sure temp mbstring has 0 at cse.  */
65       *cse = '\0';
66       i = MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, cs, -1, NULL, 0);
67       if (i > 0)
68         i -= 1; /* Remove zero terminator from length.  */
69       *wcse = (wchar_t *) wcs + i;
70     }
71   free (cs);
72 
73   return ret;
74 }
75