diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml new file mode 100644 index 0000000..66d381e --- /dev/null +++ b/.github/workflows/ubuntu.yml @@ -0,0 +1,40 @@ +name: Ubuntu 20.04 CI (GCC 9) + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + ubuntu-build: + if: >- + ! contains(toJSON(github.event.commits.*.message), '[skip ci]') && + ! contains(toJSON(github.event.commits.*.message), '[skip github]') + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Use cmake (debug) + run: | + mkdir builddebug && + cd builddebug && + cmake -DCMAKE_BUILD_TYPE=buildundefsani .. && + cmake --build . && + ctest --output-on-failure + - name: Use cmake (release) + run: | + mkdir buildrelease && + cd buildrelease && + cmake -DCMAKE_BUILD_TYPE=Release .. && + cmake --build . && + ctest --output-on-failure + + - name: Use cmake (undefined sanitizer) + run: | + mkdir buildundefsani && + cd buildundefsani && + cmake -DSTREAMVBYTE_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=buildundefsani .. && + cmake --build . && + ctest --output-on-failure \ No newline at end of file diff --git a/.github/workflows/vs.yml b/.github/workflows/vs.yml new file mode 100644 index 0000000..754fe9e --- /dev/null +++ b/.github/workflows/vs.yml @@ -0,0 +1,43 @@ +name: VS16-CI + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + ci: + if: >- + ! contains(toJSON(github.event.commits.*.message), '[skip ci]') && + ! contains(toJSON(github.event.commits.*.message), '[skip github]') + name: windows-vs16 + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + include: + - {gen: Visual Studio 16 2019, arch: Win32, static: ON} + - {gen: Visual Studio 16 2019, arch: Win32, static: OFF} + - {gen: Visual Studio 16 2019, arch: x64, static: ON} + - {gen: Visual Studio 16 2019, arch: x64, static: OFF} + steps: + - name: checkout + uses: actions/checkout@v2 + - name: Configure + run: | + cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_BUILD_STATIC=${{matrix.static}} -B build + - name: Build Debug + run: cmake --build build --config Debug --verbose + - name: Build Release + run: cmake --build build --config Release --verbose + - name: Run Release tests + run: | + cd build + ctest -C Release --output-on-failure + - name: Run Debug tests + run: | + cd build + ctest -C Debug --output-on-failure \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index fe33681..162dcf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,29 +6,7 @@ if (NOT CMAKE_BUILD_TYPE) endif() project(STREAMVBYTE VERSION "0.0.1") -cmake_policy(SET CMP0065 OLD) -set(CMAKE_EXPORT_COMPILE_COMMANDS 1) -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -v" ) -set(BASE_FLAGS - "-std=c99" - "-fPIC" - "-Wextra" - "-pedantic" - "-Wshadow" -) -if(CMAKE_BUILD_TYPE MATCHES Debug) - set(BASE_FLAGS - ${BASE_FLAGS} - "-O0" - "-ggdb" - ) -else() - set(BASE_FLAGS - ${BASE_FLAGS} - "-O3" - "-g" - ) -endif() + if (MSVC) add_definitions( "-D__restrict__=__restrict" @@ -73,13 +51,16 @@ install( TARGETS streamvbyte streamvbyte_static DESTINATION lib) ## -march=native is not supported on some platforms -if(NOT MSVC) -if(NOT STREAMVBYTE_DISABLE_NATIVE) -set(OPT_FLAGS "-march=native") +if(NOT MSVC AND NOT STREAMVBYTE_DISABLE_NATIVE AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(AMD64.*|x64.*|x86.*)" ) + set(OPT_FLAGS "-march=native") endif() + +option(STREAMVBYTE_SANITIZE_UNDEFINED "Sanitize undefined behavior" OFF) +if(STREAMVBYTE_SANITIZE_UNDEFINED) + add_compile_options(-fsanitize=undefined -fno-sanitize-recover=all) + add_link_options(-fsanitize=undefined -fno-sanitize-recover=all) endif() -set(CMAKE_C_FLAGS "${STD_FLAGS} ${OPT_FLAGS} ${INCLUDE_FLAGS} ${WARNING_FLAGS} ${SANITIZE_FLAGS} ") MESSAGE( STATUS "CMAKE_SYSTEM_PROCESSOR: " ${CMAKE_SYSTEM_PROCESSOR}) MESSAGE( STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} ) # this tends to be "sticky" so you can remain unknowingly in debug mode diff --git a/src/streamvbyte_zigzag.c b/src/streamvbyte_zigzag.c index dffbecb..31e363d 100644 --- a/src/streamvbyte_zigzag.c +++ b/src/streamvbyte_zigzag.c @@ -1,8 +1,8 @@ #include "streamvbyte_zigzag.h" static inline -uint32_t _zigzag_encode_32 (int32_t val) { - return (val + val) ^ (val >> 31); +uint32_t _zigzag_encode_32 (uint32_t val) { + return (val + val) ^ ((int32_t)val >> 31); } void zigzag_encode(const int32_t * in, uint32_t * out, size_t N) { diff --git a/tests/unit.c b/tests/unit.c index bd8e009..93027a1 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -47,6 +47,37 @@ int zigzagtests() { return isok; } + +// Fixtures from https://developers.google.com/protocol-buffers/docs/encoding#signed_integers +int zigzagfixturestests() { + const int32_t original[] = {0, -1, 1, -2, 2147483647, -2147483648}; + const uint32_t encoded[] = {0, 1, 2, 3, 4294967294, 4294967295}; + + uint32_t out[] = {0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa}; + + zigzag_encode(original, out, 6); + + for (size_t i = 0; i < 6; ++i) { + if (encoded[i] != out[i]) { + printf("[zigzag_encode] %ju != %ju\n", (uintmax_t)encoded[i], (uintmax_t)out[i]); + return -1; + } + } + + int32_t roundtrip[] = {0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555, 0x55555555}; + + zigzag_decode((const uint32_t *)out, roundtrip, 6); + + for (size_t i = 0; i < 6; ++i) { + if (original[i] != roundtrip[i]) { + printf("[zigzag_decode] %jd != %jd\n", (intmax_t)original[i], (intmax_t)roundtrip[i]); + return -1; + } + } + + return 0; +} + // return -1 in case of failure int basictests() { int N = 4096;