MSVC support
authorMarko Kreen <markokr@gmail.com>
Sat, 5 Jan 2013 19:04:11 +0000 (21:04 +0200)
committerMarko Kreen <markokr@gmail.com>
Sat, 5 Jan 2013 21:51:03 +0000 (23:51 +0200)
* Antimake extension 'msvc'
* Hardcoded config <usual/config.msvc.h>
* More guarded headers

Usage:
1. Install coreutils and make from gnuwin32
2. Make sure VC env variables are loaded (PATH)
3. Copy build_msvc.mk to build.mk

It would be nice to make it work with MSYS/MINGW32 + VC,
but their filename mangling makes it messy.

17 files changed:
Makefile
build_msvc.mk [new file with mode: 0644]
m4/usual.m4
mk/amext-msvc.mk [new file with mode: 0644]
test/Makefile
test/test_base.c
test/test_bits.c
test/test_cfparser.c
test/test_cxalloc.c
test/test_fnmatch.c
test/test_string.c
usual/base.h
usual/base_win32.h
usual/config_msvc.h [new file with mode: 0644]
usual/event.h
usual/socket_win32.h
usual/time.h

index 944c208bcd04a982a2eff1b9694ff9d3b737359e..2f7745e1453c7176102db35386b9b70771a72c4b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ libusual_a_SOURCES = usual/config.h.in \
        usual/bits.h \
        usual/cbtree.h usual/cbtree.c \
        usual/cfparser.h usual/cfparser.c \
+       usual/config_msvc.h \
        usual/crypto/digest.h usual/crypto/digest.c \
        usual/crypto/hmac.h usual/crypto/hmac.c \
        usual/crypto/keccak.h usual/crypto/keccak.c \
