1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "simdjson.h"
// We get spurious "maybe used uninitialized" warnings under GCC 12.
using namespace simdjson;
#if defined(__GNUC__) && !defined(__clang__)
#if __GNUC__ >= 12
SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
#endif
#endif
// This ensures the compiler can't rearrange them into the proper order (which causes it to work!)
simdjson_never_inline bool check_point(simdjson_result<ondemand::value> xval, simdjson_result<ondemand::value> yval) {
// Verify the expected release behavior
uint64_t x, y;
if (!xval.get(x)) { return false; }
if (!yval.get(y)) { return false; }
std::cout << x << "," << y << std::endl;
return true;
}
bool test_check_point() {
auto json = R"(
{
"x": 1,
"y": 2 3
)"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
return check_point(doc["x"], doc["y"]);
}
// Run a test function in a fork and check whether it exited with an assert signal
template<typename F>
bool assert_test(const F& f) {
pid_t pid = fork();
if (pid == -1) {
std::cerr << "fork failed" << std::endl;
exit(1);
}
if (!pid) {
//
// This code runs in the fork (so we run the test function)
//
bool succeeded = f();
exit(succeeded ? 0 : 1);
}
//
// This code runs in the original executable (so we wait for the fork and check the exit code)
//
int exit_code = 0;
if (waitpid(pid, &exit_code, 0) == pid_t(-1)) {
std::cerr << "waitpid failed: " << std::string_view(strerror(errno)) << std::endl;
exit(1);
}
// Test passes if the child exited with an assert signal
return WIFSIGNALED(exit_code);
}
int main(void) {
// To verify that the program asserts (which sends a signal), we fork a new process and use wait()
// to check the resulting error code. If it's a signal error code, we consider the
// test to have passed.
// From https://stackoverflow.com/a/33694733
bool succeeded = true;
#ifndef NDEBUG
succeeded |= assert_test(test_check_point);
#endif
return succeeded ? 0 : 1;
}
|