1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright 2010 VMware, Inc.
3*61046927SAndroid Build Coastguard Worker * All Rights Reserved.
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the
7*61046927SAndroid Build Coastguard Worker * "Software"), to deal in the Software without restriction, including
8*61046927SAndroid Build Coastguard Worker * without limitation the rights to use, copy, modify, merge, publish,
9*61046927SAndroid Build Coastguard Worker * distribute, sub license, and/or sell copies of the Software, and to
10*61046927SAndroid Build Coastguard Worker * permit persons to whom the Software is furnished to do so, subject to
11*61046927SAndroid Build Coastguard Worker * the following conditions:
12*61046927SAndroid Build Coastguard Worker *
13*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the
14*61046927SAndroid Build Coastguard Worker * next paragraph) shall be included in all copies or substantial portions
15*61046927SAndroid Build Coastguard Worker * of the Software.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19*61046927SAndroid Build Coastguard Worker * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20*61046927SAndroid Build Coastguard Worker * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
21*61046927SAndroid Build Coastguard Worker * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22*61046927SAndroid Build Coastguard Worker * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23*61046927SAndroid Build Coastguard Worker * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker */
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #if defined(_GNU_SOURCE) && defined(HAVE_STRTOD_L)
30*61046927SAndroid Build Coastguard Worker #include <locale.h>
31*61046927SAndroid Build Coastguard Worker #ifdef HAVE_XLOCALE_H
32*61046927SAndroid Build Coastguard Worker #include <xlocale.h>
33*61046927SAndroid Build Coastguard Worker #endif
34*61046927SAndroid Build Coastguard Worker #endif
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker #include "strtod.h"
37*61046927SAndroid Build Coastguard Worker #include "util/u_call_once.h"
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #if defined(_GNU_SOURCE) && defined(HAVE_STRTOD_L)
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker static locale_t loc;
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker static void
_mesa_locale_fini(void)44*61046927SAndroid Build Coastguard Worker _mesa_locale_fini(void)
45*61046927SAndroid Build Coastguard Worker {
46*61046927SAndroid Build Coastguard Worker freelocale(loc);
47*61046927SAndroid Build Coastguard Worker }
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker static void
_mesa_locale_init_once(void)50*61046927SAndroid Build Coastguard Worker _mesa_locale_init_once(void)
51*61046927SAndroid Build Coastguard Worker {
52*61046927SAndroid Build Coastguard Worker loc = newlocale(LC_CTYPE_MASK, "C", NULL);
53*61046927SAndroid Build Coastguard Worker atexit(_mesa_locale_fini);
54*61046927SAndroid Build Coastguard Worker }
55*61046927SAndroid Build Coastguard Worker
56*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE locale_t
_mesa_get_locale(void)57*61046927SAndroid Build Coastguard Worker _mesa_get_locale(void)
58*61046927SAndroid Build Coastguard Worker {
59*61046927SAndroid Build Coastguard Worker static util_once_flag once = UTIL_ONCE_FLAG_INIT;
60*61046927SAndroid Build Coastguard Worker util_call_once(&once, _mesa_locale_init_once);
61*61046927SAndroid Build Coastguard Worker return loc;
62*61046927SAndroid Build Coastguard Worker }
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker #endif
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker /**
67*61046927SAndroid Build Coastguard Worker * Wrapper around strtod which uses the "C" locale so the decimal
68*61046927SAndroid Build Coastguard Worker * point is always '.'
69*61046927SAndroid Build Coastguard Worker */
70*61046927SAndroid Build Coastguard Worker double
_mesa_strtod(const char * s,char ** end)71*61046927SAndroid Build Coastguard Worker _mesa_strtod(const char *s, char **end)
72*61046927SAndroid Build Coastguard Worker {
73*61046927SAndroid Build Coastguard Worker #if defined(_GNU_SOURCE) && defined(HAVE_STRTOD_L)
74*61046927SAndroid Build Coastguard Worker return strtod_l(s, end, _mesa_get_locale());
75*61046927SAndroid Build Coastguard Worker #else
76*61046927SAndroid Build Coastguard Worker return strtod(s, end);
77*61046927SAndroid Build Coastguard Worker #endif
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker /**
82*61046927SAndroid Build Coastguard Worker * Wrapper around strtof which uses the "C" locale so the decimal
83*61046927SAndroid Build Coastguard Worker * point is always '.'
84*61046927SAndroid Build Coastguard Worker */
85*61046927SAndroid Build Coastguard Worker float
_mesa_strtof(const char * s,char ** end)86*61046927SAndroid Build Coastguard Worker _mesa_strtof(const char *s, char **end)
87*61046927SAndroid Build Coastguard Worker {
88*61046927SAndroid Build Coastguard Worker #if defined(_GNU_SOURCE) && defined(HAVE_STRTOD_L)
89*61046927SAndroid Build Coastguard Worker return strtof_l(s, end, _mesa_get_locale());
90*61046927SAndroid Build Coastguard Worker #elif defined(HAVE_STRTOF)
91*61046927SAndroid Build Coastguard Worker return strtof(s, end);
92*61046927SAndroid Build Coastguard Worker #else
93*61046927SAndroid Build Coastguard Worker return (float) strtod(s, end);
94*61046927SAndroid Build Coastguard Worker #endif
95*61046927SAndroid Build Coastguard Worker }
96