From 01676944571953088e3fe233c6aef38c18957485 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Mon, 10 Jul 2017 20:45:24 +0300 Subject: [PATCH] mdbx: building mdbx-tools for Windows. Change-Id: I9019c4382b7108ec7c442d2b0d4be044a3cb136a --- dll.vcxproj | 10 +++ mdbx.h | 2 + mdbx.sln | 75 +++++++++++++++-- src/tools/mdbx_chk.c | 111 ++++++++++++++---------- src/tools/mdbx_chk.vcxproj | 162 ++++++++++++++++++++++++++++++++++++ src/tools/mdbx_copy.c | 57 ++++++++++--- src/tools/mdbx_copy.vcxproj | 162 ++++++++++++++++++++++++++++++++++++ src/tools/mdbx_dump.c | 71 ++++++++++------ src/tools/mdbx_dump.vcxproj | 162 ++++++++++++++++++++++++++++++++++++ src/tools/mdbx_load.c | 87 ++++++++++++++----- src/tools/mdbx_load.vcxproj | 162 ++++++++++++++++++++++++++++++++++++ src/tools/mdbx_stat.c | 57 ++++++++++--- src/tools/mdbx_stat.vcxproj | 162 ++++++++++++++++++++++++++++++++++++ src/tools/wingetopt.c | 75 +++++++++++++++++ src/tools/wingetopt.h | 26 ++++++ test/test.vcxproj | 16 ++-- 16 files changed, 1267 insertions(+), 130 deletions(-) create mode 100644 src/tools/mdbx_chk.vcxproj create mode 100644 src/tools/mdbx_copy.vcxproj create mode 100644 src/tools/mdbx_dump.vcxproj create mode 100644 src/tools/mdbx_load.vcxproj create mode 100644 src/tools/mdbx_stat.vcxproj create mode 100644 src/tools/wingetopt.c create mode 100644 src/tools/wingetopt.h 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