Commit d6b95124 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

* i18n_strtod: locale-agnostic strtod() (accepts both comma and dot as decimal separator)

 * us_strtod, us_atof: same as i18n_* but only accept dot in any case
   (this will be useful when parsing stream output chain which uses comma to separate
    options)
parent 88fcc88c
......@@ -49,7 +49,11 @@ VLC_EXPORT( char *, EnsureUTF8, ( char * ) );
VLC_EXPORT( char *, FromUTF32, ( const wchar_t * ) );
VLC_EXPORT( char *, __vlc_fix_readdir_charset, ( vlc_object_t *, const char * ) );
#define vlc_fix_readdir_charset(a,b) __vlc_fix_readdir_charset(VLC_OBJECT(a),b)
extern double i18n_strtod( const char *, char ** );
extern double i18n_atof( const char * );
extern double us_strtod( const char *, char ** );
extern double us_atof( const char * );
# ifdef __cplusplus
}
......
......@@ -380,25 +380,72 @@ char *__vlc_fix_readdir_charset( vlc_object_t *p_this, const char *psz_string )
* dot (which is the american default), and comma (which is used in France,
* the country with the most VLC developers, among others).
*
* i18n_atof() has the same prototype as ANSI C atof() but it accepts
* i18n_strtod() has the same prototype as ANSI C strtod() but it accepts
* either decimal separator when deserializing the string to a float number,
* independant of the local computer setting.
*/
double i18n_atof( const char *str )
double i18n_strtod( const char *str, char **end )
{
char *end;
double d = strtod( str, &end );
char *end_buf, e;
double d;
if(( *end == ',' ) || ( *end == '.' ))
if( end == NULL )
end = &end_buf;
d = strtod( str, end );
e = **end;
if(( e == ',' ) || ( e == '.' ))
{
char *dup = strdup( str );
char dup[strlen( str ) + 1];
strcpy( dup, str );
if( dup == NULL )
return d;
dup[end - str] = ( *end == ',' ) ? '.' : ',';
d = strtod( dup, &end );
free( dup );
dup[*end - str] = ( e == ',' ) ? '.' : ',';
d = strtod( dup, end );
}
return d;
}
/**
* i18n_atof() has the same prototype as ANSI C atof() but it accepts
* either decimal separator when deserializing the string to a float number,
* independant of the local computer setting.
*/
double i18n_atof( const char *str )
{
return i18n_strtod( str, NULL );
}
/**
* us_strtod() has the same prototype as ANSI C strtod() but it expects
* a dot as decimal separator regardless of the system locale.
*/
double us_strtod( const char *str, char **end )
{
char dup[strlen( str ) + 1], *ptr;
double d;
strcpy( dup, str );
ptr = strchr( dup, ',' );
if( ptr != NULL )
*ptr = '\0';
d = strtod( dup, &ptr );
if( end != NULL )
*end = (char *)&str[ptr - dup];
return d;
}
/**
* us_atof() has the same prototype as ANSI C atof() but it expects a dot
* as decimal separator, regardless of the system locale.
*/
double us_atof( const char *str )
{
return us_strtod( str, NULL );
}
......@@ -27,15 +27,44 @@
int main (void)
{
const char dot9[] = "999999.999999";
const char comma9[] = "999999,999999";
const char sharp9[] = "999999#999999";
char *end;
assert (i18n_atof("0") == 0.);
assert (i18n_atof("1") == 1.);
assert (i18n_atof("1.") == 1.);
assert (i18n_atof("1,") == 1.);
assert (i18n_atof("1#") == 1.);
assert (i18n_atof("999999.999999") == 999999.999999);
assert (i18n_atof("999999,999999") == 999999.999999);
assert (i18n_atof("999999#999999") == 999999.);
assert (i18n_atof(dot9) == 999999.999999);
assert (i18n_atof(comma9) == 999999.999999);
assert (i18n_atof(sharp9) == 999999.);
assert (i18n_atof("invalid") == 0.);
assert (us_atof("0") == 0.);
assert (us_atof("1") == 1.);
assert (us_atof("1.") == 1.);
assert (us_atof("1,") == 1.);
assert (us_atof("1#") == 1.);
assert (us_atof(dot9) == 999999.999999);
assert (us_atof(comma9) == 999999.);
assert (us_atof(sharp9) == 999999.);
assert (us_atof("invalid") == 0.);
assert ((i18n_strtod(dot9, &end ) == 999999.999999)
&& (*end == '\0'));
assert ((i18n_strtod(comma9, &end ) == 999999.999999)
&& (*end == '\0'));
assert ((i18n_strtod(sharp9, &end ) == 999999.)
&& (*end == '#'));
assert ((us_strtod(dot9, &end ) == 999999.999999)
&& (*end == '\0'));
assert ((us_strtod(comma9, &end ) == 999999.)
&& (*end == ','));
assert ((us_strtod(sharp9, &end ) == 999999.)
&& (*end == '#'));
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment