Move the Win32-specific FS code to its own code;...

...the new source file is not compiled directly
This commit is contained in:
Ignacio R. Morelle 2008-03-14 18:59:55 +00:00
parent 9840d115fa
commit 01ddb5473d
2 changed files with 238 additions and 225 deletions

View file

@ -27,234 +27,10 @@
#include <sys/stat.h>
#ifdef _WIN32
/* /////////////////////////////////////////////////////////////////////////
* This code swiped from dirent.c in the unixem library, version 1.7.3.
* See http://synesis.com.au/software/unixem.html for full sources.
* It's under BSD license.
*/
#include <direct.h>
#include <io.h>
#include <errno.h>
#include <stdlib.h>
#include <windows.h>
/* /////////////////////////////////////////////////////////////////////////
* Compiler differences
*/
#if defined(__BORLANDC__)
# define DIRENT_PROVIDED_BY_COMPILER
#elif defined(__DMC__)
# define DIRENT_PROVIDED_BY_COMPILER
#elif defined(__GNUC__)
# define DIRENT_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(DIRENT_PROVIDED_BY_COMPILER)
#include <dirent.h>
#else
/* ////////////////////////////////////////////////////////////////////// */
#include <stddef.h>
#ifndef NAME_MAX
# define NAME_MAX (260)
#endif /* !NAME_MAX */
struct dirent
{
char d_name[NAME_MAX + 1]; /*!< file name (null-terminated) */
int d_mode;
};
struct 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. */
};
#ifndef FILE_ATTRIBUTE_ERROR
# define FILE_ATTRIBUTE_ERROR (0xFFFFFFFF)
#endif /* FILE_ATTRIBUTE_ERROR */
/* /////////////////////////////////////////////////////////////////////////
* Helper functions
*/
static HANDLE 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);
}
/* /////////////////////////////////////////////////////////////////////////
* 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=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;
}
}
}
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;
}
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;
}
}
/*
* Microsoft C uses _stat instead of stat,
* for both the function name and the structure name.
* See <http://svn.ghostscript.com:8080/ghostscript/trunk/gs/src/stat_.h>
*/
#ifdef _MSC_VER
# define stat _stat
namespace {
typedef int mode_t;
}
#endif
#ifndef S_IFMT
#define S_IFMT (S_IFDIR|S_IFREG)
#endif
#ifndef S_ISREG
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
#endif /* !DIRENT_PROVIDED_BY_COMPILER */
#define mkdir(a,b) (_mkdir(a))
#include "filesystem_win32.ii"
#else /* !_WIN32 */
#include <unistd.h>
#include <dirent.h>
#endif /* !_WIN32 */
#ifdef __BEOS__

237
src/filesystem_win32.ii Normal file
View file

@ -0,0 +1,237 @@
/* $Id$ */
/*
Copyright (C) 2003 - 2008 by David White <dave@whitevine.net>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
or at your option any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
//! @file filesystem_win32.ii
//! Win32 platform-specific filesystem code.
/* /////////////////////////////////////////////////////////////////////////
* This code swiped from dirent.c in the unixem library, version 1.7.3.
* See http://synesis.com.au/software/unixem.html for full sources.
* It's under BSD license.
*/
#include <direct.h>
#include <io.h>
#include <errno.h>
#include <stdlib.h>
#include <windows.h>
/* /////////////////////////////////////////////////////////////////////////
* Compiler differences
*/
#if defined(__BORLANDC__)
# define DIRENT_PROVIDED_BY_COMPILER
#elif defined(__DMC__)
# define DIRENT_PROVIDED_BY_COMPILER
#elif defined(__GNUC__)
# define DIRENT_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(DIRENT_PROVIDED_BY_COMPILER)
#include <dirent.h>
#else
/* ////////////////////////////////////////////////////////////////////// */
#include <stddef.h>
#ifndef NAME_MAX
# define NAME_MAX (260)
#endif /* !NAME_MAX */
struct dirent
{
char d_name[NAME_MAX + 1]; /*!< file name (null-terminated) */
int d_mode;
};
struct 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. */
};
#ifndef FILE_ATTRIBUTE_ERROR
# define FILE_ATTRIBUTE_ERROR (0xFFFFFFFF)
#endif /* FILE_ATTRIBUTE_ERROR */
/* /////////////////////////////////////////////////////////////////////////
* Helper functions
*/
static HANDLE 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);
}
/* /////////////////////////////////////////////////////////////////////////
* 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=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;
}
}
}
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;
}
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;
}
}
/*
* Microsoft C uses _stat instead of stat,
* for both the function name and the structure name.
* See <http://svn.ghostscript.com:8080/ghostscript/trunk/gs/src/stat_.h>
*/
#ifdef _MSC_VER
# define stat _stat
namespace {
typedef int mode_t;
}
#endif
#ifndef S_IFMT
#define S_IFMT (S_IFDIR|S_IFREG)
#endif
#ifndef S_ISREG
#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
#endif /* !DIRENT_PROVIDED_BY_COMPILER */
#define mkdir(a,b) (_mkdir(a))