Skip to content

Commit

Permalink
Merge branch 'develop' into tree-stream
Browse files Browse the repository at this point in the history
  • Loading branch information
ludocode committed Apr 7, 2017
2 parents 1773959 + 708e455 commit 3896e6c
Show file tree
Hide file tree
Showing 25 changed files with 1,065 additions and 467 deletions.
7 changes: 5 additions & 2 deletions .travis.yml
@@ -1,5 +1,8 @@
language: c

dist: trusty
sudo: false

addons:
apt:
packages:
Expand All @@ -26,5 +29,5 @@ env:
matrix:
include:
- os: osx
compiler: xcodebuild
env: ""
compiler: clang
env: "OSX=1"
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,8 @@ New Features:

- The writer now supports a v4 compatibility mode. Call `mpack_writer_set_version(writer, mpack_version_v4);` to encode without using the `raw8` and `bin` types.

- The stdio helpers now allow reading from a `FILE*`. `_init_file()` functions have been renamed to `_init_filename()`. The old names will continue to work for a few more versions.

Changes:

- The reader's skip function is no longer ignored under `MPACK_OPTIMIZE_FOR_SIZE`.
Expand Down
2 changes: 1 addition & 1 deletion SConscript
Expand Up @@ -21,7 +21,7 @@ prog = env.Program("mpack-test", srcs,
# whether it's available though because we want to force mpack developers
# to install and use it if their architecture supports it.

if valgrind and platform.machine() in ["i386", "x86_64"]:
if valgrind and platform.system() == "Linux" and platform.machine() in ["i386", "x86_64"]:
valgrind = "valgrind --leak-check=full --error-exitcode=1 "
valgrind += "--suppressions=tools/valgrind-suppressions "
# travis version of valgrind is too old, doesn't support leak kinds
Expand Down
29 changes: 20 additions & 9 deletions SConstruct
@@ -1,8 +1,14 @@
import platform, os

emptytest = "int main(void){return 0;}\n"

def CheckFlags(context, cppflags, linkflags = [], message = None, testcode = emptytest, testformat = '.c'):
simpletest = """
int main(int argc, char** argv) {
// array dereference to test for the existence of
// sanitizer libs when using -fsanitize (libubsan)
return argv[argc - 1] == 0;
}
"""

def CheckFlags(context, cppflags, linkflags = [], message = None, testcode = simpletest, testformat = '.c'):
if message == None:
message = " ".join(cppflags + ((cppflags != linkflags) and linkflags or []))
context.Message("Checking for " + message + " support... ")
Expand Down Expand Up @@ -32,7 +38,7 @@ for x in os.environ.keys():

env.Append(CPPFLAGS = [
"-Wall", "-Wextra", "-Werror",
"-Wconversion", "-Wno-sign-conversion", "-Wundef",
"-Wconversion", "-Wundef",
"-Wshadow", "-Wcast-qual",
"-Isrc", "-Itest",
"-DMPACK_SCONS=1",
Expand All @@ -47,7 +53,7 @@ env.Append(LINKFLAGS = [

AddFlagIfSupported("-Wmissing-variable-declarations")
AddFlagIfSupported("-Wstrict-aliasing=1")
AddFlagIfSupported("-Wno-float-conversion")
AddFlagIfSupported("-Wfloat-conversion")
AddFlagIfSupported("-Wmisleading-indentation")


Expand Down Expand Up @@ -177,18 +183,23 @@ if ARGUMENTS.get('all'):
if conf.CheckFlags(cxxflags + ["-std=gnu++11"], [], "-std=gnu++11"):
AddBuilds("gnuxx11", allfeatures + allconfigs + cxxflags + ["-std=gnu++11"]) # Clang supports _Generic in gnu++11 mode

# 32-bit build
# 32-bit builds
if conf.CheckFlags(["-m32"], ["-m32"]):
AddBuilds("32", allfeatures + allconfigs + cflags + ["-m32"], ["-m32"])
AddBuilds("cxx32", allfeatures + allconfigs + cxxflags + ["-std=c++98", "-m32"], ["-m32"])
AddBuilds("32bit", allfeatures + allconfigs + cflags + ["-m32"], ["-m32"])
AddBuilds("cxx-32bit", allfeatures + allconfigs + cxxflags + ["-std=c++98", "-m32"], ["-m32"])
if conf.CheckFlags(cxxflags + ["-std=c++11", "-m32"], ["-m32"], "-std=c++11"):
AddBuilds("cxx11-32bit", allfeatures + allconfigs + cxxflags + ["-std=c++11", "-m32"], ["-m32"])

# sanitize build tests
sanitizers = {
"stack-protector": ["-Wstack-protector", "-fstack-protector-all"],
"memory": ["-fsanitize=memory"],
"undefined": ["-fsanitize=undefined"],
"address": ["-fsanitize=address"],
"safestack": ["-fsanitize=safe-stack"],
}
# memory sanitizer isn't working on the version of Clang on Travis-CI's Trusty container right now
if not ("CC" in os.environ and os.environ["CC"] == "clang" and "TRAVIS" in os.environ):
sanitizers["memory"] = ["-fsanitize=memory"]
for name, flags in sanitizers.items():
if conf.CheckFlags(flags, flags):
AddBuilds("sanitize-" + name, allfeatures + allconfigs + cflags + flags, flags, valgrind=False)
2 changes: 2 additions & 0 deletions docs/features.md
Expand Up @@ -32,6 +32,7 @@ Feedback is welcome! Please let me know if any entries in the table are incorrec
| Support for new (2.0) spec ||||
| Compatible with older (1.0) spec ||||
| UTF-8 verification || | |
| Type-generic write helpers ||| |

Most of the features above are optional when supported and can be configured in all libraries. In particular, UTF-8 verification is optional with MPack; compound size tracking is optional and disabled in release by default with MPack; and 1.0 (v4) spec compatibility is optional with CMP (v5/2.0 is the recommended and default usage.)

Expand Down Expand Up @@ -61,3 +62,4 @@ Most of the features above are optional when supported and can be configured in

*Compatible with older (1.0) spec* means the ability to produce messages compatible with parsers that only understand the old v4/1.0 version of MessagePack. A backwards-compatible encoder must at a minimum support writing an old-style raw without "str8", since there was no "raw8" type in old MessagePack.

*Type-generic write helpers* means a generic write function or macro that can serialize based on the static type of the argument, in at least one of C11 or C++. (The reference [msgpack-c][msgpack-c] currently supports this only in C++ mode. MPack supports this both in C++ with templates and in C11 with `_Generic`.)
5 changes: 3 additions & 2 deletions src/mpack/mpack-common.c
Expand Up @@ -39,6 +39,7 @@ const char* mpack_error_to_string(mpack_error_t error) {
MPACK_ERROR_STRING_CASE(mpack_error_memory);
MPACK_ERROR_STRING_CASE(mpack_error_bug);
MPACK_ERROR_STRING_CASE(mpack_error_data);
MPACK_ERROR_STRING_CASE(mpack_error_eof);
#undef MPACK_ERROR_STRING_CASE
default: break;
}
Expand Down Expand Up @@ -81,11 +82,11 @@ int mpack_tag_cmp(mpack_tag_t left, mpack_tag_t right) {
// positive numbers may be stored as int; convert to uint
if (left.type == mpack_type_int && left.v.i >= 0) {
left.type = mpack_type_uint;
left.v.u = left.v.i;
left.v.u = (uint64_t)left.v.i;
}
if (right.type == mpack_type_int && right.v.i >= 0) {
right.type = mpack_type_uint;
right.v.u = right.v.i;
right.v.u = (uint64_t)right.v.i;
}

if (left.type != right.type)
Expand Down
64 changes: 28 additions & 36 deletions src/mpack/mpack-common.h
Expand Up @@ -151,6 +151,7 @@ typedef enum mpack_error_t {
mpack_error_memory, /**< An allocation failure occurred. */
mpack_error_bug, /**< The MPack API was used incorrectly. (This will always assert in debug mode.) */
mpack_error_data, /**< The contained data is not valid. */
mpack_error_eof, /**< The reader failed to read because of file or socket EOF */
} mpack_error_t;

/**
Expand Down Expand Up @@ -198,133 +199,124 @@ typedef struct mpack_tag_t {
/** The value for non-compound types. */
union
{
bool b; /**< The value if the type is bool. */
float f; /**< The value if the type is float. */
double d; /**< The value if the type is double. */
int64_t i; /**< The value if the type is signed int. */
uint64_t u; /**< The value if the type is unsigned int. */
uint32_t l; /**< The number of bytes if the type is str, bin or ext. */
int64_t i; /**< The value if the type is signed int. */
double d; /**< The value if the type is double. */
float f; /**< The value if the type is float. */
bool b; /**< The value if the type is bool. */

/** The number of bytes if the type is str, bin or ext. */
uint32_t l;

/** The element count if the type is an array, or the number of
key/value pairs if the type is map. */
uint32_t n;
} v;
} mpack_tag_t;

#define MPACK_TAG_ZERO {(mpack_type_t)0, 0, {0}}

/** Generates a nil tag. */
MPACK_INLINE mpack_tag_t mpack_tag_nil(void) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_nil;
return ret;
}

/** Generates a bool tag. */
MPACK_INLINE mpack_tag_t mpack_tag_bool(bool value) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_bool;
ret.v.b = value;
return ret;
}

/** Generates a bool tag with value true. */
MPACK_INLINE mpack_tag_t mpack_tag_true(void) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_bool;
ret.v.b = true;
return ret;
}

/** Generates a bool tag with value false. */
MPACK_INLINE mpack_tag_t mpack_tag_false(void) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_bool;
ret.v.b = false;
return ret;
}

/** Generates a signed int tag. */
MPACK_INLINE mpack_tag_t mpack_tag_int(int64_t value) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_int;
ret.v.i = value;
return ret;
}

