]> git.sesse.net Git - vlc/commitdiff
- Attempt to implement (To|From)Locale on MSVC
authorRémi Denis-Courmont <rem@videolan.org>
Sun, 12 Feb 2006 11:39:00 +0000 (11:39 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Sun, 12 Feb 2006 11:39:00 +0000 (11:39 +0000)
- Make (To|From)Locale a no-op on OSes always using UTF-8

include/main.h
src/libvlc.c
src/misc/unicode.c

index 8b05e2b46a48807586726b1aec2ca23f4085d8fd..8505478d054c3120ec83cb6e69499daa672e57fe 100644 (file)
@@ -51,12 +51,6 @@ struct libvlc_t
     /* The message bank */
     msg_bank_t             msg_bank;
 
-    /* UTF-8 conversion */
-    vlc_mutex_t            from_locale_lock;
-    vlc_mutex_t            to_locale_lock;
-    vlc_iconv_t            from_locale;
-    vlc_iconv_t            to_locale;
-
     /* The module bank */
     module_bank_t *        p_module_bank;
 
index ad475f6e456c0b7fc4ebdfce6670f3b452fb2609..ca7b62acc5c3f972b3c03e0db897a7bc27686b0c 100644 (file)
 #include <stdio.h>                                              /* sprintf() */
 #include <string.h>                                            /* strerror() */
 #include <stdlib.h>                                                /* free() */
-#ifdef HAVE_ASSERT
-# include <assert.h>
-#else
-# define assert( c ) ((void)0)
-#endif
 
 #ifndef WIN32
 #   include <netinet/in.h>                            /* BSD: struct in_addr */
@@ -102,8 +97,8 @@ static int AddIntfInternal( int i_object, char const *psz_module,
                              vlc_bool_t b_block, vlc_bool_t b_play,
                              int i_options, char **ppsz_options );
 
-static void LocaleInit( void );
-static void LocaleDeinit( void );
+void LocaleInit( vlc_object_t * );
+void LocaleDeinit( void );
 static void SetLanguage   ( char const * );
 static int  GetFilenames  ( vlc_t *, int, char *[] );
 static void Help          ( vlc_t *, char const *psz_help_name );
@@ -235,9 +230,6 @@ int VLC_Create( void )
         libvlc.p_module_bank = NULL;
 
         libvlc.b_ready = VLC_TRUE;
-
-        /* UTF-8 convertor are initialized after the locale */
-        libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
     }
     vlc_mutex_unlock( lockval.p_address );
     var_Destroy( p_libvlc, "libvlc" );
@@ -329,7 +321,7 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
      * Global iconv, must be done after setlocale()
      * so that vlc_current_charset() works.
      */
-    LocaleInit();
+    LocaleInit( (vlc_object_t *)p_vlc );
 
     /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
     msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
@@ -478,8 +470,13 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
 
         /* Reset the default domain */
         SetLanguage( psz_language );
-        LocaleDeinit();
-        LocaleInit();
+
+        /* Should not be needed (otherwise, fixes should rather be
+         * attempted on vlc_current_charset().
+         * Also, if the locale charset is overriden, anything that has been
+         * translated until now would have to be retranslated. */
+        /*LocaleDeinit();
+        LocaleInit( (vlc_object_t *)p_vlc );*/
 
         /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
         msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
@@ -1962,47 +1959,6 @@ static int  AddIntfInternal( int i_object, char const *psz_module,
     return VLC_SUCCESS;
 };
 
