Changeset 86b94ec7c0873824d346e41a1c7f1a289057f552

Show
Ignore:
Timestamp:
02/12/06 12:39:00 (3 years ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1139744340 +0000
git-parent:

[0f968b65396064faf5bdd6da605ef95413a12824]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1139744340 +0000
Message:

- Attempt to implement (To|From)Locale on MSVC
- Make (To|From)Locale a no-op on OSes always using UTF-8

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/main.h

    r26d5b73 r86b94ec  
    5151    /* The message bank */ 
    5252    msg_bank_t             msg_bank; 
    53  
    54     /* UTF-8 conversion */ 
    55     vlc_mutex_t            from_locale_lock; 
    56     vlc_mutex_t            to_locale_lock; 
    57     vlc_iconv_t            from_locale; 
    58     vlc_iconv_t            to_locale; 
    5953 
    6054    /* The module bank */ 
  • src/libvlc.c

    r4bfb6da r86b94ec  
    4343#include <string.h>                                            /* strerror() */ 
    4444#include <stdlib.h>                                                /* free() */ 
    45 #ifdef HAVE_ASSERT 
    46 # include <assert.h> 
    47 #else 
    48 # define assert( c ) ((void)0) 
    49 #endif 
    5045 
    5146#ifndef WIN32 
     
    10398                             int i_options, char **ppsz_options ); 
    10499 
    105 static void LocaleInit( void ); 
    106 static void LocaleDeinit( void ); 
     100void LocaleInit( vlc_object_t * ); 
     101void LocaleDeinit( void ); 
    107102static void SetLanguage   ( char const * ); 
    108103static int  GetFilenames  ( vlc_t *, int, char *[] ); 
     
    236231 
    237232        libvlc.b_ready = VLC_TRUE; 
    238  
    239         /* UTF-8 convertor are initialized after the locale */ 
    240         libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1); 
    241233    } 
    242234    vlc_mutex_unlock( lockval.p_address ); 
     
    330322     * so that vlc_current_charset() works. 
    331323     */ 
    332     LocaleInit(); 
     324    LocaleInit( (vlc_object_t *)p_vlc ); 
    333325 
    334326    /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */ 
     
    479471        /* Reset the default domain */ 
    480472        SetLanguage( psz_language ); 
    481         LocaleDeinit(); 
    482         LocaleInit(); 
     473 
     474        /* Should not be needed (otherwise, fixes should rather be 
     475         * attempted on vlc_current_charset(). 
     476         * Also, if the locale charset is overriden, anything that has been 
     477         * translated until now would have to be retranslated. */ 
     478        /*LocaleDeinit(); 
     479        LocaleInit( (vlc_object_t *)p_vlc );*/ 
    483480 
    484481        /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */ 
     
    19631960}; 
    19641961 
    1965 static void LocaleInit( void ) 
    1966 { 
    1967     char *psz_charset; 
    1968  
    1969     if( !vlc_current_charset( &psz_charset ) ) 
    1970     { 
    1971         char *psz_conv = psz_charset; 
    1972  
    1973         /* 
    1974          * Still allow non-ASCII characters when the locale is not set. 
    1975          * Western Europeans are being favored for historical reasons. 
    1976          */ 
    1977         psz_conv = strcmp( psz_charset, "ASCII" ) 
    1978             ? psz_charset : "CP1252"; 
    1979  
    1980         vlc_mutex_init( p_libvlc, &libvlc.from_locale_lock ); 
    1981         vlc_mutex_init( p_libvlc, &libvlc.to_locale_lock ); 
    1982         libvlc.from_locale = vlc_iconv_open( "UTF-8", psz_charset ); 
    1983         libvlc.to_locale = vlc_iconv_open( psz_charset, "UTF-8" ); 
    1984         if( !libvlc.to_locale ) 
    1985         { 
    1986             /* Not sure it is the right thing to do, but at least it 
    1987              doesn't make vlc crash with msvc ! */ 
    1988             libvlc.to_locale = (vlc_iconv_t)(-1); 
    1989         } 
    1990     } 
    1991     else 
    1992         libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1); 
    1993     free( psz_charset ); 
    1994 } 
    1995  
    1996 static void LocaleDeinit( void ) 
    1997 { 
    1998     if( libvlc.to_locale != (vlc_iconv_t)(-1) ) 
    1999     { 
    2000         vlc_mutex_destroy( &libvlc.from_locale_lock ); 
    2001         vlc_mutex_destroy( &libvlc.to_locale_lock ); 
    2002         vlc_iconv_close( libvlc.from_locale ); 
    2003         vlc_iconv_close( libvlc.to_locale ); 
    2004     } 
    2005 } 
    20061962 
    20071963/***************************************************************************** 
     
    20512007         * to the US standard (ie. with dot as decimal point), so we keep 
    20522008         * C for LC_NUMERIC. */ 
    2053         setlocale(LC_NUMERIC, "C" ); 
     2009        setlocale( LC_NUMERIC, "C" ); 
    20542010    } 
    20552011 
     
    26962652#endif 
    26972653} 
    2698  
    2699 /***************************************************************************** 
    2700  * FromLocale: converts a locale string to UTF-8 
    2701  *****************************************************************************/ 
    2702 char *FromLocale( const char *locale ) 
    2703 { 
    2704     if( locale == NULL ) 
    2705         return NULL; 
    2706  
    2707     if( libvlc.from_locale != (vlc_iconv_t)(-1) ) 
    2708     { 
    2709         char *iptr = (char *)locale, *output, *optr; 
    2710         size_t inb, outb; 
    2711  
    2712         /* 
    2713          * We are not allowed to modify the locale pointer, even if we cast it 
    2714          * to non-const. 
    2715          */ 
    2716         inb = strlen( locale ); 
    2717         /* FIXME: I'm not sure about the value for the multiplication 
    2718          * (for western people, multiplication by 3 (Latin9) is sufficient) */ 
    2719         outb = inb * 6 + 1; 
    2720  
    2721         optr = output = calloc( outb , 1); 
    2722  
    2723         vlc_mutex_lock( &libvlc.from_locale_lock ); 
    2724         vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL ); 
    2725  
    2726         while( vlc_iconv( libvlc.from_locale, &iptr, &inb, &optr, &outb ) 
    2727                                                                == (size_t)-1 ) 
    2728         { 
    2729             *optr++ = '?'; 
    2730             outb--; 
    2731             iptr++; 
    2732             inb--; 
    2733             vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL ); 
    2734         } 
    2735     vlc_mutex_unlock( &libvlc.from_locale_lock ); 
    2736  
    2737         assert (inb == 0); 
    2738         assert (*iptr == '\0'); 
    2739         assert (*optr == '\0'); 
    2740         assert (strlen( output ) == (size_t)(optr - output)); 
    2741         return realloc( output, optr - output + 1 ); 
    2742     } 
    2743     return (char *)locale; 
    2744 } 
    2745  
    2746 /***************************************************************************** 
    2747  * ToLocale: converts an UTF-8 string to locale 
    2748  *****************************************************************************/ 
    2749 char *ToLocale( const char *utf8 ) 
    2750 { 
    2751     if( utf8 == NULL ) 
    2752         return NULL; 
    2753  
    2754     if( libvlc.to_locale != (vlc_iconv_t)(-1) ) 
    2755     { 
    2756         char *iptr = (char *)utf8, *output, *optr; 
    2757         size_t inb, outb; 
    2758  
    2759         /* 
    2760          * We are not allowed to modify the locale pointer, even if we cast it 
    2761          * to non-const. 
    2762          */ 
    2763         inb = strlen( utf8 ); 
    2764         /* FIXME: I'm not sure about the value for the multiplication 
    2765          * (for western people, multiplication is not needed) */ 
    2766         outb = inb * 2 + 1; 
    2767  
    2768         optr = output = calloc( outb, 1 ); 
    2769         vlc_mutex_lock( &libvlc.to_locale_lock ); 
    2770         vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL ); 
    2771  
    2772         while( vlc_iconv( libvlc.to_locale, &iptr, &inb, &optr, &outb ) 
    2773                                                                == (size_t)-1 ) 
    2774         { 
    2775             *optr++ = '?'; /* should not happen, and yes, it sucks */ 
    2776             outb--; 
    2777             iptr++; 
    2778             inb--; 
    2779             vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL ); 
    2780         } 
    2781         vlc_mutex_unlock( &libvlc.to_locale_lock ); 
    2782  
    2783         assert (inb == 0); 
    2784         assert (*iptr == '\0'); 
    2785         assert (*optr == '\0'); 
    2786         assert (strlen( output ) == (size_t)(optr - output)); 
    2787     return realloc( output, optr - output + 1 ); 
    2788     } 
    2789     return (char *)utf8; 
    2790 } 
    2791  
    2792 void LocaleFree( const char *str ) 
    2793 { 
    2794     if( ( str != NULL ) && ( libvlc.to_locale != (vlc_iconv_t)(-1) ) ) 
    2795         free( (char *)str ); 
    2796 } 
  • src/misc/unicode.c

    r9efc237 r86b94ec  
    2828#include "charset.h" 
    2929 
     30#ifdef HAVE_ASSERT 
     31# include <assert.h> 
     32#else 
     33# define assert( c ) ((void)0) 
     34#endif 
     35 
    3036#include <stdio.h> 
    3137#include <sys/types.h> 
    3238#include <dirent.h> 
     39 
     40#ifdef __APPLE__ 
     41/* Define this if the OS always use UTF-8 internally */ 
     42# define ASSUME_UTF8 1 
     43#endif 
     44 
     45#if !(defined (WIN32) && defined (ASSUME_UTF8)) 
     46# define USE_ICONV 1 
     47#endif 
     48 
     49#if defined (USE_ICONV) && !defined (HAVE_ICONV) 
     50# error No UTF8 charset conversion implemented on this platform! 
     51#endif 
     52 
     53 
     54 
     55#ifdef USE_ICONV 
     56static struct { 
     57    vlc_iconv_t hd; 
     58    vlc_mutex_t lock; 
     59} from_locale, to_locale; 
     60#endif 
     61 
     62void LocaleInit( vlc_object_t *p_this ) 
     63{ 
     64#ifdef USE_ICONV 
     65    char *psz_charset; 
     66 
     67    if( vlc_current_charset( &psz_charset ) ) 
     68        /* UTF-8 */ 
     69        from_locale.hd = to_locale.hd = (vlc_iconv_t)(-1); 
     70    else 
     71    { 
     72        /* not UTF-8 */ 
     73        char *psz_conv = psz_charset; 
     74 
     75        /* 
     76         * Still allow non-ASCII characters when the locale is not set. 
     77         * Western Europeans are being favored for historical reasons. 
     78         */ 
     79        psz_conv = strcmp( psz_charset, "ASCII" ) 
     80                ? psz_charset : "ISO-8859-1"; 
     81 
     82        vlc_mutex_init( p_this, &from_locale.lock ); 
     83        vlc_mutex_init( p_this, &to_locale.lock ); 
     84        from_locale.hd = vlc_iconv_open( "UTF-8", psz_charset ); 
     85        to_locale.hd = vlc_iconv_open( psz_charset, "UTF-8" ); 
     86    } 
     87 
     88    free( psz_charset ); 
     89 
     90    assert( (from_locale.hd == (vlc_iconv_t)(-1)) 
     91            == (to_locale.hd == (vlc_iconv_t)(-1)) ); 
     92#else 
     93    (void)p_this; 
     94#endif 
     95} 
     96 
     97void LocaleDeinit( void ) 
     98{ 
     99#ifdef USE_ICONV 
     100    if( to_locale.hd != (vlc_iconv_t)(-1) ) 
     101    { 
     102        vlc_iconv_close( to_locale.hd ); 
     103        vlc_mutex_destroy( &to_locale.lock ); 
     104    } 
     105 
     106    if( from_locale.hd != (vlc_iconv_t)(-1) ) 
     107    { 
     108        vlc_iconv_close( from_locale.hd ); 
     109        vlc_mutex_destroy( &from_locale.lock ); 
     110    } 
     111#endif 
     112} 
     113 
     114#ifdef WIN32 
     115static char *MB2MB( const char *string, UINT fromCP, UINT toCP ) 
     116{ 
     117    char *out; 
     118    int ilen = strlen( string ), olen = (4 / sizeof (wchar_t)) * ilen + 1; 
     119    wchar_t wide[olen]; 
     120 
     121    ilen = MultiByteToWideChar( fromCP, 0, string, ilen + 1, wide, olen ); 
     122    if( ilen == 0 ) 
     123        return NULL; 
     124 
     125    olen = 4 * ilen + 1; 
     126    out = malloc( olen ); 
     127 
     128    olen = WideCharToMultiByte( toCP, 0, wide, ilen, out, olen, NULL, NULL ); 
     129    if( olen == 0 ) 
     130    { 
     131        free( out ); 
     132        return NULL; 
     133    } 
     134    return realloc( out, olen ); 
     135} 
     136#endif 
     137 
     138/***************************************************************************** 
     139 * FromLocale: converts a locale string to UTF-8 
     140 *****************************************************************************/ 
     141char *FromLocale( const char *locale ) 
     142{ 
     143    if( locale == NULL ) 
     144        return NULL; 
     145 
     146#ifndef WIN32 
     147# ifdef USE_ICONV 
     148    if( from_locale.hd != (vlc_iconv_t)(-1) ) 
     149    { 
     150        char *iptr = (char *)locale, *output, *optr; 
     151        size_t inb, outb; 
     152 
     153        /* 
     154         * We are not allowed to modify the locale pointer, even if we cast it 
     155         * to non-const. 
     156         */ 
     157        inb = strlen( locale ); 
     158        /* FIXME: I'm not sure about the value for the multiplication 
     159         * (for western people, multiplication by 3 (Latin9) is needed). 
     160         * While UTF-8 could reach 6 bytes, no existing code point exceeds 
     161         * 4 bytes. */ 
     162        outb = inb * 4 + 1; 
     163 
     164        optr = output = malloc( outb ); 
     165 
     166        vlc_mutex_lock( &from_locale.lock ); 
     167        vlc_iconv( from_locale.hd, NULL, NULL, NULL, NULL ); 
     168 
     169        while( vlc_iconv( from_locale.hd, &iptr, &inb, &optr, &outb ) 
     170               == (size_t)-1 ) 
     171        { 
     172            *optr++ = '?'; 
     173            outb--; 
     174            iptr++; 
     175            inb--; 
     176            vlc_iconv( from_locale.hd, NULL, NULL, NULL, NULL ); 
     177        } 
     178        vlc_mutex_unlock( &from_locale.lock ); 
     179 
     180        assert (inb == 0); 
     181        assert (*iptr == '\0'); 
     182        assert (*optr == '\0'); 
     183        assert (strlen( output ) == (size_t)(optr - output)); 
     184        return realloc( output, optr - output + 1 ); 
     185    } 
     186# endif /* USE_ICONV */ 
     187    return (char *)locale; 
     188#else /* WIN32 */ 
     189    return MB2MB( locale, CP_ACP, CP_UTF8 ); 
     190#endif 
     191} 
     192 
     193/***************************************************************************** 
     194 * ToLocale: converts an UTF-8 string to locale 
     195 *****************************************************************************/ 
     196char *ToLocale( const char *utf8 ) 
     197{ 
     198    if( utf8 == NULL ) 
     199        return NULL; 
     200 
     201#ifndef WIN32 
     202# ifdef USE_ICONV 
     203    if( to_locale.hd != (vlc_iconv_t)(-1) ) 
     204    { 
     205        char *iptr = (char *)utf8, *output, *optr; 
     206        size_t inb, outb; 
     207 
     208        /* 
     209        * We are not allowed to modify the locale pointer, even if we cast it 
     210        * to non-const. 
     211        */ 
     212        inb = strlen( utf8 ); 
     213        /* FIXME: I'm not sure about the value for the multiplication 
     214        * (for western people, multiplication is not needed) */ 
     215        outb = inb * 2 + 1; 
     216 
     217        optr = output = malloc( outb ); 
     218        vlc_mutex_lock( &to_locale.lock ); 
     219        vlc_iconv( to_locale.hd, NULL, NULL, NULL, NULL ); 
     220 
     221        while( vlc_iconv( to_locale.hd, &iptr, &inb, &optr, &outb ) 
     222               == (size_t)-1 ) 
     223        { 
     224            *optr++ = '?'; /* should not happen, and yes, it sucks */ 
     225            outb--; 
     226            iptr++; 
     227            inb--; 
     228            vlc_iconv( to_locale.hd, NULL, NULL, NULL, NULL ); 
     229        } 
     230        vlc_mutex_unlock( &to_locale.lock ); 
     231 
     232        assert (inb == 0); 
     233        assert (*iptr == '\0'); 
     234        assert (*optr == '\0'); 
     235        assert (strlen( output ) == (size_t)(optr - output)); 
     236        return realloc( output, optr - output + 1 ); 
     237    } 
     238# endif /* USE_ICONV */ 
     239    return (char *)utf8; 
     240#else /* WIN32 */ 
     241    return MB2MB( utf8, CP_UTF8, CP_ACP ); 
     242#endif 
     243} 
     244 
     245void LocaleFree( const char *str ) 
     246{ 
     247#ifdef USE_ICONV 
     248    if( to_locale.hd == (vlc_iconv_t)(-1) ) 
     249        return; 
     250#endif 
     251 
     252#ifndef ASSUME_UTF8 
     253    if( str != NULL ) 
     254        free( (char *)str ); 
     255#endif 
     256} 
    33257 
    34258/*****************************************************************************