Initial import of libdpf.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
e4e666f459
4563 changed files with 1690372 additions and 0 deletions
198
thirdparty/portable-snippets/tests/CMakeLists.txt
vendored
Normal file
198
thirdparty/portable-snippets/tests/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
project(portable-snippet-tests)
|
||||
|
||||
enable_testing()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
|
||||
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/munit/munit.c")
|
||||
find_program(GIT git)
|
||||
if(GIT)
|
||||
execute_process(COMMAND ${GIT} submodule update --init --recursive)
|
||||
else()
|
||||
message (FATAL_ERROR "It looks like you don't have submodules checked out. Please run `git submodule update --init --recursive'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_OPENMP)
|
||||
find_package(OpenMP REQUIRED)
|
||||
endif()
|
||||
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(clock_gettime CLOCK_GETTIME_RES)
|
||||
if(CLOCK_GETTIME_RES)
|
||||
set(CLOCK_GETTIME_EXISTS yes)
|
||||
else()
|
||||
set(orig_req_libs "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};rt")
|
||||
|
||||
check_function_exists(clock_gettime CLOCK_GETTIME_LIBRT_RES)
|
||||
if(CLOCK_GETTIME_LIBRT_RES)
|
||||
set(CLOCK_GETTIME_EXISTS yes)
|
||||
set(CLOCK_GETTIME_LIBRARY "rt")
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${orig_req_libs}")
|
||||
unset(orig_req_libs)
|
||||
endif()
|
||||
|
||||
include (AddCompilerFlags)
|
||||
|
||||
set(PSNIP_C_FLAGS)
|
||||
|
||||
if(FATAL_WARNINGS)
|
||||
set_compiler_specific_flags(VARIABLE FATAL_WARNING_FLAGS
|
||||
GCCISH -Werror
|
||||
MSVC /WX)
|
||||
list(APPEND PSNIP_C_FLAGS ${FATAL_WARNING_FLAGS})
|
||||
endif()
|
||||
|
||||
if(ENABLE_AGGRESSIVE_WARNINGS)
|
||||
set_compiler_specific_flags(VARIABLE EXTRA_WARNING_FLAGS
|
||||
GCCISH
|
||||
-Wall
|
||||
-Waggregate-return
|
||||
-Wcast-align
|
||||
-Wclobbered
|
||||
-Wempty-body
|
||||
-Werror=format=2
|
||||
-Werror=format-security
|
||||
-Werror=implicit-function-declaration
|
||||
-Werror=init-self
|
||||
-Werror=missing-include-dirs
|
||||
-Werror=missing-prototypes
|
||||
-Werror=pointer-arith
|
||||
-Wextra
|
||||
-Wformat-nonliteral
|
||||
-Wformat-security
|
||||
-Wignored-qualifiers
|
||||
-Winit-self
|
||||
-Winvalid-pch
|
||||
-Wlogical-op
|
||||
-Wmissing-declarations
|
||||
-Wmissing-format-attribute
|
||||
-Wmissing-include-dirs
|
||||
-Wmissing-noreturn
|
||||
-Wmissing-parameter-type
|
||||
-Wmissing-prototypes
|
||||
-Wnested-externs
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-strict-aliasing
|
||||
-Wno-uninitialized
|
||||
-Wno-unused-parameter
|
||||
-Wold-style-definition
|
||||
-Woverride-init
|
||||
-Wpacked
|
||||
-Wpointer-arith
|
||||
-Wredundant-decls
|
||||
-Wreturn-type
|
||||
-Wshadow
|
||||
-Wsign-compare
|
||||
-Wstrict-prototypes
|
||||
-Wswitch-enum
|
||||
-Wsync-nand
|
||||
-Wtype-limits
|
||||
-Wundef
|
||||
-Wuninitialized
|
||||
-WUnsafe-loop-optimizations
|
||||
-Wwrite-strings
|
||||
-Wsuggest-attribute=format
|
||||
PGI
|
||||
-Minform=inform
|
||||
MSVC
|
||||
/W4
|
||||
/analyze)
|
||||
|
||||
list(APPEND PSNIP_C_FLAGS ${EXTRA_WARNING_FLAGS})
|
||||
endif()
|
||||
|
||||
if(NOT ENABLE_SANITIZER STREQUAL "")
|
||||
if(ENABLE_SANITIZER STREQUAL "undefined")
|
||||
set_compiler_specific_flags(VARIABLE UBSAN_FLAGS
|
||||
GCCISH -fsanitize=undefined
|
||||
GCC -fno-sanitize-recover=undefined,float-cast-overflow,float-divide-by-zero
|
||||
CLANG -fno-sanitize-recover=undefined,integer)
|
||||
list(APPEND PSNIP_C_FLAGS ${UBSAN_FLAGS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS_DEBUG)
|
||||
set(CMAKE_C_FLAGS_RELEASE)
|
||||
|
||||
set_compiler_specific_flags(
|
||||
VARIABLE PSNIP_RELEASE_FLAGS
|
||||
GCCISH -O3 -DNDEBUG)
|
||||
foreach(flag ${PSNIP_RELEASE_FLAGS})
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${flag}")
|
||||
endforeach()
|
||||
|
||||
set_compiler_specific_flags(
|
||||
VARIABLE PSNIP_DEBUG_FLAGS
|
||||
GCCISH -O3 -g)
|
||||
foreach(flag ${PSNIP_DEBUG_FLAGS})
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${flag}")
|
||||
endforeach()
|
||||
|
||||
add_library(munit munit/munit.c)
|
||||
set_property(TARGET munit PROPERTY C_STANDARD "99")
|
||||
if("${CLOCK_GETTIME_EXISTS}")
|
||||
target_compile_definitions(munit PRIVATE "MUNIT_ALLOW_CLOCK_GETTIME")
|
||||
target_link_libraries(munit "${CLOCK_GETTIME_LIBRARY}")
|
||||
endif()
|
||||
|
||||
function(psnip_add_tests)
|
||||
set(options)
|
||||
set(oneValueArgs TARGET)
|
||||
set(multiValueArgs SOURCES TESTS)
|
||||
cmake_parse_arguments(PSNIP_TEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
add_executable("${PSNIP_TEST_TARGET}" ${PSNIP_TEST_SOURCES})
|
||||
target_link_libraries("${PSNIP_TEST_TARGET}" munit)
|
||||
target_add_compiler_flags("${PSNIP_TEST_TARGET}" ${PSNIP_C_FLAGS})
|
||||
|
||||
if(PSNIP_TEST_TESTS)
|
||||
foreach(TEST ${PSNIP_TEST_TESTS})
|
||||
add_test(NAME "${TEST}"
|
||||
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:${PSNIP_TEST_TARGET}> "${TEST}")
|
||||
endforeach(TEST)
|
||||
else()
|
||||
add_test(NAME "/${PSNIP_TEST_TARGET}"
|
||||
COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $<TARGET_FILE:${PSNIP_TEST_TARGET}>)
|
||||
endif()
|
||||
endfunction(psnip_add_tests)
|
||||
|
||||
psnip_add_tests(TARGET endian SOURCES endian.c)
|
||||
psnip_add_tests(TARGET atomic SOURCES atomic.c)
|
||||
psnip_add_tests(TARGET builtin SOURCES builtin.c
|
||||
TESTS "/builtin" "/intrin" "/wrapper")
|
||||
psnip_add_tests(TARGET safe-math SOURCES safe-math.c)
|
||||
psnip_add_tests(TARGET unaligned SOURCES unaligned.c)
|
||||
psnip_add_tests(TARGET clock SOURCES clock.c)
|
||||
psnip_add_tests(TARGET once SOURCES once.c)
|
||||
psnip_add_tests(TARGET cpu SOURCES cpu.c ../cpu/cpu.c)
|
||||
psnip_add_tests(TARGET random SOURCES random.c ../random/random.c ../cpu/cpu.c)
|
||||
|
||||
if(ENABLE_PTHREADS)
|
||||
find_package (Threads REQUIRED)
|
||||
foreach(tgt once cpu random)
|
||||
target_link_libraries(${tgt} ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_compile_definitions(${tgt} PRIVATE PSNIP_ENABLE_PTHREADS)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(ENABLE_OPENMP)
|
||||
foreach(tgt atomic once cpu random)
|
||||
target_compile_options(${tgt} PRIVATE ${OpenMP_C_FLAGS})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if("${CLOCK_GETTIME_EXISTS}")
|
||||
target_link_libraries(clock "${CLOCK_GETTIME_LIBRARY}")
|
||||
else()
|
||||
target_compile_definitions(clock PRIVATE "PSNIP_CLOCK_NO_LIBRT")
|
||||
endif()
|
||||
101
thirdparty/portable-snippets/tests/atomic.c
vendored
Normal file
101
thirdparty/portable-snippets/tests/atomic.c
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include <stdlib.h>
|
||||
#include "../exact-int/exact-int.h"
|
||||
#include "../atomic/atomic.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
|
||||
static psnip_atomic_int64 value64 = PSNIP_ATOMIC_VAR_INIT(9);
|
||||
static psnip_atomic_int32 value32 = PSNIP_ATOMIC_VAR_INIT(9);
|
||||
#endif
|
||||
|
||||
static MunitResult
|
||||
test_atomic_int64(const MunitParameter params[], void* data) {
|
||||
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
|
||||
psnip_int64_t v, expected;
|
||||
#endif
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
|
||||
v = psnip_atomic_int64_load(&value64);
|
||||
munit_assert_int64(v, ==, 9);
|
||||
|
||||
v = v * v * v;
|
||||
psnip_atomic_int64_store(&value64, v);
|
||||
v = psnip_atomic_int64_load(&value64);
|
||||
munit_assert_int64(v, ==, 729);
|
||||
|
||||
psnip_atomic_int64_add(&value64, 1000);
|
||||
v = psnip_atomic_int64_load(&value64);
|
||||
munit_assert_int64(v, ==, 1729);
|
||||
|
||||
psnip_atomic_int64_sub(&value64, 729);
|
||||
v = psnip_atomic_int64_load(&value64);
|
||||
munit_assert_int64(v, ==, 1000);
|
||||
|
||||
do {
|
||||
expected = psnip_atomic_int64_load(&value64);
|
||||
v = expected * expected;
|
||||
} while (!psnip_atomic_int64_compare_exchange(&value64, &expected, v));
|
||||
v = psnip_atomic_int64_load(&value64);
|
||||
munit_assert_int64(v, ==, 1000 * 1000);
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_atomic_int32(const MunitParameter params[], void* data) {
|
||||
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
|
||||
psnip_int32_t v, expected;
|
||||
#endif
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
#if !defined(PSNIP_ATOMIC_NOT_FOUND)
|
||||
v = psnip_atomic_int32_load(&value32);
|
||||
munit_assert_int32(v, ==, 9);
|
||||
|
||||
v = v * v * v;
|
||||
psnip_atomic_int32_store(&value32, v);
|
||||
v = psnip_atomic_int32_load(&value32);
|
||||
munit_assert_int32(v, ==, 729);
|
||||
|
||||
psnip_atomic_int32_add(&value32, 1000);
|
||||
v = psnip_atomic_int32_load(&value32);
|
||||
munit_assert_int32(v, ==, 1729);
|
||||
|
||||
psnip_atomic_int32_sub(&value32, 729);
|
||||
v = psnip_atomic_int32_load(&value32);
|
||||
munit_assert_int32(v, ==, 1000);
|
||||
|
||||
do {
|
||||
expected = psnip_atomic_int32_load(&value32);
|
||||
v = expected * expected;
|
||||
} while (!psnip_atomic_int32_compare_exchange(&value32, &expected, v));
|
||||
v = psnip_atomic_int32_load(&value32);
|
||||
munit_assert_int32(v, ==, 1000 * 1000);
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/atomic/int64", test_atomic_int64, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/atomic/int32", test_atomic_int32, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
1640
thirdparty/portable-snippets/tests/builtin.c
vendored
Normal file
1640
thirdparty/portable-snippets/tests/builtin.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
175
thirdparty/portable-snippets/tests/clock.c
vendored
Normal file
175
thirdparty/portable-snippets/tests/clock.c
vendored
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
#define _POSIX_C_SOURCE 199309L
|
||||
|
||||
#include "../exact-int/exact-int.h"
|
||||
#include "../clock/clock.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
/* These tests can yield false positives in some situations, but I'm
|
||||
* having trouble thinking of better ways to test. Ideas welcome. */
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include <unistd.h>
|
||||
# define sleep_seconds(n) sleep(n)
|
||||
#else
|
||||
# include <Windows.h>
|
||||
# define sleep_seconds(n) Sleep((n) * 1000)
|
||||
#endif
|
||||
|
||||
static MunitResult
|
||||
test_clock_wall_time(const MunitParameter params[], void* data) {
|
||||
#if defined(PSNIP_CLOCK_WALL_METHOD)
|
||||
struct PsnipClockTimespec res;
|
||||
psnip_uint32_t precision = psnip_clock_get_precision(PSNIP_CLOCK_TYPE_WALL);
|
||||
time_t t;
|
||||
int r;
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_logf(MUNIT_LOG_DEBUG, "Wall clock method: %d", PSNIP_CLOCK_WALL_METHOD);
|
||||
|
||||
munit_assert_uint32(precision, !=, 0);
|
||||
|
||||
t = time(NULL);
|
||||
/* This test may fail if more than 1 second passes here, but this
|
||||
* thread could conceivably be preempted for longer. */
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &res);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
munit_assert_uint64(t, <=, res.seconds);
|
||||
munit_assert_uint64(t, >=, res.seconds - 1);
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int ts_difference(struct PsnipClockTimespec* earlier, struct PsnipClockTimespec* later) {
|
||||
return
|
||||
(int) ((later->seconds - earlier->seconds) * 1000) +
|
||||
(int) ((((psnip_int64_t) later->nanoseconds) - ((psnip_int64_t) earlier->nanoseconds)) / 1000000);
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_clock_wall_veracity(const MunitParameter params[], void* data) {
|
||||
#if defined(PSNIP_CLOCK_WALL_METHOD)
|
||||
struct PsnipClockTimespec res1, res2;
|
||||
int elapsed_ms;
|
||||
int r;
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &res1);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
/* Assuming we aren't interrupted by a signal, aren't suspended for
|
||||
* much more than 1 seconds, etc. */
|
||||
sleep_seconds(1);
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &res2);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
elapsed_ms = ts_difference(&res1, &res2);
|
||||
|
||||
munit_assert_int(elapsed_ms, >, 900);
|
||||
munit_assert_int(elapsed_ms, <, 1100);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_clock_cpu(const MunitParameter params[], void* data) {
|
||||
#if defined(PSNIP_CLOCK_CPU_METHOD)
|
||||
struct PsnipClockTimespec res1, res2;
|
||||
psnip_uint32_t precision = psnip_clock_get_precision(PSNIP_CLOCK_TYPE_WALL);
|
||||
int r;
|
||||
int elapsed_ms;
|
||||
|
||||
munit_logf(MUNIT_LOG_DEBUG, "CPU clock method: %d", PSNIP_CLOCK_CPU_METHOD);
|
||||
|
||||
munit_assert_uint32(precision, !=, 0);
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &res1);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
sleep_seconds(1);
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_WALL, &res2);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
elapsed_ms = ts_difference(&res1, &res2);
|
||||
|
||||
munit_assert_int(elapsed_ms, >=, 1000);
|
||||
if (precision >= 1000)
|
||||
munit_assert_int(elapsed_ms, <=, 1100);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_clock_monotonic(const MunitParameter params[], void* data) {
|
||||
|
||||
#if defined(PSNIP_CLOCK_MONOTONIC_METHOD)
|
||||
struct PsnipClockTimespec res1, res2;
|
||||
int r;
|
||||
int elapsed_ms;
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_MONOTONIC, &res1);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
/* Assuming we aren't interrupted by a signal, aren't suspended for
|
||||
* much more than 2 seconds, etc. */
|
||||
sleep_seconds(1);
|
||||
|
||||
r = psnip_clock_get_time(PSNIP_CLOCK_TYPE_MONOTONIC, &res2);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
elapsed_ms = ts_difference(&res1, &res2);
|
||||
|
||||
munit_assert_int(elapsed_ms, >, 900);
|
||||
munit_assert_int(elapsed_ms, <, 1100);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
return MUNIT_OK;
|
||||
#else
|
||||
return MUNIT_SKIP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/clock/wall/time", test_clock_wall_time, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/clock/wall/veracity", test_clock_wall_veracity, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/clock/cpu", test_clock_cpu, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/clock/monotonic", test_clock_monotonic, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 16384, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
171
thirdparty/portable-snippets/tests/cmake/AddCompilerFlags.cmake
vendored
Normal file
171
thirdparty/portable-snippets/tests/cmake/AddCompilerFlags.cmake
vendored
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
# This module provides a convenient way to add C/C++ compiler flags if
|
||||
# the compiler supports them.
|
||||
|
||||
include (CheckCCompilerFlag)
|
||||
include (CheckCXXCompilerFlag)
|
||||
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
|
||||
# Depending on the settings, some compilers will accept unknown flags.
|
||||
# We try to disable this behavior by also passing these flags when we
|
||||
# check if a flag is supported.
|
||||
set (ADD_COMPILER_FLAGS_PREPEND "")
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
set (ADD_COMPILER_FLAGS_PREPEND "-Wall -Wextra -Werror")
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set (ADD_COMPILER_FLAGS_PREPEND "-Werror=unknown-warning-option")
|
||||
endif ()
|
||||
|
||||
##
|
||||
# Set a variable to different flags, depending on which compiler is in
|
||||
# use.
|
||||
#
|
||||
# Example:
|
||||
# set_compiler_flags(VARIABLE varname MSVC /wd666 INTEL /wd1729)
|
||||
#
|
||||
# This will set varname to /wd666 if the compiler is MSVC, and /wd1729
|
||||
# if it is Intel.
|
||||
#
|
||||
# Possible compilers:
|
||||
# - GCC: GNU C Compiler
|
||||
# - GCCISH: A compiler that (tries to) be GCC-compatible on the CLI
|
||||
# (i.e., anything but MSVC).
|
||||
# - CLANG: clang
|
||||
# - MSVC: Microsoft Visual C++ compiler
|
||||
# - INTEL: Intel C Compiler
|
||||
# - PGI: PGI C Compiler
|
||||
#
|
||||
# Note: the compiler is determined based on the value of the
|
||||
# CMAKE_C_COMPILER_ID variable, not CMAKE_CXX_COMPILER_ID.
|
||||
##
|
||||
function (set_compiler_specific_flags)
|
||||
set (oneValueArgs VARIABLE)
|
||||
set (multiValueArgs GCC GCCISH INTEL CLANG MSVC PGI)
|
||||
cmake_parse_arguments(COMPILER_SPECIFIC_FLAGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
unset (options)
|
||||
unset (oneValueArgs)
|
||||
unset (multiValueArgs)
|
||||
|
||||
set (compiler_flags)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_GCC})
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_CLANG})
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_INTEL})
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_MSVC})
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "PGI")
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_PGI})
|
||||
endif()
|
||||
|
||||
set(GCCISH_COMPILERS GNU Clang Intel)
|
||||
list(FIND GCCISH_COMPILERS "${CMAKE_C_COMPILER_ID}" IS_GCCISH)
|
||||
if (IS_GCCISH GREATER -1)
|
||||
list (APPEND compiler_flags ${COMPILER_SPECIFIC_FLAGS_GCCISH})
|
||||
endif ()
|
||||
|
||||
set (${COMPILER_SPECIFIC_FLAGS_VARIABLE} "${compiler_flags}" PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
function (source_file_add_compiler_flags_unchecked file)
|
||||
set (flags ${ARGV})
|
||||
list (REMOVE_AT flags 0)
|
||||
get_source_file_property (sources ${file} SOURCES)
|
||||
|
||||
foreach (flag ${flags})
|
||||
get_source_file_property (existing ${file} COMPILE_FLAGS)
|
||||
if ("${existing}" STREQUAL "NOTFOUND")
|
||||
set_source_files_properties (${file}
|
||||
PROPERTIES COMPILE_FLAGS "${flag}")
|
||||
else ()
|
||||
set_source_files_properties (${file}
|
||||
PROPERTIES COMPILE_FLAGS "${existing} ${flag}")
|
||||
endif ()
|
||||
endforeach (flag)
|
||||
endfunction ()
|
||||
|
||||
function (source_file_add_compiler_flags file)
|
||||
set (flags ${ARGV})
|
||||
list (REMOVE_AT flags 0)
|
||||
get_source_file_property (sources ${file} SOURCES)
|
||||
|
||||
foreach (flag ${flags})
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
# Because https://gcc.gnu.org/wiki/FAQ#wnowarning
|
||||
string (REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}")
|
||||
else ()
|
||||
set (flag_to_test ${flag})
|
||||
endif ()
|
||||
|
||||
if (file MATCHES "\\.c$")
|
||||
string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CFLAG_${flag_to_test}")
|
||||
CHECK_C_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name})
|
||||
elseif (file MATCHES "\\.(cpp|cc|cxx)$")
|
||||
string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" test_name "CXXFLAG_${flag_to_test}")
|
||||
CHECK_CXX_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${test_name})
|
||||
endif ()
|
||||
|
||||
if (${test_name})
|
||||
source_file_add_compiler_flags_unchecked (${file} ${flag})
|
||||
endif ()
|
||||
|
||||
unset (test_name)
|
||||
unset (flag_to_test)
|
||||
endforeach (flag)
|
||||
|
||||
unset (flags)
|
||||
endfunction ()
|
||||
|
||||
function (target_add_compiler_flags target)
|
||||
set (flags ${ARGV})
|
||||
list (REMOVE_AT flags 0)
|
||||
get_target_property (sources ${target} SOURCES)
|
||||
|
||||
foreach (source ${sources})
|
||||
source_file_add_compiler_flags (${source} ${flags})
|
||||
endforeach (source)
|
||||
|
||||
unset (flags)
|
||||
unset (sources)
|
||||
endfunction (target_add_compiler_flags)
|
||||
|
||||
# global_add_compiler_flags (flag1 [flag2 [flag3 ...]]):
|
||||
#
|
||||
# This just adds the requested compiler flags to
|
||||
# CMAKE_C/CXX_FLAGS variable if they work with the compiler.
|
||||
function (global_add_compiler_flags)
|
||||
set (flags ${ARGV})
|
||||
|
||||
foreach (flag ${flags})
|
||||
if ("GNU" STREQUAL "${CMAKE_C_COMPILER_ID}")
|
||||
# Because https://gcc.gnu.org/wiki/FAQ#wnowarning
|
||||
string (REGEX REPLACE "\\-Wno\\-(.+)" "-W\\1" flag_to_test "${flag}")
|
||||
else ()
|
||||
set (flag_to_test "${flag}")
|
||||
endif ()
|
||||
|
||||
string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" c_test_name "CFLAG_${flag_to_test}")
|
||||
CHECK_C_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${c_test_name})
|
||||
if (${c_test_name})
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
|
||||
endif ()
|
||||
unset (c_test_name)
|
||||
|
||||
string (REGEX REPLACE "[^a-zA-Z0-9]+" "_" cxx_test_name "CFLAG_${flag_to_test}")
|
||||
CHECK_CXX_COMPILER_FLAG ("${ADD_COMPILER_FLAGS_PREPEND} ${flag_to_test}" ${cxx_test_name})
|
||||
if (${cxx_test_name})
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
|
||||
endif ()
|
||||
unset (cxx_test_name)
|
||||
|
||||
unset (flag_to_test)
|
||||
endforeach (flag)
|
||||
|
||||
unset (flags)
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" PARENT_SCOPE)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
|
||||
endfunction (global_add_compiler_flags)
|
||||
40
thirdparty/portable-snippets/tests/cmake/FindClockGettime.cmake
vendored
Normal file
40
thirdparty/portable-snippets/tests/cmake/FindClockGettime.cmake
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
include (CheckFunctionExists)
|
||||
|
||||
set(ClockGettime_LIBRARIES "")
|
||||
set(ClockGettime_FOUND 0)
|
||||
mark_as_advanced(ClockGettime_LIBRARIES CLOCK_GETTIME_FOUND)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES_orig "${CMAKE_REQUIRED_LIBRARIES}")
|
||||
set(CMAKE_REQUIRED_LIBRARIES "")
|
||||
|
||||
check_function_exists(clock_gettime ClockGettime_LIBC)
|
||||
if(ClockGettime_LIBC)
|
||||
set(ClockGettime_LIBRARIES "")
|
||||
set(ClockGettime_FOUND 1)
|
||||
else()
|
||||
set(CMAKE_REQUIRED_LIBRARIES rt)
|
||||
check_function_exists(clock_gettime ClockGettime_LIBRT)
|
||||
|
||||
if(ClockGettime_LIBRT)
|
||||
set(ClockGettime_LIBRARIES rt)
|
||||
set(ClockGettime_FOUND 1)
|
||||
else()
|
||||
# mingw puts clock_gettime in pthreads
|
||||
set(CMAKE_REQUIRED_LIBRARIES pthread)
|
||||
check_function_exists(clock_gettime ClockGettime_LIBPTHREAD)
|
||||
|
||||
if(ClockGettime_LIBPTHREAD)
|
||||
set(ClockGettime_LIBRARIES pthread)
|
||||
set(ClockGettime_FOUND 1)
|
||||
endif()
|
||||
|
||||
unset(ClockGettime_LIBPTHREAD)
|
||||
endif()
|
||||
|
||||
unset(ClockGettime_LIBRT)
|
||||
endif()
|
||||
|
||||
unset(ClockGettime_LIBC)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES_orig}")
|
||||
unset(CMAKE_REQUIRED_LIBRARIES_orig)
|
||||
57
thirdparty/portable-snippets/tests/cpu.c
vendored
Normal file
57
thirdparty/portable-snippets/tests/cpu.c
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "../exact-int/exact-int.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
static MunitResult
|
||||
test_cpu_info(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 7))
|
||||
# if defined(PSNIP_CPU_ARCH_X86_64) || defined(PSNIP_CPU_ARCH_X86)
|
||||
__builtin_cpu_init();
|
||||
|
||||
munit_assert_int(__builtin_cpu_supports("cmov") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_CMOV));
|
||||
munit_assert_int(__builtin_cpu_supports("mmx") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_MMX));
|
||||
munit_assert_int(__builtin_cpu_supports("popcnt") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_POPCNT));
|
||||
munit_assert_int(__builtin_cpu_supports("sse") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_SSE));
|
||||
munit_assert_int(__builtin_cpu_supports("sse2") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_SSE2));
|
||||
munit_assert_int(__builtin_cpu_supports("sse3") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_SSE3));
|
||||
munit_assert_int(__builtin_cpu_supports("sse4.1") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_SSE4_1));
|
||||
munit_assert_int(__builtin_cpu_supports("sse4.2") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_SSE4_2));
|
||||
munit_assert_int(__builtin_cpu_supports("avx") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX));
|
||||
munit_assert_int(__builtin_cpu_supports("avx2") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX2));
|
||||
#if __GNUC__ >= 5
|
||||
munit_assert_int(__builtin_cpu_supports("avx512f") != 0, ==, psnip_cpu_feature_check(PSNIP_CPU_FEATURE_X86_AVX512F));
|
||||
#endif
|
||||
|
||||
return MUNIT_OK;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return MUNIT_SKIP;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_cpu_count(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_int(psnip_cpu_count(), >, 0);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/cpu/info", test_cpu_info, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/cpu/count", test_cpu_count, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
139
thirdparty/portable-snippets/tests/endian.c
vendored
Normal file
139
thirdparty/portable-snippets/tests/endian.c
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "../exact-int/exact-int.h"
|
||||
#include "../endian/endian.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
const union {
|
||||
unsigned char bytes[2];
|
||||
psnip_uint16_t value;
|
||||
} test_data_16 = {
|
||||
{ 1, 2 }
|
||||
};
|
||||
|
||||
const union {
|
||||
unsigned char bytes[4];
|
||||
psnip_uint32_t value;
|
||||
} test_data_32 = {
|
||||
{ 1, 2, 3, 4 }
|
||||
};
|
||||
|
||||
const union {
|
||||
unsigned char bytes[8];
|
||||
psnip_uint64_t value;
|
||||
} test_data_64 = {
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8 }
|
||||
};
|
||||
|
||||
#if !defined(UINT8_C)
|
||||
# define UINT8_C(c) ((psnip_uint8_t) (c ## U))
|
||||
#endif
|
||||
#if !defined(UINT16_C)
|
||||
# define UINT16_C(c) ((psnip_uint16_t) (c ## U))
|
||||
#endif
|
||||
#if !defined(UINT32_C)
|
||||
# define UINT32_C(c) c ## U
|
||||
#endif
|
||||
#if !defined(UINT64_C)
|
||||
# define UINT64_C(c) c ## ULL
|
||||
#endif
|
||||
|
||||
static MunitResult
|
||||
test_endian_swap_known(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_uint16(psnip_builtin_bswap16(UINT16_C(0xefbe)), ==, UINT16_C(0xbeef));
|
||||
munit_assert_uint32(psnip_builtin_bswap32(UINT32_C(0xefbeadde)), ==, UINT32_C(0xdeadbeef));
|
||||
munit_assert_uint64(psnip_builtin_bswap64(UINT64_C(0x0df0dde0fe0fdcba)), ==, UINT64_C(0xbadc0ffee0ddf00d));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_endian_swap_random(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_uint16(psnip_builtin_bswap16(UINT16_C(0xefbe)), ==, UINT16_C(0xbeef));
|
||||
{
|
||||
const psnip_uint16_t input = (psnip_uint16_t) munit_rand_uint32();
|
||||
const psnip_uint16_t swapped = psnip_builtin_bswap16(input);
|
||||
const psnip_uint16_t double_swapped = psnip_builtin_bswap16(swapped);
|
||||
|
||||
munit_assert_uint16(input, ==, double_swapped);
|
||||
}
|
||||
|
||||
munit_assert_uint32(psnip_builtin_bswap32(UINT32_C(0xefbeadde)), ==, UINT32_C(0xdeadbeef));
|
||||
{
|
||||
const psnip_uint32_t input = munit_rand_uint32();
|
||||
const psnip_uint32_t swapped = psnip_builtin_bswap32(input);
|
||||
const psnip_uint32_t double_swapped = psnip_builtin_bswap32(swapped);
|
||||
|
||||
munit_assert_uint32(input, ==, double_swapped);
|
||||
}
|
||||
|
||||
munit_assert_uint64(psnip_builtin_bswap64(UINT64_C(0xdf0dde0fe0fdcba)), ==, UINT64_C(0xbadc0ffee0ddf00d));
|
||||
{
|
||||
const psnip_uint64_t input = (((psnip_uint64_t) munit_rand_uint32()) << 32) | munit_rand_uint32();
|
||||
const psnip_uint64_t swapped = psnip_builtin_bswap64(input);
|
||||
const psnip_uint64_t double_swapped = psnip_builtin_bswap64(swapped);
|
||||
|
||||
munit_assert_uint64(input, ==, double_swapped);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_endian_from_be(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_uint16(psnip_endian_be16(test_data_16.value), ==, UINT16_C(0x0102));
|
||||
munit_assert_uint32(psnip_endian_be32(test_data_32.value), ==, UINT32_C(0x01020304));
|
||||
munit_assert_uint64(psnip_endian_be64(test_data_64.value), ==, UINT64_C(0x0102030405060708));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_endian_from_le(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_uint16(psnip_endian_le16(test_data_16.value), ==, UINT16_C(0x0201));
|
||||
munit_assert_uint32(psnip_endian_le32(test_data_32.value), ==, UINT32_C(0x04030201));
|
||||
munit_assert_uint64(psnip_endian_le64(test_data_64.value), ==, UINT64_C(0x0807060504030201));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_endian_match_rt(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
#if defined(PSNIP_ENDIAN_ORDER)
|
||||
munit_assert_uint32(PSNIP_ENDIAN_ORDER, ==, PSNIP_ENDIAN_ORDER_RT);
|
||||
#endif
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/endian/swap/known", test_endian_swap_known, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/endian/swap/random", test_endian_swap_random, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/endian/from-be", test_endian_from_be, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/endian/from-le", test_endian_from_le, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ (char*) "/endian/match-rt", test_endian_match_rt, NULL, NULL, MUNIT_TEST_OPTION_SINGLE_ITERATION, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 16384, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
34
thirdparty/portable-snippets/tests/munit/.appveyor.yml
vendored
Normal file
34
thirdparty/portable-snippets/tests/munit/.appveyor.yml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
version: "{build}"
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- ARCHITECTURE: x64
|
||||
MSVC_VER: 14
|
||||
- ARCHITECTURE: x86
|
||||
MSVC_VER: 14
|
||||
- ARCHITECTURE: x64
|
||||
MSVC_VER: 12
|
||||
- ARCHITECTURE: x86
|
||||
MSVC_VER: 12
|
||||
- ARCHITECTURE: x86
|
||||
MSVC_VER: 11
|
||||
- ARCHITECTURE: x86
|
||||
MSVC_VER: 10
|
||||
- ARCHITECTURE: x86
|
||||
MSVC_VER: 9
|
||||
|
||||
branches:
|
||||
except:
|
||||
- master
|
||||
- /^(wip\/)?(travis|osx|mingw|ipp)(\-.+)?$/
|
||||
|
||||
configuration: Debug
|
||||
|
||||
install:
|
||||
|
||||
before_build:
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio %MSVC_VER%.0\VC\vcvarsall.bat" %ARCHITECTURE%
|
||||
|
||||
build_script: cl.exe /W4 /WX /Feexample munit.c example.c
|
||||
|
||||
test_script: example.exe --color always
|
||||
2
thirdparty/portable-snippets/tests/munit/.dir-locals.el
vendored
Normal file
2
thirdparty/portable-snippets/tests/munit/.dir-locals.el
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
((nil . ((indent-tabs-mode . nil)
|
||||
(c-basic-offset . 2))))
|
||||
6
thirdparty/portable-snippets/tests/munit/.gitignore
vendored
Normal file
6
thirdparty/portable-snippets/tests/munit/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
*~
|
||||
.#*
|
||||
/*.o
|
||||
/example
|
||||
/*.exe
|
||||
/*.dll
|
||||
142
thirdparty/portable-snippets/tests/munit/.travis.yml
vendored
Normal file
142
thirdparty/portable-snippets/tests/munit/.travis.yml
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
language: c
|
||||
sudo: false
|
||||
dist: trusty
|
||||
branches:
|
||||
except:
|
||||
- /^(wip\/)?(appveyor|msvc|mingw|windows)(\-.+)?$/
|
||||
- /^master$/
|
||||
matrix:
|
||||
include:
|
||||
###
|
||||
## Linux builds using various versions of GCC.
|
||||
###
|
||||
- env: C_COMPILER=gcc-6
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- env: C_COMPILER=gcc-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-5
|
||||
- g++-5
|
||||
# - env: C_COMPILER=gcc-4.9
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - gcc-4.9
|
||||
# - g++-4.9
|
||||
- env: C_COMPILER=gcc-4.8
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.8
|
||||
- g++-4.8
|
||||
# - env: C_COMPILER=gcc-4.7
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - gcc-4.7
|
||||
# - g++-4.7
|
||||
- env: C_COMPILER=gcc-4.6
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.6
|
||||
- g++-4.6
|
||||
# - os: linux
|
||||
# env: C_COMPILER=gcc-4.5
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - gcc-4.5
|
||||
# - g++-4.5
|
||||
- env: C_COMPILER=gcc-4.4
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-4.4
|
||||
- g++-4.4
|
||||
|
||||
###
|
||||
## clang on Linux
|
||||
###
|
||||
- env: C_COMPILER=clang-3.9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise-3.9
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- clang-3.9
|
||||
# - env: C_COMPILER=clang-3.8
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - llvm-toolchain-precise-3.8
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - clang-3.8
|
||||
- env: C_COMPILER=clang-3.7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise-3.7
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- clang-3.7
|
||||
# - env: C_COMPILER=clang-3.6
|
||||
# addons:
|
||||
# apt:
|
||||
# sources:
|
||||
# - llvm-toolchain-precise-3.6
|
||||
# - ubuntu-toolchain-r-test
|
||||
# packages:
|
||||
# - clang-3.6
|
||||
- env: C_COMPILER=clang-3.5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- llvm-toolchain-precise-3.5
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- clang-3.5
|
||||
|
||||
###
|
||||
## PGI
|
||||
###
|
||||
- env: C_COMPILER=pgcc OPENMP=y
|
||||
|
||||
###
|
||||
## OS X
|
||||
###
|
||||
- os: osx
|
||||
|
||||
before_install:
|
||||
- if [ -n "${C_COMPILER}" ]; then export CC="${C_COMPILER}"; fi
|
||||
- if [ "${C_COMPILER}" = "pgcc" ]; then wget -q -O /dev/stdout 'https://raw.githubusercontent.com/nemequ/pgi-travis/master/install-pgi.sh' | /bin/sh; fi
|
||||
|
||||
script:
|
||||
- make CC="${CC}" AGGRESSIVE_WARNINGS=y EXTENSION="${EXTENSION}" OPENMP="${OPENMP}" ASAN="${ASAN}" UBSAN="${UBSAN}"
|
||||
- make test
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
21
thirdparty/portable-snippets/tests/munit/COPYING
vendored
Normal file
21
thirdparty/portable-snippets/tests/munit/COPYING
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
µnit Testing Framework
|
||||
Copyright (c) 2013-2016 Evan Nemerson <evan@nemerson.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
55
thirdparty/portable-snippets/tests/munit/Makefile
vendored
Normal file
55
thirdparty/portable-snippets/tests/munit/Makefile
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Using µnit is very simple; just include the header and add the C
|
||||
# file to your sources. That said, here is a simple Makefile to build
|
||||
# the example.
|
||||
|
||||
CSTD:=99
|
||||
OPENMP:=n
|
||||
ASAN:=n
|
||||
UBSAN:=n
|
||||
EXTENSION:=
|
||||
TEST_ENV:=
|
||||
CFLAGS:=
|
||||
AGGRESSIVE_WARNINGS=n
|
||||
|
||||
ifeq ($(CC),pgcc)
|
||||
CFLAGS+=-c$(CSTD)
|
||||
else
|
||||
CFLAGS+=-std=c$(CSTD)
|
||||
endif
|
||||
|
||||
ifeq ($(OPENMP),y)
|
||||
ifeq ($(CC),pgcc)
|
||||
CFLAGS+=-mp
|
||||
else
|
||||
CFLAGS+=-fopenmp
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(SANITIZER),)
|
||||
CFLAGS+=-fsanitize=$(SANITIZER)
|
||||
endif
|
||||
|
||||
ifneq ($(CC),pgcc)
|
||||
ifeq ($(EXTRA_WARNINGS),y)
|
||||
CFLAGS+=-Wall -Wextra -Werror
|
||||
endif
|
||||
|
||||
ifeq ($(ASAN),y)
|
||||
CFLAGS+=-fsanitize=address
|
||||
endif
|
||||
|
||||
ifeq ($(UBSAN),y)
|
||||
CFLAGS+=-fsanitize=undefined
|
||||
endif
|
||||
endif
|
||||
|
||||
example$(EXTENSION): munit.h munit.c example.c
|
||||
$(CC) $(CFLAGS) -o $@ munit.c example.c
|
||||
|
||||
test:
|
||||
$(TEST_ENV) ./example$(EXTENSION)
|
||||
|
||||
clean:
|
||||
rm -f example$(EXTENSION)
|
||||
|
||||
all: example$(EXTENSION)
|
||||
40
thirdparty/portable-snippets/tests/munit/README.md
vendored
Normal file
40
thirdparty/portable-snippets/tests/munit/README.md
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
# µnit
|
||||
|
||||
µnit is a small but full-featured unit testing framework for C. It has
|
||||
no dependencies (beyond libc), is permissively licensed (MIT), and is
|
||||
easy to include into any project.
|
||||
|
||||
For more information, see
|
||||
[the µnit web site](https://nemequ.github.io/munit).
|
||||
|
||||
[](https://travis-ci.org/nemequ/munit)
|
||||
[](https://ci.appveyor.com/project/quixdb/munit/branch/master)
|
||||
|
||||
## Features
|
||||
|
||||
Features µnit currently includes include:
|
||||
|
||||
* Handy assertion macros which make for nice error messages.
|
||||
* Reproducible cross-platform random number generation, including
|
||||
support for supplying a seed via CLI.
|
||||
* Timing of both wall-clock and CPU time.
|
||||
* Parameterized tests.
|
||||
* Nested test suites.
|
||||
* Flexible CLI.
|
||||
* Forking
|
||||
([except on Windows](https://github.com/nemequ/munit/issues/2)).
|
||||
* Hiding output of successful tests.
|
||||
|
||||
Features µnit does not currently include, but some day may include
|
||||
(a.k.a., if you file a PR…), include:
|
||||
|
||||
* [TAP](http://testanything.org/) support; feel free to discuss in
|
||||
[issue #1](https://github.com/nemequ/munit/issues/1)
|
||||
|
||||
## Documentation
|
||||
|
||||
See [the µnit web site](https://nemequ.github.io/munit).
|
||||
|
||||
Additionally, there is a heavily-commented
|
||||
[example.c](https://github.com/nemequ/munit/blob/master/example.c) in
|
||||
the repository.
|
||||
351
thirdparty/portable-snippets/tests/munit/example.c
vendored
Normal file
351
thirdparty/portable-snippets/tests/munit/example.c
vendored
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
/* Example file for using µnit.
|
||||
*
|
||||
* µnit is MIT-licensed, but for this file and this file alone:
|
||||
*
|
||||
* To the extent possible under law, the author(s) of this file have
|
||||
* waived all copyright and related or neighboring rights to this
|
||||
* work. See <https://creativecommons.org/publicdomain/zero/1.0/> for
|
||||
* details.
|
||||
*********************************************************************/
|
||||
|
||||
#include "munit.h"
|
||||
|
||||
/* This is just to disable an MSVC warning about conditional
|
||||
* expressions being constant, which you shouldn't have to do for your
|
||||
* code. It's only here because we want to be able to do silly things
|
||||
* like assert that 0 != 1 for our demo. */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4127)
|
||||
#endif
|
||||
|
||||
/* Tests are functions that return void, and take a single void*
|
||||
* parameter. We'll get to what that parameter is later. */
|
||||
static MunitResult
|
||||
test_compare(const MunitParameter params[], void* data) {
|
||||
/* We'll use these later */
|
||||
const unsigned char val_uchar = 'b';
|
||||
const short val_short = 1729;
|
||||
double pi = 3.141592654;
|
||||
char* stewardesses = "stewardesses";
|
||||
char* most_fun_word_to_type;
|
||||
|
||||
/* These are just to silence compiler warnings about the parameters
|
||||
* being unused. */
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
/* Let's start with the basics. */
|
||||
munit_assert(0 != 1);
|
||||
|
||||
/* There is also the more verbose, though slightly more descriptive
|
||||
munit_assert_true/false: */
|
||||
munit_assert_false(0);
|
||||
|
||||
/* You can also call munit_error and munit_errorf yourself. We
|
||||
* won't do it is used to indicate a failure, but here is what it
|
||||
* would look like: */
|
||||
/* munit_error("FAIL"); */
|
||||
/* munit_errorf("Goodbye, cruel %s", "world"); */
|
||||
|
||||
/* There are macros for comparing lots of types. */
|
||||
munit_assert_char('a', ==, 'a');
|
||||
|
||||
/* Sure, you could just assert('a' == 'a'), but if you did that, a
|
||||
* failed assertion would just say something like "assertion failed:
|
||||
* val_uchar == 'b'". µnit will tell you the actual values, so a
|
||||
* failure here would result in something like "assertion failed:
|
||||
* val_uchar == 'b' ('X' == 'b')." */
|
||||
munit_assert_uchar(val_uchar, ==, 'b');
|
||||
|
||||
/* Obviously we can handle values larger than 'char' and 'uchar'.
|
||||
* There are versions for char, short, int, long, long long,
|
||||
* int8/16/32/64_t, as well as the unsigned versions of them all. */
|
||||
munit_assert_short(42, <, val_short);
|
||||
|
||||
/* There is also support for size_t.
|
||||
*
|
||||
* The longest word in English without repeating any letters is
|
||||
* "uncopyrightables", which has uncopyrightable (and
|
||||
* dermatoglyphics, which is the study of fingerprints) beat by a
|
||||
* character */
|
||||
munit_assert_size(strlen("uncopyrightables"), >, strlen("dermatoglyphics"));
|
||||
|
||||
/* Of course there is also support for doubles and floats. */
|
||||
munit_assert_double(pi, ==, 3.141592654);
|
||||
|
||||
/* If you want to compare two doubles for equality, you might want
|
||||
* to consider using munit_assert_double_equal. It compares two
|
||||
* doubles for equality within a precison of 1.0 x 10^-(precision).
|
||||
* Note that precision (the third argument to the macro) needs to be
|
||||
* fully evaluated to an integer by the preprocessor so µnit doesn't
|
||||
* have to depend pow, which is often in libm not libc. */
|
||||
munit_assert_double_equal(3.141592654, 3.141592653589793, 9);
|
||||
|
||||
/* And if you want to check strings for equality (or inequality),
|
||||
* there is munit_assert_string_equal/not_equal.
|
||||
*
|
||||
* "stewardesses" is the longest word you can type on a QWERTY
|
||||
* keyboard with only one hand, which makes it loads of fun to type.
|
||||
* If I'm going to have to type a string repeatedly, let's make it a
|
||||
* good one! */
|
||||
munit_assert_string_equal(stewardesses, "stewardesses");
|
||||
|
||||
/* A personal favorite macro which is fantastic if you're working
|
||||
* with binary data, is the one which naïvely checks two blobs of
|
||||
* memory for equality. If this fails it will tell you the offset
|
||||
* of the first differing byte. */
|
||||
munit_assert_memory_equal(7, stewardesses, "steward");
|
||||
|
||||
/* You can also make sure that two blobs differ *somewhere*: */
|
||||
munit_assert_memory_not_equal(8, stewardesses, "steward");
|
||||
|
||||
/* There are equal/not_equal macros for pointers, too: */
|
||||
most_fun_word_to_type = stewardesses;
|
||||
munit_assert_ptr_equal(most_fun_word_to_type, stewardesses);
|
||||
|
||||
/* And null/not_null */
|
||||
munit_assert_null(NULL);
|
||||
munit_assert_not_null(most_fun_word_to_type);
|
||||
|
||||
/* Lets verify that the data parameter is what we expected. We'll
|
||||
* see where this comes from in a bit.
|
||||
*
|
||||
* Note that the casting isn't usually required; if you give this
|
||||
* function a real pointer (instead of a number like 0xdeadbeef) it
|
||||
* would work as expected. */
|
||||
munit_assert_ptr_equal(data, (void*)(uintptr_t)0xdeadbeef);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_rand(const MunitParameter params[], void* user_data) {
|
||||
int random_int;
|
||||
double random_dbl;
|
||||
munit_uint8_t data[5];
|
||||
|
||||
(void) params;
|
||||
(void) user_data;
|
||||
|
||||
/* One thing missing from a lot of unit testing frameworks is a
|
||||
* random number generator. You can't just use srand/rand because
|
||||
* the implementation varies across different platforms, and it's
|
||||
* important to be able to look at the seed used in a failing test
|
||||
* to see if you can reproduce it. Some randomness is a fantastic
|
||||
* thing to have in your tests, I don't know why more people don't
|
||||
* do it...
|
||||
*
|
||||
* µnit's PRNG is re-seeded with the same value for each iteration
|
||||
* of each test. The seed is retrieved from the MUNIT_SEED
|
||||
* envirnment variable or, if none is provided, one will be
|
||||
* (pseudo-)randomly generated. */
|
||||
|
||||
/* If you need an integer in a given range */
|
||||
random_int = munit_rand_int_range(128, 4096);
|
||||
munit_assert_int(random_int, >=, 128);
|
||||
munit_assert_int(random_int, <=, 4096);
|
||||
|
||||
/* Or maybe you want a double, between 0 and 1: */
|
||||
random_dbl = munit_rand_double();
|
||||
munit_assert_double(random_dbl, >=, 0.0);
|
||||
munit_assert_double(random_dbl, <=, 1.0);
|
||||
|
||||
/* Of course, you want to be able to reproduce bugs discovered
|
||||
* during testing, so every time the tests are run they print the
|
||||
* random seed used. When you want to reproduce a result, just put
|
||||
* that random seed in the MUNIT_SEED environment variable; it even
|
||||
* works on different platforms.
|
||||
*
|
||||
* If you want this to pass, use 0xdeadbeef as the random seed and
|
||||
* uncomment the next line of code. Note that the PRNG is not
|
||||
* re-seeded between iterations of the same test, so this will only
|
||||
* work on the first iteration. */
|
||||
/* munit_assert_uint32(munit_rand_uint32(), ==, 1306447409); */
|
||||
|
||||
/* You can also get blobs of random memory: */
|
||||
munit_rand_memory(sizeof(data), data);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
/* This test case shows how to accept parameters. We'll see how to
|
||||
* specify them soon.
|
||||
*
|
||||
* By default, every possible variation of a parameterized test is
|
||||
* run, but you can specify parameters manually if you want to only
|
||||
* run specific test(s), or you can pass the --single argument to the
|
||||
* CLI to have the harness simply choose one variation at random
|
||||
* instead of running them all. */
|
||||
static MunitResult
|
||||
test_parameters(const MunitParameter params[], void* user_data) {
|
||||
const char* foo;
|
||||
const char* bar;
|
||||
|
||||
(void) user_data;
|
||||
|
||||
/* The "foo" parameter is specified as one of the following values:
|
||||
* "one", "two", or "three". */
|
||||
foo = munit_parameters_get(params, "foo");
|
||||
/* Similarly, "bar" is one of "four", "five", or "six". */
|
||||
bar = munit_parameters_get(params, "bar");
|
||||
/* "baz" is a bit more complicated. We don't actually specify a
|
||||
* list of valid values, so by default NULL is passed. However, the
|
||||
* CLI will accept any value. This is a good way to have a value
|
||||
* that is usually selected randomly by the test, but can be
|
||||
* overridden on the command line if desired. */
|
||||
/* const char* baz = munit_parameters_get(params, "baz"); */
|
||||
|
||||
/* Notice that we're returning MUNIT_FAIL instead of writing an
|
||||
* error message. Error messages are generally preferable, since
|
||||
* they make it easier to diagnose the issue, but this is an
|
||||
* option.
|
||||
*
|
||||
* Possible values are:
|
||||
* - MUNIT_OK: Sucess
|
||||
* - MUNIT_FAIL: Failure
|
||||
* - MUNIT_SKIP: The test was skipped; usually this happens when a
|
||||
* particular feature isn't in use. For example, if you're
|
||||
* writing a test which uses a Wayland-only feature, but your
|
||||
* application is running on X11.
|
||||
* - MUNIT_ERROR: The test failed, but not because of anything you
|
||||
* wanted to test. For example, maybe your test downloads a
|
||||
* remote resource and tries to parse it, but the network was
|
||||
* down.
|
||||
*/
|
||||
|
||||
if (strcmp(foo, "one") != 0 &&
|
||||
strcmp(foo, "two") != 0 &&
|
||||
strcmp(foo, "three") != 0)
|
||||
return MUNIT_FAIL;
|
||||
|
||||
if (strcmp(bar, "red") != 0 &&
|
||||
strcmp(bar, "green") != 0 &&
|
||||
strcmp(bar, "blue") != 0)
|
||||
return MUNIT_FAIL;
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
/* The setup function, if you provide one, for a test will be run
|
||||
* before the test, and the return value will be passed as the sole
|
||||
* parameter to the test function. */
|
||||
static void*
|
||||
test_compare_setup(const MunitParameter params[], void* user_data) {
|
||||
(void) params;
|
||||
|
||||
munit_assert_string_equal(user_data, "µnit");
|
||||
return (void*) (uintptr_t) 0xdeadbeef;
|
||||
}
|
||||
|
||||
/* To clean up after a test, you can use a tear down function. The
|
||||
* fixture argument is the value returned by the setup function
|
||||
* above. */
|
||||
static void
|
||||
test_compare_tear_down(void* fixture) {
|
||||
munit_assert_ptr_equal(fixture, (void*)(uintptr_t)0xdeadbeef);
|
||||
}
|
||||
|
||||
static char* foo_params[] = {
|
||||
(char*) "one", (char*) "two", (char*) "three", NULL
|
||||
};
|
||||
|
||||
static char* bar_params[] = {
|
||||
(char*) "red", (char*) "green", (char*) "blue", NULL
|
||||
};
|
||||
|
||||
static MunitParameterEnum test_params[] = {
|
||||
{ (char*) "foo", foo_params },
|
||||
{ (char*) "bar", bar_params },
|
||||
{ (char*) "baz", NULL },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
/* Creating a test suite is pretty simple. First, you'll need an
|
||||
* array of tests: */
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{
|
||||
/* The name is just a unique human-readable way to identify the
|
||||
* test. You can use it to run a specific test if you want, but
|
||||
* usually it's mostly decorative. */
|
||||
(char*) "/example/compare",
|
||||
/* You probably won't be surprised to learn that the tests are
|
||||
* functions. */
|
||||
test_compare,
|
||||
/* If you want, you can supply a function to set up a fixture. If
|
||||
* you supply NULL, the user_data parameter from munit_suite_main
|
||||
* will be used directly. If, however, you provide a callback
|
||||
* here the user_data parameter will be passed to this callback,
|
||||
* and the return value from this callback will be passed to the
|
||||
* test function.
|
||||
*
|
||||
* For our example we don't really need a fixture, but lets
|
||||
* provide one anyways. */
|
||||
test_compare_setup,
|
||||
/* If you passed a callback for the fixture setup function, you
|
||||
* may want to pass a corresponding callback here to reverse the
|
||||
* operation. */
|
||||
test_compare_tear_down,
|
||||
/* Finally, there is a bitmask for options you can pass here. You
|
||||
* can provide either MUNIT_TEST_OPTION_NONE or 0 here to use the
|
||||
* defaults. */
|
||||
MUNIT_TEST_OPTION_NONE,
|
||||
NULL
|
||||
},
|
||||
/* Usually this is written in a much more compact format; all these
|
||||
* comments kind of ruin that, though. Here is how you'll usually
|
||||
* see entries written: */
|
||||
{ (char*) "/example/rand", test_rand, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
/* To tell the test runner when the array is over, just add a NULL
|
||||
* entry at the end. */
|
||||
{ (char*) "/example/parameters", test_parameters, NULL, NULL, MUNIT_TEST_OPTION_NONE, test_params },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
/* If you wanted to have your test suite run other test suites you
|
||||
* could declare an array of them. Of course each sub-suite can
|
||||
* contain more suites, etc. */
|
||||
/* static const MunitSuite other_suites[] = { */
|
||||
/* { "/second", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE }, */
|
||||
/* { NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE } */
|
||||
/* }; */
|
||||
|
||||
/* Now we'll actually declare the test suite. You could do this in
|
||||
* the main function, or on the heap, or whatever you want. */
|
||||
static const MunitSuite test_suite = {
|
||||
/* This string will be prepended to all test names in this suite;
|
||||
* for example, "/example/rand" will become "/µnit/example/rand".
|
||||
* Note that, while it doesn't really matter for the top-level
|
||||
* suite, NULL signal the end of an array of tests; you should use
|
||||
* an empty string ("") instead. */
|
||||
(char*) "",
|
||||
/* The first parameter is the array of test suites. */
|
||||
test_suite_tests,
|
||||
/* In addition to containing test cases, suites can contain other
|
||||
* test suites. This isn't necessary in this example, but it can be
|
||||
* a great help to projects with lots of tests by making it easier
|
||||
* to spread the tests across many files. This is where you would
|
||||
* put "other_suites" (which is commented out above). */
|
||||
NULL,
|
||||
/* An interesting feature of µnit is that it supports automatically
|
||||
* running multiple iterations of the tests. This is usually only
|
||||
* interesting if you make use of the PRNG to randomize your tests
|
||||
* cases a bit, or if you are doing performance testing and want to
|
||||
* average multiple runs. 0 is an alias for 1. */
|
||||
1,
|
||||
/* Just like MUNIT_TEST_OPTION_NONE, you can provide
|
||||
* MUNIT_SUITE_OPTION_NONE or 0 to use the default settings. */
|
||||
MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
/* This is only necessary for EXIT_SUCCESS and EXIT_FAILURE, which you
|
||||
* *should* be using but probably aren't (no, zero and non-zero don't
|
||||
* always mean success and failure). I guess my point is that nothing
|
||||
* about µnit requires it. */
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
/* Finally, we'll actually run our test suite! That second argument
|
||||
* is the user_data parameter which will be passed either to the
|
||||
* test or (if provided) the fixture setup function. */
|
||||
return munit_suite_main(&test_suite, (void*) "µnit", argc, argv);
|
||||
}
|
||||
2047
thirdparty/portable-snippets/tests/munit/munit.c
vendored
Normal file
2047
thirdparty/portable-snippets/tests/munit/munit.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
533
thirdparty/portable-snippets/tests/munit/munit.h
vendored
Normal file
533
thirdparty/portable-snippets/tests/munit/munit.h
vendored
Normal file
|
|
@ -0,0 +1,533 @@
|
|||
/* µnit Testing Framework
|
||||
* Copyright (c) 2013-2017 Evan Nemerson <evan@nemerson.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(MUNIT_H)
|
||||
#define MUNIT_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MUNIT_VERSION(major, minor, revision) \
|
||||
(((major) << 16) | ((minor) << 8) | (revision))
|
||||
|
||||
#define MUNIT_CURRENT_VERSION MUNIT_VERSION(0, 4, 1)
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
# define munit_int8_t __int8
|
||||
# define munit_uint8_t unsigned __int8
|
||||
# define munit_int16_t __int16
|
||||
# define munit_uint16_t unsigned __int16
|
||||
# define munit_int32_t __int32
|
||||
# define munit_uint32_t unsigned __int32
|
||||
# define munit_int64_t __int64
|
||||
# define munit_uint64_t unsigned __int64
|
||||
#else
|
||||
# include <stdint.h>
|
||||
# define munit_int8_t int8_t
|
||||
# define munit_uint8_t uint8_t
|
||||
# define munit_int16_t int16_t
|
||||
# define munit_uint16_t uint16_t
|
||||
# define munit_int32_t int32_t
|
||||
# define munit_uint32_t uint32_t
|
||||
# define munit_int64_t int64_t
|
||||
# define munit_uint64_t uint64_t
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
# if !defined(PRIi8)
|
||||
# define PRIi8 "i"
|
||||
# endif
|
||||
# if !defined(PRIi16)
|
||||
# define PRIi16 "i"
|
||||
# endif
|
||||
# if !defined(PRIi32)
|
||||
# define PRIi32 "i"
|
||||
# endif
|
||||
# if !defined(PRIi64)
|
||||
# define PRIi64 "I64i"
|
||||
# endif
|
||||
# if !defined(PRId8)
|
||||
# define PRId8 "d"
|
||||
# endif
|
||||
# if !defined(PRId16)
|
||||
# define PRId16 "d"
|
||||
# endif
|
||||
# if !defined(PRId32)
|
||||
# define PRId32 "d"
|
||||
# endif
|
||||
# if !defined(PRId64)
|
||||
# define PRId64 "I64d"
|
||||
# endif
|
||||
# if !defined(PRIx8)
|
||||
# define PRIx8 "x"
|
||||
# endif
|
||||
# if !defined(PRIx16)
|
||||
# define PRIx16 "x"
|
||||
# endif
|
||||
# if !defined(PRIx32)
|
||||
# define PRIx32 "x"
|
||||
# endif
|
||||
# if !defined(PRIx64)
|
||||
# define PRIx64 "I64x"
|
||||
# endif
|
||||
# if !defined(PRIu8)
|
||||
# define PRIu8 "u"
|
||||
# endif
|
||||
# if !defined(PRIu16)
|
||||
# define PRIu16 "u"
|
||||
# endif
|
||||
# if !defined(PRIu32)
|
||||
# define PRIu32 "u"
|
||||
# endif
|
||||
# if !defined(PRIu64)
|
||||
# define PRIu64 "I64u"
|
||||
# endif
|
||||
# if !defined(bool)
|
||||
# define bool int
|
||||
# endif
|
||||
# if !defined(true)
|
||||
# define true (!0)
|
||||
# endif
|
||||
# if !defined(false)
|
||||
# define false (!!0)
|
||||
# endif
|
||||
#else
|
||||
# include <inttypes.h>
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define MUNIT_LIKELY(expr) (__builtin_expect ((expr), 1))
|
||||
# define MUNIT_UNLIKELY(expr) (__builtin_expect ((expr), 0))
|
||||
# define MUNIT_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
# define MUNIT_LIKELY(expr) (expr)
|
||||
# define MUNIT_UNLIKELY(expr) (expr)
|
||||
# define MUNIT_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__PGI)
|
||||
# define MUNIT_ARRAY_PARAM(name) name
|
||||
#else
|
||||
# define MUNIT_ARRAY_PARAM(name)
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# define MUNIT_SIZE_MODIFIER "z"
|
||||
# define MUNIT_CHAR_MODIFIER "hh"
|
||||
# define MUNIT_SHORT_MODIFIER "h"
|
||||
#else
|
||||
# if defined(_M_X64) || defined(__amd64__)
|
||||
# define MUNIT_SIZE_MODIFIER "I64"
|
||||
# else
|
||||
# define MUNIT_SIZE_MODIFIER ""
|
||||
# endif
|
||||
# define MUNIT_CHAR_MODIFIER ""
|
||||
# define MUNIT_SHORT_MODIFIER ""
|
||||
#endif
|
||||
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||
# define MUNIT_NO_RETURN _Noreturn
|
||||
#elif defined(__GNUC__)
|
||||
# define MUNIT_NO_RETURN __attribute__((__noreturn__))
|
||||
#elif defined(_MSC_VER)
|
||||
# define MUNIT_NO_RETURN __declspec(noreturn)
|
||||
#else
|
||||
# define MUNIT_NO_RETURN
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
|
||||
# define MUNIT__PUSH_DISABLE_MSVC_C4127 __pragma(warning(push)) __pragma(warning(disable:4127))
|
||||
# define MUNIT__POP_DISABLE_MSVC_C4127 __pragma(warning(pop))
|
||||
#else
|
||||
# define MUNIT__PUSH_DISABLE_MSVC_C4127
|
||||
# define MUNIT__POP_DISABLE_MSVC_C4127
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
MUNIT_LOG_DEBUG,
|
||||
MUNIT_LOG_INFO,
|
||||
MUNIT_LOG_WARNING,
|
||||
MUNIT_LOG_ERROR
|
||||
} MunitLogLevel;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__MINGW32__)
|
||||
# define MUNIT_PRINTF(string_index, first_to_check) __attribute__((format (printf, string_index, first_to_check)))
|
||||
#else
|
||||
# define MUNIT_PRINTF(string_index, first_to_check)
|
||||
#endif
|
||||
|
||||
MUNIT_PRINTF(4, 5)
|
||||
void munit_logf_ex(MunitLogLevel level, const char* filename, int line, const char* format, ...);
|
||||
|
||||
#define munit_logf(level, format, ...) \
|
||||
munit_logf_ex(level, __FILE__, __LINE__, format, __VA_ARGS__)
|
||||
|
||||
#define munit_log(level, msg) \
|
||||
munit_logf(level, "%s", msg)
|
||||
|
||||
MUNIT_NO_RETURN
|
||||
MUNIT_PRINTF(3, 4)
|
||||
void munit_errorf_ex(const char* filename, int line, const char* format, ...);
|
||||
|
||||
#define munit_errorf(format, ...) \
|
||||
munit_errorf_ex(__FILE__, __LINE__, format, __VA_ARGS__)
|
||||
|
||||
#define munit_error(msg) \
|
||||
munit_errorf("%s", msg)
|
||||
|
||||
#define munit_assert(expr) \
|
||||
do { \
|
||||
if (!MUNIT_LIKELY(expr)) { \
|
||||
munit_error("assertion failed: " #expr); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_true(expr) \
|
||||
do { \
|
||||
if (!MUNIT_LIKELY(expr)) { \
|
||||
munit_error("assertion failed: " #expr " is not true"); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_false(expr) \
|
||||
do { \
|
||||
if (!MUNIT_LIKELY(!(expr))) { \
|
||||
munit_error("assertion failed: " #expr " is not false"); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_type_full(prefix, suffix, T, fmt, a, op, b) \
|
||||
do { \
|
||||
T munit_tmp_a_ = (a); \
|
||||
T munit_tmp_b_ = (b); \
|
||||
if (!(munit_tmp_a_ op munit_tmp_b_)) { \
|
||||
munit_errorf("assertion failed: " #a " " #op " " #b " (" prefix "%" fmt suffix " " #op " " prefix "%" fmt suffix ")", \
|
||||
munit_tmp_a_, munit_tmp_b_); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_type(T, fmt, a, op, b) \
|
||||
munit_assert_type_full("", "", T, fmt, a, op, b)
|
||||
|
||||
#define munit_assert_char(a, op, b) \
|
||||
munit_assert_type_full("'\\x", "'", char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b)
|
||||
#define munit_assert_uchar(a, op, b) \
|
||||
munit_assert_type_full("'\\x", "'", unsigned char, "02" MUNIT_CHAR_MODIFIER "x", a, op, b)
|
||||
#define munit_assert_short(a, op, b) \
|
||||
munit_assert_type(short, MUNIT_SHORT_MODIFIER "d", a, op, b)
|
||||
#define munit_assert_ushort(a, op, b) \
|
||||
munit_assert_type(unsigned short, MUNIT_SHORT_MODIFIER "u", a, op, b)
|
||||
#define munit_assert_int(a, op, b) \
|
||||
munit_assert_type(int, "d", a, op, b)
|
||||
#define munit_assert_uint(a, op, b) \
|
||||
munit_assert_type(unsigned int, "u", a, op, b)
|
||||
#define munit_assert_long(a, op, b) \
|
||||
munit_assert_type(long int, "ld", a, op, b)
|
||||
#define munit_assert_ulong(a, op, b) \
|
||||
munit_assert_type(unsigned long int, "lu", a, op, b)
|
||||
#define munit_assert_llong(a, op, b) \
|
||||
munit_assert_type(long long int, "lld", a, op, b)
|
||||
#define munit_assert_ullong(a, op, b) \
|
||||
munit_assert_type(unsigned long long int, "llu", a, op, b)
|
||||
|
||||
#define munit_assert_size(a, op, b) \
|
||||
munit_assert_type(size_t, MUNIT_SIZE_MODIFIER "u", a, op, b)
|
||||
|
||||
#define munit_assert_float(a, op, b) \
|
||||
munit_assert_type(float, "f", a, op, b)
|
||||
#define munit_assert_double(a, op, b) \
|
||||
munit_assert_type(double, "g", a, op, b)
|
||||
#define munit_assert_ptr(a, op, b) \
|
||||
munit_assert_type(const void*, "p", a, op, b)
|
||||
|
||||
#define munit_assert_int8(a, op, b) \
|
||||
munit_assert_type(munit_int8_t, PRIi8, a, op, b)
|
||||
#define munit_assert_uint8(a, op, b) \
|
||||
munit_assert_type(munit_uint8_t, PRIu8, a, op, b)
|
||||
#define munit_assert_int16(a, op, b) \
|
||||
munit_assert_type(munit_int16_t, PRIi16, a, op, b)
|
||||
#define munit_assert_uint16(a, op, b) \
|
||||
munit_assert_type(munit_uint16_t, PRIu16, a, op, b)
|
||||
#define munit_assert_int32(a, op, b) \
|
||||
munit_assert_type(munit_int32_t, PRIi32, a, op, b)
|
||||
#define munit_assert_uint32(a, op, b) \
|
||||
munit_assert_type(munit_uint32_t, PRIu32, a, op, b)
|
||||
#define munit_assert_int64(a, op, b) \
|
||||
munit_assert_type(munit_int64_t, PRIi64, a, op, b)
|
||||
#define munit_assert_uint64(a, op, b) \
|
||||
munit_assert_type(munit_uint64_t, PRIu64, a, op, b)
|
||||
|
||||
#define munit_assert_double_equal(a, b, precision) \
|
||||
do { \
|
||||
const double munit_tmp_a_ = (a); \
|
||||
const double munit_tmp_b_ = (b); \
|
||||
const double munit_tmp_diff_ = ((munit_tmp_a_ - munit_tmp_b_) < 0) ? \
|
||||
-(munit_tmp_a_ - munit_tmp_b_) : \
|
||||
(munit_tmp_a_ - munit_tmp_b_); \
|
||||
if (MUNIT_UNLIKELY(munit_tmp_diff_ > 1e-##precision)) { \
|
||||
munit_errorf("assertion failed: " #a " == " #b " (%0." #precision "g == %0." #precision "g)", \
|
||||
munit_tmp_a_, munit_tmp_b_); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#include <string.h>
|
||||
#define munit_assert_string_equal(a, b) \
|
||||
do { \
|
||||
const char* munit_tmp_a_ = a; \
|
||||
const char* munit_tmp_b_ = b; \
|
||||
if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) != 0)) { \
|
||||
munit_errorf("assertion failed: string " #a " == " #b " (\"%s\" == \"%s\")", \
|
||||
munit_tmp_a_, munit_tmp_b_); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_string_not_equal(a, b) \
|
||||
do { \
|
||||
const char* munit_tmp_a_ = a; \
|
||||
const char* munit_tmp_b_ = b; \
|
||||
if (MUNIT_UNLIKELY(strcmp(munit_tmp_a_, munit_tmp_b_) == 0)) { \
|
||||
munit_errorf("assertion failed: string " #a " != " #b " (\"%s\" == \"%s\")", \
|
||||
munit_tmp_a_, munit_tmp_b_); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_memory_equal(size, a, b) \
|
||||
do { \
|
||||
const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \
|
||||
const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \
|
||||
const size_t munit_tmp_size_ = (size); \
|
||||
if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) != 0) { \
|
||||
size_t munit_tmp_pos_; \
|
||||
for (munit_tmp_pos_ = 0 ; munit_tmp_pos_ < munit_tmp_size_ ; munit_tmp_pos_++) { \
|
||||
if (munit_tmp_a_[munit_tmp_pos_] != munit_tmp_b_[munit_tmp_pos_]) { \
|
||||
munit_errorf("assertion failed: memory " #a " == " #b ", at offset %" MUNIT_SIZE_MODIFIER "u", munit_tmp_pos_); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_memory_not_equal(size, a, b) \
|
||||
do { \
|
||||
const unsigned char* munit_tmp_a_ = (const unsigned char*) (a); \
|
||||
const unsigned char* munit_tmp_b_ = (const unsigned char*) (b); \
|
||||
const size_t munit_tmp_size_ = (size); \
|
||||
if (MUNIT_UNLIKELY(memcmp(munit_tmp_a_, munit_tmp_b_, munit_tmp_size_)) == 0) { \
|
||||
munit_errorf("assertion failed: memory" #a " != " #b " (%zu bytes)", munit_tmp_size_); \
|
||||
} \
|
||||
MUNIT__PUSH_DISABLE_MSVC_C4127 \
|
||||
} while (0) \
|
||||
MUNIT__POP_DISABLE_MSVC_C4127
|
||||
|
||||
#define munit_assert_ptr_equal(a, b) \
|
||||
munit_assert_ptr(a, ==, b)
|
||||
#define munit_assert_ptr_not_equal(a, b) \
|
||||
munit_assert_ptr(a, !=, b)
|
||||
#define munit_assert_null(ptr) \
|
||||
munit_assert_ptr(ptr, ==, NULL)
|
||||
#define munit_assert_not_null(ptr) \
|
||||
munit_assert_ptr(ptr, !=, NULL)
|
||||
#define munit_assert_ptr_null(ptr) \
|
||||
munit_assert_ptr(ptr, ==, NULL)
|
||||
#define munit_assert_ptr_not_null(ptr) \
|
||||
munit_assert_ptr(ptr, !=, NULL)
|
||||
|
||||
/*** Memory allocation ***/
|
||||
|
||||
void* munit_malloc_ex(const char* filename, int line, size_t size);
|
||||
|
||||
#define munit_malloc(size) \
|
||||
munit_malloc_ex(__FILE__, __LINE__, (size))
|
||||
|
||||
#define munit_new(type) \
|
||||
((type*) munit_malloc(sizeof(type)))
|
||||
|
||||
#define munit_calloc(nmemb, size) \
|
||||
munit_malloc((nmemb) * (size))
|
||||
|
||||
#define munit_newa(type, nmemb) \
|
||||
((type*) munit_calloc((nmemb), sizeof(type)))
|
||||
|
||||
/*** Random number generation ***/
|
||||
|
||||
void munit_rand_seed(munit_uint32_t seed);
|
||||
munit_uint32_t munit_rand_uint32(void);
|
||||
int munit_rand_int_range(int min, int max);
|
||||
double munit_rand_double(void);
|
||||
void munit_rand_memory(size_t size, munit_uint8_t buffer[MUNIT_ARRAY_PARAM(size)]);
|
||||
|
||||
/*** Tests and Suites ***/
|
||||
|
||||
typedef enum {
|
||||
/* Test successful */
|
||||
MUNIT_OK,
|
||||
/* Test failed */
|
||||
MUNIT_FAIL,
|
||||
/* Test was skipped */
|
||||
MUNIT_SKIP,
|
||||
/* Test failed due to circumstances not intended to be tested
|
||||
* (things like network errors, invalid parameter value, failure to
|
||||
* allocate memory in the test harness, etc.). */
|
||||
MUNIT_ERROR
|
||||
} MunitResult;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char** values;
|
||||
} MunitParameterEnum;
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* value;
|
||||
} MunitParameter;
|
||||
|
||||
const char* munit_parameters_get(const MunitParameter params[], const char* key);
|
||||
|
||||
typedef enum {
|
||||
MUNIT_TEST_OPTION_NONE = 0,
|
||||
MUNIT_TEST_OPTION_SINGLE_ITERATION = 1 << 0,
|
||||
MUNIT_TEST_OPTION_TODO = 1 << 1
|
||||
} MunitTestOptions;
|
||||
|
||||
typedef MunitResult (* MunitTestFunc)(const MunitParameter params[], void* user_data_or_fixture);
|
||||
typedef void* (* MunitTestSetup)(const MunitParameter params[], void* user_data);
|
||||
typedef void (* MunitTestTearDown)(void* fixture);
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
MunitTestFunc test;
|
||||
MunitTestSetup setup;
|
||||
MunitTestTearDown tear_down;
|
||||
MunitTestOptions options;
|
||||
MunitParameterEnum* parameters;
|
||||
} MunitTest;
|
||||
|
||||
typedef enum {
|
||||
MUNIT_SUITE_OPTION_NONE = 0
|
||||
} MunitSuiteOptions;
|
||||
|
||||
typedef struct MunitSuite_ MunitSuite;
|
||||
|
||||
struct MunitSuite_ {
|
||||
char* prefix;
|
||||
MunitTest* tests;
|
||||
MunitSuite* suites;
|
||||
unsigned int iterations;
|
||||
MunitSuiteOptions options;
|
||||
};
|
||||
|
||||
int munit_suite_main(const MunitSuite* suite, void* user_data, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);
|
||||
|
||||
/* Note: I'm not very happy with this API; it's likely to change if I
|
||||
* figure out something better. Suggestions welcome. */
|
||||
|
||||
typedef struct MunitArgument_ MunitArgument;
|
||||
|
||||
struct MunitArgument_ {
|
||||
char* name;
|
||||
bool (* parse_argument)(const MunitSuite* suite, void* user_data, int* arg, int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)]);
|
||||
void (* write_help)(const MunitArgument* argument, void* user_data);
|
||||
};
|
||||
|
||||
int munit_suite_main_custom(const MunitSuite* suite,
|
||||
void* user_data,
|
||||
int argc, char* const argv[MUNIT_ARRAY_PARAM(argc + 1)],
|
||||
const MunitArgument arguments[]);
|
||||
|
||||
#if defined(MUNIT_ENABLE_ASSERT_ALIASES)
|
||||
|
||||
#define assert_true(expr) munit_assert_true(expr)
|
||||
#define assert_false(expr) munit_assert_false(expr)
|
||||
#define assert_char(a, op, b) munit_assert_char(a, op, b)
|
||||
#define assert_uchar(a, op, b) munit_assert_uchar(a, op, b)
|
||||
#define assert_short(a, op, b) munit_assert_short(a, op, b)
|
||||
#define assert_ushort(a, op, b) munit_assert_ushort(a, op, b)
|
||||
#define assert_int(a, op, b) munit_assert_int(a, op, b)
|
||||
#define assert_uint(a, op, b) munit_assert_uint(a, op, b)
|
||||
#define assert_long(a, op, b) munit_assert_long(a, op, b)
|
||||
#define assert_ulong(a, op, b) munit_assert_ulong(a, op, b)
|
||||
#define assert_llong(a, op, b) munit_assert_llong(a, op, b)
|
||||
#define assert_ullong(a, op, b) munit_assert_ullong(a, op, b)
|
||||
#define assert_size(a, op, b) munit_assert_size(a, op, b)
|
||||
#define assert_float(a, op, b) munit_assert_float(a, op, b)
|
||||
#define assert_double(a, op, b) munit_assert_double(a, op, b)
|
||||
#define assert_ptr(a, op, b) munit_assert_ptr(a, op, b)
|
||||
|
||||
#define assert_int8(a, op, b) munit_assert_int8(a, op, b)
|
||||
#define assert_uint8(a, op, b) munit_assert_uint8(a, op, b)
|
||||
#define assert_int16(a, op, b) munit_assert_int16(a, op, b)
|
||||
#define assert_uint16(a, op, b) munit_assert_uint16(a, op, b)
|
||||
#define assert_int32(a, op, b) munit_assert_int32(a, op, b)
|
||||
#define assert_uint32(a, op, b) munit_assert_uint32(a, op, b)
|
||||
#define assert_int64(a, op, b) munit_assert_int64(a, op, b)
|
||||
#define assert_uint64(a, op, b) munit_assert_uint64(a, op, b)
|
||||
|
||||
#define assert_double_equal(a, b, precision) munit_assert_double_equal(a, b, precision)
|
||||
#define assert_string_equal(a, b) munit_assert_string_equal(a, b)
|
||||
#define assert_string_not_equal(a, b) munit_assert_string_not_equal(a, b)
|
||||
#define assert_memory_equal(size, a, b) munit_assert_memory_equal(size, a, b)
|
||||
#define assert_memory_not_equal(size, a, b) munit_assert_memory_not_equal(size, a, b)
|
||||
#define assert_ptr_equal(a, b) munit_assert_ptr_equal(a, b)
|
||||
#define assert_ptr_not_equal(a, b) munit_assert_ptr_not_equal(a, b)
|
||||
#define assert_ptr_null(ptr) munit_assert_null_equal(ptr)
|
||||
#define assert_ptr_not_null(ptr) munit_assert_not_null(ptr)
|
||||
|
||||
#define assert_null(ptr) munit_assert_null(ptr)
|
||||
#define assert_not_null(ptr) munit_assert_not_null(ptr)
|
||||
|
||||
#endif /* defined(MUNIT_ENABLE_ASSERT_ALIASES) */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(MUNIT_H) */
|
||||
|
||||
#if defined(MUNIT_ENABLE_ASSERT_ALIASES)
|
||||
# if defined(assert)
|
||||
# undef assert
|
||||
# endif
|
||||
# define assert(expr) munit_assert(expr)
|
||||
#endif
|
||||
45
thirdparty/portable-snippets/tests/once.c
vendored
Normal file
45
thirdparty/portable-snippets/tests/once.c
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#if defined(PSNIP_ENABLE_PTHREADS)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
#include "../exact-int/exact-int.h"
|
||||
#include "../once/once.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
static psnip_once test_once_basic_once = PSNIP_ONCE_INIT;
|
||||
static int test_once_basic_times_called = 0;
|
||||
|
||||
static void test_once_basic_init(void) {
|
||||
munit_assert_int(test_once_basic_times_called, ==, 0);
|
||||
test_once_basic_times_called++;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_once_basic(const MunitParameter params[], void* data) {
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_assert_int(test_once_basic_times_called, ==, 0);
|
||||
psnip_once_call(&test_once_basic_once, &test_once_basic_init);
|
||||
munit_assert_int(test_once_basic_times_called, ==, 1);
|
||||
psnip_once_call(&test_once_basic_once, &test_once_basic_init);
|
||||
munit_assert_int(test_once_basic_times_called, ==, 1);
|
||||
psnip_once_call(&test_once_basic_once, &test_once_basic_init);
|
||||
munit_assert_int(test_once_basic_times_called, ==, 1);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
/* TODO: thread safety test. */
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/once/basic", test_once_basic, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
93
thirdparty/portable-snippets/tests/random.c
vendored
Normal file
93
thirdparty/portable-snippets/tests/random.c
vendored
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include "../exact-int/exact-int.h"
|
||||
#include "../random/random.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
static MunitResult
|
||||
test_random_secure(const MunitParameter params[], void* data) {
|
||||
psnip_uint8_t buf[4096] = { 0, };
|
||||
int r;
|
||||
size_t p;
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
r = psnip_random_bytes(PSNIP_RANDOM_SOURCE_SECURE, sizeof(buf), buf);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
/* Make sure we actually read some data. */
|
||||
for (p = 0 ; p < sizeof(buf) ; p++)
|
||||
if (buf[p] != 0)
|
||||
break;
|
||||
|
||||
munit_assert_size(p, <, sizeof(buf));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_random_reproducible(const MunitParameter params[], void* data) {
|
||||
const psnip_uint32_t test_data[] = {
|
||||
0x8a4b308cU, 0x15534978U, 0xfec18d9aU, 0x7f345f7dU,
|
||||
0x297766eeU, 0x771fb9f4U, 0x31e5a255U, 0xd0c9819dU,
|
||||
0xef73a350U, 0xd9d26480U, 0xb5367e1aU, 0xc1a02725U,
|
||||
0x8b2a1228U, 0x735c43f6U, 0x63ca3280U, 0x9bcd8362U,
|
||||
0xac305d31U, 0x45f16be6U, 0x53247d92U, 0x363d54fbU,
|
||||
0xaccbf201U, 0xc5963be4U, 0x646402c1U, 0xcbbf2841U,
|
||||
0x16c42c02U, 0xf1b19a74U, 0xe2c78da3U, 0x352ac7a4U,
|
||||
0x0e208ef3U, 0x94fec876U, 0x9fd96b4bU, 0x3ed00c53U
|
||||
};
|
||||
psnip_uint32_t buf[sizeof(test_data) / sizeof(test_data[0])] = { 0, };
|
||||
size_t i;
|
||||
int r;
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
psnip_random_set_seed(1729);
|
||||
|
||||
r = psnip_random_bytes(PSNIP_RANDOM_SOURCE_REPRODUCIBLE, sizeof(buf), (psnip_uint8_t*) buf);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
for (i = 0 ; i < sizeof(buf) / sizeof(buf[0]) ; i++) {
|
||||
munit_assert_uint32(buf[i], ==, test_data[i]);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_random_fast(const MunitParameter params[], void* data) {
|
||||
psnip_uint8_t buf[4096] = { 0, };
|
||||
int r;
|
||||
size_t p;
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
r = psnip_random_bytes(PSNIP_RANDOM_SOURCE_FAST, sizeof(buf), buf);
|
||||
munit_assert_int(r, ==, 0);
|
||||
|
||||
/* Make sure we actually read some data. */
|
||||
for (p = 0 ; p < sizeof(buf) ; p++)
|
||||
if (buf[p] != 0)
|
||||
break;
|
||||
|
||||
munit_assert_size(p, <, sizeof(buf));
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/random/secure", test_random_secure, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/random/reproducible", test_random_reproducible, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/random/fast", test_random_fast, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
211
thirdparty/portable-snippets/tests/safe-math.c
vendored
Normal file
211
thirdparty/portable-snippets/tests/safe-math.c
vendored
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#include "../exact-int/exact-int.h"
|
||||
#define PSNIP_BUILTIN_EMULATE_NATIVE
|
||||
#include "../safe-math/safe-math.h"
|
||||
|
||||
#include "munit/munit.h"
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
static MunitResult
|
||||
test_safe_generic(const MunitParameter params[], void* user_data) {
|
||||
unsigned long long a = 1, b = 1, res;
|
||||
|
||||
(void) params;
|
||||
(void) user_data;
|
||||
|
||||
do {
|
||||
if (!psnip_safe_add(&res, a, b)) {
|
||||
munit_logf(MUNIT_LOG_DEBUG, "%llu + %llu overflows", a, b);
|
||||
break;
|
||||
}
|
||||
|
||||
munit_logf(MUNIT_LOG_DEBUG, "%llu + %llu = %llu", a, b, res);
|
||||
a = b;
|
||||
b = res;
|
||||
} while (1);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TESTS(T, name, min, max) \
|
||||
static MunitResult \
|
||||
test_safe_##name##_add(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_add(&result, 0, 1)); \
|
||||
munit_assert_##name(result, ==, 1); \
|
||||
munit_assert_true(psnip_safe_##name##_add(&result, 1, 1)); \
|
||||
munit_assert_##name(result, ==, 2); \
|
||||
munit_assert_true(psnip_safe_##name##_add(&result, 1, max - 1)); \
|
||||
munit_assert_##name(result, ==, max); \
|
||||
munit_assert_false(psnip_safe_##name##_add(&result, max, 1)); \
|
||||
return MUNIT_OK; \
|
||||
} \
|
||||
\
|
||||
static MunitResult \
|
||||
test_safe_##name##_sub(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_sub(&result, 1, 1)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
munit_assert_false(psnip_safe_##name##_sub(&result, min, 1)); \
|
||||
munit_assert_true(psnip_safe_##name##_sub(&result, max, 1)); \
|
||||
munit_assert_##name(result, ==, max - 1); \
|
||||
return MUNIT_OK; \
|
||||
} \
|
||||
\
|
||||
static MunitResult \
|
||||
test_safe_##name##_mul(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_mul(&result, 2, 2)); \
|
||||
munit_assert_##name(result, ==, 4); \
|
||||
munit_assert_true(psnip_safe_##name##_mul(&result, 0, max)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
munit_assert_true(psnip_safe_##name##_mul(&result, max, 0)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
munit_assert_true(psnip_safe_##name##_mul(&result, min, 0)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
return MUNIT_OK; \
|
||||
} \
|
||||
\
|
||||
static MunitResult \
|
||||
test_safe_##name##_div(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_div(&result, 2, 2)); \
|
||||
munit_assert_##name(result, ==, 1); \
|
||||
munit_assert_false(psnip_safe_##name##_div(&result, 1, 0)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
return MUNIT_OK; \
|
||||
} \
|
||||
\
|
||||
static MunitResult \
|
||||
test_safe_##name##_mod(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_mod(&result, 10, 4)); \
|
||||
munit_assert_##name(result, ==, 2); \
|
||||
munit_assert_false(psnip_safe_##name##_mod(&result, 1, 0)); \
|
||||
munit_assert_##name(result, ==, 0); \
|
||||
return MUNIT_OK; \
|
||||
}
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TESTS_S(T, name, min, max) \
|
||||
DEFINE_PSNIP_SAFE_TESTS(T, name, min, max) \
|
||||
static MunitResult \
|
||||
test_safe_##name##_div_signed(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_false(psnip_safe_##name##_div(&result, min, -1)); \
|
||||
munit_assert_##name(result, ==, min); \
|
||||
return MUNIT_OK; \
|
||||
} \
|
||||
\
|
||||
static MunitResult \
|
||||
test_safe_##name##_neg_signed(const MunitParameter params[], void* user_data) { \
|
||||
T result; \
|
||||
(void) params; \
|
||||
(void) user_data; \
|
||||
munit_assert_true(psnip_safe_##name##_neg(&result, max)); \
|
||||
munit_assert_##name(result, ==, -max); \
|
||||
munit_assert_false(psnip_safe_##name##_neg(&result, min)); \
|
||||
munit_assert_##name(result, ==, max); \
|
||||
return MUNIT_OK; \
|
||||
}
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TEST_ENTRY(name, op) \
|
||||
{ (char*) "/" #name "/" #op, test_safe_##name##_##op, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TEST_ENTRY_S(name, op) \
|
||||
{ (char*) "/" #name "/" #op "/signed", test_safe_##name##_##op##_signed, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TEST_ENTRIES(name) \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY(name, add), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY(name, sub), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY(name, mul), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY(name, div), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY(name, mod)
|
||||
|
||||
#define DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(name) \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(name), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY_S(name, div), \
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRY_S(name, neg)
|
||||
|
||||
#if CHAR_MIN < 0
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(char, char, CHAR_MIN, CHAR_MAX)
|
||||
#else
|
||||
DEFINE_PSNIP_SAFE_TESTS (char, char, CHAR_MIN, CHAR_MAX)
|
||||
#endif
|
||||
DEFINE_PSNIP_SAFE_TESTS (unsigned char, uchar, 0, UCHAR_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(short, short, SHRT_MIN, SHRT_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS (unsigned short, ushort, 0, USHRT_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(int, int, INT_MIN, INT_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS (unsigned int, uint, 0, UINT_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(long, long, LONG_MIN, LONG_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS (unsigned long, ulong, 0, ULONG_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(long long, llong, LLONG_MIN, LLONG_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS (unsigned long long, ullong, 0, ULLONG_MAX)
|
||||
#if defined(SIZE_MAX)
|
||||
DEFINE_PSNIP_SAFE_TESTS (size_t, size, 0, SIZE_MAX)
|
||||
#endif
|
||||
#if !defined(PSNIP_SAFE_NO_FIXED)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(psnip_int8_t, int8, (-0x7fLL-1), 0x7f)
|
||||
DEFINE_PSNIP_SAFE_TESTS (psnip_uint8_t, uint8, 0, 0xffU)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(psnip_int16_t, int16, (-0x7fffLL-1), 0x7fff)
|
||||
DEFINE_PSNIP_SAFE_TESTS (psnip_uint16_t, uint16, 0, 0xffffU)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(psnip_int32_t, int32, (-0x7fffffffLL-1), 0x7fffffffL)
|
||||
DEFINE_PSNIP_SAFE_TESTS (psnip_uint32_t, uint32, 0, 0xffffffffUL)
|
||||
DEFINE_PSNIP_SAFE_TESTS_S(psnip_int64_t, int64, (-0x7fffffffffffffffLL-1), 0x7fffffffffffffffLL)
|
||||
DEFINE_PSNIP_SAFE_TESTS (psnip_uint64_t, uint64, 0, 0xffffffffffffffffULL)
|
||||
#endif /* !defined(PSNIP_SAFE_NO_FIXED) */
|
||||
|
||||
static MunitTest psnip_safe_test_suite_tests[] = {
|
||||
#if CHAR_MIN < 0
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(char),
|
||||
#else
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(char),
|
||||
#endif
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uchar),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(short),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(ushort),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(int),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uint),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(long),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(ulong),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(llong),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(ullong),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(size),
|
||||
#if !defined(PSNIP_SAFE_NO_FIXED)
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(int8),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uint8),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(int16),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uint16),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(int32),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uint32),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES_S(int64),
|
||||
DEFINE_PSNIP_SAFE_TEST_ENTRIES(uint64),
|
||||
#endif /* !defined(PSNIP_SAFE_NO_FIXED) */
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
{ (char*) "/generic", test_safe_generic, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
#endif
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "/safe-math",
|
||||
psnip_safe_test_suite_tests,
|
||||
NULL,
|
||||
1,
|
||||
MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
146
thirdparty/portable-snippets/tests/unaligned.c
vendored
Normal file
146
thirdparty/portable-snippets/tests/unaligned.c
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
#define PSNIP_UNALIGNED_ALLOW_UNDEFINED
|
||||
/* #define PSNIP_UNALIGNED_ALLOW_UBSAN */
|
||||
/* #define PSNIP_UNALIGNED_IMPL 2 */
|
||||
/* #define PSNIP_UNALIGNED_IMPL 3 */
|
||||
|
||||
#include "../exact-int/exact-int.h"
|
||||
#include "../unaligned/unaligned.h"
|
||||
#include "munit/munit.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static psnip_uint8_t buffer[1024 * 1024];
|
||||
|
||||
static MunitResult
|
||||
test_unaligned_uint64(const MunitParameter params[], void* data) {
|
||||
psnip_uint64_t v;
|
||||
psnip_uint8_t* c = buffer;
|
||||
psnip_uint8_t* e = &(buffer[sizeof(buffer)]) - sizeof(v);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
while (c <= e) {
|
||||
munit_rand_memory(sizeof(v), (psnip_uint8_t*) &v);
|
||||
v ^= psnip_unaligned_load_uint64(c);
|
||||
psnip_unaligned_store_uint64(c, v);
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_unaligned_uint32(const MunitParameter params[], void* data) {
|
||||
psnip_uint32_t v;
|
||||
psnip_uint8_t* c = buffer;
|
||||
psnip_uint8_t* e = &(buffer[sizeof(buffer)]) - sizeof(v);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
while (c <= e) {
|
||||
munit_rand_memory(sizeof(v), (psnip_uint8_t*) &v);
|
||||
v ^= psnip_unaligned_load_uint32(c);
|
||||
psnip_unaligned_store_uint32(c, v);
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_unaligned_uint16(const MunitParameter params[], void* data) {
|
||||
psnip_uint16_t v;
|
||||
psnip_uint8_t* c = buffer;
|
||||
psnip_uint8_t* e = &(buffer[sizeof(buffer)]) - sizeof(v);
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
while (c <= e) {
|
||||
munit_rand_memory(sizeof(v), (psnip_uint8_t*) &v);
|
||||
v ^= psnip_unaligned_load_uint16(c);
|
||||
psnip_unaligned_store_uint16(c, v);
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
/* Try to get the compiler to vectorize this; SIMD instructions are
|
||||
more likely to have problems with unaligned accesses. */
|
||||
#if defined(__GNUC__)
|
||||
# if !defined(__clang__)
|
||||
__attribute__((__optimize__(3),__noinline__))
|
||||
# else
|
||||
__attribute__((__noinline__))
|
||||
# endif
|
||||
#endif
|
||||
static void
|
||||
dangerous_copy(size_t count, psnip_uint64_t* dest, const psnip_uint64_t* src) {
|
||||
size_t i;
|
||||
for (i = 0 ; i < count ; i++) {
|
||||
psnip_unaligned_store_uint64(&(dest[i]), psnip_unaligned_load_uint64(&(src[i])));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# if defined(__has_attribute) && !defined(__ibmxl__)
|
||||
# if __has_attribute(optnone)
|
||||
__attribute__((__optnone__))
|
||||
# endif
|
||||
# elif !defined(__clang__)
|
||||
__attribute__((__optimize__(0)))
|
||||
# endif
|
||||
__attribute__((__noinline__))
|
||||
#endif
|
||||
static MunitResult
|
||||
test_unaligned_uint64_tempt(const MunitParameter params[], void* data) {
|
||||
static psnip_uint8_t buffer2[sizeof(buffer)];
|
||||
psnip_uint8_t buffer_x = 0;
|
||||
psnip_uint8_t buffer_y = 0;
|
||||
size_t i;
|
||||
|
||||
(void) params;
|
||||
(void) data;
|
||||
|
||||
munit_rand_memory(sizeof(buffer), buffer);
|
||||
|
||||
|
||||
dangerous_copy((sizeof(buffer) / sizeof(psnip_uint64_t)) - 1,
|
||||
(void*) (buffer2 + 1), (void*) (buffer + 1));
|
||||
|
||||
/* XOR all the data together, just to try to convince the compiler
|
||||
* not to optimize anything away. */
|
||||
|
||||
for (i = 1 ; i < (sizeof(buffer) - (sizeof(psnip_uint64_t) - 1)) ; i++) {
|
||||
buffer_x ^= buffer[i];
|
||||
buffer_y ^= buffer[i];
|
||||
}
|
||||
|
||||
munit_assert_uint8(buffer_x, ==, buffer_y);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest test_suite_tests[] = {
|
||||
{ (char*) "/unaligned/uint64", test_unaligned_uint64, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/unaligned/uint32", test_unaligned_uint32, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/unaligned/uint16", test_unaligned_uint16, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ (char*) "/unaligned/uint64/tempt", test_unaligned_uint64_tempt, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL },
|
||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||
};
|
||||
|
||||
static const MunitSuite test_suite = {
|
||||
(char*) "", test_suite_tests, NULL, 1, MUNIT_SUITE_OPTION_NONE
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)]) {
|
||||
munit_rand_memory(sizeof(buffer), buffer);
|
||||
|
||||
return munit_suite_main(&test_suite, NULL, argc, argv);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue