diff --git a/tests/.gitignore b/tests/.gitignore index 1f3e1d8..d84037d 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,5 +1,7 @@ +.DS_Store +.vscode *.dSYM -a.out +*.out *.test *.o *.svg @@ -8,6 +10,10 @@ a.out *.cov.html *.out.js *.out.wasm +*.c.wasm +*.c.test +*.c.worker.js +relations.h libgeos fuzz-* slow-* diff --git a/tests/genrelations.sh b/tests/genrelations.sh new file mode 100755 index 0000000..f239e85 --- /dev/null +++ b/tests/genrelations.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -e +cd $(dirname "${BASH_SOURCE[0]}") + +compfile() { + hexdump -v -e '16/1 "_x%02X" "\n"' $1 | \ + sed 's/_/\\/g; s/\\x //g; s/.*/ "&"/' + echo ";" +} + +compheader() { + echo "// Auto generated file, DO NOT EDIT" + for file in relations/*.jsonc + do + filename=$(basename $file) + filename="${filename%.*}_jsonc" + echo "static const char $filename[] =" + compfile $file + done + echo " +struct relation { + const char *name; + const char *data; +}; + +static struct relation relations[] = {" + for file in relations/*.jsonc + do + filename=$(basename $file) + filename="${filename%.*}_jsonc" + printf " { \"%s\", %s },\n" $(basename $file) $filename + done + + echo "};" +} + +compheader > relations.h + diff --git a/tests/run.sh b/tests/run.sh index 4b9a6bb..ae5f081 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -13,8 +13,8 @@ finish() { rm -fr *.profraw rm -fr *.dSYM rm -fr *.profdata - rm -fr *.out.wasm - rm -fr *.out.js + rm -fr *.wasm + rm -fr *.js if [[ "$OK" != "1" ]]; then echo "FAIL" fi @@ -91,6 +91,15 @@ if [[ "$1" != "bench" ]]; then else CFLAGS=${CFLAGS:-"-O3"} fi +if [[ "$CC" == "emcc" ]]; then + # Running emscripten + CFLAGS="$CFLAGS -sASYNCIFY -sALLOW_MEMORY_GROWTH -sSTACK_SIZE=5MB" + CFLAGS="$CFLAGS -Wno-limited-postlink-optimizations" + CFLAGS="$CFLAGS -Wno-unused-command-line-argument" + CFLAGS="$CFLAGS -Wno-pthreads-mem-growth" + CFLAGS="$CFLAGS -O3" # needs optimizations for test_wkb_max_depth test +fi + CC=${CC:-cc} echo "CC: $CC" echo "CFLAGS: $CFLAGS" @@ -106,6 +115,8 @@ if [[ "$NOSANS" == "1" ]]; then fi echo "TG Commit: `git rev-parse --short HEAD 2>&1 || true`" +./genrelations.sh + # GEOS - used for benchmarking if [[ "$GEOS_BENCH" == "1" ]]; then CFLAGS="$CFLAGS -DGEOS_BENCH" @@ -185,6 +196,8 @@ else fi if [[ "$VALGRIND" == "1" ]]; then valgrind --leak-check=yes ./$f.test $@ + elif [[ "$CC" == "emcc" ]]; then + node ./$f.test $@ else ./$f.test $@ fi diff --git a/tests/test_relations.c b/tests/test_relations.c index 27a70e0..91f2b5b 100644 --- a/tests/test_relations.c +++ b/tests/test_relations.c @@ -412,53 +412,40 @@ static bool test_case(const char *path, const char *org_json, return ok; } -static bool test_relation_file(const char *name) { +static bool test_relation_file(struct relation *rel) { bool ok = true; - char path[512]; - snprintf(path, sizeof(path), "relations/%s", name); - FILE *f = fopen(path, "rb"); - assert(f); - fseek(f, 0, SEEK_END); - size_t sz = ftell(f); - char *jsrc = malloc(sz+1); + char *jsrc = malloc(strlen(rel->data)+1); assert(jsrc); - rewind(f); - assert(fread(jsrc, 1, sz, f) == sz); - jsrc[sz] = '\0'; - json_strip_jsonc(jsrc, sz); + strcpy(jsrc, rel->data); + json_strip_jsonc(jsrc, strlen(jsrc)); if (!json_valid(jsrc)) { - fprintf(stderr, "invalid json: %s\n", path); + fprintf(stderr, "invalid json: %s\n", rel->name); abort(); } struct json json = json_parse(jsrc); json = json_first(json); while (json_exists(json)) { - if (!test_case(name, jsrc, strlen(jsrc), json)) { + if (!test_case(rel->name, jsrc, strlen(jsrc), json)) { ok = false; } json = json_next(json); } free(jsrc); - fclose(f); return ok; } void test_relations_cases(void) { bool ok = true; - DIR *dp = opendir("./relations"); - assert(dp); - struct dirent *ep; - while ((ep = readdir (dp)) != NULL) { - if (strstr(ep->d_name, ".json")) { - if (strstr(ep->d_name, only_file) || strcmp(only_file, "all") == 0) - { - if (!test_relation_file(ep->d_name)) { - ok = false; - } + int nrelations = sizeof(relations) / sizeof(struct relation); + for (int i = 0; i < nrelations; i++) { + struct relation *rel = &relations[i]; + if (strstr(rel->name, only_file) || strcmp(only_file, "all") == 0) + { + if (!test_relation_file(rel)) { + ok = false; } } } - closedir(dp); if (!ok) { exit(1); } diff --git a/tests/test_wkb.c b/tests/test_wkb.c index 5c6c85b..c3dc372 100644 --- a/tests/test_wkb.c +++ b/tests/test_wkb.c @@ -651,7 +651,7 @@ void test_wkb_max_depth() { char *wkt; struct tg_geom *geom; - int depths[] = { 1, 100 , 1000, 1023, 1024, 1025, 2000 }; + int depths[] = { 1, 100, 1000, 1023, 1024, 1025, 2000 }; for (size_t i = 0; i < sizeof(depths)/sizeof(int); i++) { wkt = make_deep_wkb(depths[i]); diff --git a/tests/tests.h b/tests/tests.h index 4044ed3..d77aab0 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -452,6 +452,7 @@ bool eqish(double a, double b) { #endif #pragma GCC diagnostic ignored "-Wextra" #pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Woverlength-strings" size_t total_allocs = 0; size_t total_mem = 0; @@ -776,4 +777,7 @@ struct tg_geom *load_geom(const char *name, enum tg_index ix) { struct tg_geom *load_geom_flipped(const char *name, enum tg_index ix) { return _load_geom(name, ix, true); } + +#include "relations.h" // Auto generated from "run.sh" + #endif // TESTS_H diff --git a/tg.c b/tg.c index 2274c58..fd55cdd 100644 --- a/tg.c +++ b/tg.c @@ -12789,9 +12789,9 @@ static size_t parse_wkb(const uint8_t *wkb, size_t len, size_t i, int depth, // Set the 'swap' bool which indicates that the wkb numbers need swapping // to match the host endianness. -#if BYTE_ORDER == BIG_ENDIAN +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ bool swap = wkb[i] == 1; -#elif BYTE_ORDER == LITTLE_ENDIAN +#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ bool swap = wkb[i] == 0; #else #error "cannot determine byte order" @@ -12899,7 +12899,7 @@ static void write_wkb_type(struct writer *wr, const struct head *head) { } static void write_posn_wkb(struct writer *wr, struct tg_point posn) { -#if BYTE_ORDER == LITTLE_ENDIAN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if (wr->count+16 < wr->n) { memcpy(wr->dst+wr->count, &posn, 16); wr->count += 16; @@ -12912,7 +12912,7 @@ static void write_posn_wkb(struct writer *wr, struct tg_point posn) { static void write_posn_wkb_3(struct writer *wr, struct tg_point posn, double z) { -#if BYTE_ORDER == LITTLE_ENDIAN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if (wr->count+24 < wr->n) { memcpy(wr->dst+wr->count, ((double[3]){posn.x, posn.y, z}), 24); wr->count += 24; @@ -12927,7 +12927,7 @@ static void write_posn_wkb_3(struct writer *wr, struct tg_point posn, double z) static void write_posn_wkb_4(struct writer *wr, struct tg_point posn, double z, double m) { -#if BYTE_ORDER == LITTLE_ENDIAN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if (wr->count+32 < wr->n) { memcpy(wr->dst+wr->count, ((double[4]){posn.x, posn.y, z, m}), 32); wr->count += 32; @@ -12944,7 +12944,7 @@ static int write_ring_points_wkb(struct writer *wr, const struct tg_ring *ring) { write_uint32le(wr, ring->npoints); size_t needed = ring->npoints*16; -#if BYTE_ORDER == LITTLE_ENDIAN +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ if (wr->count+needed <= wr->n) { memcpy(wr->dst+wr->count, ring->points, needed); wr->count += needed;