]> git.sesse.net Git - mlt/commitdiff
Implement LC_NUMERIC handling for non-glibc and non-Darwin OS.
authorDan Dennedy <dan@dennedy.org>
Thu, 27 Feb 2014 06:18:44 +0000 (22:18 -0800)
committerDan Dennedy <dan@dennedy.org>
Thu, 27 Feb 2014 06:18:44 +0000 (22:18 -0800)
src/framework/mlt_properties.c
src/framework/mlt_property.c
src/framework/mlt_property.h

index c5ca94a92129a8553204fcb1c9896ccf819da34f..887562c3467fee9dff0de058e5e04d885497f054 100644 (file)
@@ -148,8 +148,11 @@ int mlt_properties_set_lcnumeric( mlt_properties self, const char *locale )
                if ( list->locale )
                        freelocale( list->locale );
                list->locale = newlocale( LC_NUMERIC_MASK, locale, NULL );
+#else
+               if ( list->locale )
+                       free( list->locale );
+               list->locale = strdup( locale );
 #endif
-               error = list->locale == NULL;
        }
        else
                error = 1;
@@ -173,13 +176,13 @@ const char* mlt_properties_get_lcnumeric( mlt_properties self )
        if ( list->locale )
        {
 #if defined(__DARWIN__)
-               result = querylocale( LC_NUMERIC, list->locale );
+        result = querylocale( LC_NUMERIC, list->locale );
 #elif defined(__GLIBC__)
-               result = list->locale->__names[ LC_NUMERIC ];
+        result = list->locale->__names[ LC_NUMERIC ];
 #else
-               // TODO: not yet sure what to do on other platforms
+               result = list->locale;
 #endif
-       }
+    }
        return result;
 }
 
@@ -1398,6 +1401,9 @@ void mlt_properties_close( mlt_properties self )
                        // Cleanup locale
                        if ( list->locale )
                                freelocale( list->locale );
+#else
+                       if ( list->locale )
+                               free( list->locale );
 #endif
 
                        // Clear up the list
index 251cc33585bfd52d020d6554b1d62aed35bace4e..ab8730f4cbfb978293b3dcb867d47f5b675fd25b 100644 (file)
@@ -265,13 +265,14 @@ int mlt_property_set_data( mlt_property self, void *value, int length, mlt_destr
 /** Parse a SMIL clock value.
  *
  * \private \memberof mlt_property_s
+ * \param self a property
  * \param s the string to parse
  * \param fps frames per second
  * \param locale the locale to use for parsing a real number value
  * \return position in frames
  */
 
-static int time_clock_to_frames( const char *s, double fps, locale_t locale )
+static int time_clock_to_frames( mlt_property self, const char *s, double fps, locale_t locale )
 {
        char *pos, *copy = strdup( s );
        int hours = 0, minutes = 0;
@@ -279,6 +280,22 @@ static int time_clock_to_frames( const char *s, double fps, locale_t locale )
 
        s = copy;
        pos = strrchr( s, ':' );
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+       char *orig_localename = NULL;
+       if ( locale )
+       {
+               // Protect damaging the global locale from a temporary locale on another thread.
+               pthread_mutex_lock( &self->mutex );
+               
+               // Get the current locale
+               orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+               
+               // Set the new locale
+               setlocale( LC_NUMERIC, locale );
+       }
+#endif
+
        if ( pos ) {
 #if defined(__GLIBC__) || defined(__DARWIN__)
                if ( locale )
@@ -305,6 +322,16 @@ static int time_clock_to_frames( const char *s, double fps, locale_t locale )
 #endif
                        seconds = strtod( s, NULL );
        }
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+       if ( locale ) {
+               // Restore the current locale
+               setlocale( LC_NUMERIC, orig_localename );
+               free( orig_localename );
+               pthread_mutex_unlock( &self->mutex );
+       }
+#endif
+
        free( copy );
 
        return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) );
@@ -313,12 +340,13 @@ static int time_clock_to_frames( const char *s, double fps, locale_t locale )
 /** Parse a SMPTE timecode string.
  *
  * \private \memberof mlt_property_s
+ * \param self a property
  * \param s the string to parse
  * \param fps frames per second
  * \return position in frames
  */
 
