aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-06-29 21:17:43 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-01 16:01:31 +0300
commitbac02200267495741e85db90607186ce4e0593b3 (patch)
treed01cd65d0019a7be916c3c8a5d9f4780f91afdb1
parente0b126d8c7f691856ec4d80bb57cb1ba5c71fd69 (diff)
Port to MSVC
-rw-r--r--butl/filesystem11
-rw-r--r--butl/filesystem.cxx40
-rw-r--r--butl/process.cxx9
-rw-r--r--tests/base64/driver.cxx7
-rw-r--r--tests/timestamp/driver.cxx10
5 files changed, 67 insertions, 10 deletions
diff --git a/butl/filesystem b/butl/filesystem
index 565f465..780779f 100644
--- a/butl/filesystem
+++ b/butl/filesystem
@@ -5,14 +5,21 @@
#ifndef BUTL_FILESYSTEM
#define BUTL_FILESYSTEM
-#include <sys/types.h> // mode_t
-
#ifndef _WIN32
# include <dirent.h> // DIR
#else
# include <stddef.h> // intptr_t
#endif
+// VC's sys/types.h header file doesn't define mode_t type. So let's define it
+// ourselves according to the POSIX specification.
+//
+#ifndef _MSC_VER
+# include <sys/types.h> // mode_t
+#else
+ typedef int mode_t;
+#endif
+
#include <cstddef> // ptrdiff_t
#include <cstdint> // uint16_t
#include <utility> // move()
diff --git a/butl/filesystem.cxx b/butl/filesystem.cxx
index c3d21cd..0ff0e28 100644
--- a/butl/filesystem.cxx
+++ b/butl/filesystem.cxx
@@ -5,34 +5,45 @@
#include <butl/filesystem>
#ifndef _WIN32
-# include <dirent.h> // struct dirent, *dir()
-# include <unistd.h> // symlink(), link()
+# include <dirent.h> // struct dirent, *dir()
+# include <unistd.h> // symlink(), link(), stat(), rmdir(), unlink()
+# include <sys/types.h> // stat
+# include <sys/stat.h> // stat(), lstat(), S_IS*, mkdir()
#else
# include <butl/win32-utility>
-# include <io.h> // _find*()
-# include <direct.h> // _mkdir()
+# include <io.h> // _find*(), _unlink()
+# include <direct.h> // _mkdir(), _rmdir()
+# include <sys/types.h> // _stat
+# include <sys/stat.h> // _stat(), S_IF*
# include <cassert>
#endif
-#include <errno.h> // errno, E*
-#include <unistd.h> // stat, rmdir(), unlink()
-#include <sys/types.h> // stat
-#include <sys/stat.h> // stat(), lstat(), S_IS*, mkdir()
+#include <errno.h> // errno, E*
#include <memory> // unique_ptr
#include <system_error>
using namespace std;
+#ifdef _MSC_VER // Unlikely to be fixed in newer versions.
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
namespace butl
{
bool
dir_exists (const path& p)
{
+#ifndef _WIN32
struct stat s;
if (stat (p.string ().c_str (), &s) != 0)
+#else
+ struct _stat s;
+ if (_stat (p.string ().c_str (), &s) != 0)
+#endif
{
if (errno == ENOENT || errno == ENOTDIR)
return false;
@@ -46,8 +57,13 @@ namespace butl
bool
file_exists (const path& p)
{
+#ifndef _WIN32
struct stat s;
if (stat (p.string ().c_str (), &s) != 0)
+#else
+ struct _stat s;
+ if (_stat (p.string ().c_str (), &s) != 0)
+#endif
{
if (errno == ENOENT || errno == ENOTDIR)
return false;
@@ -102,7 +118,11 @@ namespace butl
{
rmdir_status r (rmdir_status::success);
+#ifndef _WIN32
if (rmdir (p.string ().c_str ()) != 0)
+#else
+ if (_rmdir (p.string ().c_str ()) != 0)
+#endif
{
if (errno == ENOENT)
r = rmdir_status::not_exist;
@@ -146,7 +166,11 @@ namespace butl
{
rmfile_status r (rmfile_status::success);
+#ifndef _WIN32
if (unlink (p.string ().c_str ()) != 0)
+#else
+ if (_unlink (p.string ().c_str ()) != 0)
+#endif
{
if (errno == ENOENT || errno == ENOTDIR)
r = rmfile_status::not_exist;
diff --git a/butl/process.cxx b/butl/process.cxx
index aaab915..e67e12e 100644
--- a/butl/process.cxx
+++ b/butl/process.cxx
@@ -32,6 +32,15 @@ using namespace std;
using namespace butl::win32;
#endif
+#ifdef _MSC_VER // Unlikely to be fixed in newer versions.
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+
+# define STDIN_FILENO 0
+# define STDOUT_FILENO 1
+# define STDERR_FILENO 2
+#endif // _MSC_VER
+
namespace butl
{
class auto_fd
diff --git a/tests/base64/driver.cxx b/tests/base64/driver.cxx
index e43e04a..a65ddbb 100644
--- a/tests/base64/driver.cxx
+++ b/tests/base64/driver.cxx
@@ -23,6 +23,13 @@ encode (const string& i, const string& o)
if (r)
{
is.seekg (0);
+
+ // VC 19 seekg() doesn't clear eofbit.
+ //
+#if defined(_MSC_VER) && _MSC_VER <= 1900
+ is.clear ();
+#endif
+
ostringstream os;
base64_encode (os, is);
r = os.str () == o && is.eof ();
diff --git a/tests/timestamp/driver.cxx b/tests/timestamp/driver.cxx
index f5f30b9..e732629 100644
--- a/tests/timestamp/driver.cxx
+++ b/tests/timestamp/driver.cxx
@@ -108,7 +108,17 @@ main ()
// Invalid input (%[] unrelated).
//
assert (fail ("Apr 08 19:31:10.123456789 ABC", "%b %d %H:%M:%S%[.N] %Y"));
+
+// This doesn't work in VC 19 because their implementation of std::get_time()
+// has a bug. Due to this bug std::get_time() parses the input
+// "Apr 19:31:10 2016" for the format "%b %d %H:%M:%S %Y" as if the input were
+// "Apr 19 00:31:10 2016".
+//
+#if !defined(_MSC_VER) || _MSC_VER > 1900
assert (fail ("Apr 19:31:10 2016", "%b %d %H:%M:%S %Y"));
+ assert (fail (":31 2016", "%H:%M %Y"));
+#endif
+
assert (fail ("Opr 08 19:31:10 2016", "%b %d %H:%M:%S %Y"));
// Parse valid input with a valid format.