diff --git a/build_msvc.mk b/build_msvc.mk
new file mode 100644 (file)
index 0000000..8d5fdc5
--- /dev/null
@@ -0,0 +1,7 @@
+
+AM_FEATURES = msvc
+
+abs_top_srcdir = $(dir $(filter %/build.mk, $(MAKEFILE_LIST)))
+
+include $(abs_top_srcdir)/mk/antimake.mk
+
index 7ae5de7805ebd72644fa82c3412cae8323b39381..35ad396e9f88e18fcb9c344d51c9ae7a7e83ec7d 100644 (file)
@@ -165,6 +165,7 @@ dnl
 dnl  AC_USUAL_HEADER_CHECK:  Basic headers
 dnl
 AC_DEFUN([AC_USUAL_HEADER_CHECK], [
+AC_CHECK_HEADERS([inttypes.h stdbool.h unistd.h sys/time.h])
 AC_CHECK_HEADERS([sys/socket.h poll.h sys/poll.h sys/un.h])
 AC_CHECK_HEADERS([arpa/inet.h netinet/in.h netinet/tcp.h])
 AC_CHECK_HEADERS([sys/param.h sys/uio.h pwd.h grp.h])
diff --git a/mk/amext-msvc.mk b/mk/amext-msvc.mk
new file mode 100644 (file)
index 0000000..0148fe5
--- /dev/null
@@ -0,0 +1,38 @@
+
+Printf = printf $(subst %,%%,$(1)) $(2)
+
+SHELL = cmd.exe
+
+EXEEXT = .exe
+LIBEXT = .lib
+OBJEXT = .obj
+
+CC = cl -nologo
+CFLAGS = -O2
+WFLAGS =
+WFLAGS = -W2 -WX
+CPP = $(CC) -E
+
+AR = lib
+ARFLAGS = -nologo -out:$(call vcFixPath,$@)
+
+LDFLAGS = 
+
+MKDIR_P = mkdir
+
+MkDir = $(if $(wildcard $(1)),,md $(call vcFixPath,$(1)))
+
+LIBS = -lws2_32 -ladvapi32
+
+vcFixPath = $(subst /,\,$(1))
+vcFixLibs = $(patsubst %.a,%.lib,$(patsubst -l%,%.lib,$(1)))
+vcFixAll = $(call vcFixPath,$(call vcFixLibs,$(1)))
+
+AM_LANG_C_COMPILE = $(COMPILE) -c -Fo$(call vcFixPath,$@) $<
+
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -Fe$(call vcFixPath,$@)
+
+ar_lib = lib -nologo -out:$(call vcFixAll,$@) $^
+AM_LANG_C_LINK = $(LINK) $(call vcFixAll,$^ $(AM_LIBS) $(LIBS)) $(AM_LT_RPATH)
+
+
index c232ec75b8cc60345ce682d3180fd26e227440cc..ed9dd50c52ee34709e2eaf989c46f39493116126 100644 (file)
@@ -20,14 +20,14 @@ regtest_compat_SOURCES := $(regtest_system_SOURCES)
 nodist_regtest_compat_SOURCES = test_config.h
 
 regtest_compat_EMBED_LIBUSUAL = 1
-regtest_system_EMBED_LIBUSUAL = 1
+#regtest_system_EMBED_LIBUSUAL = 1
 
-regtest_system_LDADD = -lanl
-regtest_system_LDFLAGS = -pthread
+regtest_system_LDADD = ../libusual.a
+regtest_system_LDFLAGS = #-pthread
 
 regtest_system_CPPFLAGS = -I.. -I.
 regtest_compat_CPPFLAGS := $(regtest_system_CPPFLAGS) -DUSUAL_TEST_CONFIG
-regtest_compat_LDFLAGS = -pthread
+regtest_compat_LDFLAGS = #-pthread
 
 EXTRA_DIST = Makefile tinytest_demo.c force_compat.sed test_cfparser.ini
 
index 06023b7246f6b62697120a2b67157c26a055fd99..3d9a4404f7ec765614001bbcf856c15554caf191 100644 (file)
@@ -45,12 +45,14 @@ static void test_ptr(void *p)
 end:;
 }
 
+#ifdef _PACKED
 struct packed {
        char a;
        int b;
        char c;
        short d;
 } _PACKED;
+#endif
 
 static void test_misc(void *_p)
 {
@@ -65,8 +67,10 @@ static void test_misc(void *_p)
        int_check(ARRAY_NELEM(s_2), 2);
 
        int_check(strcmp(__func__, "test_misc"), 0);
-
+#ifdef _PACKED
        int_check(sizeof(struct packed), 8);
+#endif
+
 end:;
 }
 
index 1fb5ba2fea377b83c0a4586398aa71ca0e319441..0ba2b23953ebcd70f0ec1dfaf81d2ee01c98c269 100644 (file)
@@ -33,7 +33,7 @@ static void test_rol(void *p)
 
        /* rol64 */
        ull_check(rol64(1, 1), 2);
-       ull_check(rol64(1, 63), 0x8000000000000000);
+       ull_check(rol64(1, 63), 0x8000000000000000ULL);
 end:;
 }
 
index ca68b24935d05607bea91e4fd707d5fea2c504c1..2409c83bcdfd1fb88d5669776f55632ec188c19c 100644 (file)
@@ -108,7 +108,7 @@ static void *get_two(void *top_arg, const char *sect_name)
 
 static const struct CfSect rsects [] = {
        { "one", rkeys1 },
-       { "two", rkeys2, .base_lookup = get_two, },
+       { "two", rkeys2, get_two, },
        { NULL },
 };
 
index 294c33bbdec0a6a9a9f4269678689b14f267bb01..cd33325a53614d4784fa83c55079c1e792a23978 100644 (file)
@@ -57,14 +57,14 @@ static void log_free(void *ctx, const void *ptr)
 }
 
 static const struct CxOps log_ops = {
-       .c_alloc = log_alloc,
-       .c_realloc = log_realloc,
-       .c_free = log_free,
+       log_alloc,
+       log_realloc,
+       log_free,
 };
 
 static const struct CxMem log_libc = {
-       .ops = &log_ops,
-       .ctx = (void*)&cx_libc_allocator,
+       &log_ops,
+       (void*)&cx_libc_allocator,
 };
 
 #define log_check(x) str_check(logbuf, x); reset();