-static int time_code_to_frames( const char *s, double fps )
+static int time_code_to_frames( mlt_property self, const char *s, double fps )
 {
        char *pos, *copy = strdup( s );
        int hours = 0, minutes = 0, seconds = 0, frames;
@@ -374,13 +402,15 @@ static int time_code_to_frames( const char *s, double fps )
  * contains a period or comma character, the string is parsed as a clock value:
  * HH:MM:SS. Otherwise, the time value is parsed as a SMPTE timecode: HH:MM:SS:FF.
  * \private \memberof mlt_property_s
- * \param value a string to convert
+ * \param self a property
  * \param fps frames per second, used when converting from time value
  * \param locale the locale to use when converting from time clock value
  * \return the resultant integer
  */
-static int mlt_property_atoi( const char *value, double fps, locale_t locale )
+static int mlt_property_atoi( mlt_property self, double fps, locale_t locale )
 {
+       const char *value = self->prop_string;
+       
        // Parse a hex color value as #RRGGBB or #AARRGGBB.
        if ( value[0] == '#' )
        {
@@ -397,9 +427,9 @@ static int mlt_property_atoi( const char *value, double fps, locale_t locale )
        else if ( fps > 0 && strchr( value, ':' ) )
        {
                if ( strchr( value, '.' ) || strchr( value, ',' ) )
-                       return time_clock_to_frames( value, fps, locale );
+                       return time_clock_to_frames( self, value, fps, locale );
                else
-                       return time_code_to_frames( value, fps );
+                       return time_code_to_frames( self, value, fps );
        }
        else
        {
@@ -429,7 +459,7 @@ int mlt_property_get_int( mlt_property self, double fps, locale_t locale )
        else if ( self->types & mlt_prop_rect && self->data )
                return ( int ) ( (mlt_rect*) self->data )->x;
        else if ( ( self->types & mlt_prop_string ) && self->prop_string )
-               return mlt_property_atoi( self->prop_string, fps, locale );
+               return mlt_property_atoi( self, fps, locale );
        return 0;
 }
 
@@ -441,32 +471,58 @@ int mlt_property_get_int( mlt_property self, double fps, locale_t locale )
  * If the numeric string ends with '%' then the value is divided by 100 to convert
  * it into a ratio.
  * \private \memberof mlt_property_s
- * \param value the string to convert
+ * \param self a property
  * \param fps frames per second, used when converting from time value
  * \param locale the locale to use when converting from time clock value
  * \return the resultant real number
  */
-static double mlt_property_atof( const char *value, double fps, locale_t locale )
+static double mlt_property_atof( mlt_property self, double fps, locale_t locale )
 {
-       if ( fps > 0 && strchr( value, ':' ) )
+       const char *value = self->prop_string;
+
+    if ( fps > 0 && strchr( value, ':' ) )
        {
                if ( strchr( value, '.' ) || strchr( value, ',' ) )
-                       return time_clock_to_frames( value, fps, locale );
+                       return time_clock_to_frames( self, value, fps, locale );
                else
-                       return time_code_to_frames( value, fps );
+                       return time_code_to_frames( self, value, fps );
        }
        else
        {
                char *end = NULL;
                double result;
+
 #if defined(__GLIBC__) || defined(__DARWIN__)
                if ( locale )
                        result = strtod_l( value, &end, locale );
-        else
+               else
+#else
+               char *orig_localename = NULL;
+               if ( locale ) {
+                       // Protect damaging the global locale from a temporary locale on another thread.
+                       pthread_mutex_lock( &self->mutex );
+                       
+                       // Get the current locale
+                       orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+                       
+                       // Set the new locale
+                       setlocale( LC_NUMERIC, locale );
+               }
 #endif
+
                        result = strtod( value, &end );
                if ( end && end[0] == '%' )
                        result /= 100.0;
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+               if ( locale ) {
+                       // Restore the current locale
+                       setlocale( LC_NUMERIC, orig_localename );
+                       free( orig_localename );
+                       pthread_mutex_unlock( &self->mutex );
+               }
+#endif
+
                return result;
        }
 }
@@ -493,7 +549,7 @@ double mlt_property_get_double( mlt_property self, double fps, locale_t locale )
        else if ( self->types & mlt_prop_rect && self->data )
                return ( (mlt_rect*) self->data )->x;
        else if ( ( self->types & mlt_prop_string ) && self->prop_string )
-               return mlt_property_atof( self->prop_string, fps, locale );
+               return mlt_property_atof( self, fps, locale );
        return 0;
 }
 
@@ -520,7 +576,7 @@ mlt_position mlt_property_get_position( mlt_property self, double fps, locale_t
        else if ( self->types & mlt_prop_rect && self->data )
                return ( mlt_position ) ( (mlt_rect*) self->data )->x;
        else if ( ( self->types & mlt_prop_string ) && self->prop_string )
-               return ( mlt_position )mlt_property_atoi( self->prop_string, fps, locale );
+               return ( mlt_position )mlt_property_atoi( self, fps, locale );
        return 0;
 }
 
@@ -647,8 +703,7 @@ char *mlt_property_get_string_l( mlt_property self, locale_t locale )
 #elif defined(__GLIBC__)
                const char *localename = locale->__names[ LC_NUMERIC ];
 #else
-               // TODO: not yet sure what to do on other platforms
-               const char *localename = NULL;
+               const char *localename = locale;
 #endif
                // Protect damaging the global locale from a temporary locale on another thread.
                pthread_mutex_lock( &self->mutex );
@@ -857,7 +912,7 @@ static void time_clock_from_frames( int frames, double fps, char *s )
 char *mlt_property_get_time( mlt_property self, mlt_time_format format, double fps, locale_t locale )
 {
        char *orig_localename = NULL;
-       const char *localename = NULL;
+       const char *localename = "C";
 
        // Optimization for mlt_time_frames
        if ( format == mlt_time_frames )
@@ -970,12 +1025,36 @@ static int is_property_numeric( mlt_property self, locale_t locale )
        {
                double temp;
                char *p = NULL;
+               
 #if defined(__GLIBC__) || defined(__DARWIN__)
                if ( locale )
                        temp = strtod_l( self->prop_string, &p, locale );
                else
+#else
+               char *orig_localename = NULL;
+               if ( locale ) {
+                       // Protect damaging the global locale from a temporary locale on another thread.
+                       pthread_mutex_lock( &self->mutex );
+                       
+                       // Get the current locale
+                       orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+                       
+                       // Set the new locale
+                       setlocale( LC_NUMERIC, locale );
+               }
 #endif
+
                temp = strtod( self->prop_string, &p );
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+               if ( locale ) {
+                       // Restore the current locale
+                       setlocale( LC_NUMERIC, orig_localename );
+                       free( orig_localename );
+                       pthread_mutex_unlock( &self->mutex );
+               }
+#endif
+
                result = ( p != self->prop_string );
        }
        return result;
@@ -1076,7 +1155,7 @@ int mlt_property_interpolate( mlt_property self, mlt_property p[],
                }
                else
                {
-                       double value;
+                       double value = 0.0;
                        if ( interp == mlt_keyframe_linear )
                        {
                                double points[2];
@@ -1440,10 +1519,24 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale )
                rect.x = ( double )self->prop_int64;
        else if ( ( self->types & mlt_prop_string ) && self->prop_string )
        {
-               //return mlt_property_atof( self->prop_string, fps, locale );
                char *value = self->prop_string;
                char *p = NULL;
                int count = 0;
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+               char *orig_localename = NULL;
+               if ( locale ) {
+                       // Protect damaging the global locale from a temporary locale on another thread.
+                       pthread_mutex_lock( &self->mutex );
+                       
+                       // Get the current locale
+                       orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+                       
+                       // Set the new locale
+                       setlocale( LC_NUMERIC, locale );
+               }
+#endif
+
                while ( *value )
                {
                        double temp;
@@ -1481,7 +1574,16 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale )
                        value = p;
                        count ++;
                }
-       }
+
+#if !defined(__GLIBC__) && !defined(__DARWIN__)
+               if ( locale ) {
+                       // Restore the current locale
+                       setlocale( LC_NUMERIC, orig_localename );
+                       free( orig_localename );
+                       pthread_mutex_unlock( &self->mutex );
+               }
+#endif
+    }
        return rect;
 }
 
index c951762ddb44acf1e784d62fea49c68fea598036..75f6de9993d9e7c95c0604942e7c30e161fb89e7 100644 (file)
@@ -35,7 +35,7 @@
 #if defined(__GLIBC__) || defined(__DARWIN__) || (__FreeBSD_version >= 900506)
 #include <xlocale.h>
 #else
-typedef void* locale_t;
+typedef char* locale_t;
 #endif
 
 extern mlt_property mlt_property_init( );