-static void LocaleInit( void )
-{
-    char *psz_charset;
-
-    if( !vlc_current_charset( &psz_charset ) )
-    {
-        char *psz_conv = psz_charset;
-
-        /*
-         * Still allow non-ASCII characters when the locale is not set.
-         * Western Europeans are being favored for historical reasons.
-         */
-        psz_conv = strcmp( psz_charset, "ASCII" )
-            ? psz_charset : "CP1252";
-
-        vlc_mutex_init( p_libvlc, &libvlc.from_locale_lock );
-        vlc_mutex_init( p_libvlc, &libvlc.to_locale_lock );
-        libvlc.from_locale = vlc_iconv_open( "UTF-8", psz_charset );
-        libvlc.to_locale = vlc_iconv_open( psz_charset, "UTF-8" );
-        if( !libvlc.to_locale )
-        {
-            /* Not sure it is the right thing to do, but at least it
-             doesn't make vlc crash with msvc ! */
-            libvlc.to_locale = (vlc_iconv_t)(-1);
-        }
-    }
-    else
-        libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
-    free( psz_charset );
-}
-
-static void LocaleDeinit( void )
-{
-    if( libvlc.to_locale != (vlc_iconv_t)(-1) )
-    {
-        vlc_mutex_destroy( &libvlc.from_locale_lock );
-        vlc_mutex_destroy( &libvlc.to_locale_lock );
-        vlc_iconv_close( libvlc.from_locale );
-        vlc_iconv_close( libvlc.to_locale );
-    }
-}
 
 /*****************************************************************************
  * SetLanguage: set the interface language.
@@ -2050,7 +2006,7 @@ static void SetLanguage ( char const *psz_lang )
         /* many code paths assume that float numbers are formatted according
          * to the US standard (ie. with dot as decimal point), so we keep
          * C for LC_NUMERIC. */
-        setlocale(LC_NUMERIC, "C" );
+        setlocale( LC_NUMERIC, "C" );
     }
 
     /* Specify where to find the locales for current domain */
@@ -2695,102 +2651,3 @@ static void InitDeviceValues( vlc_t *p_vlc )
     }
 #endif
 }
-
-/*****************************************************************************
- * FromLocale: converts a locale string to UTF-8
- *****************************************************************************/
-char *FromLocale( const char *locale )
-{
-    if( locale == NULL )
-        return NULL;
-
-    if( libvlc.from_locale != (vlc_iconv_t)(-1) )
-    {
-        char *iptr = (char *)locale, *output, *optr;
-        size_t inb, outb;
-
-        /*
-         * We are not allowed to modify the locale pointer, even if we cast it
-         * to non-const.
-         */
-        inb = strlen( locale );
-        /* FIXME: I'm not sure about the value for the multiplication
-         * (for western people, multiplication by 3 (Latin9) is sufficient) */
-        outb = inb * 6 + 1;
-
-        optr = output = calloc( outb , 1);
-
-        vlc_mutex_lock( &libvlc.from_locale_lock );
-        vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
-
-        while( vlc_iconv( libvlc.from_locale, &iptr, &inb, &optr, &outb )
-                                                               == (size_t)-1 )
-        {
-            *optr++ = '?';
-            outb--;
-            iptr++;
-            inb--;
-            vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
-        }
-       vlc_mutex_unlock( &libvlc.from_locale_lock );
-
-        assert (inb == 0);
-        assert (*iptr == '\0');
-        assert (*optr == '\0');
-        assert (strlen( output ) == (size_t)(optr - output));
-        return realloc( output, optr - output + 1 );
-    }
-    return (char *)locale;
-}
-
-/*****************************************************************************
- * ToLocale: converts an UTF-8 string to locale
- *****************************************************************************/
-char *ToLocale( const char *utf8 )
-{
-    if( utf8 == NULL )
-        return NULL;
-
-    if( libvlc.to_locale != (vlc_iconv_t)(-1) )
-    {
-        char *iptr = (char *)utf8, *output, *optr;
-        size_t inb, outb;
-
-        /*
-         * We are not allowed to modify the locale pointer, even if we cast it
-         * to non-const.
-         */
-        inb = strlen( utf8 );
-        /* FIXME: I'm not sure about the value for the multiplication
-         * (for western people, multiplication is not needed) */
-        outb = inb * 2 + 1;
-
-        optr = output = calloc( outb, 1 );
-        vlc_mutex_lock( &libvlc.to_locale_lock );
-        vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
-
-        while( vlc_iconv( libvlc.to_locale, &iptr, &inb, &optr, &outb )
-                                                               == (size_t)-1 )
-        {
-            *optr++ = '?'; /* should not happen, and yes, it sucks */
-            outb--;
-            iptr++;
-            inb--;
-            vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
-        }
-        vlc_mutex_unlock( &libvlc.to_locale_lock );
-
-        assert (inb == 0);
-        assert (*iptr == '\0');
-        assert (*optr == '\0');
-        assert (strlen( output ) == (size_t)(optr - output));
-       return realloc( output, optr - output + 1 );
-    }
-    return (char *)utf8;
-}
-
-void LocaleFree( const char *str )
-{
-    if( ( str != NULL ) && ( libvlc.to_locale != (vlc_iconv_t)(-1) ) )
-        free( (char *)str );
-}
index 100f379e5adf35c4f7323365af9d6e82fadd5bb5..b3333f2c1fd279828a960b7ca10a19aed5f8d3be 100644 (file)
 #include <vlc/vlc.h>
 #include "charset.h"
 
