* i18n_strtod: locale-agnostic strtod() (accepts both comma and dot as decimal separ...
authorRémi Denis-Courmont <rem@videolan.org>
Wed, 8 Mar 2006 12:25:29 +0000 (12:25 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Wed, 8 Mar 2006 12:25:29 +0000 (12:25 +0000)
 * 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)

include/charset.h
src/misc/charset.c
src/test/i18n_atof.c

index a739859..7fd2cf2 100644 (file)
@@ -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
 }
index a575f72..2a66d67 100644 (file)
@@ -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 );
+}
+
index 4ac8eee..b7307ee 100644 (file)
 
 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;
 }