summaryrefslogtreecommitdiff
path: root/src/lib/eina
diff options
context:
space:
mode:
authorYoungbok Shin <youngb.shin@samsung.com>2018-08-22 01:53:11 +0000
committerCedric BAIL <cedric@osg.samsung.com>2018-11-29 16:15:59 -0800
commitbef1c5cc433b89add2cf0292e1098e1bd74ac640 (patch)
tree9f2f60fcc9f0009cd70172c1d463849f62b3fec9 /src/lib/eina
parent3a89ea15b9d58f195986cb363f421782b0150272 (diff)
eina: add locale-independent eina_convert_strtod_c function
strtod's behavior is changed by system locale. http://man7.org/linux/man-pages/man3/strtod.3.html https://en.wikipedia.org/wiki/Decimal_separator Because of this, strtod(0.5) returns 0.0 in some locales. When a given value string is locale-independent, strtod has to be replaced to eina_convert_strtod_c function. Internally, it calls strtod_l function with "C" locale. @feature Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Reviewed-by: Vincent Torri <vincent.torri@gmail.com> Differential Revision: https://phab.enlightenment.org/D6644
Diffstat (limited to 'src/lib/eina')
-rw-r--r--src/lib/eina/eina_convert.c10
-rw-r--r--src/lib/eina/eina_convert.h16
-rw-r--r--src/lib/eina/eina_main.c19
-rw-r--r--src/lib/eina/eina_private.h6
4 files changed, 51 insertions, 0 deletions
diff --git a/src/lib/eina/eina_convert.c b/src/lib/eina/eina_convert.c
index 2943b37343..152ef5be4a 100644
--- a/src/lib/eina/eina_convert.c
+++ b/src/lib/eina/eina_convert.c
@@ -453,6 +453,16 @@ eina_convert_atofp(const char *src, int length, Eina_F32p32 *fp)
453 return EINA_TRUE; 453 return EINA_TRUE;
454} 454}
455 455
456EAPI double
457eina_convert_strtod_c(const char *nptr, char **endptr)
458{
459#ifdef _WIN32
460 return _strtod_l(nptr, endptr, _eina_c_locale_get());
461#else
462 return strtod_l(nptr, endptr, _eina_c_locale_get());
463#endif
464}
465
456/** 466/**
457 * @} 467 * @}
458 */ 468 */
diff --git a/src/lib/eina/eina_convert.h b/src/lib/eina/eina_convert.h
index 026fc6c8f6..337cd88ad8 100644
--- a/src/lib/eina/eina_convert.h
+++ b/src/lib/eina/eina_convert.h
@@ -334,6 +334,22 @@ EAPI Eina_Bool eina_convert_atofp(const char *src,
334 Eina_F32p32 *fp) EINA_ARG_NONNULL(1, 3); 334 Eina_F32p32 *fp) EINA_ARG_NONNULL(1, 3);
335 335
336/** 336/**
337 * @brief Converts a string to a floating point number.
338 *
339 * @param[in] nptr a string to convert. It shouldn't be NULL.
340 * @param[out] endptr If endptr is not NULL, a pointer to the character after the last
341 * character used in the conversion is stored in the location referenced
342 * by endptr.
343 * @return a double type floating point number.
344 *
345 * This function returns converted floating point number with locale-independency.
346 * Actually, it use "C" locale for strtod_l function internally. If you need strtod
347 * without locale-dependency, this function can replace strtod.
348 * For more information, please refer documents of strtod, strtod_l.
349 */
350EAPI double eina_convert_strtod_c(const char *nptr, char **endptr);
351
352/**
337 * @} 353 * @}
338 */ 354 */
339 355
diff --git a/src/lib/eina/eina_main.c b/src/lib/eina/eina_main.c
index 024d1e3eaa..535e4e7611 100644
--- a/src/lib/eina/eina_main.c
+++ b/src/lib/eina/eina_main.c
@@ -85,6 +85,7 @@ static int _eina_main_count = 0;
85static int _eina_main_thread_count = 0; 85static int _eina_main_thread_count = 0;
86#endif 86#endif
87static int _eina_log_dom = -1; 87static int _eina_log_dom = -1;
88static locale_t _eina_c_locale;
88 89
89#ifdef ERR 90#ifdef ERR
90#undef ERR 91#undef ERR
@@ -285,6 +286,12 @@ eina_init(void)
285 if (EINA_LIKELY(_eina_main_count > 0)) 286 if (EINA_LIKELY(_eina_main_count > 0))
286 return ++_eina_main_count; 287 return ++_eina_main_count;
287 288
289#ifdef _WIN32
290 _eina_c_locale = _create_locale(LC_ALL, "C");
291#else
292 _eina_c_locale = newlocale(LC_ALL_MASK, "C", NULL);
293#endif
294
288 srand(time(NULL)); 295 srand(time(NULL));
289 while (eina_seed == 0) 296 while (eina_seed == 0)
290 eina_seed = rand(); 297 eina_seed = rand();
@@ -348,6 +355,12 @@ eina_init(void)
348 return 1; 355 return 1;
349} 356}
350 357
358locale_t
359_eina_c_locale_get(void)
360{
361 return _eina_c_locale;
362}
363
351EAPI int 364EAPI int
352eina_shutdown(void) 365eina_shutdown(void)
353{ 366{
@@ -359,6 +372,12 @@ eina_shutdown(void)
359 _eina_main_count--; 372 _eina_main_count--;
360 if (EINA_UNLIKELY(_eina_main_count == 0)) 373 if (EINA_UNLIKELY(_eina_main_count == 0))
361 { 374 {
375#ifdef _WIN32
376 _free_locale(_eina_c_locale);
377#else
378 freelocale(_eina_c_locale);
379#endif
380
362 eina_log_timing(_eina_log_dom, 381 eina_log_timing(_eina_log_dom,
363 EINA_LOG_STATE_START, 382 EINA_LOG_STATE_START,
364 EINA_LOG_STATE_SHUTDOWN); 383 EINA_LOG_STATE_SHUTDOWN);
diff --git a/src/lib/eina/eina_private.h b/src/lib/eina/eina_private.h
index eab59586c1..be826e0fb0 100644
--- a/src/lib/eina/eina_private.h
+++ b/src/lib/eina/eina_private.h
@@ -20,6 +20,7 @@
20#define EINA_PRIVATE_H_ 20#define EINA_PRIVATE_H_
21 21
22#include <stdarg.h> 22#include <stdarg.h>
23#include <locale.h>
23 24
24#ifdef _WIN32 25#ifdef _WIN32
25# include <Evil.h> 26# include <Evil.h>
@@ -151,6 +152,11 @@ Eina_Stringshare *eina_file_sanitize(const char *path);
151 152
152void eina_freeq_main_set(Eina_FreeQ *fq); 153void eina_freeq_main_set(Eina_FreeQ *fq);
153 154
155#ifdef _WIN32
156typedef _locale_t locale_t;
157#endif
158locale_t _eina_c_locale_get(void);
159
154#include "eina_inline_private.h" 160#include "eina_inline_private.h"
155 161
156#endif /* EINA_PRIVATE_H_ */ 162#endif /* EINA_PRIVATE_H_ */