index 25d26dcc72dec701371bc825fe79cc9e8a03484c..e41677bbf55fbc0cd02d3a81386979f8c89da35c 100644 (file)
@@ -2,6 +2,7 @@
 #include <usual/fnmatch.h>
 
 #include <usual/string.h>
+#include <usual/wchar.h>
 #include "test_common.h"
 
 /*
@@ -52,12 +53,14 @@ static void test_fnmatch_posix(void *p)
        int_check(0, fnmatch("[*?[][*?[][*?[]", "*?[", 0));
        int_check(0, fnmatch("[[:alpha:]][![:alpha:]]", "a9", 0));
        int_check(0, fnmatch("[[:alnum:]][![:alnum:]]", "9-", 0));
+#ifdef iswblank
        int_check(0, fnmatch("[[:blank:]][![:blank:]]", " -", 0));
+#endif
        int_check(0, fnmatch("[[:cntrl:]][![:cntrl:]]", "\tx", 0));
        int_check(0, fnmatch("[[:digit:]][![:digit:]]", "9a", 0));
        int_check(0, fnmatch("[[:graph:]][![:graph:]]", "a\t", 0));
        int_check(0, fnmatch("[[:lower:]][![:lower:]]", "aA", 0));
-       int_check(0, fnmatch("[[:print:]][![:print:]]", "a\t", 0));
+       int_check(0, fnmatch("[[:print:]][![:print:]]", "a\n", 0));
        int_check(0, fnmatch("[[:punct:]][![:punct:]]", ".x", 0));
        int_check(0, fnmatch("[[:space:]][![:space:]]", " x", 0));
        int_check(0, fnmatch("[[:upper:]][![:upper:]]", "Ff", 0));
index 10132134e235efddae052f95bf75b654f516367d..ee90d990c90e41b974950e79ec70aa9e81ca0681 100644 (file)
@@ -1,7 +1,9 @@
 
 #include <usual/base.h>
 #include <string.h>
+#ifdef HAVE_LIBGEN_H
 #include <libgen.h>
+#endif
 
 #undef basename
 #undef dirname
index 9f4d065e4c9ba2913e405b54914db4cbb118cc9a..6cf4bf9cf083bdb9a68ca608820ac1693553692a 100644 (file)
@@ -23,6 +23,8 @@
 
 #ifdef USUAL_TEST_CONFIG
 #include "test_config.h"
+#elif defined(_MSC_VER)
+#include <usual/config_msvc.h>
 #else
 #include <usual/config.h>
 #endif
 #endif
 
 #include <sys/types.h>
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
+#endif
 #include <stddef.h>
 #include <stdint.h>
+#ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
-#include <stdbool.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <unistd.h>
 #include <assert.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STDBOOL_H
+#include <stdbool.h>
+#else
+/* we really want bool type */
+typedef enum { true=1, false=0 } bool;
+#endif
 
 #ifdef WIN32
 #include <usual/base_win32.h>
 #define _COMPILER_ICC(ver) (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= (ver)))
 
 /** Disable padding for structure */
+#ifndef _MSC_VER
 #define _PACKED                        __attribute__((packed))
+#endif
 
 /*
  * Make sure __func__ works.
index 8bf37579d1c054bd948d0f073ec60bd0c0260fca..c1489abe705d3cd587ab5b4fa4c80e650b3299fb 100644 (file)
 
 #include <windows.h>
 
+#ifndef ECONNABORTED
 #define ECONNABORTED WSAECONNABORTED
+#endif
+#ifndef EMSGSIZE
 #define EMSGSIZE WSAEMSGSIZE
+#endif
+#ifndef EINPROGRESS
 #define EINPROGRESS WSAEWOULDBLOCK /* WSAEINPROGRESS */
