/*****************************************************************************
* libc.c: Extra libc function for some systems.
*****************************************************************************
- * Copyright (C) 2002 the VideoLAN team
+ * Copyright (C) 2002-2006 the VideoLAN team
* $Id$
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Gildas Bazin <gbazin@videolan.org>
* Derk-Jan Hartman <hartman at videolan dot org>
* Christophe Massiot <massiot@via.ecp.fr>
+ * Rémi Denis-Courmont <rem à videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#endif
#if defined(WIN32) || defined(UNDER_CE)
+# undef _wopendir
+# undef _wreaddir
+# undef _wclosedir
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
/*****************************************************************************
* lldiv: returns quotient and remainder
*****************************************************************************/
-#if defined(SYS_BEOS)
+#if defined(SYS_BEOS) \
+ || (defined (__FreeBSD__) && (__FreeBSD__ < 5))
lldiv_t vlc_lldiv( long long numer, long long denom )
{
lldiv_t d;
}
#endif
+
+/**
+ * Copy a string to a sized buffer. The result is always nul-terminated
+ * (contrary to strncpy()).
+ *
+ * @param dest destination buffer
+ * @param src string to be copied
+ * @param len maximum number of characters to be copied plus one for the
+ * terminating nul.
+ *
+ * @return strlen(src)
+ */
+#ifndef HAVE_STRLCPY
+extern size_t vlc_strlcpy (char *tgt, const char *src, size_t bufsize)
+{
+ size_t length;
+
+ for (length = 1; (length < bufsize) && *src; length++)
+ *tgt++ = *src++;
+
+ if (bufsize)
+ *tgt = '\0';
+
+ while (*src++)
+ length++;
+
+ return length - 1;
+}
+#endif
+
/*****************************************************************************
* vlc_*dir_wrapper: wrapper under Windows to return the list of drive letters
* when called with an empty argument or just '\'
*****************************************************************************/
#if defined(WIN32) && !defined(UNDER_CE)
+# include <assert.h>
+
typedef struct vlc_DIR
{
- DIR *p_real_dir;
+ _WDIR *p_real_dir;
int i_drives;
- struct dirent dd_dir;
+ struct _wdirent dd_dir;
vlc_bool_t b_insert_back;
} vlc_DIR;
-void *vlc_opendir_wrapper( const char *psz_path )
+void *vlc_wopendir( const wchar_t *wpath )
{
vlc_DIR *p_dir;
- DIR *p_real_dir;
+ _WDIR *p_real_dir;
- if ( psz_path == NULL || psz_path[0] == '\0'
- || (psz_path[0] == '\\' && psz_path[1] == '\0') )
+ if ( wpath == NULL || wpath[0] == '\0'
+ || (wcscmp (wpath, L"\\") == 0) )
{
/* Special mode to list drive letters */
p_dir = malloc( sizeof(vlc_DIR) );
return (void *)p_dir;
}
- p_real_dir = opendir( psz_path );
+ p_real_dir = _wopendir( wpath );
if ( p_real_dir == NULL )
return NULL;
p_dir = malloc( sizeof(vlc_DIR) );
p_dir->p_real_dir = p_real_dir;
- p_dir->b_insert_back = ( psz_path[1] == ':' && psz_path[2] == '\\'
- && psz_path[3] =='\0' );
+
+ assert (wpath[0]); // wpath[1] is defined
+ p_dir->b_insert_back = !wcscmp (wpath + 1, L":\\");
return (void *)p_dir;
}
-struct dirent *vlc_readdir_wrapper( void *_p_dir )
+struct _wdirent *vlc_wreaddir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
unsigned int i;
{
if ( p_dir->b_insert_back )
{
+ /* Adds "..", gruik! */
p_dir->dd_dir.d_ino = 0;
p_dir->dd_dir.d_reclen = 0;
p_dir->dd_dir.d_namlen = 2;
- strcpy( p_dir->dd_dir.d_name, ".." );
+ wcscpy( p_dir->dd_dir.d_name, L".." );
p_dir->b_insert_back = VLC_FALSE;
return &p_dir->dd_dir;
}
- return readdir( p_dir->p_real_dir );
+ return _wreaddir( p_dir->p_real_dir );
}
/* Drive letters mode */
if ( i >= 26 )
return NULL; /* this should not happen */
- sprintf( p_dir->dd_dir.d_name, "%c:\\", 'A' + i );
- p_dir->dd_dir.d_namlen = strlen(p_dir->dd_dir.d_name);
+ swprintf( p_dir->dd_dir.d_name, L"%c:\\", 'A' + i );
+ p_dir->dd_dir.d_namlen = wcslen(p_dir->dd_dir.d_name);
p_dir->i_drives &= ~(1UL << i);
return &p_dir->dd_dir;
}
-int vlc_closedir_wrapper( void *_p_dir )
+int vlc_wclosedir( void *_p_dir )
{
vlc_DIR *p_dir = (vlc_DIR *)_p_dir;
+ int i_ret = 0;
if ( p_dir->p_real_dir != NULL )
- {
- int i_ret = closedir( p_dir->p_real_dir );
- free( p_dir );
- return i_ret;
- }
+ i_ret = _wclosedir( p_dir->p_real_dir );
free( p_dir );
- return 0;
-}
-#else
-void *vlc_opendir_wrapper( const char *psz_path )
-{
- return (void *)opendir( psz_path );
-}
-struct dirent *vlc_readdir_wrapper( void *_p_dir )
-{
- return readdir( (DIR *)_p_dir );
-}
-int vlc_closedir_wrapper( void *_p_dir )
-{
- return closedir( (DIR *)_p_dir );
+ return i_ret;
}
#endif
* scandir: scan a directory alpha-sorted
*****************************************************************************/
#if !defined( HAVE_SCANDIR )
+/* FIXME: I suspect this is dead code -> utf8_scandir */
+#ifdef WIN32
+# undef opendir
+# undef readdir
+# undef closedir
+#endif
int vlc_alphasort( const struct dirent **a, const struct dirent **b )
{
return strcoll( (*a)->d_name, (*b)->d_name );
struct dirent ** pp_list;
int ret, size;
- if( !namelist || !( p_dir = vlc_opendir_wrapper( name ) ) ) return -1;
+ if( !namelist || !( p_dir = opendir( name ) ) ) return -1;
ret = 0;
pp_list = NULL;
- while( ( p_content = vlc_readdir_wrapper( p_dir ) ) )
+ while( ( p_content = readdir( p_dir ) ) )
{
if( filter && !filter( p_content ) )
{
ret++;
}
- vlc_closedir_wrapper( p_dir );
+ closedir( p_dir );
if( compar )
{