summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/BString.h15
-rw-r--r--includes/Exceptions.h34
-rw-r--r--includes/Handle.h20
-rw-r--r--includes/Main.h2
-rw-r--r--includes/Printer.h10
-rw-r--r--includes/Task.h4
-rw-r--r--includes/TaskMan.h12
-rw-r--r--includes/msc/inttypes.h306
-rw-r--r--includes/msc/stdint.h259
-rw-r--r--msvc-config.h36
-rw-r--r--src/BString.cc2
-rw-r--r--src/Exceptions.cc11
-rw-r--r--src/Handle.cc9
-rw-r--r--src/Input.cc15
-rw-r--r--src/Output.cc15
-rw-r--r--src/Task.cc2
-rw-r--r--src/TaskMan.cc4
17 files changed, 722 insertions, 34 deletions
diff --git a/includes/BString.h b/includes/BString.h
index 0cfb8b8..9f68e9a 100644
--- a/includes/BString.h
+++ b/includes/BString.h
@@ -12,7 +12,14 @@
#include <string>
#include <vector>
-#ifdef _WIN32
+#ifdef _MSC_VER
+typedef size_t ssize_t;
+#define printfwarning(a, b)
+#else
+#define printfwarning(a, b) __attribute__((format(printf, a, b)))
+#endif
+
+#if defined(_WIN32) && !defined(_MSC_VER)
int vsscanf(const char *, const char *, va_list);
#endif
@@ -35,12 +42,12 @@ class String : private std::string {
String(const std::string & s) : std::string(s) { }
String(String && s) : std::string(s) { }
- String & set(const char * fmt, va_list) __attribute__((format(printf, 2, 0)));
- String & set(const char * fmt, ...) __attribute__((format(printf, 2, 3))) { va_list ap; va_start(ap, fmt); set(fmt, ap); va_end(ap); return *this; }
+ String & set(const char * fmt, va_list) printfwarning(2, 0);
+ String & set(const char * fmt, ...) printfwarning(2, 3) { va_list ap; va_start(ap, fmt); set(fmt, ap); va_end(ap); return *this; }
String & set(const String & fmt, ...) { va_list ap; va_start(ap, fmt); set(fmt.to_charp(), ap); va_end(ap); return *this; }
int scanf(const char * fmt, va_list ap) const { return ::vsscanf(c_str(), fmt, ap); }
- int scanf(const char * fmt, ...) const __attribute__((format(scanf, 2, 3))) { va_list ap; va_start(ap, fmt); int r = scanf(fmt, ap); va_end(ap); return r; }
+ int scanf(const char * fmt, ...) const printfwarning(2, 3) { va_list ap; va_start(ap, fmt); int r = scanf(fmt, ap); va_end(ap); return r; }
int scanf(const String & fmt, ...) const { va_list ap; va_start(ap, fmt); int r = scanf(fmt.to_charp(), ap); va_end(ap); return r; }
const char * to_charp(size_t begin = 0) const { return c_str() + begin; }
diff --git a/includes/Exceptions.h b/includes/Exceptions.h
index 729f523..d296eb1 100644
--- a/includes/Exceptions.h
+++ b/includes/Exceptions.h
@@ -2,7 +2,11 @@
#include <stdarg.h>
#include <typeinfo>
+
+#ifndef _MSC_VER
#include <cxxabi.h>
+#endif
+
#include <BString.h>
#include <vector>
@@ -56,7 +60,7 @@ class RessourceException : public GeneralException {
RessourceException(const String & msg, const char * details) : GeneralException(msg, details) { }
};
-void ExitHelper(const String & msg, const char * fmt = NULL, ...) __attribute__((format(printf, 2, 3)));
+void ExitHelper(const String & msg, const char * fmt = NULL, ...) printfwarning(2, 3);
static inline void * malloc(size_t size) {
void * r = ::malloc(size);
@@ -89,7 +93,7 @@ static inline void AssertHelperInner(const String & msg, const char * details =
throw GeneralException(msg, details);
}
-static inline void AssertHelper(const String & msg, const char * fmt, ...) __attribute__((format(printf, 2, 3)));
+static inline void AssertHelper(const String & msg, const char * fmt, ...) printfwarning(2, 3);
static inline void AssertHelper(const String & msg, const char * fmt, ...) {
String details;
@@ -115,40 +119,52 @@ static inline void TestHelper(const String & msg) throw (TestException) {
template<typename T>
ClassName::ClassName(T * ptr) {
- int status;
- m_demangled = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
+#ifdef _MSC_VER
+ m_demangled = strdup(typeid(*ptr).name());
+#else
+ int status;
+ m_demangled = abi::__cxa_demangle(typeid(*ptr).name(), 0, 0, &status);
+#endif
}
};
+#ifdef _MSC_VER
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
+#else
+#define likely(expr) __builtin_expect((expr), !0)
+#define unlikely(expr) __builtin_expect((expr), 0)
+#endif
+
#define Failure(msg) Balau::AssertHelper(msg);
#define FailureDetails(msg, ...) Balau::AssertHelper(msg, __VA_ARGS__);
-#define IAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+#define IAssert(c, ...) if (unlikely(!(c))) { \
Balau::String msg; \
msg.set("Internal Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
Balau::AssertHelper(msg, __VA_ARGS__); \
}
-#define AAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+#define AAssert(c, ...) if (unlikely(!(c))) { \
Balau::String msg; \
msg.set("API Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
Balau::AssertHelper(msg, __VA_ARGS__); \
}
-#define RAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+#define RAssert(c, ...) if (unlikely(!(c))) { \
Balau::String msg; \
msg.set("Ressource Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
Balau::ExitHelper(msg, __VA_ARGS__); \
}
-#define EAssert(c, ...) if (!__builtin_expect(!!(c), 0)) { \
+#define EAssert(c, ...) if (unlikely(!(c))) { \
Balau::String msg; \
msg.set("Execution Assertion " #c " failed at %s:%i", __FILE__, __LINE__); \
Balau::AssertHelper(msg, __VA_ARGS__); \
}
-#define TAssert(c) if (!__builtin_expect(!!(c), 0)) { \
+#define TAssert(c) if (unlikely(!(c))) { \
Balau::String msg; \
msg.set("UnitTest Assert " #c " failed at %s:%i", __FILE__, __LINE__); \
Balau::TestHelper(msg); \
diff --git a/includes/Handle.h b/includes/Handle.h
index 15415a6..941748e 100644
--- a/includes/Handle.h
+++ b/includes/Handle.h
@@ -30,6 +30,12 @@ class BaseEvent;
};
+#ifdef _MSC_VER
+#define WARN_UNUSED_RESULT
+#else
+#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#endif
+
class Handle {
public:
virtual ~Handle() { AAssert(m_refCount == 0, "Do not use handles directly; warp them in IO<>"); }
@@ -44,8 +50,8 @@ class Handle {
virtual bool canSeek();
virtual bool canRead();
virtual bool canWrite();
- virtual ssize_t read(void * buf, size_t count) throw (GeneralException) __attribute__((warn_unused_result));
- virtual ssize_t write(const void * buf, size_t count) throw (GeneralException) __attribute__((warn_unused_result));
+ virtual ssize_t read(void * buf, size_t count) throw (GeneralException) WARN_UNUSED_RESULT;
+ virtual ssize_t write(const void * buf, size_t count) throw (GeneralException) WARN_UNUSED_RESULT;
virtual void rseek(off_t offset, int whence = SEEK_SET) throw (GeneralException);
virtual void wseek(off_t offset, int whence = SEEK_SET) throw (GeneralException);
virtual off_t rtell() throw (GeneralException);
@@ -77,11 +83,11 @@ class Handle {
// these need to be changed into Future<>s
template <size_t L>
- ssize_t writeString(const char (&str)[L]) __attribute__((warn_unused_result));
- ssize_t writeString(const String & str) __attribute__((warn_unused_result)) { return forceWrite(str.to_charp(), str.strlen()); }
- ssize_t writeString(const char * str, ssize_t len) __attribute__((warn_unused_result)) { return forceWrite(str, len); }
- ssize_t forceRead(void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException) __attribute__((warn_unused_result));
- ssize_t forceWrite(const void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException) __attribute__((warn_unused_result));
+ ssize_t writeString(const char (&str)[L]) WARN_UNUSED_RESULT;
+ ssize_t writeString(const String & str) WARN_UNUSED_RESULT { return forceWrite(str.to_charp(), str.strlen()); }
+ ssize_t writeString(const char * str, ssize_t len) WARN_UNUSED_RESULT { return forceWrite(str, len); }
+ ssize_t forceRead(void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException) WARN_UNUSED_RESULT;
+ ssize_t forceWrite(const void * buf, size_t count, Events::BaseEvent * evt = NULL) throw (GeneralException) WARN_UNUSED_RESULT;
protected:
Handle() : m_refCount(0) { }
diff --git a/includes/Main.h b/includes/Main.h
index 10a27b7..7a2a001 100644
--- a/includes/Main.h
+++ b/includes/Main.h
@@ -39,7 +39,7 @@ class Main {
Main() : m_status(UNKNOWN) { IAssert(s_application == NULL, "There can't be two main apps"); s_application = this; }
static Status getStatus() { return s_application->m_status; }
int bootstrap(int _argc, char ** _argv);
- static bool hasMain() { return s_application; }
+ static bool hasMain() { return !!s_application; }
private:
Status m_status;
static Main * s_application;
diff --git a/includes/Printer.h b/includes/Printer.h
index 8494e49..d0eeab7 100644
--- a/includes/Printer.h
+++ b/includes/Printer.h
@@ -59,14 +59,14 @@ class Printer {
static Printer * getPrinter();
static void log(uint32_t level, const String & fmt, ...) { va_list ap; va_start(ap, fmt); vlog(level, fmt.to_charp(), ap); va_end(ap); }
- static void log(uint32_t level, const char * fmt, ...) __attribute__((format(printf, 2, 3))) { va_list ap; va_start(ap, fmt); vlog(level, fmt, ap); va_end(ap); }
- static void vlog(uint32_t level, const char * fmt, va_list ap) __attribute__((format(printf, 2, 0))) { getPrinter()->_log(level, fmt, ap); }
+ static void log(uint32_t level, const char * fmt, ...) printfwarning(2, 3) { va_list ap; va_start(ap, fmt); vlog(level, fmt, ap); va_end(ap); }
+ static void vlog(uint32_t level, const char * fmt, va_list ap) printfwarning(2, 0) { getPrinter()->_log(level, fmt, ap); }
static void print(const String & fmt, ...) { va_list ap; va_start(ap, fmt); vprint(fmt.to_charp(), ap); va_end(ap); }
- static void print(const char * fmt, ...) __attribute__((format(printf, 1, 2))) { va_list ap; va_start(ap, fmt); vprint(fmt, ap); va_end(ap); }
- static void vprint(const char * fmt, va_list ap) __attribute__((format(printf, 1, 0))) { getPrinter()->_print(fmt, ap); }
+ static void print(const char * fmt, ...) printfwarning(1, 2) { va_list ap; va_start(ap, fmt); vprint(fmt, ap); va_end(ap); }
+ static void vprint(const char * fmt, va_list ap) printfwarning(1, 0) { getPrinter()->_print(fmt, ap); }
#ifdef DEBUG
- static void elog(uint32_t engine, const char * fmt, ...) __attribute__((format(printf, 2, 3))) { va_list ap; va_start(ap, fmt); getPrinter()->_log(M_ENGINE_DEBUG, fmt, ap); }
+ static void elog(uint32_t engine, const char * fmt, ...) printfwarning(2, 3) { va_list ap; va_start(ap, fmt); getPrinter()->_log(M_ENGINE_DEBUG, fmt, ap); }
#else
static void elog(uint32_t engine, const char * fmt, ...) { }
#endif
diff --git a/includes/Task.h b/includes/Task.h
index a3dbb48..3d206ff 100644
--- a/includes/Task.h
+++ b/includes/Task.h
@@ -10,6 +10,10 @@
#include <Exceptions.h>
#include <Printer.h>
+#ifdef _MSC_VER
+#include <Windows.h> // for CALLBACK
+#endif
+
namespace Balau {
namespace Events { class BaseEvent; };
diff --git a/includes/TaskMan.h b/includes/TaskMan.h
index e388123..e187a56 100644
--- a/includes/TaskMan.h
+++ b/includes/TaskMan.h
@@ -5,14 +5,20 @@
#include <coro.h>
#endif
#include <ev++.h>
+#ifdef _MSC_VER
+#include <hash_set>
+#else
#include <ext/hash_set>
+#endif
#include <queue>
#include <Async.h>
#include <Threads.h>
#include <Exceptions.h>
#include <Task.h>
+#ifndef _MSC_VER
namespace gnu = __gnu_cxx;
+#endif
namespace Balau {
@@ -81,8 +87,12 @@ class TaskMan {
friend class TaskScheduler;
template<class T>
friend T * createAsyncOp(T * op);
- struct taskHasher { size_t operator()(const Task * t) const { return reinterpret_cast<uintptr_t>(t); } };
+#ifdef _MSC_VER
+ typedef stdext::hash_set<Task *> taskHash_t;
+#else
+ struct taskHasher { size_t operator()(const Task * t) const { return reinterpret_cast<uintptr_t>(t); } };
typedef gnu::hash_set<Task *, taskHasher> taskHash_t;
+#endif
taskHash_t m_tasks, m_signaledTasks;
Queue<Task> m_pendingAdd;
struct ev_loop * m_loop;
diff --git a/includes/msc/inttypes.h b/includes/msc/inttypes.h
new file mode 100644
index 0000000..ac7e32b
--- /dev/null
+++ b/includes/msc/inttypes.h
@@ -0,0 +1,306 @@
+// ISO C9x compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2013 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. 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.
+//
+// 3. Neither the name of the product nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64 // [
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else // _WIN64 ][
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64 // [
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else // _WIN64 ][
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+ imaxdiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/includes/msc/stdint.h b/includes/msc/stdint.h
new file mode 100644
index 0000000..0c7ed54
--- /dev/null
+++ b/includes/msc/stdint.h
@@ -0,0 +1,259 @@
+// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2013 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. 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.
+//
+// 3. Neither the name of the product nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+/*
+#if _MSC_VER >= 1600 // [
+#include <stdint.h>
+#else // ] _MSC_VER >= 1600 [
+*/
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
+// Check out Issue 9 for the details.
+#ifndef INTMAX_C // [
+# define INTMAX_C INT64_C
+#endif // INTMAX_C ]
+#ifndef UINTMAX_C // [
+# define UINTMAX_C UINT64_C
+#endif // UINTMAX_C ]
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+//#endif // _MSC_VER >= 1600 ]
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/msvc-config.h b/msvc-config.h
new file mode 100644
index 0000000..75474ed
--- /dev/null
+++ b/msvc-config.h
@@ -0,0 +1,36 @@
+#define WIN32
+
+#define HAVE_PROPER_ICONV
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRT_NONSTDC_NO_DEPRECATE
+
+#define HAVE_PROPER_ICONV
+
+#define PTW32_STATIC_
+#define __CLEANUP_C 1
+#define PTW32_BUILD_INLINED 1
+#define PTW32_STATIC_LIB 1
+#define HAVE_PTW32_CONFIG_H 1
+
+#define PIC 1
+
+#define STDC_HEADERS 1
+#define WORDS_LITTLEENDIAN 1
+#define CORO_LOSER 1
+#define _FILE_OFFSET_BITS 64
+#define EMBED_LIBEIO 1
+
+#define EV_STANDALONE 1
+
+#define HAVE_INTTYPES_H 1
+#define HAVE_MEMORY_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
+
+#define HAVE_FLOOR 1
+
+#define EV_STAT_ENABLE 0
diff --git a/src/BString.cc b/src/BString.cc
index bf7b4e3..57febcd 100644
--- a/src/BString.cc
+++ b/src/BString.cc
@@ -63,7 +63,7 @@ Balau::String & Balau::String::do_rtrim() {
break;
if ((i == 0) && isspace(buffer[0]))
- assign("", 0);
+ clear();
else
erase(p);
diff --git a/src/Exceptions.cc b/src/Exceptions.cc
index a9df9e6..b4646ce 100644
--- a/src/Exceptions.cc
+++ b/src/Exceptions.cc
@@ -27,11 +27,16 @@ void Balau::GeneralException::genTrace() {
for (i = 0; i < frames; i++) {
SymFromAddr(process, (DWORD64)(stack[i]), 0, symbol);
- int status;
+ int status = 0;
String line;
+#ifndef _MSC_VER
char * demangled = abi::__cxa_demangle(symbol->Name, 0, 0, &status);
- line.set("%i: 0x%08x (%s)", i, symbol->Address, status == 0 ? demangled : symbol->Name);
- free(demangled);
+#else
+ char * demangled = NULL;
+#endif
+ line.set("%i: 0x%08x (%s)", i, symbol->Address, status == 0 && demangled ? demangled : symbol->Name);
+ if (demangled)
+ free(demangled);
m_trace.push_back(line);
}
diff --git a/src/Handle.cc b/src/Handle.cc
index 1a5255d..3b40c84 100644
--- a/src/Handle.cc
+++ b/src/Handle.cc
@@ -8,6 +8,11 @@
#include "Printer.h"
#include "Async.h"
+#ifdef _MSC_VER
+#include <direct.h>
+typedef int mode_t;
+#endif
+
#ifdef _WIN32
static const char * strerror_r(int errorno, char * buf, size_t bufsize) {
#ifdef _MSVC
@@ -237,7 +242,11 @@ class AsyncOpMkdir : public Balau::AsyncOperation {
public:
AsyncOpMkdir(const char * path, mode_t mode, cbResults_t * results) : m_path(path), m_mode(mode), m_results(results) { }
virtual void run() {
+#ifdef _MSC_VER
+ int r = m_results->result = mkdir(m_path);
+#else
int r = m_results->result = mkdir(m_path, m_mode);
+#endif
m_results->errorno = r < 0 ? errno : 0;
}
virtual void done() {
diff --git a/src/Input.cc b/src/Input.cc
index 481545e..c1b7b98 100644
--- a/src/Input.cc
+++ b/src/Input.cc
@@ -3,7 +3,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#else
+#include <io.h>
+#endif
#include "Async.h"
#include "Input.h"
#include "Task.h"
@@ -35,7 +39,11 @@ class AsyncOpOpen : public Balau::AsyncOperation {
public:
AsyncOpOpen(const char * path, cbResults_t * results) : m_path(path), m_results(results) { }
virtual void run() {
+#ifdef _MSC_VER
+ const ssize_t r = m_results->result = _open(m_path, O_RDONLY);
+#else
const ssize_t r = m_results->result = open(m_path, O_RDONLY);
+#endif
m_results->errorno = r < 0 ? errno : 0;
}
virtual void done() {
@@ -182,7 +190,7 @@ void Balau::Input::close() throw (GeneralException) {
m_fd = -1;
if (cbResults->result < 0) {
char buf[4096];
- char * str = strerror_r(cbResults->errorno, buf, sizeof(buf));
+ const char * str = strerror_r(cbResults->errorno, buf, sizeof(buf));
throw GeneralException(String("Unable to close file ") + m_name + ": " + str);
}
delete cbResults;
@@ -211,7 +219,12 @@ class AsyncOpRead : public Balau::AsyncOperation {
public:
AsyncOpRead(int fd, void * buf, size_t count, off_t offset, cbResults_t * results) : m_fd(fd), m_buf(buf), m_count(count), m_offset(offset), m_results(results) { }
virtual void run() {
+#ifdef _MSC_VER
+ IAssert(0, "Not yet implemented");
+ const ssize_t r = 0;
+#else
const ssize_t r = m_results->result = pread(m_fd, m_buf, m_count, m_offset);
+#endif
m_results->errorno = r < 0 ? errno : 0;
}
virtual void done() {
diff --git a/src/Output.cc b/src/Output.cc
index 03c0d6e..261884e 100644
--- a/src/Output.cc
+++ b/src/Output.cc
@@ -3,7 +3,11 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#else
+#include <io.h>
+#endif
#include "Async.h"
#include "Output.h"
#include "Task.h"
@@ -35,7 +39,11 @@ class AsyncOpOpen : public Balau::AsyncOperation {
public:
AsyncOpOpen(const char * path, bool truncate, cbResults_t * results) : m_path(path), m_truncate(truncate), m_results(results) { }
virtual void run() {
+#ifdef _MSC_VER
+ const ssize_t r = m_results->result = _open(m_path, O_WRONLY | O_CREAT | (m_truncate ? O_TRUNC : 0), 0755);
+#else
const ssize_t r = m_results->result = open(m_path, O_WRONLY | O_CREAT | (m_truncate ? O_TRUNC : 0), 0755);
+#endif
m_results->errorno = r < 0 ? errno : 0;
}
virtual void done() {
@@ -182,7 +190,7 @@ void Balau::Output::close() throw (GeneralException) {
m_fd = -1;
if (cbResults->result < 0) {
char buf[4096];
- char * str = strerror_r(cbResults->errorno, buf, sizeof(buf));
+ const char * str = strerror_r(cbResults->errorno, buf, sizeof(buf));
throw GeneralException(String("Unable to close file ") + m_name + ": " + str);
}
delete cbResults;
@@ -211,7 +219,12 @@ class AsyncOpWrite : public Balau::AsyncOperation {
public:
AsyncOpWrite(int fd, const void * buf, size_t count, off_t offset, cbResults_t * results) : m_fd(fd), m_buf(buf), m_count(count), m_offset(offset), m_results(results) { }
virtual void run() {
+#ifdef _MSC_VER
+ IAssert(0, "Not yet implemented");
+ const ssize_t r = 0;
+#else
const ssize_t r = m_results->result = pwrite(m_fd, m_buf, m_count, m_offset);
+#endif
m_results->errorno = r < 0 ? errno : 0;
}
virtual void done() {
diff --git a/src/Task.cc b/src/Task.cc
index b294fa9..9bf7c5b 100644
--- a/src/Task.cc
+++ b/src/Task.cc
@@ -30,7 +30,7 @@ void Balau::Task::setup(TaskMan * taskMan, void * stack) {
m_stack = stack;
coro_create(&m_ctx, coroutineTrampoline, this, m_stack, size);
#else
- Assert(!stack, "We shouldn't allocate stacks with Fibers");
+ IAssert(!stack, "We shouldn't allocate stacks with Fibers");
m_stack = NULL;
m_fiber = CreateFiber(size, coroutineTrampoline, this);
#endif
diff --git a/src/TaskMan.cc b/src/TaskMan.cc
index 71d5bc6..03801a3 100644
--- a/src/TaskMan.cc
+++ b/src/TaskMan.cc
@@ -5,6 +5,10 @@
#include "Main.h"
#include "Local.h"
+#ifdef _MSC_VER
+#include <Windows.h>
+#endif
+
static Balau::AsyncManager s_async;
namespace {