Skip to content

Commit

Permalink
Support Emscripten
Browse files Browse the repository at this point in the history
    CC=emcc tests/run.sh
  • Loading branch information
tidwall committed Mar 30, 2024
1 parent 1b835df commit 5473087
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 36 deletions.
8 changes: 7 additions & 1 deletion tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.DS_Store
.vscode
*.dSYM
a.out
*.out
*.test
*.o
*.svg
Expand All @@ -8,6 +10,10 @@ a.out
*.cov.html
*.out.js
*.out.wasm
*.c.wasm
*.c.test
*.c.worker.js
relations.h
libgeos
fuzz-*
slow-*
Expand Down
39 changes: 39 additions & 0 deletions tests/genrelations.sh
Original file line number Diff line number Diff line change
@@ -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

17 changes: 15 additions & 2 deletions tests/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down
39 changes: 13 additions & 26 deletions tests/test_relations.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_wkb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
4 changes: 4 additions & 0 deletions tests/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
12 changes: 6 additions & 6 deletions tg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 5473087

Please sign in to comment.