summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-06-25 03:00:31 +1000
committer Vas Crabb <vas@vastheman.com>2016-06-25 03:35:23 +1000
commit5cee9e9bc4fe03dc561d3a7a87ecadcf89743e2b (patch)
tree84c962bcfb8f0fdfd73d6b4e317f140034958ce3
parent20a95045e16ab69cfb13c6d3cf520e63aa553102 (diff)
POSIX implementation for new directory read features, cleanup of Windows implementation, return directory handle as smart pointer, fix full build [Vas Crabb]
-rw-r--r--scripts/src/osd/sdl.lua3
-rw-r--r--scripts/src/osd/windows.lua2
-rw-r--r--src/devices/bus/nubus/nubus_image.cpp7
-rw-r--r--src/devices/bus/nubus/nubus_image.h2
-rw-r--r--src/emu/diimage.cpp6
-rw-r--r--src/emu/fileio.cpp8
-rw-r--r--src/emu/fileio.h6
-rw-r--r--src/frontend/mame/clifront.cpp6
-rw-r--r--src/frontend/mame/pluginopts.cpp7
-rw-r--r--src/lib/util/zippath.cpp8
-rw-r--r--src/osd/modules/file/posixdir.cpp293
-rw-r--r--src/osd/modules/file/posixfile.cpp18
-rw-r--r--src/osd/modules/file/windir.cpp (renamed from src/osd/windows/windir.cpp)142
-rw-r--r--src/osd/modules/file/winfile.cpp8
-rw-r--r--src/osd/modules/render/bgfx/chainentryreader.cpp6
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp4
-rw-r--r--src/osd/osdcore.h8
-rw-r--r--src/osd/sdl/sdldir.cpp316
-rw-r--r--src/tools/romcmp.cpp14
-rw-r--r--src/tools/src2html.cpp16
20 files changed, 432 insertions, 448 deletions
diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua
index 7766b69873d..4094e48c6be 100644
--- a/scripts/src/osd/sdl.lua
+++ b/scripts/src/osd/sdl.lua
@@ -461,7 +461,6 @@ project ("ocore_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/strconv.h",
MAME_DIR .. "src/osd/osdsync.cpp",
MAME_DIR .. "src/osd/osdsync.h",
- MAME_DIR .. "src/osd/sdl/sdldir.cpp",
MAME_DIR .. "src/osd/modules/osdmodule.cpp",
MAME_DIR .. "src/osd/modules/osdmodule.h",
MAME_DIR .. "src/osd/modules/lib/osdlib_" .. SDLOS_TARGETOS .. ".cpp",
@@ -470,6 +469,7 @@ project ("ocore_" .. _OPTIONS["osd"])
if BASE_TARGETOS=="unix" then
files {
+ MAME_DIR .. "src/osd/modules/file/posixdir.cpp",
MAME_DIR .. "src/osd/modules/file/posixfile.cpp",
MAME_DIR .. "src/osd/modules/file/posixfile.h",
MAME_DIR .. "src/osd/modules/file/posixptty.cpp",
@@ -480,6 +480,7 @@ project ("ocore_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/windows",
}
files {
+ MAME_DIR .. "src/osd/modules/file/windir.cpp",
MAME_DIR .. "src/osd/modules/file/winfile.cpp",
MAME_DIR .. "src/osd/modules/file/winfile.h",
MAME_DIR .. "src/osd/modules/file/winptty.cpp",
diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua
index 9307c6dec71..a6e40c7aadc 100644
--- a/scripts/src/osd/windows.lua
+++ b/scripts/src/osd/windows.lua
@@ -244,13 +244,13 @@ project ("ocore_" .. _OPTIONS["osd"])
MAME_DIR .. "src/osd/osdsync.cpp",
MAME_DIR .. "src/osd/osdsync.h",
MAME_DIR .. "src/osd/windows/main.cpp",
- MAME_DIR .. "src/osd/windows/windir.cpp",
MAME_DIR .. "src/osd/windows/winutf8.cpp",
MAME_DIR .. "src/osd/windows/winutf8.h",
MAME_DIR .. "src/osd/windows/winutil.cpp",
MAME_DIR .. "src/osd/windows/winutil.h",
MAME_DIR .. "src/osd/modules/osdmodule.cpp",
MAME_DIR .. "src/osd/modules/osdmodule.h",
+ MAME_DIR .. "src/osd/modules/file/windir.cpp",
MAME_DIR .. "src/osd/modules/file/winfile.cpp",
MAME_DIR .. "src/osd/modules/file/winfile.h",
MAME_DIR .. "src/osd/modules/file/winptty.cpp",
diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp
index d7752e3babc..2a13a9c8613 100644
--- a/src/devices/bus/nubus/nubus_image.cpp
+++ b/src/devices/bus/nubus/nubus_image.cpp
@@ -271,7 +271,7 @@ READ32_MEMBER( nubus_image_device::image_super_r )
WRITE32_MEMBER( nubus_image_device::file_cmd_w )
{
- const osd_directory_entry *dp;
+ const osd::directory::entry *dp;
char fullpath[1024];
UINT64 filesize;
@@ -290,11 +290,10 @@ WRITE32_MEMBER( nubus_image_device::file_cmd_w )
}
break;
case kFileCmdGetFirstListing:
- if(filectx.dirp) osd_closedir(filectx.dirp);
- filectx.dirp = osd_opendir((const char *)filectx.curdir);
+ filectx.dirp = osd::directory::open((const char *)filectx.curdir);
case kFileCmdGetNextListing:
if (filectx.dirp) {
- dp = osd_readdir(filectx.dirp);
+ dp = filectx.dirp->read();
if(dp) {
strncpy((char*)filectx.filename, dp->name, sizeof(filectx.filename));
} else {
diff --git a/src/devices/bus/nubus/nubus_image.h b/src/devices/bus/nubus/nubus_image.h
index dda6e55fc02..6badecd4f0d 100644
--- a/src/devices/bus/nubus/nubus_image.h
+++ b/src/devices/bus/nubus/nubus_image.h
@@ -18,7 +18,7 @@ struct nbfilectx {
UINT32 curcmd;
UINT8 filename[128];
UINT8 curdir[1024];
- osd_directory *dirp;
+ osd::directory::ptr dirp;
osd_file::ptr fd;
UINT64 filelen;
UINT32 bytecount;
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 9c6ed4f2013..b6c32826a5a 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -300,9 +300,9 @@ bool device_image_interface::try_change_working_directory(const char *subdir)
bool done = false;
auto directory = osd::directory::open(m_working_directory.c_str());
- if (directory != nullptr)
+ if (directory)
{
- while(!done && (entry = directory->read()) != nullptr)
+ while (!done && (entry = directory->read()) != nullptr)
{
if (!core_stricmp(subdir, entry->name))
{
@@ -311,7 +311,7 @@ bool device_image_interface::try_change_working_directory(const char *subdir)
}
}
- delete directory;
+ directory.reset();
}
/* did we successfully identify the directory? */
diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp
index 55231dc845c..1fe26071acb 100644
--- a/src/emu/fileio.cpp
+++ b/src/emu/fileio.cpp
@@ -89,9 +89,6 @@ file_enumerator::file_enumerator(const char *searchpath)
file_enumerator::~file_enumerator()
{
- // close anything open
- if (m_curdir != nullptr)
- delete m_curdir;
}
@@ -106,7 +103,7 @@ const osd::directory::entry *file_enumerator::next()
while (1)
{
// if no open directory, get the next path
- while (m_curdir == nullptr)
+ while (!m_curdir)
{
// if we fail to get anything more, we're done
if (!m_iterator.next(m_pathbuffer))
@@ -122,8 +119,7 @@ const osd::directory::entry *file_enumerator::next()
return result;
// we're done; close this directory
- delete m_curdir;
- m_curdir = nullptr;
+ m_curdir.reset();
}
}
diff --git a/src/emu/fileio.h b/src/emu/fileio.h
index d71b350559c..411e211d17b 100644
--- a/src/emu/fileio.h
+++ b/src/emu/fileio.h
@@ -67,9 +67,9 @@ public:
private:
// internal state
- path_iterator m_iterator;
- osd::directory *m_curdir;
- std::string m_pathbuffer;
+ path_iterator m_iterator;
+ osd::directory::ptr m_curdir;
+ std::string m_pathbuffer;
//int m_buflen;
};
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index 6f0f319dc44..3679441957a 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -1810,8 +1810,8 @@ media_identifier::media_identifier(emu_options &options)
void media_identifier::identify(const char *filename)
{
// first try to open as a directory
- osd::directory *directory = osd::directory::open(filename);
- if (directory != nullptr)
+ osd::directory::ptr directory = osd::directory::open(filename);
+ if (directory)
{
// iterate over all files in the directory
for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
@@ -1822,7 +1822,7 @@ void media_identifier::identify(const char *filename)
}
// close the directory and be done
- delete directory;
+ directory.reset();
}
// if that failed, and the filename ends with .zip, identify as a ZIP file
diff --git a/src/frontend/mame/pluginopts.cpp b/src/frontend/mame/pluginopts.cpp
index ad24cbbeef0..0dd9ca7bcf9 100644
--- a/src/frontend/mame/pluginopts.cpp
+++ b/src/frontend/mame/pluginopts.cpp
@@ -39,8 +39,8 @@ plugin_options::plugin_options()
void plugin_options::parse_json(std::string path)
{
// first try to open as a directory
- osd::directory *directory = osd::directory::open(path.c_str());
- if (directory != nullptr)
+ osd::directory::ptr directory = osd::directory::open(path);
+ if (directory)
{
// iterate over all files in the directory
for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
@@ -89,8 +89,5 @@ void plugin_options::parse_json(std::string path)
}
}
}
-
- // close the directory and be done
- delete directory;
}
}
diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp
index 48a919a8cad..3322c1152cc 100644
--- a/src/lib/util/zippath.cpp
+++ b/src/lib/util/zippath.cpp
@@ -37,9 +37,9 @@ class zippath_directory
public:
zippath_directory()
: returned_parent(false)
- , directory(nullptr)
+ , directory()
, called_zip_first(false)
- , zipfile(nullptr)
+ , zipfile()
, returned_dirlist()
{
}
@@ -52,7 +52,7 @@ public:
/* specific to normal directories */
/** @brief Pathname of the directory. */
- osd::directory *directory;
+ osd::directory::ptr directory;
/* specific to ZIP directories */
/** @brief true to called zip first. */
@@ -840,7 +840,7 @@ done:
void zippath_closedir(zippath_directory *directory)
{
if (directory->directory != nullptr)
- delete directory->directory;
+ directory->directory.reset();
if (directory->zipfile != nullptr)
directory->zipfile.reset();
diff --git a/src/osd/modules/file/posixdir.cpp b/src/osd/modules/file/posixdir.cpp
new file mode 100644
index 00000000000..d08d6869c6c
--- /dev/null
+++ b/src/osd/modules/file/posixdir.cpp
@@ -0,0 +1,293 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdldir.c - SDL core directory access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE
+#endif
+
+#ifdef __linux__
+#ifndef __USE_LARGEFILE64
+#define __USE_LARGEFILE64
+#endif
+#ifndef __USE_BSD
+#define __USE_BSD
+#endif
+#endif
+
+#ifdef WIN32
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__bsdi__) && !defined(__DragonFly__)
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE < 500
+#undef _XOPEN_SOURCE
+#endif
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+#endif
+
+#undef _POSIX_C_SOURCE // to get DT_xxx on OS X
+
+
+#include "osdcore.h"
+#include "modules/lib/osdlib.h"
+#include "util/strformat.h"
+
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+
+namespace osd {
+namespace {
+//============================================================
+// CONSTANTS
+//============================================================
+
+#if defined(WIN32)
+constexpr char PATHSEPCH = '\\';
+constexpr char INVPATHSEPCH = '/';
+#else
+constexpr char PATHSEPCH = '/';
+constexpr char INVPATHSEPCH = '\\';
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(EMSCRIPTEN) || defined(__ANDROID__) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+using sdl_dirent = struct dirent;
+using sdl_stat = struct stat;
+#define sdl_readdir readdir
+#define sdl_stat_fn stat
+#else
+using sdl_dirent = struct dirent64;
+using sdl_stat = struct stat64;
+#define sdl_readdir readdir64
+#define sdl_stat_fn stat64
+#endif
+
+#define HAS_DT_XXX (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__))
+
+
+
+//============================================================
+// TYPE DEFINITIONS
+//============================================================
+
+class posix_directory : public osd::directory
+{
+public:
+ posix_directory();
+ virtual ~posix_directory() override;
+
+ virtual const entry *read() override;
+
+ bool open(std::string const &dirname);
+
+private:
+ typedef std::unique_ptr<DIR, int (*)(DIR *)> dir_ptr;
+
+ entry m_entry;
+ sdl_dirent *m_data;
+ dir_ptr m_fd;
+ std::string m_path;
+};
+
+
+//============================================================
+// posix_directory::~posix_directory
+//============================================================
+
+posix_directory::posix_directory()
+ : m_entry()
+ , m_data(nullptr)
+ , m_fd(nullptr, &::closedir)
+ , m_path()
+{
+}
+
+
+//============================================================
+// posix_directory::~posix_directory
+//============================================================
+
+posix_directory::~posix_directory()
+{
+}
+
+
+//============================================================
+// posix_directory::read
+//============================================================
+
+const osd::directory::entry *posix_directory::read()
+{
+ m_data = sdl_readdir(m_fd.get());
+ if (!m_data)
+ return nullptr;
+
+ m_entry.name = m_data->d_name;
+
+ sdl_stat st;
+ bool stat_err(0 > sdl_stat_fn(util::string_format("%s%c%s", m_path, PATHSEPCH, m_data->d_name).c_str(), &st));
+
+#if HAS_DT_XXX
+ switch (m_data->d_type)
+ {
+ case DT_DIR:
+ m_entry.type = entry::entry_type::DIR;
+ break;
+ case DT_REG:
+ m_entry.type = entry::entry_type::FILE;
+ break;
+ case DT_LNK:
+ if (stat_err)
+ m_entry.type = entry::entry_type::OTHER;
+ else if (S_ISDIR(st.st_mode))
+ m_entry.type = entry::entry_type::DIR;
+ else
+ m_entry.type = entry::entry_type::FILE;
+ break;
+ default:
+ m_entry.type = entry::entry_type::OTHER;
+ }
+#else
+ if (stat_err)
+ m_entry.type = entry::entry_type::OTHER;
+ else if (S_ISDIR(st.st_mode))
+ m_entry.type = entry::entry_type::DIR;
+ else
+ m_entry.type = entry::entry_type::FILE;
+#endif
+ m_entry.size = stat_err ? 0 : std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
+ m_entry.last_modified = std::chrono::system_clock::from_time_t(st.st_mtime);
+ return &m_entry;
+}
+
+
+//============================================================
+// posix_directory::open
+//============================================================
+
+bool posix_directory::open(std::string const &dirname)
+{
+ assert(!m_fd);
+
+ osd_subst_env(m_path, dirname);
+ m_fd.reset(::opendir(m_path.c_str()));
+ return bool(m_fd);
+}
+
+} // anonymous namespace
+
+
+//============================================================
+// osd::directory::open
+//============================================================
+
+directory::ptr directory::open(std::string const &dirname)
+{
+ ptr dir;
+ try { dir.reset(new posix_directory); }
+ catch (...) { return nullptr; }
+
+ if (!dir->open(dirname))
+ return nullptr;
+
+ return dir;
+}
+
+} // namespace osd
+
+
+//============================================================
+// osd_subst_env
+//============================================================
+
+void osd_subst_env(std::string &dst, std::string const &src)
+{
+ std::string result, var;
+ auto start = src.begin();
+
+ // a leading tilde expands as $HOME
+ if ((src.end() != start) && ('~' == *start))
+ {
+ char const *const home = std::getenv("HOME");
+ if (home)
+ {
+ ++start;
+ if ((src.end() == start) || (osd::PATHSEPCH == *start))
+ result.append(home);
+ else
+ result.push_back('~');
+ }
+ }
+
+ while (src.end() != start)
+ {
+ // find $ marking start of environment variable or end of string
+ auto it = start;
+ while ((src.end() != it) && ('$' != *it)) ++it;
+ if (start != it) result.append(start, it);
+ start = it;
+
+ if (src.end() != start)
+ {
+ start = ++it;
+ if ((src.end() != start) && ('{' == *start))
+ {
+ start = ++it;
+ for (++it; (src.end() != it) && ('}' != *it); ++it) { }
+ if (src.end() == it)
+ {
+ result.append("${").append(start, it);
+ start = it;
+ }
+ else
+ {
+ var.assign(start, it);
+ start = ++it;
+ const char *const exp = std::getenv(var.c_str());
+ if (exp)
+ result.append(exp);
+ else
+ fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
+ }
+ }
+ else if ((src.end() != start) && (('_' == *start) || std::isalnum(*start)))
+ {
+ for (++it; (src.end() != it) && (('_' == *it) || std::isalnum(*it)); ++it) { }
+ var.assign(start, it);
+ start = it;
+ const char *const exp = std::getenv(var.c_str());
+ if (exp)
+ result.append(exp);
+ else
+ fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
+ }
+ else
+ {
+ result.push_back('$');
+ }
+ }
+ }
+
+ dst = std::move(result);
+}
diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp
index 8c3d2860060..8b8dc004da0 100644
--- a/src/osd/modules/file/posixfile.cpp
+++ b/src/osd/modules/file/posixfile.cpp
@@ -14,8 +14,13 @@
#endif
#ifdef __linux__
+#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
+#ifndef __USE_BSD
+#define __USE_BSD
+#endif
+#endif
#ifdef WIN32
#define _FILE_OFFSET_BITS 64
@@ -337,7 +342,7 @@ int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UIN
// osd_stat
//============================================================
-osd_directory_entry *osd_stat(const std::string &path)
+std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
{
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO) || defined(__ANDROID__)
struct stat st;
@@ -350,13 +355,18 @@ osd_directory_entry *osd_stat(const std::string &path)
// create an osd_directory_entry; be sure to make sure that the caller can
// free all resources by just freeing the resulting osd_directory_entry
- osd_directory_entry *const result = reinterpret_cast<osd_directory_entry *>(osd_malloc_array(sizeof(osd_directory_entry) + path.length() + 1));
+ osd::directory::entry *result;
+ try { result = reinterpret_cast<osd::directory::entry *>(::operator new(sizeof(*result) + path.length() + 1)); }
+ catch (...) { return nullptr; }
+ new (result) osd::directory::entry;
+
std::strcpy(reinterpret_cast<char *>(result) + sizeof(*result), path.c_str());
result->name = reinterpret_cast<char *>(result) + sizeof(*result);
- result->type = S_ISDIR(st.st_mode) ? ENTTYPE_DIR : ENTTYPE_FILE;
+ result->type = S_ISDIR(st.st_mode) ? osd::directory::entry::entry_type::DIR : osd::directory::entry::entry_type::FILE;
result->size = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
+ result->last_modified = std::chrono::system_clock::from_time_t(st.st_mtime);
- return result;
+ return std::unique_ptr<osd::directory::entry>(result);
}
diff --git a/src/osd/windows/windir.cpp b/src/osd/modules/file/windir.cpp
index 32c5ec232ae..e6eecfab4a2 100644
--- a/src/osd/windows/windir.cpp
+++ b/src/osd/modules/file/windir.cpp
@@ -12,10 +12,6 @@
#include <shlwapi.h>
#include <tchar.h>
-// standard C headers
-#include <stdio.h>
-#include <ctype.h>
-
// MAME headers
#include "osdcore.h"
@@ -23,84 +19,45 @@
#include "strconv.h"
#include "winutil.h"
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-namespace
-{
- class win_directory : public osd::directory
- {
- public:
- win_directory();
- ~win_directory();
-
- virtual const entry *read() override;
-
- HANDLE m_find; // handle to the finder
- bool m_is_first; // true if this is the first entry
- entry m_entry; // current entry's data
- WIN32_FIND_DATA m_data; // current raw data
- };
-};
+// standard C headers
+#include <stdio.h>
+#include <ctype.h>
+#include <cassert>
+#include <cstring>
+namespace osd {
+namespace {
//============================================================
-// osd::directory::open
+// TYPE DEFINITIONS
//============================================================
-osd::directory *osd::directory::open(const char *dirname)
+class win_directory : public directory
{
- win_directory *dir = nullptr;
- TCHAR *t_dirname = nullptr;
- TCHAR *dirfilter = nullptr;
- size_t dirfilter_size;
-
- // allocate memory to hold the osd_tool_directory structure
- dir = new win_directory();
- if (dir == nullptr)
- goto error;
-
- // convert the path to TCHARs
- t_dirname = tstring_from_utf8(dirname);
- if (t_dirname == nullptr)
- goto error;
+public:
+ win_directory();
+ virtual ~win_directory() override;
- // append \*.* to the directory name
- dirfilter_size = _tcslen(t_dirname) + 5;
- dirfilter = (TCHAR *)malloc(dirfilter_size * sizeof(*dirfilter));
- if (dirfilter == nullptr)
- goto error;
- _sntprintf(dirfilter, dirfilter_size, TEXT("%s\\*.*"), t_dirname);
+ virtual const entry *read() override;
- // attempt to find the first file
- dir->m_find = FindFirstFileEx(dirfilter, FindExInfoStandard, &dir->m_data, FindExSearchNameMatch, nullptr, 0);
-
-error:
- // cleanup
- if (t_dirname != nullptr)
- osd_free(t_dirname);
- if (dirfilter != nullptr)
- free(dirfilter);
- if (dir != nullptr && dir->m_find == INVALID_HANDLE_VALUE)
- {
- delete dir;
- dir = nullptr;
- }
- return dir;
-}
+ bool open(std::string const &dirname);
+private:
+ HANDLE m_find; // handle to the finder
+ bool m_is_first; // true if this is the first entry
+ entry m_entry; // current entry's data
+ WIN32_FIND_DATA m_data; // current raw data
+};
//============================================================
// win_directory::win_directory
//============================================================
win_directory::win_directory()
- : m_find(INVALID_HANDLE_VALUE), m_is_first(true)
+ : m_find(INVALID_HANDLE_VALUE)
+ , m_is_first(true)
{
- memset(&m_entry, 0, sizeof(m_entry));
- memset(&m_data, 0, sizeof(m_data));
+ std::memset(&m_data, 0, sizeof(m_data));
}
@@ -122,7 +79,7 @@ win_directory::~win_directory()
// win_directory::read
//============================================================
-const osd::directory::entry *win_directory::read()
+const directory::entry *win_directory::read()
{
// if we've previously allocated a name, free it now
if (m_entry.name != nullptr)
@@ -142,7 +99,56 @@ const osd::directory::entry *win_directory::read()
// extract the data
m_entry.name = utf8_from_tstring(m_data.cFileName);
m_entry.type = win_attributes_to_entry_type(m_data.dwFileAttributes);
- m_entry.size = m_data.nFileSizeLow | ((UINT64) m_data.nFileSizeHigh << 32);
+ m_entry.size = m_data.nFileSizeLow | (std::uint64_t(m_data.nFileSizeHigh) << 32);
m_entry.last_modified = win_time_point_from_filetime(&m_data.ftLastWriteTime);
return (m_entry.name != nullptr) ? &m_entry : nullptr;
}
+
+
+//============================================================
+// win_directory::open
+//============================================================
+
+bool win_directory::open(std::string const &dirname)
+{
+ assert(m_find == INVALID_HANDLE_VALUE);
+
+ // convert the path to TCHARs
+ std::unique_ptr<TCHAR, void (*)(void *)> const t_dirname(tstring_from_utf8(dirname.c_str()), &osd_free);
+ if (!t_dirname)
+ return false;
+
+ // append \*.* to the directory name
+ auto const dirfilter_size = _tcslen(t_dirname.get()) + 5;
+ std::unique_ptr<TCHAR []> dirfilter;
+ try { dirfilter.reset(new TCHAR[dirfilter_size]); }
+ catch (...) { return false; }
+ _sntprintf(dirfilter.get(), dirfilter_size, TEXT("%s\\*.*"), t_dirname.get());
+
+ // attempt to find the first file
+ m_find = FindFirstFileEx(dirfilter.get(), FindExInfoStandard, &m_data, FindExSearchNameMatch, nullptr, 0);
+ if (m_find == INVALID_HANDLE_VALUE)
+ return false;
+}
+
+} // anonymous namespace
+
+
+//============================================================
+// osd::directory::open
+//============================================================
+
+directory::ptr directory::open(std::string const &dirname)
+{
+ // allocate memory to hold the osd_tool_directory structure
+ ptr dir;
+ try { dir.reset(new win_directory()); }
+ catch (...) { return nullptr; }
+
+ if (!dir->open(dirname))
+ return false;
+
+ return dir;
+}
+
+} // namesapce osd
diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp
index 13af3a025c8..c304259b915 100644
--- a/src/osd/modules/file/winfile.cpp
+++ b/src/osd/modules/file/winfile.cpp
@@ -381,9 +381,11 @@ std::unique_ptr<osd::directory::entry> osd_stat(const std::string &path)
// create an osd::directory::entry; be sure to make sure that the caller can
// free all resources by just freeing the resulting osd::directory::entry
- osd::directory::entry *result = (osd::directory::entry *) ::operator new(sizeof(*result) + path.length() + 1);
- if (!result)
- return nullptr;
+ osd::directory::entry *result;
+ try { result = reinterpret_cast<osd::directory::entry *>(::operator new(sizeof(*result) + path.length() + 1)); }
+ catch (...) { return nullptr; }
+ new (result) osd::directory::entry;
+
strcpy(((char *) result) + sizeof(*result), path.c_str());
result->name = ((char *) result) + sizeof(*result);
result->type = win_attributes_to_entry_type(find_data.dwFileAttributes);
diff --git a/src/osd/modules/render/bgfx/chainentryreader.cpp b/src/osd/modules/render/bgfx/chainentryreader.cpp
index c169a0cd441..278a795f6e7 100644
--- a/src/osd/modules/render/bgfx/chainentryreader.cpp
+++ b/src/osd/modules/render/bgfx/chainentryreader.cpp
@@ -115,8 +115,8 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
directory_path += "/" + file_directory;
}
- osd::directory *directory = osd::directory::open(directory_path.c_str());
- if (directory != nullptr)
+ osd::directory::ptr directory = osd::directory::open(directory_path);
+ if (directory)
{
for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
{
@@ -159,8 +159,6 @@ bgfx_chain_entry* chain_entry_reader::read_from_value(const Value& value, std::s
}
}
}
-
- delete directory;
}
}
}
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index eaf8297a4ee..d4c59f9bb6a 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -91,7 +91,7 @@ void chain_manager::destroy_unloaded_chains()
void chain_manager::find_available_chains(std::string root, std::string path)
{
- osd::directory *directory = osd::directory::open((root + path).c_str());
+ osd::directory::ptr directory = osd::directory::open(root + path);
if (directory != nullptr)
{
for (const osd::directory::entry *entry = directory->read(); entry != nullptr; entry = directory->read())
@@ -128,8 +128,6 @@ void chain_manager::find_available_chains(std::string root, std::string path)
}
}
}
-
- delete directory;
}
}
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index 137f49d58e9..141f3db55d9 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -21,11 +21,11 @@
#include "osdcomm.h"
+#include <chrono>
#include <cstdarg>
#include <cstdint>
#include <memory>
#include <string>
-#include <chrono>
/***************************************************************************
@@ -304,6 +304,8 @@ namespace osd
class directory
{
public:
+ typedef std::unique_ptr<directory> ptr;
+
// osd::directory::entry contains basic information about a file when iterating through
// a directory
class entry
@@ -319,7 +321,7 @@ namespace osd
const char * name; // name of the entry
entry_type type; // type of the entry
- UINT64 size; // size of the entry
+ std::uint64_t size; // size of the entry
std::chrono::system_clock::time_point last_modified; // last modified time
};
@@ -336,7 +338,7 @@ namespace osd
// which contains opaque data necessary to traverse the directory; on
// failure, this function should return nullptr
// -----------------------------------------------------------------------------
- static directory *open(const char *dirname);
+ static ptr open(std::string const &dirname);
// -----------------------------------------------------------------------------
// osd::directory::~directory: close an open directory
diff --git a/src/osd/sdl/sdldir.cpp b/src/osd/sdl/sdldir.cpp
deleted file mode 100644
index fcae732ed53..00000000000
--- a/src/osd/sdl/sdldir.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdldir.c - SDL core directory access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#ifdef SDLMAME_WIN32
-#include "../windows/windir.cpp"
-#else
-
-#ifndef _LARGEFILE64_SOURCE
-#define _LARGEFILE64_SOURCE
-#endif
-
-#ifdef SDLMAME_LINUX
-#define __USE_LARGEFILE64
-#endif
-#ifndef SDLMAME_BSD
-#ifdef _XOPEN_SOURCE
-#undef _XOPEN_SOURCE
-#endif
-#define _XOPEN_SOURCE 500
-#endif
-
-#include <cctype>
-#include <cstdlib>
-#include <utility>
-
-//#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#ifndef __USE_BSD
-#define __USE_BSD // to get DT_xxx on Linux
-#endif
-#undef _POSIX_C_SOURCE // to get DT_xxx on OS X
-#include <dirent.h>
-
-#include "osdcore.h"
-#include "modules/lib/osdlib.h"
-
-#if defined(SDLMAME_WIN32)
-#define PATHSEPCH '\\'
-#define INVPATHSEPCH '/'
-#else
-#define PATHSEPCH '/'
-#define INVPATHSEPCH '\\'
-#endif
-
-#if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) || defined(SDLMAME_ANDROID)
-typedef struct dirent sdl_dirent;
-typedef struct stat sdl_stat;
-#define sdl_readdir readdir
-#define sdl_stat_fn stat
-#else
-typedef struct dirent64 sdl_dirent;
-typedef struct stat64 sdl_stat;
-#define sdl_readdir readdir64
-#define sdl_stat_fn stat64
-#endif
-
-#define HAS_DT_XXX defined(SDLMAME_LINUX) || defined(SDLMAME_BSD) || defined(SDLMAME_DARWIN)
-
-struct osd_directory
-{
- osd_directory_entry ent;
- sdl_dirent *data;
- DIR *fd;
- char *path;
-};
-
-static char *build_full_path(const char *path, const char *file)
-{
- char *ret = (char *) osd_malloc_array(strlen(path)+strlen(file)+2);
- char *p = ret;
-
- strcpy(p, path);
- p += strlen(path);
- *p++ = PATHSEPCH;
- strcpy(p, file);
- return ret;
-}
-
-
-#if HAS_DT_XXX
-static osd_dir_entry_type get_attributes_enttype(int attributes, char *path)
-{
- switch ( attributes )
- {
- case DT_DIR:
- return ENTTYPE_DIR;
-
- case DT_REG:
- return ENTTYPE_FILE;
-
- case DT_LNK:
- {
- struct stat s;
-
- if ( stat(path, &s) != 0 )
- return ENTTYPE_OTHER;
- else
- return S_ISDIR(s.st_mode) ? ENTTYPE_DIR : ENTTYPE_FILE;
- }
-
- default:
- return ENTTYPE_OTHER;
- }
-}
-#else
-
-static osd_dir_entry_type get_attributes_stat(const char *file)
-{
- sdl_stat st;
- if(sdl_stat_fn(file, &st))
- return (osd_dir_entry_type) 0;
-
- if (S_ISDIR(st.st_mode))
- return ENTTYPE_DIR;
- else
- return ENTTYPE_FILE;
-}
-#endif
-
-static UINT64 osd_get_file_size(const char *file)
-{
- sdl_stat st;
- if(sdl_stat_fn(file, &st))
- return 0;
- return st.st_size;
-}
-
-//============================================================
-// osd_opendir
-//============================================================
-
-osd_directory *osd_opendir(const char *dirname)
-{
- osd_directory *dir = nullptr;
- char *tmpstr, *envstr;
- int i, j;
-
- dir = (osd_directory *) osd_malloc(sizeof(osd_directory));
- if (dir)
- {
- memset(dir, 0, sizeof(osd_directory));
- dir->fd = nullptr;
- }
-
- tmpstr = (char *) osd_malloc_array(strlen(dirname)+1);
- strcpy(tmpstr, dirname);
-
- if (tmpstr[0] == '$')
- {
- envstr = (char *) osd_malloc_array(strlen(tmpstr)+1);
-
- strcpy(envstr, tmpstr);
-
- i = 0;
- while (envstr[i] != PATHSEPCH && envstr[i] != INVPATHSEPCH && envstr[i] != 0 && envstr[i] != '.')
- {
- i++;
- }
-
- envstr[i] = '\0';
-
- const char *envval = osd_getenv(&envstr[1]);
- if (envval != nullptr)
- {
- j = strlen(envval) + strlen(tmpstr) + 1;
- osd_free(tmpstr);
- tmpstr = (char *) osd_malloc_array(j);
-
- // start with the value of $HOME
- strcpy(tmpstr, envval);
- // replace the null with a path separator again
- envstr[i] = PATHSEPCH;
- // append it
- strcat(tmpstr, &envstr[i]);
- }
- else
- fprintf(stderr, "Warning: osd_opendir environment variable %s not found.\n", envstr);
- osd_free(envstr);
- }
-
- dir->fd = opendir(tmpstr);
- dir->path = tmpstr;
-
- if (dir && (dir->fd == nullptr))
- {
- osd_free(dir->path);
- osd_free(dir);
- dir = nullptr;
- }
-
- return dir;
-}
-
-
-//============================================================
-// osd_readdir
-//============================================================
-
-const osd_directory_entry *osd_readdir(osd_directory *dir)
-{
- char *temp;
- dir->data = sdl_readdir(dir->fd);
-
- if (dir->data == nullptr)
- return nullptr;
-
- dir->ent.name = dir->data->d_name;
- temp = build_full_path(dir->path, dir->data->d_name);
- #if HAS_DT_XXX
- dir->ent.type = get_attributes_enttype(dir->data->d_type, temp);
- #else
- dir->ent.type = get_attributes_stat(temp);
- #endif
- dir->ent.size = osd_get_file_size(temp);
- osd_free(temp);
- return &dir->ent;
-}
-
-
-//============================================================
-// osd_closedir
-//============================================================
-
-void osd_closedir(osd_directory *dir)
-{
- if (dir->fd != nullptr)
- closedir(dir->fd);
- osd_free(dir->path);
- osd_free(dir);
-}
-
-
-//============================================================
-// osd_subst_env
-//============================================================
-
-void osd_subst_env(std::string &dst, std::string const &src)
-{
- std::string result, var;
- auto start = src.begin();
-
- // a leading tilde expands as $HOME
- if ((src.end() != start) && ('~' == *start))
- {
- char const *const home = std::getenv("HOME");
- if (home)
- {
- ++start;
- if ((src.end() == start) || (PATHSEPCH == *start))
- result.append(home);
- else
- result.push_back('~');
- }
- }
-
- while (src.end() != start)
- {
- // find $ marking start of environment variable or end of string
- auto it = start;
- while ((src.end() != it) && ('$' != *it)) ++it;
- if (start != it) result.append(start, it);
- start = it;
-
- if (src.end() != start)
- {
- start = ++it;
- if ((src.end() != start) && ('{' == *start))
- {
- start = ++it;
- for (++it; (src.end() != it) && ('}' != *it); ++it) { }
- if (src.end() == it)
- {
- result.append("${").append(start, it);
- start = it;
- }
- else
- {
- var.assign(start, it);
- start = ++it;
- const char *const exp = std::getenv(var.c_str());
- if (exp)
- result.append(exp);
- else
- fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
- }
- }
- else if ((src.end() != start) && (('_' == *start) || std::isalnum(*start)))
- {
- for (++it; (src.end() != it) && (('_' == *it) || std::isalnum(*it)); ++it) { }
- var.assign(start, it);
- start = it;
- const char *const exp = std::getenv(var.c_str());
- if (exp)
- result.append(exp);
- else
- fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
- }
- else
- {
- result.push_back('$');
- }
- }
- }
-
- dst = std::move(result);
-}
-
-#endif
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp
index 641667b6342..0545da64c64 100644
--- a/src/tools/romcmp.cpp
+++ b/src/tools/romcmp.cpp
@@ -448,22 +448,20 @@ static void printname(const fileinfo *file1,const fileinfo *file2,float score,in
static int load_files(int i, int *found, const char *path)
{
- osd_directory *dir;
-
/* attempt to open as a directory first */
- dir = osd_opendir(path);
- if (dir != nullptr)
+ auto dir = osd::directory::open(path);
+ if (dir)
{
- const osd_directory_entry *d;
+ const osd::directory::entry *d;
/* load all files in directory */
- while ((d = osd_readdir(dir)) != nullptr)
+ while ((d = dir->read()) != nullptr)
{
const char *d_name = d->name;
char buf[255+1];
sprintf(buf, "%s%c%s", path, PATH_DELIM, d_name);
- if (d->type == ENTTYPE_FILE)
+ if (d->type == osd::directory::entry::entry_type::FILE)
{
UINT64 size = d->size;
while (size && (size & 1) == 0) size >>= 1;
@@ -484,7 +482,7 @@ static int load_files(int i, int *found, const char *path)
}
}
}
- osd_closedir(dir);
+ dir.reset();
}
/* if not, try to open as a ZIP file */
diff --git a/src/tools/src2html.cpp b/src/tools/src2html.cpp
index 38260a62879..9d89a7d220f 100644
--- a/src/tools/src2html.cpp
+++ b/src/tools/src2html.cpp
@@ -324,7 +324,7 @@ static int compare_list_entries(const void *p1, const void *p2)
static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std::string &dstdir, std::string &tempheader, std::string &tempfooter)
{
- static const osd_dir_entry_type typelist[] = { ENTTYPE_DIR, ENTTYPE_FILE };
+ static const osd::directory::entry::entry_type typelist[] = { osd::directory::entry::entry_type::DIR, osd::directory::entry::entry_type::FILE };
// extract a normalized subpath
std::string srcdir_subpath;
@@ -344,10 +344,10 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std:
int result = 0;
for (int entindex = 0; entindex < ARRAY_LENGTH(typelist) && result == 0; entindex++)
{
- osd_dir_entry_type entry_type = typelist[entindex];
+ auto entry_type = typelist[entindex];
// open the directory and iterate through it
- osd_directory *dir = osd_opendir(srcdir.c_str());
+ auto dir = osd::directory::open(srcdir.c_str());
if (dir == nullptr)
{
result = 1;
@@ -355,10 +355,10 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std:
}
// build up the list of files
- const osd_directory_entry *entry;
+ const osd::directory::entry *entry;
int found = 0;
list_entry *list = nullptr;
- while ((entry = osd_readdir(dir)) != nullptr)
+ while ((entry = dir->read()) != nullptr)
if (entry->type == entry_type && entry->name[0] != '.')
{
auto lentry = new list_entry;
@@ -369,7 +369,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std:
}
// close the directory
- osd_closedir(dir);
+ dir.reset();
// skip if nothing found
if (found == 0)
@@ -398,7 +398,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std:
{
// add a header
if (curlist == list)
- indexfile->printf("\t<h2>%s</h2>\n\t<ul>\n", (entry_type == ENTTYPE_DIR) ? "Directories" : "Files");
+ indexfile->printf("\t<h2>%s</h2>\n\t<ul>\n", (entry_type == osd::directory::entry::entry_type::DIR) ? "Directories" : "Files");
// build the source filename
std::string srcfile;
@@ -406,7 +406,7 @@ static int recurse_dir(int srcrootlen, int dstrootlen, std::string &srcdir, std:
// if we have a file, output it
std::string dstfile;
- if (entry_type == ENTTYPE_FILE)
+ if (entry_type == osd::directory::entry::entry_type::FILE)
{
// make sure we care, first
file_type type = FILE_TYPE_INVALID;