Revert "Revert "eina: add locale-independent eina_convert_strtod_c function""

This reverts commit ddd2638758.
This commit is contained in:
Marcel Hollerbach 2018-12-05 11:04:23 +01:00 committed by Christopher Michael
parent dc4eb5d728
commit 23c1e63eaa
5 changed files with 72 additions and 0 deletions

View File

@ -453,6 +453,16 @@ eina_convert_atofp(const char *src, int length, Eina_F32p32 *fp)
return EINA_TRUE; return EINA_TRUE;
} }
EAPI double
eina_convert_strtod_c(const char *nptr, char **endptr)
{
#ifdef _WIN32
return _strtod_l(nptr, endptr, _eina_c_locale_get());
#else
return strtod_l(nptr, endptr, _eina_c_locale_get());
#endif
}
/** /**
* @} * @}
*/ */

View File

@ -333,6 +333,22 @@ EAPI Eina_Bool eina_convert_atofp(const char *src,
int length, int length,
Eina_F32p32 *fp) EINA_ARG_NONNULL(1, 3); Eina_F32p32 *fp) EINA_ARG_NONNULL(1, 3);
/**
* @brief Converts a string to a floating point number.
*
* @param[in] nptr a string to convert. It shouldn't be NULL.
* @param[out] endptr If endptr is not NULL, a pointer to the character after the last
* character used in the conversion is stored in the location referenced
* by endptr.
* @return a double type floating point number.
*
* This function returns converted floating point number with locale-independency.
* Actually, it use "C" locale for strtod_l function internally. If you need strtod
* without locale-dependency, this function can replace strtod.
* For more information, please refer documents of strtod, strtod_l.
*/
EAPI double eina_convert_strtod_c(const char *nptr, char **endptr);
/** /**
* @} * @}
*/ */

View File

@ -85,6 +85,7 @@ static int _eina_main_count = 0;
static int _eina_main_thread_count = 0; static int _eina_main_thread_count = 0;
#endif #endif
static int _eina_log_dom = -1; static int _eina_log_dom = -1;
static locale_t _eina_c_locale;
#ifdef ERR #ifdef ERR
#undef ERR #undef ERR
@ -285,6 +286,12 @@ eina_init(void)
if (EINA_LIKELY(_eina_main_count > 0)) if (EINA_LIKELY(_eina_main_count > 0))
return ++_eina_main_count; return ++_eina_main_count;
#ifdef _WIN32
_eina_c_locale = _create_locale(LC_ALL, "C");
#else
_eina_c_locale = newlocale(LC_ALL_MASK, "C", NULL);
#endif
srand(time(NULL)); srand(time(NULL));
while (eina_seed == 0) while (eina_seed == 0)
eina_seed = rand(); eina_seed = rand();
@ -348,6 +355,12 @@ eina_init(void)
return 1; return 1;
} }
locale_t
_eina_c_locale_get(void)
{
return _eina_c_locale;
}
EAPI int EAPI int
eina_shutdown(void) eina_shutdown(void)
{ {
@ -359,6 +372,12 @@ eina_shutdown(void)
_eina_main_count--; _eina_main_count--;
if (EINA_UNLIKELY(_eina_main_count == 0)) if (EINA_UNLIKELY(_eina_main_count == 0))
{ {
#ifdef _WIN32
_free_locale(_eina_c_locale);
#else
freelocale(_eina_c_locale);
#endif
eina_log_timing(_eina_log_dom, eina_log_timing(_eina_log_dom,
EINA_LOG_STATE_START, EINA_LOG_STATE_START,
EINA_LOG_STATE_SHUTDOWN); EINA_LOG_STATE_SHUTDOWN);

View File

@ -20,6 +20,7 @@
#define EINA_PRIVATE_H_ #define EINA_PRIVATE_H_
#include <stdarg.h> #include <stdarg.h>
#include <locale.h>
#ifdef _WIN32 #ifdef _WIN32
# include <Evil.h> # include <Evil.h>
@ -151,6 +152,11 @@ Eina_Stringshare *eina_file_sanitize(const char *path);
void eina_freeq_main_set(Eina_FreeQ *fq); void eina_freeq_main_set(Eina_FreeQ *fq);
#ifdef _WIN32
typedef _locale_t locale_t;
#endif
locale_t _eina_c_locale_get(void);
#include "eina_inline_private.h" #include "eina_inline_private.h"
#endif /* EINA_PRIVATE_H_ */ #endif /* EINA_PRIVATE_H_ */

View File

@ -160,10 +160,31 @@ _eina_convert_fp_check(double d, Eina_F32p32 fp, int length)
} }
EFL_END_TEST EFL_END_TEST
static void
_eina_convert_strtod_c_check(const char *str, double expected_result)
{
double result = eina_convert_strtod_c(str, NULL);
fail_if(result != expected_result);
}
EFL_START_TEST(eina_convert_strtod_c_simple)
{
_eina_convert_strtod_c_check("0.0", 0.0);
_eina_convert_strtod_c_check("0.5", 0.5);
_eina_convert_strtod_c_check("1.0", 1.0);
_eina_convert_strtod_c_check("-0.5", -0.5);
_eina_convert_strtod_c_check("-1.0", -1.0);
_eina_convert_strtod_c_check("3.45e-2", 0.0345);
_eina_convert_strtod_c_check("3.45e+2", 345.0);
}
EFL_END_TEST
void void
eina_test_convert(TCase *tc) eina_test_convert(TCase *tc)
{ {
tcase_add_test(tc, eina_convert_simple); tcase_add_test(tc, eina_convert_simple);
tcase_add_test(tc, eina_convert_double); tcase_add_test(tc, eina_convert_double);
tcase_add_test(tc, eina_convert_fp); tcase_add_test(tc, eina_convert_fp);
tcase_add_test(tc, eina_convert_strtod_c_simple);
} }