Merge remote-tracking branch 'refs/remotes/cabo/master' into windows
Conflicts:
include/cn-cbor/cn-cbor.h
src/cn-cbor.c
src/cn-get.c
diff --git a/.gitignore b/.gitignore
index 2eef09e..4e0b78a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,20 @@
new.out
*.o
build
+
+# Emacs temp files
+*~
+
+# Visual Studio build directories
+Debug
+Release
+*.vcxproj
+*.vcxproj.filters
+
+# Output of cmake
+CMakeCache.txt
+CMakeFiles
+Makefile
+*.cmake
+install_manifest.txt
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 195c780..fb5a071 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,6 +23,7 @@
option ( coveralls "Generate coveralls data" ON )
option ( coveralls_send "Send data to coveralls site" OFF )
option ( build_docs "Create docs using Doxygen" ${DOXYGEN_FOUND} )
+option ( build_shared_libs "Build Shared Libraries" ON)
option ( no_floats "Build without floating point support" OFF )
set ( dist_dir ${CMAKE_BINARY_DIR}/dist )
@@ -50,6 +51,15 @@
endif ()
endif()
+if ( MSVC )
+ set (coveralls OFF)
+endif ()
+
+set (LIB_TYPE STATIC)
+if (build_shared_libs)
+ set (LIB_TYPE SHARED)
+endif (build_shared_libs)
+
message ( "Build type: ${CMAKE_BUILD_TYPE}" )
if ( CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
diff --git a/include/cn-cbor/cn-cbor.h b/include/cn-cbor/cn-cbor.h
index bf71af8..a0f9e4e 100644
--- a/include/cn-cbor/cn-cbor.h
+++ b/include/cn-cbor/cn-cbor.h
@@ -7,6 +7,18 @@
#ifndef CN_CBOR_H
#define CN_CBOR_H
+#ifndef MYLIB_EXPORT
+#if defined (_WIN32)
+#if defined(CN_CBOR_IS_DLL)
+#define MYLIB_EXPORT __declspec(dllimport)
+#else
+#define MYLIB_EXPORT
+#endif /* CN_CBOR_IS_DLL */
+#else /* defined (_WIN32) */
+#define MYLIB_EXPORT
+#endif
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -16,7 +28,11 @@
#include <stdbool.h>
#include <stdint.h>
+#ifdef _MSC_VER
+typedef long ssize_t;
+#else
#include <unistd.h>
+#endif
/**
* All of the different kinds of CBOR values.
@@ -86,17 +102,33 @@
/** CN_CBOR_TEXT */
const char* str;
/** CN_CBOR_INT */
+#ifdef _MSC_VER
+ int64_t sint;
+#else
long sint;
+#endif
/** CN_CBOR_UINT */
+#ifdef _MSC_VER
+ uint64_t uint;
+#else
unsigned long uint;
+#endif
/** CN_CBOR_DOUBLE */
double dbl;
/** for use during parsing */
- unsigned long count;
+#ifdef _MSC_VER
+ uint64_t count;
+#else
+ unsigned long count;
+#endif
} v; /* TBD: optimize immediate */
/** Number of children.
* @note: for maps, this is 2x the number of entries */
+#ifdef _MSC_VER
+ size_t length;
+#else
int length;
+#endif
/** The first child value */
struct cn_cbor* first_child;
/** The last child value */
@@ -144,6 +176,7 @@
*
* @todo: turn into a function to make the type safety more clear?
*/
+MYLIB_EXPORT
extern const char *cn_cbor_error_str[];
/**
@@ -218,7 +251,8 @@
* @param[out] errp Error, if NULL is returned
* @return The parsed CBOR structure, or NULL on error
*/
-cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_decode(const uint8_t *buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp);
/**
* Get a value from a CBOR map that has the given string as a key.
@@ -227,7 +261,8 @@
* @param[in] key The string to look up in the map
* @return The matching value, or NULL if the key is not found
*/
-cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key);
/**
* Get a value from a CBOR map that has the given integer as a key.
@@ -236,7 +271,8 @@
* @param[in] key The int to look up in the map
* @return The matching value, or NULL if the key is not found
*/
-cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key);
/**
* Get the item with the given index from a CBOR array.
@@ -245,7 +281,8 @@
* @param[in] idx The array index
* @return The matching value, or NULL if the index is invalid
*/
-cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx);
/**
* Free the given CBOR structure.
@@ -255,7 +292,8 @@
* @param[in] cb The CBOR value to free. May be NULL, or a root object.
* @param[in] CBOR_CONTEXT Allocation context (only if USE_CBOR_CONTEXT is defined)
*/
-void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT);
+MYLIB_EXPORT
+void cn_cbor_free(const cn_cbor* cb CBOR_CONTEXT);
/**
* Write a CBOR value and all of the child values.
@@ -279,6 +317,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created map, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
/**
@@ -291,6 +330,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -308,6 +348,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_string_create(const char* data
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -320,6 +361,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value
CBOR_CONTEXT,
cn_cbor_errback *errp);
@@ -334,6 +376,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map,
cn_cbor *cb_key, cn_cbor *cb_value,
cn_cbor_errback *errp);
@@ -349,6 +392,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map,
int64_t key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -368,6 +412,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map,
const char* key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -380,6 +425,7 @@
* @param[out] errp Error, if NULL is returned
* @return The created object, or NULL on error
*/
+MYLIB_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
/**
@@ -390,6 +436,7 @@
* @param[out] errp Error
* @return True on success
*/
+MYLIB_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array,
cn_cbor* cb_value,
cn_cbor_errback *errp);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ceb0608..ecaefa0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,7 +13,15 @@
if (use_context)
add_definitions(-DUSE_CBOR_CONTEXT)
endif()
-add_library ( cn-cbor SHARED ${cbor_srcs} )
+add_library ( cn-cbor ${LIB_TYPE} ${cbor_srcs} )
+message ( "MSVC: ${MSVC}")
+if ( MSVC )
+ message ( "test: ${build_shared_libs}")
+ message ( "verbose: ${verbose}")
+
+ target_link_libraries(cn-cbor ws2_32)
+endif()
+
target_include_directories ( cn-cbor PUBLIC ../include )
target_include_directories ( cn-cbor PRIVATE ../src )
@@ -42,9 +50,11 @@
#add_dependencies(coveralls, all)
endif()
+if (NOT MSVC)
add_custom_target(size
COMMAND echo "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
COMMAND size "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
COMMAND size -m "${CMAKE_BINARY_DIR}/src/CMakeFiles/cn-cbor.dir/cn-cbor.c.o"
DEPENDS cn-cbor
COMMENT "Output the size of the parse routine")
+endif (NOT MSVC)
diff --git a/src/cbor.h b/src/cbor.h
index 1859f09..6329477 100644
--- a/src/cbor.h
+++ b/src/cbor.h
@@ -1,6 +1,10 @@
#ifndef CBOR_PROTOCOL_H__
#define CBOR_PROTOCOL_H__
+#ifdef _MSC_VER
+#define inline _inline
+#endif
+
/* The 8 major types */
#define MT_UNSIGNED 0
#define MT_NEGATIVE 1
diff --git a/src/cn-cbor.c b/src/cn-cbor.c
index a7677ae..61416f1 100644
--- a/src/cn-cbor.c
+++ b/src/cn-cbor.c
@@ -13,15 +13,22 @@
#include <string.h>
#include <assert.h>
#include <math.h>
+#ifdef _MSC_VER
+#include <WinSock2.h> // needed for ntohl on Windows
+#else
#include <arpa/inet.h> // needed for ntohl (e.g.) on Linux
+#endif
+
+#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
#define CN_CBOR_FAIL(code) do { pb->err = code; goto fail; } while(0)
+MYLIB_EXPORT
void cn_cbor_free(cn_cbor* cb CBOR_CONTEXT) {
- cn_cbor* p = cb;
+ cn_cbor* p = (cn_cbor*) cb;
assert(!p || !p->parent);
while (p) {
cn_cbor* p1;
@@ -158,7 +165,7 @@
break;
case MT_BYTES: case MT_TEXT:
cb->v.str = (char *) pos;
- cb->length = val;
+ cb->length = (size_t) val;
TAKE(pos, ebuf, val, ;);
break;
case MT_MAP:
@@ -190,7 +197,7 @@
case AI_4:
#ifndef CBOR_NO_FLOAT
cb->type = CN_CBOR_DOUBLE;
- u32.u = val;
+ u32.u = (uint32_t) val;
cb->v.dbl = u32.f;
#else /* CBOR_NO_FLOAT */
CN_CBOR_FAIL(CN_CBOR_ERR_FLOAT_NOT_SUPPORTED);
@@ -238,7 +245,8 @@
return 0;
}
-cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_decode(const unsigned char* buf, size_t len CBOR_CONTEXT, cn_cbor_errback *errp) {
cn_cbor catcher = {CN_CBOR_INVALID, 0, {0}, 0, NULL, NULL, NULL, NULL};
struct parse_buf pb;
cn_cbor* ret;
diff --git a/src/cn-create.c b/src/cn-create.c
index bc448e9..a6f6b5b 100644
--- a/src/cn-create.c
+++ b/src/cn-create.c
@@ -8,6 +8,7 @@
#include <string.h>
#include <stdlib.h>
+#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
@@ -16,6 +17,7 @@
(v) = CN_CALLOC_CONTEXT(); \
if (!(v)) { if (errp) {errp->err = CN_CBOR_ERR_OUT_OF_MEMORY;} return NULL; }
+MYLIB_EXPORT
cn_cbor* cn_cbor_map_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
cn_cbor* ret;
@@ -27,6 +29,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_data_create(const uint8_t* data, int len
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -41,6 +44,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_string_create(const char* data
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -55,6 +59,7 @@
return ret;
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_int_create(int64_t value
CBOR_CONTEXT,
cn_cbor_errback *errp)
@@ -91,6 +96,7 @@
return true;
}
+MYLIB_EXPORT
bool cn_cbor_map_put(cn_cbor* cb_map,
cn_cbor *cb_key, cn_cbor *cb_value,
cn_cbor_errback *errp)
@@ -105,6 +111,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
bool cn_cbor_mapput_int(cn_cbor* cb_map,
int64_t key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -124,6 +131,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
bool cn_cbor_mapput_string(cn_cbor* cb_map,
const char* key, cn_cbor* cb_value
CBOR_CONTEXT,
@@ -143,6 +151,7 @@
return _append_kv(cb_map, cb_key, cb_value);
}
+MYLIB_EXPORT
cn_cbor* cn_cbor_array_create(CBOR_CONTEXT_COMMA cn_cbor_errback *errp)
{
cn_cbor* ret;
@@ -154,6 +163,7 @@
return ret;
}
+MYLIB_EXPORT
bool cn_cbor_array_append(cn_cbor* cb_array,
cn_cbor* cb_value,
cn_cbor_errback *errp)
diff --git a/src/cn-encoder.c b/src/cn-encoder.c
index 8593b39..b52a996 100644
--- a/src/cn-encoder.c
+++ b/src/cn-encoder.c
@@ -8,12 +8,19 @@
} /* Duh. */
#endif
+#ifdef _MSC_VER
+#include <WinSock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include <string.h>
+#ifndef _MSC_VER
#include <strings.h>
+#endif
#include <stdbool.h>
#include <assert.h>
+#include "dll-export.h"
#include "cn-cbor/cn-cbor.h"
#include "cbor.h"
@@ -46,6 +53,7 @@
ws->offset += sz;
#define write_byte(b) \
+ensure_writable(1); \
ws->buf[ws->offset++] = (b); \
#define write_byte_ensured(b) \
@@ -89,7 +97,7 @@
if (val < 24) {
ensure_writable(1);
- write_byte(ib | val);
+ write_byte(ib | (uint8_t) val);
} else if (val < 256) {
ensure_writable(2);
write_byte(ib | 24);
diff --git a/src/cn-error.c b/src/cn-error.c
index 4953cc9..ad48746 100644
--- a/src/cn-error.c
+++ b/src/cn-error.c
@@ -1,3 +1,6 @@
+#include "dll-export.h"
+
+MYLIB_EXPORT
const char *cn_cbor_error_str[] = {
"CN_CBOR_NO_ERROR",
"CN_CBOR_ERR_OUT_OF_DATA",
diff --git a/src/cn-get.c b/src/cn-get.c
index cc276a5..0e36495 100644
--- a/src/cn-get.c
+++ b/src/cn-get.c
@@ -2,9 +2,12 @@
#include <string.h>
#include <assert.h>
+#include "dll-export.h"
+
#include "cn-cbor/cn-cbor.h"
-cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_int(const cn_cbor* cb, int key) {
cn_cbor* cp;
assert(cb);
for (cp = cb->first_child; cp && cp->next; cp = cp->next->next) {
@@ -25,7 +28,8 @@
return NULL;
}
-cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_mapget_string(const cn_cbor* cb, const char* key) {
cn_cbor *cp;
int keylen;
assert(cb);
@@ -48,7 +52,8 @@
return NULL;
}
-cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
+MYLIB_EXPORT
+const cn_cbor* cn_cbor_index(const cn_cbor* cb, unsigned int idx) {
cn_cbor *cp;
unsigned int i = 0;
assert(cb);
diff --git a/src/dll-export.h b/src/dll-export.h
new file mode 100644
index 0000000..3d0c928
--- /dev/null
+++ b/src/dll-export.h
@@ -0,0 +1,23 @@
+// Contents of DLLDefines.h
+#ifndef _cn_cbor_DLLDEFINES_H_
+#define _cn_cbor_DLLDEFINES_H_
+
+/* Cmake will define cn_cbor_EXPORTS on Windows when it
+configures to build a shared library. If you are going to use
+another build system on windows or create the visual studio
+projects by hand you need to define cn_cbor_EXPORTS when
+building a DLL on windows.
+*/
+// We are using the Visual Studio Compiler and building Shared libraries
+
+#if defined (_WIN32)
+#if defined(CN_CBOR_IS_DLL)
+ #define MYLIB_EXPORT __declspec(dllexport)
+#else
+ #define MYLIB_EXPORT
+#endif /* cn_cbor_EXPORTS */
+#else /* defined (_WIN32) */
+ #define MYLIB_EXPORT
+#endif
+
+#endif /* _cn_cbor_DLLDEFINES_H_ */
diff --git a/test/cbor_test.c b/test/cbor_test.c
index 3326497..3266631 100644
--- a/test/cbor_test.c
+++ b/test/cbor_test.c
@@ -1,12 +1,22 @@
/*
* Copyright (c) 2015 SPUDlib authors. See LICENSE file.
*/
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#define _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#endif
+
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
+#ifdef _MSC_VER
+#include "winsock2.h"
+#endif
#include "cn-cbor/cn-cbor.h"
@@ -43,7 +53,13 @@
b->sz = len / 2;
b->ptr = malloc(b->sz);
for (i=0; i<b->sz; i++) {
+#ifdef _MSC_VER
+ unsigned int iX;
+ sscanf(inp+(2*i), "%02hx", &iX);
+ b->ptr[i] = (byte)iX;
+#else
sscanf(inp+(2*i), "%02hhx", &b->ptr[i]);
+#endif
}
return true;
}
diff --git a/test/ctest.h b/test/ctest.h
index 75fda66..409d197 100644
--- a/test/ctest.h
+++ b/test/ctest.h
@@ -16,6 +16,14 @@
#ifndef CTEST_H
#define CTEST_H
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#pragma section(".ctest")
+
+#include <io.h>
+#define isatty _isatty
+#endif
+
#ifndef UNUSED_PARAM
/**
* \def UNUSED_PARAM(p);
@@ -48,10 +56,16 @@
#ifdef __APPLE__
#define __Test_Section __attribute__ ((unused,section ("__DATA, .ctest")))
#else
+#ifdef _MSC_VER
+#define __Test_Section
+#define MS__Test_Section __declspec(allocate(".ctest"))
+#else
#define __Test_Section __attribute__ ((unused,section (".ctest")))
#endif
+#endif
#define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
+ MS__Test_Section \
struct ctest __TNAME(sname, tname) __Test_Section = { \
.ssname=#sname, \
.ttname=#tname, \
@@ -138,9 +152,13 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#ifndef _MSC_VER
#include <sys/time.h>
+#endif
#include <inttypes.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#endif
#include <stdint.h>
#include <stdlib.h>
@@ -306,6 +324,27 @@
return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
}
+#ifdef _MSC_VER
+int gettimeofday(struct timeval * tp, struct timezone * tzp)
+{
+ // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
+ static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
+
+ SYSTEMTIME system_time;
+ FILETIME file_time;
+ uint64_t time;
+
+ GetSystemTime(&system_time);
+ SystemTimeToFileTime(&system_time, &file_time);
+ time = ((uint64_t)file_time.dwLowDateTime);
+ time += ((uint64_t)file_time.dwHighDateTime) << 32;
+
+ tp->tv_sec = (long)((time - EPOCH) / 10000000L);
+ tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
+ return 0;
+}
+#endif
+
static uint64_t getCurrentTime() {
struct timeval now;
gettimeofday(&now, NULL);
@@ -377,6 +416,7 @@
}
color_output = isatty(1);
+
uint64_t t1 = getCurrentTime();
struct ctest* ctest_begin = &__TNAME(suite, test);