Index: libmpc/trunk/win32/basename.c
===================================================================
--- libmpc/trunk/win32/basename.c	(revision 362)
+++ libmpc/trunk/win32/basename.c	(revision 362)
@@ -0,0 +1,167 @@
+/* basename.c
+ *
+ * $Id: basename.c,v 1.2 2007/03/08 23:15:58 keithmarshall Exp $
+ *
+ * Provides an implementation of the "basename" function, conforming
+ * to SUSv3, with extensions to accommodate Win32 drive designators,
+ * and suitable for use on native Microsoft(R) Win32 platforms.
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ *
+ * This is free software.  You may redistribute and/or modify it as you
+ * see fit, without restriction of copyright.
+ *
+ * This software is provided "as is", in the hope that it may be useful,
+ * but WITHOUT WARRANTY OF ANY KIND, not even any implied warranty of
+ * MERCHANTABILITY, nor of FITNESS FOR ANY PARTICULAR PURPOSE.  At no
+ * time will the author accept any form of liability for any damages,
+ * however caused, resulting from the use of this software.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+#include <locale.h>
+
+#ifndef __cdecl  /* If compiling on any non-Win32 platform ... */
+#define __cdecl  /* this may not be defined.                   */
+#endif
+
+__cdecl char *basename( char *path )
+{
+  size_t len;
+  static char *retfail = NULL;
+
+  /* to handle path names for files in multibyte character locales,
+   * we need to set up LC_CTYPE to match the host file system locale
+   */
+
+  char *locale = setlocale( LC_CTYPE, NULL );
+  if( locale != NULL ) locale = strdup( locale );
+  setlocale( LC_CTYPE, "" );
+
+  if( path && *path )
+  {
+    /* allocate sufficient local storage space,
+     * in which to create a wide character reference copy of path
+     */
+
+    wchar_t refcopy[1 + (len = mbstowcs( NULL, path, 0 ))];
+
+    /* create the wide character reference copy of path,
+     * and step over the drive designator, if present ...
+     */
+
+    wchar_t *refpath = refcopy;
+    if( ((len = mbstowcs( refpath, path, len )) > 1) && (refpath[1] == L':') )
+    {
+      /* FIXME: maybe should confirm *refpath is a valid drive designator */
+
+      refpath += 2;
+    }
+
+    /* ensure that our wide character reference path is NUL terminated */
+
+    refcopy[ len ] = L'\0';
+
+    /* check again, just to ensure we still have a non-empty path name ... */
+
+    if( *refpath )
+    {
+      /* and, when we do, process it in the wide character domain ...
+       * scanning from left to right, to the char after the final dir separator
+       */
+
+      wchar_t *refname;
+      for( refname = refpath ; *refpath ; ++refpath )
+      {
+	if( (*refpath == L'/') || (*refpath == L'\\') )
+	{
+	  /* we found a dir separator ...
+	   * step over it, and any others which immediately follow it
+	   */
+
+	  while( (*refpath == L'/') || (*refpath == L'\\') )
+	    ++refpath;
+
+	  /* if we didn't reach the end of the path string ... */
+
+	  if( *refpath )
+
+	    /* then we have a new candidate for the base name */
+
+	    refname = refpath;
+
+	  /* otherwise ...
+	   * strip off any trailing dir separators which we found
+	   */
+
+	  else while(  (refpath > refname)
+	  &&          ((*--refpath == L'/') || (*refpath == L'\\'))   )
+	    *refpath = L'\0';
+	}
+      }
+
+      /* in the wide character domain ...
+       * refname now points at the resolved base name ...
+       */
+
+      if( *refname )
+      {
+	/* if it's not empty,
+	 * then we transform the full normalised path back into
+	 * the multibyte character domain, and skip over the dirname,
+	 * to return the resolved basename.
+	 */
+	
+	if( (len = wcstombs( path, refcopy, len )) != (size_t)(-1) )
+	  path[ len ] = '\0';
+	*refname = L'\0';
+	if( (len = wcstombs( NULL, refcopy, 0 )) != (size_t)(-1) )
+	  path += len;
+      }
+
+      else
+      {
+	/* the basename is empty, so return the default value of "/",
+	 * transforming from wide char to multibyte char domain, and
+	 * returning it in our own buffer.
+	 */
+
+	retfail = realloc( retfail, len = 1 + wcstombs( NULL, L"/", 0 ));
+	wcstombs( path = retfail, L"/", len );
+      }
+
+      /* restore the caller's locale, clean up, and return the result */
+
+      setlocale( LC_CTYPE, locale );
+      free( locale );
+      return( path );
+    }
+
+    /* or we had an empty residual path name, after the drive designator,
+     * in which case we simply fall through ...
+     */
+  }
+
+  /* and, if we get to here ...
+   * the path name is either NULL, or it decomposes to an empty string;
+   * in either case, we return the default value of "." in our own buffer,
+   * reloading it with the correct value, transformed from the wide char
+   * to the multibyte char domain, just in case the caller trashed it
+   * after a previous call.
+   */
+
+  retfail = realloc( retfail, len = 1 + wcstombs( NULL, L".", 0 ));
+  wcstombs( retfail, L".", len );
+
+  /* restore the caller's locale, clean up, and return the result */
+
+  setlocale( LC_CTYPE, locale );
+  free( locale );
+  return( retfail );
+}
+
+/* $RCSfile: basename.c,v $$Revision: 1.2 $: end of file */
Index: libmpc/trunk/win32/dirent.c
===================================================================
--- libmpc/trunk/win32/dirent.c	(revision 362)
+++ libmpc/trunk/win32/dirent.c	(revision 362)
@@ -0,0 +1,301 @@
+/* /////////////////////////////////////////////////////////////////////////////
+ * File:    dirent.c
+ *
+ * Purpose: Definition of the opendir() API functions for the Win32 platform.
+ *
+ * Created: 19th October 2002
+ * Updated: 12th September 2006
+ *
+ * Home:    http://synesis.com.au/software/
+ *
+ * Copyright (c) 2002-2006, Matthew Wilson and Synesis Software
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer. 
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the names of Matthew Wilson and Synesis Software nor the names of
+ *   any contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ////////////////////////////////////////////////////////////////////////// */
+
+
+#ifndef UNIXEM_DOCUMENTATION_SKIP_SECTION
+# define _SYNSOFT_VER_C_DIRENT_MAJOR      2
+# define _SYNSOFT_VER_C_DIRENT_MINOR      2
+# define _SYNSOFT_VER_C_DIRENT_REVISION   5
+# define _SYNSOFT_VER_C_DIRENT_EDIT       32
+#endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Includes
+ */
+
+#include <dirent.h>
+
+#include <unixem/unixem.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <windows.h>
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Compiler differences
+ */
+
+#if defined(__BORLANDC__)
+# define UNIXEM_opendir_PROVIDED_BY_COMPILER
+#elif defined(__DMC__)
+# define UNIXEM_opendir_PROVIDED_BY_COMPILER
+#elif defined(__GNUC__)
+# define UNIXEM_opendir_PROVIDED_BY_COMPILER
+#elif defined(__INTEL_COMPILER)
+#elif defined(_MSC_VER)
+#elif defined(__MWERKS__)
+#elif defined(__WATCOMC__)
+#else
+# error Compiler not discriminated
+#endif /* compiler */
+
+
+#if defined(UNIXEM_opendir_PROVIDED_BY_COMPILER) && \
+    !defined(UNIXEM_FORCE_ANY_COMPILER)
+# error The opendir() API is provided by this compiler, so should not be built here
+#endif /* !UNIXEM_opendir_PROVIDED_BY_COMPILER */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Constants and definitions
+ */
+
+#ifndef FILE_ATTRIBUTE_ERROR
+# define FILE_ATTRIBUTE_ERROR           (0xFFFFFFFF)
+#endif /* FILE_ATTRIBUTE_ERROR */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Typedefs
+ */
+
+struct dirent_dir
+{
+    char                directory[_MAX_DIR + 1];    /* . */
+    WIN32_FIND_DATAA    find_data;                  /* The Win32 FindFile data. */
+    HANDLE              hFind;                      /* The Win32 FindFile handle. */
+    struct dirent       dirent;                     /* The handle's entry. */
+};
+
+struct wdirent_dir
+{
+    wchar_t             directory[_MAX_DIR + 1];    /* . */
+    WIN32_FIND_DATAW    find_data;                  /* The Win32 FindFile data. */
+    HANDLE              hFind;                      /* The Win32 FindFile handle. */
+    struct wdirent      dirent;                     /* The handle's entry. */
+};
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Helper functions
+ */
+
+static HANDLE unixem__dirent__findfile_directory(char const *name, LPWIN32_FIND_DATAA data)
+{
+    char    search_spec[_MAX_PATH +1];
+
+    /* Simply add the *.*, ensuring the path separator is
+     * included.
+     */
+    (void)lstrcpyA(search_spec, name);
+    if( '\\' != search_spec[lstrlenA(search_spec) - 1] &&
+        '/' != search_spec[lstrlenA(search_spec) - 1])
+    {
+        (void)lstrcatA(search_spec, "\\*.*");
+    }
+    else
+    {
+        (void)lstrcatA(search_spec, "*.*");
+    }
+
+    return FindFirstFileA(search_spec, data);
+}
+
+#if 0
+static HANDLE unixem__dirent__wfindfile_directory(wchar_t const *name, LPWIN32_FIND_DATAW data)
+{
+    wchar_t search_spec[_MAX_PATH +1];
+
+    /* Simply add the *.*, ensuring the path separator is
+     * included.
+     */
+    lstrcpyW(search_spec, name);
+    if( L'\\' != search_spec[lstrlenW(search_spec) - 1] &&
+        L'/' != search_spec[lstrlenW(search_spec) - 1])
+    {
+        lstrcatW(search_spec, L"\\*.*");
+    }
+    else
+    {
+        lstrcatW(search_spec, L"*.*");
+    }
+
+    return FindFirstFileW(search_spec, data);
+}
+#endif /* 0 */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * API functions
+ */
+
+DIR *opendir(char const *name)
+{
+    DIR     *result =   NULL;
+    DWORD   dwAttr;
+
+    /* Must be a valid name */
+    if( !name ||
+        !*name ||
+        (dwAttr = GetFileAttributes(name)) == 0xFFFFFFFF)
+    {
+        errno = ENOENT;
+    }
+    /* Must be a directory */
+    else if(!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
+    {
+        errno = ENOTDIR;
+    }
+    else
+    {
+        result = (DIR*)malloc(sizeof(DIR));
+
+        if(result == NULL)
+        {
+            errno = ENOMEM;
+        }
+        else
+        {
+            result->hFind = unixem__dirent__findfile_directory(name, &result->find_data);
+
+            if(result->hFind == INVALID_HANDLE_VALUE)
+            {
+                free(result);
+
+                result = NULL;
+            }
+            else
+            {
+                /* Save the directory, in case of rewind. */
+                (void)lstrcpyA(result->directory, name);
+                (void)lstrcpyA(result->dirent.d_name, result->find_data.cFileName);
+                result->dirent.d_mode   =   (int)result->find_data.dwFileAttributes;
+            }
+        }
+    }
+
+#if 0
+    if(NULL != dir)
+    {
+        struct dirent *readdir(DIR *dir)
+
+    }
+#endif /* 0 */
+
+
+
+    return result;
+}
+
+int closedir(DIR *dir)
+{
+    int ret;
+
+    if(dir == NULL)
+    {
+        errno = EBADF;
+
+        ret = -1;
+    }
+    else
+    {
+        /* Close the search handle, if not already done. */
+        if(dir->hFind != INVALID_HANDLE_VALUE)
+        {
+            (void)FindClose(dir->hFind);
+        }
+
+        free(dir);
+
+        ret = 0;
+    }
+
+    return ret;
+}
+
+void rewinddir(DIR *dir)
+{
+    /* Close the search handle, if not already done. */
+    if(dir->hFind != INVALID_HANDLE_VALUE)
+    {
+        (void)FindClose(dir->hFind);
+    }
+
+    dir->hFind = unixem__dirent__findfile_directory(dir->directory, &dir->find_data);
+
+    if(dir->hFind != INVALID_HANDLE_VALUE)
+    {
+        (void)lstrcpyA(dir->dirent.d_name, dir->find_data.cFileName);
+    }
+}
+
+struct dirent *readdir(DIR *dir)
+{
+    /* The last find exhausted the matches, so return NULL. */
+    if(dir->hFind == INVALID_HANDLE_VALUE)
+    {
+        if(FILE_ATTRIBUTE_ERROR == dir->find_data.dwFileAttributes)
+        {
+            errno = EBADF;
+        }
+        else
+        {
+            dir->find_data.dwFileAttributes = FILE_ATTRIBUTE_ERROR;
+        }
+
+        return NULL;
+    }
+    else
+    {
+        /* Copy the result of the last successful match to
+         * dirent.
+         */
+        (void)lstrcpyA(dir->dirent.d_name, dir->find_data.cFileName);
+
+        /* Attempt the next match. */
+        if(!FindNextFileA(dir->hFind, &dir->find_data))
+        {
+            /* Exhausted all matches, so close and null the
+             * handle.
+             */
+            (void)FindClose(dir->hFind);
+            dir->hFind = INVALID_HANDLE_VALUE;
+        }
+
+        return &dir->dirent;
+    }
+}
+
+/* ////////////////////////////////////////////////////////////////////////// */
Index: libmpc/trunk/win32/dirent.h
===================================================================
--- libmpc/trunk/win32/dirent.h	(revision 362)
+++ libmpc/trunk/win32/dirent.h	(revision 362)
@@ -0,0 +1,186 @@
+/* /////////////////////////////////////////////////////////////////////////////
+ * File:    dirent.h
+ *
+ * Purpose: Declaration of the opendir() API functions and types for the
+ *          Win32 platform.
+ *
+ * Created: 19th October 2002
+ * Updated: 12th September 2006
+ *
+ * Home:    http://synesis.com.au/software/
+ *
+ * Copyright (c) 2002-2006, Matthew Wilson and Synesis Software
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the names of Matthew Wilson and Synesis Software nor the names of
+ *   any contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ////////////////////////////////////////////////////////////////////////// */
+
+
+/** \file dirent.h
+ *
+ * Contains the declarations for the opendir()/readdir() API.
+ */
+
+#ifndef SYNSOFT_UNIXEM_INCL_H_DIRENT
+#define SYNSOFT_UNIXEM_INCL_H_DIRENT
+
+#ifndef UNIXEM_DOCUMENTATION_SKIP_SECTION
+# define SYNSOFT_UNIXEM_VER_H_DIRENT_MAJOR      3
+# define SYNSOFT_UNIXEM_VER_H_DIRENT_MINOR      3
+# define SYNSOFT_UNIXEM_VER_H_DIRENT_REVISION   1
+# define SYNSOFT_UNIXEM_VER_H_DIRENT_EDIT       29
+#endif /* !UNIXEM_DOCUMENTATION_SKIP_SECTION */
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/** \weakgroup unixem Synesis Software UNIX Emulation for Win32
+ * \brief The UNIX emulation library
+ */
+
+/** \weakgroup unixem_dirent opendir()/readdir() API
+ * \ingroup UNIXem unixem
+ * \brief This API provides facilities for enumerating the contents of directories
+ * @{
+ */
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#ifndef _WIN32
+# error This file is only currently defined for compilation on Win32 systems
+#endif /* _WIN32 */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Includes
+ */
+
+#include <stddef.h>
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Constants and definitions
+ */
+
+#ifndef NAME_MAX
+# define NAME_MAX   (260)   /*!< \brief The maximum number of characters (including null terminator) in a directory entry name */
+#endif /* !NAME_MAX */
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * Typedefs
+ */
+
+typedef struct dirent_dir   DIR; /*!< \brief Handle type for ANSI directory enumeration. \note dirent_dir is defined internally */
+typedef struct wdirent_dir  wDIR; /*!< \brief Handle type for Unicode directory enumeration. \note dirent_dir is defined internally */
+
+/** \brief Results structure for readdir()
+ */
+struct dirent
+{
+    char    d_name[NAME_MAX + 1];      /*!< file name (null-terminated) */
+    int     d_mode;
+};
+
+/** \brief Results structure for wreaddir()
+ */
+struct wdirent
+{
+    wchar_t d_name[NAME_MAX + 1];   /*!< file name (null-terminated) */
+    int     d_mode;
+};
+
+/* /////////////////////////////////////////////////////////////////////////////
+ * API functions
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** \brief Returns a pointer to the next directory entry.
+ *
+ * This function opens the directory named by filename, and returns a
+ * directory to be used to in subsequent operations. NULL is returned
+ * if name cannot be accessed, or if resources cannot be acquired to
+ * process the request.
+ *
+ * \param name The name of the directory to search
+ * \return The directory handle from which the entries are read or NULL
+ */
+DIR             *opendir(const char *name);
+/** \brief Identical semantics to opendir(), but for Unicode searches.
+ */
+wDIR            *wopendir(const wchar_t *name);
+
+/** \brief Closes a directory handle
+ *
+ * This function closes a directory handle that was opened with opendir()
+ * and releases any resources associated with that directory handle.
+ *
+ * \param dir The directory handle from which the entries are read
+ * \return 0 on success, or -1 to indicate error.
+ */
+int             closedir(DIR *dir);
+/** \brief Identical semantics to closedir(), but for Unicode searches.
+ */
+int             wclosedir(wDIR *dir);
+
+/** \brief Resets a directory search position
+ *
+ * This function resets the position of the named directory handle to
+ * the beginning of the directory.
+ *
+ * \param dir The directory handle whose position should be reset
+ */
+void            rewinddir(DIR *dir);
+/** \brief Identical semantics to rewinddir(), but for Unicode searches.
+ */
+void            wrewinddir(wDIR *dir);
+
+/** \brief Returns a pointer to the next directory entry.
+ *
+ * This function returns a pointer to the next directory entry, or NULL upon
+ * reaching the end of the directory or detecting an invalid seekdir() operation
+ *
+ * \param dir The directory handle from which the entries are read
+ * \return A dirent structure or NULL
+ */
+struct dirent   *readdir(DIR *dir);
+/** \brief Identical semantics to readdir(), but for Unicode searches.
+ */
+struct wdirent  *wreaddir(wDIR *dir);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+/** @} // end of group unixem_dirent */
+
+/* ////////////////////////////////////////////////////////////////////////// */
+
+#endif /* SYNSOFT_UNIXEM_INCL_H_DIRENT */
+
+/* ////////////////////////////////////////////////////////////////////////// */
Index: libmpc/trunk/win32/libgen.h
===================================================================
--- libmpc/trunk/win32/libgen.h	(revision 362)
+++ libmpc/trunk/win32/libgen.h	(revision 362)
@@ -0,0 +1,31 @@
+#ifndef _LIBGEN_H_
+/* 
+ * libgen.h
+ *
+ * $Id: libgen.h,v 1.2 2007/06/23 07:34:15 dannysmith Exp $
+ *
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Functions for splitting pathnames into dirname and basename components.
+ *
+ */
+#define _LIBGEN_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern __cdecl __MINGW_NOTHROW char *basename (char *);
+extern __cdecl __MINGW_NOTHROW char *dirname  (char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _LIBGEN_H_: end of file */
+
