1 /*****************************************************************************
2 * libc.c: Extra libc function for some systems.
3 *****************************************************************************
4 * Copyright (C) 2002 VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Samuel Hocevar <sam@zoy.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
24 #include <string.h> /* strdup() */
34 #if defined(HAVE_ICONV)
38 /*****************************************************************************
39 * getenv: just in case, but it should never be called
40 *****************************************************************************/
41 #if !defined( HAVE_GETENV )
42 char *vlc_getenv( const char *name )
48 /*****************************************************************************
49 * strdup: returns a malloc'd copy of a string
50 *****************************************************************************/
51 #if !defined( HAVE_STRDUP )
52 char *vlc_strdup( const char *string )
54 return strndup( string, strlen( string ) );
58 /*****************************************************************************
59 * strndup: returns a malloc'd copy of at most n bytes of string
60 * Does anyone know whether or not it will be present in Jaguar?
61 *****************************************************************************/
62 #if !defined( HAVE_STRNDUP )
63 char *vlc_strndup( const char *string, size_t n )
66 size_t len = strlen( string );
68 len = __MIN( len, n );
69 psz = (char*)malloc( len + 1 );
73 memcpy( (void*)psz, (const void*)string, len );
81 /*****************************************************************************
82 * strcasecmp: compare two strings ignoring case
83 *****************************************************************************/
84 #if !defined( HAVE_STRCASECMP ) && !defined( HAVE_STRICMP )
85 int vlc_strcasecmp( const char *s1, const char *s2 )
89 while( !i_delta && *s1 && *s2 )
93 if( *s1 >= 'A' && *s1 <= 'Z' )
98 if( *s2 >= 'A' && *s2 <= 'Z' )
100 i_delta += 'A' - 'a';
110 /*****************************************************************************
111 * strncasecmp: compare n chars from two strings ignoring case
112 *****************************************************************************/
113 #if !defined( HAVE_STRNCASECMP ) && !defined( HAVE_STRNICMP )
114 int vlc_strncasecmp( const char *s1, const char *s2, size_t n )
118 while( n-- && !i_delta && *s1 )
122 if( *s1 >= 'A' && *s1 <= 'Z' )
124 i_delta -= 'A' - 'a';
127 if( *s2 >= 'A' && *s2 <= 'Z' )
129 i_delta += 'A' - 'a';
139 /******************************************************************************
140 * strcasestr: find a substring (little) in another substring (big)
141 * Case sensitive. Return NULL if not found, return big if little == null
142 *****************************************************************************/
143 #if !defined( HAVE_STRCASESTR ) && !defined( HAVE_STRISTR )
144 char * vlc_strcasestr( const char *psz_big, const char *psz_little )
146 char *p_pos = psz_big;
148 if( !psz_big || !psz_little || !*psz_little ) return psz_big;
152 if( toupper( *p_pos ) == toupper( *psz_little ) )
154 char * psz_cur1 = p_pos + 1;
155 char * psz_cur2 = psz_little + 1;
156 while( *psz_cur1 && *psz_cur2 &&
157 toupper( *psz_cur1 ) == toupper( *psz_cur2 ) )
162 if( !*psz_cur2 ) return p_pos;
170 /*****************************************************************************
172 *****************************************************************************/
173 #if !defined(HAVE_VASPRINTF) || defined(SYS_DARWIN) || defined(SYS_BEOS)
174 int vlc_vasprintf(char **strp, const char *fmt, va_list ap)
176 /* Guess we need no more than 100 bytes. */
178 char *p = malloc( i_size );
189 /* Try to print in the allocated space. */
190 n = vsnprintf( p, i_size, fmt, ap );
192 /* If that worked, return the string. */
193 if (n > -1 && n < i_size)
198 /* Else try again with more space. */
199 if (n > -1) /* glibc 2.1 */
201 i_size = n+1; /* precisely what is needed */
205 i_size *= 2; /* twice the old size */
207 if( (p = realloc( p, i_size ) ) == NULL)
216 /*****************************************************************************
218 *****************************************************************************/
219 #if !defined(HAVE_ASPRINTF) || defined(SYS_DARWIN) || defined(SYS_BEOS)
220 int vlc_asprintf( char **strp, const char *fmt, ... )
225 va_start( args, fmt );
226 i_ret = vasprintf( strp, fmt, args );
233 /*****************************************************************************
234 * atof: convert a string to a double.
235 *****************************************************************************/
236 #if !defined( HAVE_ATOF )
237 double vlc_atof( const char *nptr )
241 int i_len = strlen( nptr ) + 1;
243 psz_tmp = malloc( i_len * sizeof(wchar_t) );
244 MultiByteToWideChar( CP_ACP, 0, nptr, -1, psz_tmp, i_len );
245 f_result = wcstod( psz_tmp, NULL );
252 /*****************************************************************************
253 * atoll: convert a string to a 64 bits int.
254 *****************************************************************************/
255 #if !defined( HAVE_ATOLL )
256 int64_t vlc_atoll( const char *str )
266 while( *str >= '0' && *str <= '9' )
268 i_value = i_value * 10 + ( *str++ - '0' );
271 return i_value * sign;
275 /*****************************************************************************
276 * lseek: reposition read/write file offset.
277 *****************************************************************************
278 * FIXME: this cast sucks!
279 *****************************************************************************/
280 #if !defined( HAVE_LSEEK )
281 off_t vlc_lseek( int fildes, off_t offset, int whence )
283 return SetFilePointer( (HANDLE)fildes, (long)offset, NULL, whence );
287 /*****************************************************************************
288 * dgettext: gettext for plugins.
289 *****************************************************************************/
290 char *vlc_dgettext( const char *package, const char *msgid )
292 #if defined( ENABLE_NLS ) \
293 && ( defined(HAVE_GETTEXT) || defined(HAVE_INCLUDED_GETTEXT) )
294 return dgettext( package, msgid );
296 return (char *)msgid;
300 /*****************************************************************************
301 * count_utf8_string: returns the number of characters in the string.
302 *****************************************************************************/
303 static int count_utf8_string( const char *psz_string )
305 int i = 0, i_count = 0;
306 while( psz_string[ i ] != 0 )
308 if( ((unsigned char *)psz_string)[ i ] < 0x80UL ) i_count++;
314 /*****************************************************************************
315 * wraptext: inserts \n at convenient places to wrap the text.
316 * Returns the modified string in a new buffer.
317 *****************************************************************************/
318 char *vlc_wraptext( const char *psz_text, int i_line, vlc_bool_t b_utf8 )
321 char *psz_line, *psz_new_text;
323 psz_line = psz_new_text = strdup( psz_text );
326 i_len = count_utf8_string( psz_text );
328 i_len = strlen( psz_text );
330 while( i_len > i_line )
332 /* Look if there is a newline somewhere. */
333 char *psz_parser = psz_line;
335 while( i_count <= i_line && *psz_parser != '\n' )
339 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser++;
344 if( *psz_parser == '\n' )
346 i_len -= (i_count + 1);
347 psz_line = psz_parser + 1;
351 /* Find the furthest space. */
352 while( psz_parser > psz_line && *psz_parser != ' ' )
356 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser--;
361 if( *psz_parser == ' ' )
364 i_len -= (i_count + 1);
365 psz_line = psz_parser + 1;
369 /* Wrapping has failed. Find the first space or newline */
370 while( i_count < i_len && *psz_parser != ' ' && *psz_parser != '\n' )
374 while( *((unsigned char *)psz_parser) >= 0x80UL ) psz_parser++;
379 if( i_count < i_len ) *psz_parser = '\n';
380 i_len -= (i_count + 1);
381 psz_line = psz_parser + 1;
387 /*****************************************************************************
389 *****************************************************************************/
390 vlc_iconv_t vlc_iconv_open( const char *tocode, const char *fromcode )
392 #if defined(HAVE_ICONV)
393 return iconv_open( tocode, fromcode );
399 size_t vlc_iconv( vlc_iconv_t cd, char **inbuf, size_t *inbytesleft,
400 char **outbuf, size_t *outbytesleft )
402 #if defined(HAVE_ICONV)
403 return iconv( cd, inbuf, inbytesleft, outbuf, outbytesleft );
405 int i_bytes = __MIN(inbytesleft, outbytesleft);
406 if( !inbuf || !outbuf || !i_bytes ) return (size_t)(-1);
407 memcpy( *outbuf, *inbuf, i_bytes );
410 inbytesleft -= i_bytes;
411 outbytesleft -= i_bytes;
416 int vlc_iconv_close( vlc_iconv_t cd )
418 #if defined(HAVE_ICONV)
419 return iconv_close( cd );