| 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 | long double __mingw_wcstold (const wchar_t * __restrict__ wcs, wchar_t ** __restrict__ wcse) |
| 27 | { |
| 28 | char * cs; |
| 29 | char * cse; |
| 30 | unsigned int i; |
| 31 | long double ret; |
| 32 | const unsigned int cp = ___lc_codepage_func(); |
| 33 | |
| 34 | /* Allocate enough room for (possibly) mb chars */ |
| 35 | cs = (char *) malloc ((wcslen(wcs)+1) * MB_CUR_MAX); |
| 36 | |
| 37 | if (cp == 0) /* C locale */ |
| 38 | { |
| 39 | for (i = 0; (wcs[i] != 0) && wcs[i] <= 255; i++) |
| 40 | cs[i] = (char) wcs[i]; |
| 41 | cs[i] = '\0'; |
| 42 | } |
| 43 | else |
| 44 | { |
| 45 | int nbytes = -1; |
| 46 | int mb_len = 0; |
| 47 | /* loop through till we hit null or invalid character */ |
| 48 | for (i = 0; (wcs[i] != 0) && (nbytes != 0); i++) |
| 49 | 	{ |
| 50 | 	 nbytes = WideCharToMultiByte(cp, WC_COMPOSITECHECK | WC_SEPCHARS, |
| 51 | 				 wcs + i, 1, cs + mb_len, MB_CUR_MAX, |
| 52 | 				 NULL, NULL); |
| 53 | 	 mb_len += nbytes; |
| 54 | 	} |
| 55 | cs[mb_len] = '\0'; |
| 56 | } |
| 57 | |
| 58 | ret = strtold (cs, &cse); |
| 59 | |
| 60 | if (wcse) |
| 61 | { |
| 62 | /* Make sure temp mbstring has 0 at cse. */ |
| 63 | *cse = '\0'; |
| 64 | i = MultiByteToWideChar (cp, MB_ERR_INVALID_CHARS, cs, -1, NULL, 0); |
| 65 | if (i > 0) |
| 66 | i -= 1; /* Remove zero terminator from length. */ |
| 67 | *wcse = (wchar_t *) wcs + i; |
| 68 | } |
| 69 | free (cs); |
| 70 | |
| 71 | return ret; |
| 72 | } |