/** Generates an unsigned int tag. */
MPACK_INLINE mpack_tag_t mpack_tag_uint(uint64_t value) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_uint;
ret.v.u = value;
return ret;
}

/** Generates a float tag. */
MPACK_INLINE mpack_tag_t mpack_tag_float(float value) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_float;
ret.v.f = value;
return ret;
}

/** Generates a double tag. */
MPACK_INLINE mpack_tag_t mpack_tag_double(double value) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_double;
ret.v.d = value;
return ret;
}

/** Generates an array tag. */
MPACK_INLINE mpack_tag_t mpack_tag_array(int32_t count) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_array;
ret.v.n = count;
ret.v.n = (uint32_t)count;
return ret;
}

/** Generates a map tag. */
MPACK_INLINE mpack_tag_t mpack_tag_map(int32_t count) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_map;
ret.v.n = count;
ret.v.n = (uint32_t)count;
return ret;
}

/** Generates a str tag. */
MPACK_INLINE mpack_tag_t mpack_tag_str(int32_t length) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_str;
ret.v.l = length;
ret.v.l = (uint32_t)length;
return ret;
}

/** Generates a bin tag. */
MPACK_INLINE mpack_tag_t mpack_tag_bin(int32_t length) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_bin;
ret.v.l = length;
ret.v.l = (uint32_t)length;
return ret;
}