+#endif
 
 #undef EAGAIN
 #define EAGAIN WSAEWOULDBLOCK /* WSAEAGAIN */
 #define srandom(s) srand(s)
 #define random() rand()
 
+#ifdef _MSC_VER
+
+#define snprintf(fmt, ...) _snprintf(fmt, __VA_ARGS__)
+
+static inline int strcasecmp(const char *a, const char *b)
+{
+       return _stricmp(a, b);
+}
+
+static inline int strncasecmp(const char *a, const char *b, size_t cnt)
+{
+       return _strnicmp(a, b, cnt);
+}
+
+typedef int ssize_t;
+
+#endif
 
 /* getrlimit() */
 #define RLIMIT_NOFILE -1
diff --git a/usual/config_msvc.h b/usual/config_msvc.h
new file mode 100644 (file)
index 0000000..32f74c4
--- /dev/null
@@ -0,0 +1,95 @@
+
+/* Define to 1 if you have the `event_base_new' function. */
+#define HAVE_EVENT_BASE_NEW 1
+
+/* Define to 1 if you have the `event_loopbreak' function. */
+#define HAVE_EVENT_LOOPBREAK 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://libusual.github.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "libusual"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "libusual 0.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "libusual"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.1"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to request cleaner win32 headers. */
+#define WIN32_LEAN_AND_MEAN 1
+
+/* Define to max win32 API version (0x0501=XP). */
+//#define WINVER 0x0501
+#define WINVER 0x0600
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#define gid_t int
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#define inline __inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#define pid_t int
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+#ifndef restrict
+#define restrict
+#endif
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#define uid_t int
+
+#define _CRT_SECURE_NO_WARNINGS 1
+
+#ifndef WIN32
+#define WIN32 1
+#endif
index f7f4e31e48ddda3101c1465ef165776bb89dd95b..28356a03441f34e6ae32b1283f10526215e1c959 100644 (file)
@@ -28,7 +28,9 @@
 
 #include <usual/base.h>
 
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
 
 #ifdef HAVE_LIBEVENT
 
index 80690f4f008661672a6cb88ebfc21e3b8f74455b..a910918994b41bc942d008d527a86c62300ba81d 100644 (file)
@@ -42,15 +42,18 @@ struct msghdr {
        int           msg_flags;
 };
 
+#ifndef SCM_RIGHTS
+#define SCM_RIGHTS 1
+#endif
+
+#ifndef CMSG_FIRSTHDR
+
 struct cmsghdr {
        int             cmsg_len;
        int             cmsg_level;
        int             cmsg_type;
 };
 
-
-#define SCM_RIGHTS 1
-
 #define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
 #define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
        & ~(sizeof (size_t) - 1))
@@ -68,6 +71,8 @@ struct cmsghdr {
        (struct cmsghdr *)((u_char *)(cmsg) + CMSG_ALIGN((cmsg)->cmsg_len))))
 #define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+CMSG_ALIGN(len))
 
+#endif
+
 /*
  * unify WSAGetLastError() with errno.
  *
@@ -212,4 +217,20 @@ struct tcp_keepalive {
 };
 #endif
 
+/*
+ * Use native poll() if available
+ */
+
+#if !defined(HAVE_POLL) && defined(POLLIN)
+
+#define HAVE_POLL
+#define poll(a,b,c) usual_poll(a,b,c)
+
+static inline int poll(struct pollfd *fds, int nfds, int timeout)
+{
+       return WSAPoll(fds, nfds, timeout);
+}
+
+#endif
+
 #endif
index 0911b4adac86e0ae317c8dee66e5d51ebbd0a420..c43c17139de9070dbb6bb3234b378d59a922806e 100644 (file)
 
 #include <usual/base.h>
 
+#ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
+
+#ifdef _WIN32
+#include <winsock2.h>
+#endif
+
 #include <time.h>
 
 /** Type to hold microseconds. */