diff --git a/dll.vcxproj b/dll.vcxproj
index 4f9b4f50..4443f553 100644
--- a/dll.vcxproj
+++ b/dll.vcxproj
@@ -28,23 +28,27 @@
DynamicLibrary
true
v140
+ MultiByte
DynamicLibrary
false
v140
true
+ MultiByte
DynamicLibrary
true
v140
+ MultiByte
DynamicLibrary
false
v140
true
+ MultiByte
@@ -68,14 +72,20 @@
true
$(Platform)\$(Configuration)\
$(SolutionDir)$(Platform)\$(Configuration)\
+ mdbx
false
$(Platform)\$(Configuration)\
$(SolutionDir)$(Platform)\$(Configuration)\
+ mdbx
false
+ mdbx
+
+
+ mdbx
diff --git a/mdbx.h b/mdbx.h
index 160bef64..3f010c4a 100644
--- a/mdbx.h
+++ b/mdbx.h
@@ -83,6 +83,7 @@ typedef SSIZE_T ssize_t;
#define MDBX_ENOSYS ERROR_NOT_SUPPORTED
#define MDBX_EIO ERROR_WRITE_FAULT
#define MDBX_EPERM ERROR_INVALID_FUNCTION
+#define MDBX_EINTR ERROR_CANCELLED
#else
@@ -102,6 +103,7 @@ typedef pthread_t mdbx_tid_t;
#define MDBX_ENOSYS ENOSYS
#define MDBX_EIO EIO
#define MDBX_EPERM EPERM
+#define MDBX_EINTR EINTR
#endif
#ifdef _MSC_VER
diff --git a/mdbx.sln b/mdbx.sln
index aa2025d8..a32249d7 100644
--- a/mdbx.sln
+++ b/mdbx.sln
@@ -7,6 +7,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test\test.vcxproj",
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dll", "dll.vcxproj", "{6D19209B-ECE7-4B9C-941C-0AA2B484F199}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0A147F9F-22D5-44E6-B389-218CFFB0C524}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_load", "src\tools\mdbx_load.vcxproj", "{15030120-5F7F-48F9-ABE5-DFC814F2A4BB}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_dump", "src\tools\mdbx_dump.vcxproj", "{15030120-5F7F-48F9-ABE5-DFC814F2A4BC}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_copy", "src\tools\mdbx_copy.vcxproj", "{15030120-5F7F-48F9-ABE5-DFC814F2A4BD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_chk", "src\tools\mdbx_chk.vcxproj", "{15030120-5F7F-48F9-ABE5-DFC814F2A4BE}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mdbx_stat", "src\tools\mdbx_stat.vcxproj", "{15030120-5F7F-48F9-ABE5-DFC814F2A4BF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -15,14 +27,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x64.ActiveCfg = Debug|x64
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x64.Build.0 = Debug|x64
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x86.ActiveCfg = Debug|Win32
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x86.Build.0 = Debug|Win32
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x64.ActiveCfg = Release|x64
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x64.Build.0 = Release|x64
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x86.ActiveCfg = Release|Win32
- {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x86.Build.0 = Release|Win32
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Debug|x64.ActiveCfg = Debug|x64
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Debug|x64.Build.0 = Debug|x64
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Debug|x86.ActiveCfg = Debug|Win32
@@ -31,8 +35,63 @@ Global
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Release|x64.Build.0 = Release|x64
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Release|x86.ActiveCfg = Release|Win32
{30E29CE6-E6FC-4D32-AA07-46A55FAF3A31}.Release|x86.Build.0 = Release|Win32
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x64.ActiveCfg = Debug|x64
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x64.Build.0 = Debug|x64
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x86.ActiveCfg = Debug|Win32
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Debug|x86.Build.0 = Debug|Win32
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x64.ActiveCfg = Release|x64
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x64.Build.0 = Release|x64
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x86.ActiveCfg = Release|Win32
+ {6D19209B-ECE7-4B9C-941C-0AA2B484F199}.Release|x86.Build.0 = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Debug|x64.ActiveCfg = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Debug|x64.Build.0 = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Debug|x86.ActiveCfg = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Debug|x86.Build.0 = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Release|x64.ActiveCfg = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Release|x64.Build.0 = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Release|x86.ActiveCfg = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}.Release|x86.Build.0 = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Debug|x64.ActiveCfg = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Debug|x64.Build.0 = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Debug|x86.ActiveCfg = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Debug|x86.Build.0 = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Release|x64.ActiveCfg = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Release|x64.Build.0 = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Release|x86.ActiveCfg = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}.Release|x86.Build.0 = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Debug|x64.ActiveCfg = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Debug|x64.Build.0 = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Debug|x86.ActiveCfg = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Debug|x86.Build.0 = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Release|x64.ActiveCfg = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Release|x64.Build.0 = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Release|x86.ActiveCfg = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}.Release|x86.Build.0 = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Debug|x64.ActiveCfg = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Debug|x64.Build.0 = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Debug|x86.ActiveCfg = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Debug|x86.Build.0 = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Release|x64.ActiveCfg = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Release|x64.Build.0 = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Release|x86.ActiveCfg = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}.Release|x86.Build.0 = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Debug|x64.ActiveCfg = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Debug|x64.Build.0 = Debug|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Debug|x86.ActiveCfg = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Debug|x86.Build.0 = Debug|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Release|x64.ActiveCfg = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Release|x64.Build.0 = Release|x64
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Release|x86.ActiveCfg = Release|Win32
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB} = {0A147F9F-22D5-44E6-B389-218CFFB0C524}
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC} = {0A147F9F-22D5-44E6-B389-218CFFB0C524}
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD} = {0A147F9F-22D5-44E6-B389-218CFFB0C524}
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE} = {0A147F9F-22D5-44E6-B389-218CFFB0C524}
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF} = {0A147F9F-22D5-44E6-B389-218CFFB0C524}
+ EndGlobalSection
EndGlobal
diff --git a/src/tools/mdbx_chk.c b/src/tools/mdbx_chk.c
index ccc0592b..92eff1aa 100644
--- a/src/tools/mdbx_chk.c
+++ b/src/tools/mdbx_chk.c
@@ -13,19 +13,13 @@
* top-level directory of the distribution or, alternatively, at
* . */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+#ifdef _MSC_VER
+#if _MSC_VER > 1800
+#pragma warning(disable : 4464) /* relative include path contains '..' */
+#endif
+#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
+#endif /* _MSC_VER */
-#include "../../mdbx.h"
#include "../bits.h"
typedef struct flagbit {
@@ -41,13 +35,26 @@ flagbit dbflags[] = {{MDBX_DUPSORT, "dupsort"},
{MDBX_INTEGERDUP, "integerdup"},
{0, NULL}};
-static volatile sig_atomic_t gotsignal;
+#if defined(_WIN32) || defined(_WIN64)
+#include "wingetopt.h"
+static volatile BOOL user_break;
+static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
+ (void)dwCtrlType;
+ user_break = true;
+ return true;
+}
+
+#else /* WINDOWS */
+
+static volatile sig_atomic_t user_break;
static void signal_handler(int sig) {
(void)sig;
- gotsignal = 1;
+ user_break = 1;
}
+#endif /* !WINDOWS */
+
#define EXIT_INTERRUPTED (EXIT_FAILURE + 4)
#define EXIT_FAILURE_SYS (EXIT_FAILURE + 3)
#define EXIT_FAILURE_MDB (EXIT_FAILURE + 2)
@@ -65,10 +72,6 @@ struct {
uint64_t pgcount;
} walk;
-static __attribute__((constructor)) void init_walk(void) {
- walk.dbi_names[0] = "@gc";
-}
-
uint64_t total_unused_bytes;
int exclusive = 2;
int envflags = MDBX_RDONLY;
@@ -91,7 +94,11 @@ struct problem {
struct problem *problems_list;
uint64_t total_problems;
-static void __attribute__((format(printf, 1, 2))) print(const char *msg, ...) {
+static void
+#ifdef __GNU__
+ __attribute__((format(printf, 1, 2)))
+#endif
+ print(const char *msg, ...) {
if (!quiet) {
va_list args;
@@ -102,7 +109,11 @@ static void __attribute__((format(printf, 1, 2))) print(const char *msg, ...) {
}
}
-static void __attribute__((format(printf, 1, 2))) error(const char *msg, ...) {
+static void
+#ifdef __GNU__
+ __attribute__((format(printf, 1, 2)))
+#endif
+ error(const char *msg, ...) {
total_problems++;
if (!quiet) {
@@ -232,7 +243,7 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx,
size_t page_size = (size_t)pgnumber * envstat.ms_psize;
int index = pagemap_lookup_dbi(dbi);
if (index < 0)
- return ENOMEM;
+ return MDBX_ENOMEM;
if (verbose > 2 && (!only_subdb || strcmp(only_subdb, dbi) == 0)) {
if (pgnumber == 1)
@@ -290,7 +301,7 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx,
problem_add("page", pgno, "already used", "in %s",
walk.dbi_names[walk.pagemap[pgno]]);
else {
- walk.pagemap[pgno] = index;
+ walk.pagemap[pgno] = (short)index;
walk.dbi_pages[index] += 1;
}
++pgno;
@@ -298,12 +309,12 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx,
}
}
- return gotsignal ? EINTR : MDBX_SUCCESS;
+ return user_break ? MDBX_EINTR : MDBX_SUCCESS;
}
typedef int(visitor)(const uint64_t record_number, const MDBX_val *key,
const MDBX_val *data);
-static int process_db(MDBX_dbi dbi, char *name, visitor *handler, int silent);
+static int process_db(MDBX_dbi dbi, char *name, visitor *handler, bool silent);
static int handle_userdb(const uint64_t record_number, const MDBX_val *key,
const MDBX_val *data) {
@@ -398,7 +409,7 @@ static int handle_maindb(const uint64_t record_number, const MDBX_val *key,
name[key->iov_len] = '\0';
userdb_count++;
- rc = process_db(-1, name, handle_userdb, 0);
+ rc = process_db(~0u, name, handle_userdb, false);
free(name);
if (rc != MDBX_INCOMPATIBLE)
return rc;
@@ -406,7 +417,7 @@ static int handle_maindb(const uint64_t record_number, const MDBX_val *key,
return handle_userdb(record_number, key, data);
}
-static int process_db(MDBX_dbi dbi, char *name, visitor *handler, int silent) {
+static int process_db(MDBX_dbi dbi, char *name, visitor *handler, bool silent) {
MDBX_cursor *mc;
MDBX_stat ms;
MDBX_val key, data;
@@ -419,7 +430,7 @@ static int process_db(MDBX_dbi dbi, char *name, visitor *handler, int silent) {
uint64_t record_count = 0, dups = 0;
uint64_t key_bytes = 0, data_bytes = 0;
- if (0 > (int)dbi) {
+ if (dbi == ~0u) {
rc = mdbx_dbi_open(txn, name, 0, &dbi);
if (rc) {
if (!name ||
@@ -489,10 +500,10 @@ static int process_db(MDBX_dbi dbi, char *name, visitor *handler, int silent) {
prev_data.iov_len = 0;
rc = mdbx_cursor_get(mc, &key, &data, MDBX_FIRST);
while (rc == MDBX_SUCCESS) {
- if (gotsignal) {
+ if (user_break) {
print(" - interrupted by signal\n");
fflush(NULL);
- rc = EINTR;
+ rc = MDBX_EINTR;
goto bailout;
}
@@ -744,16 +755,22 @@ int main(int argc, char *argv[]) {
char *envname;
int problems_maindb = 0, problems_freedb = 0, problems_meta = 0;
int dont_traversal = 0;
- struct timespec timestamp_start, timestamp_finish;
+
double elapsed;
-
- atexit(pagemap_cleanup);
-
+#if defined(_WIN32) || defined(_WIN64)
+ uint64_t timestamp_start, timestamp_finish;
+ timestamp_start = GetTickCount64();
+#else
+ struct timespec timestamp_start, timestamp_finish;
if (clock_gettime(CLOCK_MONOTONIC, ×tamp_start)) {
rc = errno;
error("clock_gettime failed, error %d %s\n", rc, mdbx_strerror(rc));
return EXIT_FAILURE_SYS;
}
+#endif
+
+ walk.dbi_names[0] = "@gc";
+ atexit(pagemap_cleanup);
if (argc < 2) {
usage(prog);
@@ -797,6 +814,9 @@ int main(int argc, char *argv[]) {
if (optind != argc - 1)
usage(prog);
+#if defined(_WIN32) || defined(_WIN64)
+ SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
+#else
#ifdef SIGPIPE
signal(SIGPIPE, signal_handler);
#endif
@@ -805,6 +825,7 @@ int main(int argc, char *argv[]) {
#endif
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
+#endif /* !WINDOWS */
envname = argv[optind];
print("Running mdbx_chk for '%s' in %s mode...\n", envname,
@@ -933,14 +954,14 @@ int main(int argc, char *argv[]) {
if (!dont_traversal) {
struct problem *saved_list;
- size_t traversal_problems;
- size_t empty_pages, lost_bytes;
+ uint64_t traversal_problems;
+ uint64_t empty_pages, lost_bytes;
print("Traversal b-tree by txn#%" PRIaTXN "...\n", txn->mt_txnid);
fflush(NULL);
- walk.pagemap = calloc(lastpgno, sizeof(*walk.pagemap));
+ walk.pagemap = calloc((size_t)lastpgno, sizeof(*walk.pagemap));
if (!walk.pagemap) {
- rc = errno ? errno : ENOMEM;
+ rc = errno ? errno : MDBX_ENOMEM;
error("calloc failed, error %d %s\n", rc, mdbx_strerror(rc));
goto bailout;
}
@@ -950,7 +971,7 @@ int main(int argc, char *argv[]) {
traversal_problems = problems_pop(saved_list);
if (rc) {
- if (rc == EINTR && gotsignal) {
+ if (rc == MDBX_EINTR && user_break) {
print(" - interrupted by signal\n");
fflush(NULL);
} else {
@@ -1017,8 +1038,8 @@ int main(int argc, char *argv[]) {
if (!verbose)
print("Iterating DBIs...\n");
- problems_maindb = process_db(-1, /* MAIN_DBI */ NULL, NULL, 0);
- problems_freedb = process_db(0 /* FREE_DBI */, "free", handle_freedb, 0);
+ problems_maindb = process_db(~0u, /* MAIN_DBI */ NULL, NULL, false);
+ problems_freedb = process_db(FREE_DBI, "free", handle_freedb, false);
if (verbose) {
uint64_t value = envinfo.me_mapsize / envstat.ms_psize;
@@ -1064,7 +1085,7 @@ int main(int argc, char *argv[]) {
"monopolistic or write-lock mode only)\n");
}
- if (!process_db(-1, NULL, handle_maindb, 1)) {
+ if (!process_db(MAIN_DBI, NULL, handle_maindb, true)) {
if (!userdb_count && verbose)
print(" - does not contain multiple databases\n");
}
@@ -1080,18 +1101,22 @@ bailout:
fflush(NULL);
if (rc) {
if (rc < 0)
- return gotsignal ? EXIT_INTERRUPTED : EXIT_FAILURE_SYS;
+ return (user_break) ? EXIT_INTERRUPTED : EXIT_FAILURE_SYS;
return EXIT_FAILURE_MDB;
}
+#if defined(_WIN32) || defined(_WIN64)
+ timestamp_finish = GetTickCount64();
+ elapsed = (timestamp_finish - timestamp_start) * 1e-3;
+#else
if (clock_gettime(CLOCK_MONOTONIC, ×tamp_finish)) {
rc = errno;
error("clock_gettime failed, error %d %s\n", rc, mdbx_strerror(rc));
return EXIT_FAILURE_SYS;
}
-
elapsed = timestamp_finish.tv_sec - timestamp_start.tv_sec +
(timestamp_finish.tv_nsec - timestamp_start.tv_nsec) * 1e-9;
+#endif /* !WINDOWS */
total_problems += problems_meta;
if (total_problems || problems_maindb || problems_freedb) {
diff --git a/src/tools/mdbx_chk.vcxproj b/src/tools/mdbx_chk.vcxproj
new file mode 100644
index 00000000..bece9d2b
--- /dev/null
+++ b/src/tools/mdbx_chk.vcxproj
@@ -0,0 +1,162 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BE}
+ Win32Proj
+ mdbx_chk
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ {6d19209b-ece7-4b9c-941c-0aa2b484f199}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/mdbx_copy.c b/src/tools/mdbx_copy.c
index 9295c7ff..2e384cac 100644
--- a/src/tools/mdbx_copy.c
+++ b/src/tools/mdbx_copy.c
@@ -13,13 +13,34 @@
* top-level directory of the distribution or, alternatively, at
* . */
-#include "../../mdbx.h"
-#include
-#include
-#include
-#include
+#ifdef _MSC_VER
+#if _MSC_VER > 1800
+#pragma warning(disable : 4464) /* relative include path contains '..' */
+#endif
+#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
+#endif /* _MSC_VER */
-static void sighandle(int sig) { (void)sig; }
+#include "../bits.h"
+
+#if defined(_WIN32) || defined(_WIN64)
+#include "wingetopt.h"
+
+static volatile BOOL user_break;
+static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
+ (void)dwCtrlType;
+ user_break = true;
+ return true;
+}
+
+#else /* WINDOWS */
+
+static volatile sig_atomic_t user_break;
+static void signal_handler(int sig) {
+ (void)sig;
+ user_break = 1;
+}
+
+#endif /* !WINDOWS */
int main(int argc, char *argv[]) {
int rc;
@@ -46,14 +67,18 @@ int main(int argc, char *argv[]) {
exit(EXIT_FAILURE);
}
+#if defined(_WIN32) || defined(_WIN64)
+ SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
+#else
#ifdef SIGPIPE
- signal(SIGPIPE, sighandle);
+ signal(SIGPIPE, signal_handler);
#endif
#ifdef SIGHUP
- signal(SIGHUP, sighandle);
+ signal(SIGHUP, signal_handler);
#endif
- signal(SIGINT, sighandle);
- signal(SIGTERM, sighandle);
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+#endif /* !WINDOWS */
act = "opening environment";
rc = mdbx_env_create(&env);
@@ -62,9 +87,15 @@ int main(int argc, char *argv[]) {
}
if (rc == MDBX_SUCCESS) {
act = "copying";
- if (argc == 2)
- rc = mdbx_env_copy2fd(env, STDOUT_FILENO, cpflags);
- else
+ if (argc == 2) {
+ mdbx_filehandle_t fd;
+#if defined(_WIN32) || defined(_WIN64)
+ fd = GetStdHandle(STD_OUTPUT_HANDLE);
+#else
+ fd = fileno(stdout);
+#endif
+ rc = mdbx_env_copy2fd(env, fd, cpflags);
+ } else
rc = mdbx_env_copy(env, argv[2], cpflags);
}
if (rc)
diff --git a/src/tools/mdbx_copy.vcxproj b/src/tools/mdbx_copy.vcxproj
new file mode 100644
index 00000000..b3b52dc2
--- /dev/null
+++ b/src/tools/mdbx_copy.vcxproj
@@ -0,0 +1,162 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BD}
+ Win32Proj
+ mdbx_copy
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ {6d19209b-ece7-4b9c-941c-0aa2b484f199}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/mdbx_dump.c b/src/tools/mdbx_dump.c
index 726cc5d0..c9fb6f20 100644
--- a/src/tools/mdbx_dump.c
+++ b/src/tools/mdbx_dump.c
@@ -13,15 +13,15 @@
* top-level directory of the distribution or, alternatively, at
* . */
-#include "../../mdbx.h"
+#ifdef _MSC_VER
+#if _MSC_VER > 1800
+#pragma warning(disable : 4464) /* relative include path contains '..' */
+#endif
+#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
+#endif /* _MSC_VER */
+
+#include "../bits.h"
#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#define PRINT 1
static int mode;
@@ -39,16 +39,29 @@ flagbit dbflags[] = {{MDBX_REVERSEKEY, "reversekey"},
{MDBX_REVERSEDUP, "reversedup"},
{0, NULL}};
-static volatile sig_atomic_t gotsig;
+#if defined(_WIN32) || defined(_WIN64)
+#include "wingetopt.h"
-static void dumpsig(int sig) {
- (void)sig;
- gotsig = 1;
+static volatile BOOL user_break;
+static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
+ (void)dwCtrlType;
+ user_break = true;
+ return true;
}
+#else /* WINDOWS */
+
+static volatile sig_atomic_t user_break;
+static void signal_handler(int sig) {
+ (void)sig;
+ user_break = 1;
+}
+
+#endif /* !WINDOWS */
+
static const char hexc[] = "0123456789abcdef";
-static void hex(unsigned char c) {
+static void dumpbyte(unsigned char c) {
putchar(hexc[c >> 4]);
putchar(hexc[c & 0xf]);
}
@@ -60,25 +73,25 @@ static void text(MDBX_val *v) {
c = v->iov_base;
end = c + v->iov_len;
while (c < end) {
- if (isprint(*c)) {
+ if (isprint(*c) && *c != '\\') {
putchar(*c);
} else {
putchar('\\');
- hex(*c);
+ dumpbyte(*c);
}
c++;
}
putchar('\n');
}
-static void byte(MDBX_val *v) {
+static void dumpval(MDBX_val *v) {
unsigned char *c, *end;
putchar(' ');
c = v->iov_base;
end = c + v->iov_len;
while (c < end) {
- hex(*c++);
+ dumpbyte(*c++);
}
putchar('\n');
}
@@ -124,16 +137,16 @@ static int dumpit(MDBX_txn *txn, MDBX_dbi dbi, char *name) {
return rc;
while ((rc = mdbx_cursor_get(mc, &key, &data, MDBX_NEXT)) == MDBX_SUCCESS) {
- if (gotsig) {
- rc = EINTR;
+ if (user_break) {
+ rc = MDBX_EINTR;
break;
}
if (mode & PRINT) {
text(&key);
text(&data);
} else {
- byte(&key);
- byte(&data);
+ dumpval(&key);
+ dumpval(&data);
}
}
printf("DATA=END\n");
@@ -212,14 +225,18 @@ int main(int argc, char *argv[]) {
if (optind != argc - 1)
usage(prog);
+#if defined(_WIN32) || defined(_WIN64)
+ SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
+#else
#ifdef SIGPIPE
- signal(SIGPIPE, dumpsig);
+ signal(SIGPIPE, signal_handler);
#endif
#ifdef SIGHUP
- signal(SIGHUP, dumpsig);
+ signal(SIGHUP, signal_handler);
#endif
- signal(SIGINT, dumpsig);
- signal(SIGTERM, dumpsig);
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+#endif /* !WINDOWS */
envname = argv[optind];
rc = mdbx_env_create(&env);
@@ -265,6 +282,10 @@ int main(int argc, char *argv[]) {
goto txn_abort;
}
while ((rc = mdbx_cursor_get(cursor, &key, NULL, MDBX_NEXT_NODUP)) == 0) {
+ if (user_break) {
+ rc = MDBX_EINTR;
+ break;
+ }
char *str;
MDBX_dbi db2;
if (memchr(key.iov_base, '\0', key.iov_len))
diff --git a/src/tools/mdbx_dump.vcxproj b/src/tools/mdbx_dump.vcxproj
new file mode 100644
index 00000000..8d4280c7
--- /dev/null
+++ b/src/tools/mdbx_dump.vcxproj
@@ -0,0 +1,162 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BC}
+ Win32Proj
+ mdbx_dump
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ {6d19209b-ece7-4b9c-941c-0aa2b484f199}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/mdbx_load.c b/src/tools/mdbx_load.c
index 5089efb0..91c1bfae 100644
--- a/src/tools/mdbx_load.c
+++ b/src/tools/mdbx_load.c
@@ -13,32 +13,49 @@
* top-level directory of the distribution or, alternatively, at
* . */
-#include "../../mdbx.h"
+#ifdef _MSC_VER
+#if _MSC_VER > 1800
+#pragma warning(disable : 4464) /* relative include path contains '..' */
+#endif
+#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
+#endif /* _MSC_VER */
+
+#include "../bits.h"
#include
-#include
-#include
-#include
-#include
-#include
-#include
+
+#if defined(_WIN32) || defined(_WIN64)
+#include "wingetopt.h"
+
+static volatile BOOL user_break;
+static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
+ (void)dwCtrlType;
+ user_break = true;
+ return true;
+}
+
+#else /* WINDOWS */
+
+static volatile sig_atomic_t user_break;
+static void signal_handler(int sig) {
+ (void)sig;
+ user_break = 1;
+}
+
+#endif /* !WINDOWS */
#define PRINT 1
#define NOHDR 2
static int mode;
static char *subname = NULL;
-
static size_t lineno;
static int version;
static int dbi_flags;
-
static char *prog;
-
static int Eof;
static MDBX_envinfo envinfo;
-
static MDBX_val kbuf, dbuf;
#define STRLENOF(s) (sizeof(s) - 1)
@@ -63,7 +80,7 @@ static void readhdr(void) {
char *ptr;
dbi_flags = 0;
- while (fgets(dbuf.iov_base, dbuf.iov_len, stdin) != NULL) {
+ while (fgets(dbuf.iov_base, (int)dbuf.iov_len, stdin) != NULL) {
lineno++;
if (!strncmp(dbuf.iov_base, "db_pagesize=", STRLENOF("db_pagesize=")) ||
!strncmp(dbuf.iov_base, "duplicates=", STRLENOF("duplicates="))) {
@@ -197,7 +214,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
}
if (c != ' ') {
lineno++;
- if (fgets(buf->iov_base, buf->iov_len, stdin) == NULL) {
+ if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) {
badend:
Eof = 1;
badend();
@@ -208,7 +225,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
goto badend;
}
}
- if (fgets(buf->iov_base, buf->iov_len, stdin) == NULL) {
+ if (fgets(buf->iov_base, (int)buf->iov_len, stdin) == NULL) {
Eof = 1;
return EOF;
}
@@ -229,7 +246,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
}
c1 = buf->iov_base;
c1 += l2;
- if (fgets((char *)c1, buf->iov_len + 1, stdin) == NULL) {
+ if (fgets((char *)c1, (int)buf->iov_len + 1, stdin) == NULL) {
Eof = 1;
badend();
return EOF;
@@ -255,7 +272,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
badend();
return EOF;
}
- *c1++ = unhex(++c2);
+ *c1++ = (char)unhex(++c2);
c2 += 2;
}
} else {
@@ -276,7 +293,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
badend();
return EOF;
}
- *c1++ = unhex(c2);
+ *c1++ = (char)unhex(c2);
c2 += 2;
}
}
@@ -294,11 +311,11 @@ static void usage(void) {
int main(int argc, char *argv[]) {
int i, rc;
- MDBX_env *env;
- MDBX_txn *txn;
- MDBX_cursor *mc;
+ MDBX_env *env = NULL;
+ MDBX_txn *txn = NULL;
+ MDBX_cursor *mc = NULL;
MDBX_dbi dbi;
- char *envname;
+ char *envname = NULL;
int envflags = 0, putflags = 0;
prog = argv[0];
@@ -347,6 +364,19 @@ int main(int argc, char *argv[]) {
if (optind != argc - 1)
usage();
+#if defined(_WIN32) || defined(_WIN64)
+ SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
+#else
+#ifdef SIGPIPE
+ signal(SIGPIPE, signal_handler);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, signal_handler);
+#endif
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+#endif /* !WINDOWS */
+
dbuf.iov_len = 4096;
dbuf.iov_base = malloc(dbuf.iov_len);
@@ -366,8 +396,14 @@ int main(int argc, char *argv[]) {
if (envinfo.me_maxreaders)
mdbx_env_set_maxreaders(env, envinfo.me_maxreaders);
- if (envinfo.me_mapsize)
- mdbx_env_set_mapsize(env, envinfo.me_mapsize);
+ if (envinfo.me_mapsize) {
+ if (envinfo.me_mapsize > SIZE_MAX) {
+ fprintf(stderr, "mdbx_env_set_mapsize failed, error %d %s\n", rc,
+ mdbx_strerror(MDBX_TOO_LARGE));
+ return EXIT_FAILURE;
+ }
+ mdbx_env_set_mapsize(env, (size_t)envinfo.me_mapsize);
+ }
#ifdef MDBX_FIXEDMAP
if (info.me_mapaddr)
@@ -385,6 +421,11 @@ int main(int argc, char *argv[]) {
kbuf.iov_base = malloc(kbuf.iov_len);
while (!Eof) {
+ if (user_break) {
+ rc = MDBX_EINTR;
+ break;
+ }
+
MDBX_val key, data;
int batch = 0;
diff --git a/src/tools/mdbx_load.vcxproj b/src/tools/mdbx_load.vcxproj
new file mode 100644
index 00000000..b0043ef3
--- /dev/null
+++ b/src/tools/mdbx_load.vcxproj
@@ -0,0 +1,162 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BB}
+ Win32Proj
+ mdbx_load
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ {6d19209b-ece7-4b9c-941c-0aa2b484f199}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/mdbx_stat.c b/src/tools/mdbx_stat.c
index b1fa22bb..eaf0371a 100644
--- a/src/tools/mdbx_stat.c
+++ b/src/tools/mdbx_stat.c
@@ -13,15 +13,35 @@
* top-level directory of the distribution or, alternatively, at
* . */
-#include
-#include
-#include
-#include
-#include
+#ifdef _MSC_VER
+#if _MSC_VER > 1800
+#pragma warning(disable : 4464) /* relative include path contains '..' */
+#endif
+#pragma warning(disable : 4996) /* The POSIX name is deprecated... */
+#endif /* _MSC_VER */
-#include "../../mdbx.h"
#include "../bits.h"
+#if defined(_WIN32) || defined(_WIN64)
+#include "wingetopt.h"
+
+static volatile BOOL user_break;
+static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) {
+ (void)dwCtrlType;
+ user_break = true;
+ return true;
+}
+
+#else /* WINDOWS */
+
+static volatile sig_atomic_t user_break;
+static void signal_handler(int sig) {
+ (void)sig;
+ user_break = 1;
+}
+
+#endif /* !WINDOWS */
+
static void prstat(MDBX_stat *ms) {
printf(" Pagesize: %u\n", ms->ms_psize);
printf(" Tree depth: %u\n", ms->ms_depth);
@@ -39,7 +59,7 @@ static void usage(char *prog) {
}
int main(int argc, char *argv[]) {
- int i, rc;
+ int o, rc;
MDBX_env *env;
MDBX_txn *txn;
MDBX_dbi dbi;
@@ -63,8 +83,8 @@ int main(int argc, char *argv[]) {
* -V: print version and exit
* (default) print stat of only the main DB
*/
- while ((i = getopt(argc, argv, "Vaefnrs:")) != EOF) {
- switch (i) {
+ while ((o = getopt(argc, argv, "Vaefnrs:")) != EOF) {
+ switch (o) {
case 'V':
printf("%s (%s, build %s)\n", mdbx_version.git.describe,
mdbx_version.git.datetime, mdbx_build.datetime);
@@ -100,6 +120,19 @@ int main(int argc, char *argv[]) {
if (optind != argc - 1)
usage(prog);
+#if defined(_WIN32) || defined(_WIN64)
+ SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true);
+#else
+#ifdef SIGPIPE
+ signal(SIGPIPE, signal_handler);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, signal_handler);
+#endif
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+#endif /* !WINDOWS */
+
envname = argv[optind];
rc = mdbx_env_create(&env);
if (rc) {
@@ -195,6 +228,10 @@ int main(int argc, char *argv[]) {
}
prstat(&mst);
while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == 0) {
+ if (user_break) {
+ rc = MDBX_EINTR;
+ break;
+ }
iptr = data.iov_base;
pages += *iptr;
if (envinfo && mei.me_latter_reader_txnid > *(size_t *)key.iov_base)
@@ -209,7 +246,7 @@ int main(int argc, char *argv[]) {
if (pg <= prev)
bad = " [bad sequence]";
prev = pg;
- pg += span;
+ pg += (unsigned)span;
for (; i >= span && iptr[i - span] == pg; span++, pg++)
;
}
diff --git a/src/tools/mdbx_stat.vcxproj b/src/tools/mdbx_stat.vcxproj
new file mode 100644
index 00000000..caf425ed
--- /dev/null
+++ b/src/tools/mdbx_stat.vcxproj
@@ -0,0 +1,162 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {15030120-5F7F-48F9-ABE5-DFC814F2A4BF}
+ Win32Proj
+ mdbx_stat
+ 8.1
+
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+ Application
+ true
+ v140
+ MultiByte
+
+
+ Application
+ false
+ v140
+ true
+ MultiByte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ true
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+ false
+ $(Platform)\$(Configuration)\$(ProjectName)\
+
+
+
+
+
+ Level4
+ Disabled
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+
+
+ Level4
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+ true
+
+
+ Console
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
+
+
+ Console
+ true
+ true
+
+
+
+
+ {6d19209b-ece7-4b9c-941c-0aa2b484f199}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tools/wingetopt.c b/src/tools/wingetopt.c
new file mode 100644
index 00000000..3762ecae
--- /dev/null
+++ b/src/tools/wingetopt.c
@@ -0,0 +1,75 @@
+/*
+ * POSIX getopt for Windows
+ *
+ * AT&T Public License
+ *
+ * Code given out at the 1985 UNIFORUM conference in Dallas.
+ */
+
+#include "wingetopt.h"
+#include
+#include
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef EOF
+#define EOF (-1)
+#endif
+
+#define ERR(s, c) \
+ if (opterr) { \
+ char errbuf[2]; \
+ errbuf[0] = (char)c; \
+ errbuf[1] = '\n'; \
+ fputs(argv[0], stderr); \
+ fputs(s, stderr); \
+ fputc(c, stderr); \
+ }
+
+int opterr = 1;
+int optind = 1;
+int optopt;
+char *optarg;
+
+int getopt(int argc, char *const argv[], const char *opts) {
+ static int sp = 1;
+ int c;
+ char *cp;
+
+ if (sp == 1)
+ if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
+ return EOF;
+ else if (strcmp(argv[optind], "--") == 0) {
+ optind++;
+ return EOF;
+ }
+ optopt = c = argv[optind][sp];
+ if (c == ':' || (cp = strchr(opts, c)) == NULL) {
+ ERR(": illegal option -- ", c);
+ if (argv[optind][++sp] == '\0') {
+ optind++;
+ sp = 1;
+ }
+ return '?';
+ }
+ if (*++cp == ':') {
+ if (argv[optind][sp + 1] != '\0')
+ optarg = &argv[optind++][sp + 1];
+ else if (++optind >= argc) {
+ ERR(": option requires an argument -- ", c);
+ sp = 1;
+ return '?';
+ } else
+ optarg = argv[optind++];
+ sp = 1;
+ } else {
+ if (argv[optind][++sp] == '\0') {
+ sp = 1;
+ optind++;
+ }
+ optarg = NULL;
+ }
+ return c;
+}
diff --git a/src/tools/wingetopt.h b/src/tools/wingetopt.h
new file mode 100644
index 00000000..fdff3683
--- /dev/null
+++ b/src/tools/wingetopt.h
@@ -0,0 +1,26 @@
+/*
+ * POSIX getopt for Windows
+ *
+ * AT&T Public License
+ *
+ * Code given out at the 1985 UNIFORUM conference in Dallas.
+ */
+
+#ifndef _WINGETOPT_H_
+#define _WINGETOPT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char *optarg;
+int getopt(int argc, char *const argv[], const char *optstring);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H_ */
diff --git a/test/test.vcxproj b/test/test.vcxproj
index 20535ff4..8df56351 100644
--- a/test/test.vcxproj
+++ b/test/test.vcxproj
@@ -34,27 +34,27 @@
Application
true
v140
- Unicode
+ MultiByte
Application
false
v140
true
- Unicode
+ MultiByte
Application
true
v140
- Unicode
+ MultiByte
Application
false
v140
true
- Unicode
+ MultiByte
@@ -95,7 +95,7 @@
Use
Level4
Disabled
- WIN32;_DEBUG;_CONSOLE;MDBX_DEBUG=1;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;_CONSOLE;MDBX_DEBUG=1;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
true
test.h
true
@@ -111,7 +111,7 @@
Use
Level4
Disabled
- _DEBUG;_CONSOLE;MDBX_DEBUG=1;%(PreprocessorDefinitions)
+ _DEBUG;_CONSOLE;MDBX_DEBUG=1;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
true
test.h
true
@@ -129,7 +129,7 @@
MaxSpeed
true
true
- WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
true
test.h
true
@@ -149,7 +149,7 @@
MaxSpeed
true
true
- NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions);LIBMDBX_IMPORTS=1
true
test.h
true