/** Generates an ext tag. */
MPACK_INLINE mpack_tag_t mpack_tag_ext(int8_t exttype, int32_t length) {
mpack_tag_t ret;
mpack_memset(&ret, 0, sizeof(ret));
mpack_tag_t ret = MPACK_TAG_ZERO;
ret.type = mpack_type_ext;
ret.exttype = exttype;
ret.v.l = length;
ret.v.l = (uint32_t)length;
return ret;
}

Expand Down
3 changes: 0 additions & 3 deletions src/mpack/mpack-expect.c
Expand Up @@ -36,7 +36,6 @@ MPACK_STATIC_INLINE uint8_t mpack_expect_native_u8(mpack_reader_t* reader) {
return 0;
type = mpack_load_u8(reader->data);
reader->data += sizeof(type);
reader->left -= sizeof(type);
return type;
}

Expand All @@ -49,7 +48,6 @@ MPACK_STATIC_INLINE uint16_t mpack_expect_native_u16(mpack_reader_t* reader) {
return 0;
type = mpack_load_u16(reader->data);
reader->data += sizeof(type);
reader->left -= sizeof(type);
return type;
}

Expand All @@ -61,7 +59,6 @@ MPACK_STATIC_INLINE uint32_t mpack_expect_native_u32(mpack_reader_t* reader) {
return 0;
type = mpack_load_u32(reader->data);
reader->data += sizeof(type);
reader->left -= sizeof(type);
return type;
}
#endif
Expand Down

0 comments on commit 3896e6c

Please sign in to comment.