Add us_asprintf function
[vlc.git] / src / text / charset.c
1 /*****************************************************************************
2  * charset.c: Locale's character encoding stuff.
3  *****************************************************************************
4  * See also unicode.c for Unicode to locale conversion helpers.
5  *
6  * Copyright (C) 2003-2008 the VideoLAN team
7  *
8  * Authors: Christophe Massiot
9  *          RĂ©mi Denis-Courmont
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <vlc_common.h>
31
32 #if !defined WIN32
33 # include <locale.h>
34 #else
35 # include <windows.h>
36 #endif
37
38 #ifdef __APPLE__
39 #   include <errno.h>
40 #   include <string.h>
41 #   include <xlocale.h>
42 #endif
43
44 #include "libvlc.h"
45 #include <vlc_charset.h>
46
47 char *vlc_fix_readdir( const char *psz_string )
48 {
49 #ifdef __APPLE__
50     vlc_iconv_t hd = vlc_iconv_open( "UTF-8", "UTF-8-MAC" );
51
52     if (hd != (vlc_iconv_t)(-1))
53     {
54         const char *psz_in = psz_string;
55         size_t i_in = strlen(psz_in);
56         size_t i_out = i_in * 2;
57         char *psz_utf8 = malloc(i_out + 1);
58         char *psz_out = psz_utf8;
59
60         size_t i_ret = vlc_iconv (hd, &psz_in, &i_in, &psz_out, &i_out);
61         vlc_iconv_close (hd);
62         if( i_ret == (size_t)(-1) || i_in )
63         {
64             free( psz_utf8 );
65             return strdup( psz_string );
66         }
67
68         *psz_out = '\0';
69         return psz_utf8;
70     }
71 #endif
72     return strdup( psz_string );
73 }
74
75
76 /**
77  * us_strtod() has the same prototype as ANSI C strtod() but it uses the
78  * POSIX/C decimal format, regardless of the current numeric locale.
79  */
80 double us_strtod( const char *str, char **end )
81 {
82     locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
83     locale_t oldloc = uselocale (loc);
84     double res = strtod (str, end);
85
86     if (loc != (locale_t)0)
87     {
88         uselocale (oldloc);
89         freelocale (loc);
90     }
91     return res;
92 }
93
94 /**
95  * us_atof() has the same prototype as ANSI C atof() but it expects a dot
96  * as decimal separator, regardless of the system locale.
97  */
98 double us_atof( const char *str )
99 {
100     return us_strtod( str, NULL );
101 }
102
103
104 /**
105  * us_asprintf() has the same prototype as asprintf(), but doesn't use
106  * the system locale.
107  */
108 int us_asprintf( char **ret, const char *format, ... )
109 {
110     va_list ap;
111     locale_t loc = newlocale( LC_NUMERIC_MASK, "C", NULL );
112     locale_t oldloc = uselocale( loc );
113     int i_rc;
114
115     va_start( ap, format );
116     i_rc = vasprintf( ret, format, ap );
117     va_end( ap );
118
119     if ( loc != (locale_t)0 )
120     {
121         uselocale( oldloc );
122         freelocale( loc );
123     }
124
125     return i_rc;
126 }