+#ifdef HAVE_ASSERT
+# include <assert.h>
+#else
+# define assert( c ) ((void)0)
+#endif
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 
+#ifdef __APPLE__
+/* Define this if the OS always use UTF-8 internally */
+# define ASSUME_UTF8 1
+#endif
+
+#if !(defined (WIN32) && defined (ASSUME_UTF8))
+# define USE_ICONV 1
+#endif
+
+#if defined (USE_ICONV) && !defined (HAVE_ICONV)
+# error No UTF8 charset conversion implemented on this platform!
+#endif
+
+
+
+#ifdef USE_ICONV
+static struct {
+    vlc_iconv_t hd;
+    vlc_mutex_t lock;
+} from_locale, to_locale;
+#endif
+
+void LocaleInit( vlc_object_t *p_this )
+{
+#ifdef USE_ICONV
+    char *psz_charset;
+
+    if( vlc_current_charset( &psz_charset ) )
+        /* UTF-8 */
+        from_locale.hd = to_locale.hd = (vlc_iconv_t)(-1);
+    else
+    {
+        /* not UTF-8 */
+        char *psz_conv = psz_charset;
+
+        /*
+         * Still allow non-ASCII characters when the locale is not set.
+         * Western Europeans are being favored for historical reasons.
+         */
+        psz_conv = strcmp( psz_charset, "ASCII" )
+                ? psz_charset : "ISO-8859-1";
+
+        vlc_mutex_init( p_this, &from_locale.lock );
+        vlc_mutex_init( p_this, &to_locale.lock );
+        from_locale.hd = vlc_iconv_open( "UTF-8", psz_charset );
+        to_locale.hd = vlc_iconv_open( psz_charset, "UTF-8" );
+    }
+
+    free( psz_charset );
+
+    assert( (from_locale.hd == (vlc_iconv_t)(-1))
+            == (to_locale.hd == (vlc_iconv_t)(-1)) );
+#else
+    (void)p_this;
+#endif
+}
+
+void LocaleDeinit( void )
+{
+#ifdef USE_ICONV
+    if( to_locale.hd != (vlc_iconv_t)(-1) )
+    {
+        vlc_iconv_close( to_locale.hd );
+        vlc_mutex_destroy( &to_locale.lock );
+    }
+
+    if( from_locale.hd != (vlc_iconv_t)(-1) )
+    {
+        vlc_iconv_close( from_locale.hd );
+        vlc_mutex_destroy( &from_locale.lock );
+    }
+#endif
+}
+
+#ifdef WIN32
+static char *MB2MB( const char *string, UINT fromCP, UINT toCP )
+{
+    char *out;
+    int ilen = strlen( string ), olen = (4 / sizeof (wchar_t)) * ilen + 1;
+    wchar_t wide[olen];
+
+    ilen = MultiByteToWideChar( fromCP, 0, string, ilen + 1, wide, olen );
+    if( ilen == 0 )
+        return NULL;
+
+    olen = 4 * ilen + 1;
+    out = malloc( olen );
+
+    olen = WideCharToMultiByte( toCP, 0, wide, ilen, out, olen, NULL, NULL );
+    if( olen == 0 )
+    {
+        free( out );
+        return NULL;
+    }
+    return realloc( out, olen );
+}
+#endif
+
+/*****************************************************************************
+ * FromLocale: converts a locale string to UTF-8
+ *****************************************************************************/
+char *FromLocale( const char *locale )
+{
+    if( locale == NULL )
+        return NULL;
+
+#ifndef WIN32
+# ifdef USE_ICONV
+    if( from_locale.hd != (vlc_iconv_t)(-1) )
+    {
+        char *iptr = (char *)locale, *output, *optr;
+        size_t inb, outb;
+
+        /*
+         * We are not allowed to modify the locale pointer, even if we cast it
+         * to non-const.
+         */
+        inb = strlen( locale );
+        /* FIXME: I'm not sure about the value for the multiplication
+         * (for western people, multiplication by 3 (Latin9) is needed).
+         * While UTF-8 could reach 6 bytes, no existing code point exceeds
+         * 4 bytes. */
+        outb = inb * 4 + 1;
+
+        optr = output = malloc( outb );
+
+        vlc_mutex_lock( &from_locale.lock );
+        vlc_iconv( from_locale.hd, NULL, NULL, NULL, NULL );
+
+        while( vlc_iconv( from_locale.hd, &iptr, &inb, &optr, &outb )
+               == (size_t)-1 )
+        {
+            *optr++ = '?';
+            outb--;
+            iptr++;
+            inb--;
+            vlc_iconv( from_locale.hd, NULL, NULL, NULL, NULL );
+        }
+        vlc_mutex_unlock( &from_locale.lock );
+
+        assert (inb == 0);
+        assert (*iptr == '\0');
+        assert (*optr == '\0');
+        assert (strlen( output ) == (size_t)(optr - output));
+        return realloc( output, optr - output + 1 );
+    }
+# endif /* USE_ICONV */
+    return (char *)locale;
+#else /* WIN32 */
+    return MB2MB( locale, CP_ACP, CP_UTF8 );
+#endif
+}
+
+/*****************************************************************************
+ * ToLocale: converts an UTF-8 string to locale
+ *****************************************************************************/
+char *ToLocale( const char *utf8 )
+{
+    if( utf8 == NULL )
+        return NULL;
+
+#ifndef WIN32
+# ifdef USE_ICONV
+    if( to_locale.hd != (vlc_iconv_t)(-1) )
+    {
+        char *iptr = (char *)utf8, *output, *optr;
+        size_t inb, outb;
+
+        /*
+        * We are not allowed to modify the locale pointer, even if we cast it
+        * to non-const.
+        */
+        inb = strlen( utf8 );
+        /* FIXME: I'm not sure about the value for the multiplication
+        * (for western people, multiplication is not needed) */
+        outb = inb * 2 + 1;
+
+        optr = output = malloc( outb );
+        vlc_mutex_lock( &to_locale.lock );
+        vlc_iconv( to_locale.hd, NULL, NULL, NULL, NULL );
+
+        while( vlc_iconv( to_locale.hd, &iptr, &inb, &optr, &outb )
+               == (size_t)-1 )
+        {
+            *optr++ = '?'; /* should not happen, and yes, it sucks */
+            outb--;
+            iptr++;
+            inb--;
+            vlc_iconv( to_locale.hd, NULL, NULL, NULL, NULL );
+        }
+        vlc_mutex_unlock( &to_locale.lock );
+
+        assert (inb == 0);
+        assert (*iptr == '\0');
+        assert (*optr == '\0');
+        assert (strlen( output ) == (size_t)(optr - output));
+        return realloc( output, optr - output + 1 );
+    }
+# endif /* USE_ICONV */
+    return (char *)utf8;
+#else /* WIN32 */
+    return MB2MB( utf8, CP_UTF8, CP_ACP );
+#endif
+}
+
+void LocaleFree( const char *str )
+{
+#ifdef USE_ICONV
+    if( to_locale.hd == (vlc_iconv_t)(-1) )
+        return;
+#endif
+
+#ifndef ASSUME_UTF8
+    if( str != NULL )
+        free( (char *)str );
+#endif
+}
+
 /*****************************************************************************
  * utf8_fopen: Calls fopen() after conversion of file name to OS locale
  *****************************************************************************/