From eb804125430e3445e85c423b28e1c41346772ed0 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 10 Sep 2021 13:20:47 -0400 Subject: Make environments and sinks part of the world Although functions/components that require minimal pre-existing state are nice, these allocate memory and could potentially share resources. So, give them a pointer to a world which can be used to configure such things. In particular, this is working towards supporting custom allocators everywhere. --- include/serd/serd.h | 21 ++++--- src/canon.c | 2 +- src/env.c | 13 +++- src/env.h | 4 ++ src/filter.c | 16 ++--- src/inserter.c | 4 +- src/node_syntax.c | 51 ++++++++++----- src/sink.c | 9 ++- test/test_env.c | 80 ++++++++++++++++-------- test/test_model.c | 10 +-- test/test_node_syntax.c | 156 ++++++++++++++++++++++++++++------------------ test/test_overflow.c | 4 +- test/test_read_chunk.c | 4 +- test/test_reader.c | 33 +++++----- test/test_reader_writer.c | 17 ++--- test/test_sink.c | 14 +++-- test/test_terse_write.c | 2 +- test/test_writer.c | 18 +++--- tools/console.c | 11 ++-- tools/console.h | 3 +- tools/serd-filter.c | 6 +- 21 files changed, 299 insertions(+), 179 deletions(-) diff --git a/include/serd/serd.h b/include/serd/serd.h index 35d31a57..9e322c0d 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -1917,15 +1917,17 @@ typedef void (*SerdFreeFunc)(void* SERD_NULLABLE ptr); /** Create a new sink. + @param world The world the new sink will be a part of. @param handle Opaque handle that will be passed to sink functions. @param event_func Function that will be called for every event. @param free_handle Free function to call on handle in serd_sink_free(). */ SERD_API SerdSink* SERD_ALLOCATED -serd_sink_new(void* SERD_NULLABLE handle, - SerdEventFunc SERD_NULLABLE event_func, - SerdFreeFunc SERD_NULLABLE free_handle); +serd_sink_new(const SerdWorld* SERD_NONNULL world, + void* SERD_NULLABLE handle, + SerdEventFunc SERD_NULLABLE event_func, + SerdFreeFunc SERD_NULLABLE free_handle); /// Free `sink` SERD_API @@ -1996,9 +1998,9 @@ typedef uint32_t SerdCanonFlags; */ SERD_API SerdSink* SERD_ALLOCATED -serd_canon_new(const SerdWorld* SERD_NULLABLE world, - const SerdSink* SERD_NONNULL target, - SerdCanonFlags flags); +serd_canon_new(const SerdWorld* SERD_NONNULL world, + const SerdSink* SERD_NONNULL target, + SerdCanonFlags flags); /** @} @@ -2012,6 +2014,8 @@ serd_canon_new(const SerdWorld* SERD_NULLABLE world, The returned sink acts like `target` in all respects, except that some statements may be dropped. + @param world The world the new sink will be a part of. + @param target The target sink to pass the filtered data to. @param subject The optional subject of the filter pattern. @@ -2028,7 +2032,8 @@ serd_canon_new(const SerdWorld* SERD_NULLABLE world, */ SERD_API SerdSink* SERD_ALLOCATED -serd_filter_new(const SerdSink* SERD_NONNULL target, +serd_filter_new(const SerdWorld* SERD_NONNULL world, + const SerdSink* SERD_NONNULL target, const SerdNode* SERD_NULLABLE subject, const SerdNode* SERD_NULLABLE predicate, const SerdNode* SERD_NULLABLE object, @@ -2047,7 +2052,7 @@ typedef struct SerdEnvImpl SerdEnv; /// Create a new environment SERD_API SerdEnv* SERD_ALLOCATED -serd_env_new(SerdStringView base_uri); +serd_env_new(SerdWorld* SERD_NONNULL world, SerdStringView base_uri); /// Copy an environment SERD_API diff --git a/src/canon.c b/src/canon.c index ac0c91c2..f8f1d8f0 100644 --- a/src/canon.c +++ b/src/canon.c @@ -191,5 +191,5 @@ serd_canon_new(const SerdWorld* const world, data->target = target; data->flags = flags; - return serd_sink_new(data, (SerdEventFunc)serd_canon_on_event, free); + return serd_sink_new(world, data, (SerdEventFunc)serd_canon_on_event, free); } diff --git a/src/env.c b/src/env.c index a6f1b5a9..71cb196f 100644 --- a/src/env.c +++ b/src/env.c @@ -32,6 +32,7 @@ typedef struct { } SerdPrefix; struct SerdEnvImpl { + SerdWorld* world; SerdNodes* nodes; SerdPrefix* prefixes; size_t n_prefixes; @@ -40,10 +41,13 @@ struct SerdEnvImpl { }; SerdEnv* -serd_env_new(const SerdStringView base_uri) +serd_env_new(SerdWorld* const world, const SerdStringView base_uri) { + assert(world); + SerdEnv* env = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl)); + env->world = world; env->nodes = serd_nodes_new(); if (env && base_uri.len) { @@ -62,6 +66,7 @@ serd_env_copy(const SerdEnv* const env) SerdEnv* copy = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl)); if (copy) { + copy->world = env->world; copy->nodes = serd_nodes_new(); copy->n_prefixes = env->n_prefixes; @@ -115,6 +120,12 @@ serd_env_equals(const SerdEnv* const a, const SerdEnv* const b) return true; } +SerdWorld* +serd_env_world(const SerdEnv* const env) +{ + return env->world; +} + SerdURIView serd_env_base_uri_view(const SerdEnv* const env) { diff --git a/src/env.h b/src/env.h index 764e036e..4a487112 100644 --- a/src/env.h +++ b/src/env.h @@ -33,6 +33,10 @@ serd_env_expand_in_place(const SerdEnv* env, SerdStringView* uri_prefix, SerdStringView* uri_suffix); +SERD_PURE_FUNC +SerdWorld* +serd_env_world(const SerdEnv* env); + SERD_CONST_FUNC SerdURIView serd_env_base_uri_view(const SerdEnv* env); diff --git a/src/filter.c b/src/filter.c index e5e8fa29..8efe1e91 100644 --- a/src/filter.c +++ b/src/filter.c @@ -70,13 +70,15 @@ serd_filter_on_event(void* const handle, const SerdEvent* const event) } SerdSink* -serd_filter_new(const SerdSink* const target, - const SerdNode* const subject, - const SerdNode* const predicate, - const SerdNode* const object, - const SerdNode* const graph, - const bool inclusive) +serd_filter_new(const SerdWorld* const world, + const SerdSink* const target, + const SerdNode* const subject, + const SerdNode* const predicate, + const SerdNode* const object, + const SerdNode* const graph, + const bool inclusive) { + assert(world); assert(target); SerdFilterData* const data = @@ -101,5 +103,5 @@ serd_filter_new(const SerdSink* const target, data->graph = serd_node_copy(graph); } - return serd_sink_new(data, serd_filter_on_event, free_data); + return serd_sink_new(world, data, serd_filter_on_event, free_data); } diff --git a/src/inserter.c b/src/inserter.c index 96caf216..9f388921 100644 --- a/src/inserter.c +++ b/src/inserter.c @@ -118,8 +118,8 @@ serd_inserter_new(SerdModel* const model, const SerdNode* const default_graph) data->model = model; data->default_graph = serd_node_copy(default_graph); - SerdSink* const sink = - serd_sink_new(data, (SerdEventFunc)serd_inserter_on_event, free); + SerdSink* const sink = serd_sink_new( + model->world, data, (SerdEventFunc)serd_inserter_on_event, free); return sink; } diff --git a/src/node_syntax.c b/src/node_syntax.c index 5c579b84..261d4b03 100644 --- a/src/node_syntax.c +++ b/src/node_syntax.c @@ -14,6 +14,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "env.h" #include "writer.h" #include "serd/serd.h" @@ -35,7 +36,8 @@ on_node_string_event(void* const handle, const SerdEvent* const event) } static SerdNode* -serd_node_from_syntax_in(const char* const str, +serd_node_from_syntax_in(SerdWorld* const world, + const char* const str, const SerdSyntax syntax, SerdEnv* const env) { @@ -50,9 +52,9 @@ serd_node_from_syntax_in(const char* const str, snprintf(doc, doc_len + 1, "%s %s .", prelude, str); - SerdNode* object = NULL; - SerdWorld* const world = serd_world_new(); - SerdSink* const sink = serd_sink_new(&object, on_node_string_event, NULL); + SerdNode* object = NULL; + SerdSink* const sink = + serd_sink_new(world, &object, on_node_string_event, NULL); SerdReader* const reader = serd_reader_new(world, @@ -73,7 +75,6 @@ serd_node_from_syntax_in(const char* const str, serd_close_input(&in); serd_reader_free(reader); serd_sink_free(sink); - serd_world_free(world); free(doc); return object; @@ -87,22 +88,34 @@ serd_node_from_syntax(const char* const str, assert(str); if (env) { - return serd_node_from_syntax_in(str, syntax, env); + return serd_node_from_syntax_in(serd_env_world(env), str, syntax, env); } - SerdEnv* const temp_env = serd_env_new(SERD_EMPTY_STRING()); - SerdNode* const node = serd_node_from_syntax_in(str, syntax, temp_env); + SerdWorld* const temp_world = serd_world_new(); + if (!temp_world) { + return NULL; + } + + SerdEnv* const temp_env = serd_env_new(temp_world, SERD_EMPTY_STRING()); + if (!temp_env) { + serd_world_free(temp_world); + return NULL; + } + + SerdNode* const node = + serd_node_from_syntax_in(temp_world, str, syntax, temp_env); serd_env_free(temp_env); + serd_world_free(temp_world); return node; } static char* -serd_node_to_syntax_in(const SerdNode* const node, +serd_node_to_syntax_in(SerdWorld* const world, + const SerdNode* const node, const SerdSyntax syntax, const SerdEnv* const env) { - SerdWorld* const world = serd_world_new(); SerdBuffer buffer = {NULL, 0}; SerdOutputStream out = serd_open_output_buffer(&buffer); SerdWriter* const writer = serd_writer_new(world, syntax, 0, env, &out, 1); @@ -118,7 +131,6 @@ serd_node_to_syntax_in(const SerdNode* const node, serd_writer_free(writer); serd_close_output(&out); - serd_world_free(world); return result; } @@ -131,12 +143,19 @@ serd_node_to_syntax(const SerdNode* const node, assert(node); if (env) { - return serd_node_to_syntax_in(node, syntax, env); + return serd_node_to_syntax_in(serd_env_world(env), node, syntax, env); } - SerdEnv* const temp_env = serd_env_new(SERD_EMPTY_STRING()); - char* const string = serd_node_to_syntax_in(node, syntax, temp_env); + SerdWorld* const temp_world = serd_world_new(); + SerdEnv* const temp_env = serd_env_new(temp_world, SERD_EMPTY_STRING()); + if (temp_env) { + char* const string = + serd_node_to_syntax_in(temp_world, node, syntax, temp_env); - serd_env_free(temp_env); - return string; + serd_env_free(temp_env); + serd_world_free(temp_world); + return string; + } + + return NULL; } diff --git a/src/sink.c b/src/sink.c index bd6f1193..3e22f11c 100644 --- a/src/sink.c +++ b/src/sink.c @@ -24,10 +24,13 @@ #include SerdSink* -serd_sink_new(void* const handle, - SerdEventFunc event_func, - SerdFreeFunc free_handle) +serd_sink_new(const SerdWorld* const world, + void* const handle, + SerdEventFunc event_func, + SerdFreeFunc free_handle) { + (void)world; + SerdSink* sink = (SerdSink*)calloc(1, sizeof(SerdSink)); sink->handle = handle; diff --git a/test/test_env.c b/test/test_env.c index 3b6e20c9..e2d53f6c 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -28,7 +28,10 @@ test_copy(void) { assert(!serd_env_copy(NULL)); - SerdEnv* const env = serd_env_new(SERD_STRING("http://example.org/base/")); + SerdWorld* const world = serd_world_new(); + + SerdEnv* const env = + serd_env_new(world, SERD_STRING("http://example.org/base/")); serd_env_set_prefix( env, SERD_STRING("eg"), SERD_STRING("http://example.org/")); @@ -49,12 +52,14 @@ test_copy(void) serd_env_free(env_copy); serd_env_free(env); + serd_world_free(world); } static void test_comparison(void) { - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_equals(env, NULL)); assert(!serd_env_equals(NULL, env)); @@ -62,6 +67,7 @@ test_comparison(void) assert(serd_env_equals(env, env)); serd_env_free(env); + serd_world_free(world); } static void @@ -89,8 +95,9 @@ count_prefixes(void* handle, const SerdEvent* event) static void test_base_uri(void) { - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); - SerdNode* const eg = serd_new_uri(SERD_STRING(NS_EG)); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); + SerdNode* const eg = serd_new_uri(SERD_STRING(NS_EG)); // Test that invalid calls work as expected assert(!serd_env_base_uri(env)); @@ -109,8 +116,9 @@ test_base_uri(void) assert(!serd_env_set_base_uri(env, SERD_EMPTY_STRING())); assert(!serd_env_base_uri(env)); - serd_env_free(env); serd_node_free(eg); + serd_env_free(env); + serd_world_free(world); } static void @@ -122,7 +130,8 @@ test_set_prefix(void) static const SerdStringView rel = SERD_STRING("rel"); static const SerdStringView base = SERD_STRING("http://example.org/"); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); // Set a valid prefix assert(!serd_env_set_prefix(env, name1, eg)); @@ -138,25 +147,28 @@ test_set_prefix(void) size_t n_prefixes = 0; SerdSink* const count_prefixes_sink = - serd_sink_new(&n_prefixes, count_prefixes, NULL); + serd_sink_new(world, &n_prefixes, count_prefixes, NULL); serd_env_write_prefixes(env, count_prefixes_sink); serd_sink_free(count_prefixes_sink); assert(n_prefixes == 3); serd_env_free(env); + serd_world_free(world); } static void test_expand_untyped_literal(void) { - SerdNode* const untyped = serd_new_string(SERD_STRING("data")); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdNode* const untyped = serd_new_string(SERD_STRING("data")); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_expand_node(env, untyped)); serd_env_free(env); serd_node_free(untyped); + serd_world_free(world); } static void @@ -164,17 +176,19 @@ test_expand_bad_uri_datatype(void) { static const SerdStringView type = SERD_STRING("Type"); + SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_nodes_new(); const SerdNode* const typed = serd_nodes_literal(nodes, SERD_STRING("data"), SERD_HAS_DATATYPE, type); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_expand_node(env, typed)); serd_env_free(env); serd_nodes_free(nodes); + serd_world_free(world); } static void @@ -182,11 +196,12 @@ test_expand_uri(void) { static const SerdStringView base = SERD_STRING("http://example.org/b/"); - SerdEnv* const env = serd_env_new(base); - SerdNode* const rel = serd_new_uri(SERD_STRING("rel")); - SerdNode* const rel_out = serd_env_expand_node(env, rel); - SerdNode* const empty = serd_new_uri(SERD_EMPTY_STRING()); - SerdNode* const empty_out = serd_env_expand_node(env, empty); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, base); + SerdNode* const rel = serd_new_uri(SERD_STRING("rel")); + SerdNode* const rel_out = serd_env_expand_node(env, rel); + SerdNode* const empty = serd_new_uri(SERD_EMPTY_STRING()); + SerdNode* const empty_out = serd_env_expand_node(env, empty); assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); assert(!strcmp(serd_node_string(empty_out), "http://example.org/b/")); @@ -196,6 +211,7 @@ test_expand_uri(void) serd_node_free(rel_out); serd_node_free(rel); serd_env_free(env); + serd_world_free(world); } static void @@ -203,27 +219,31 @@ test_expand_empty_uri_ref(void) { static const SerdStringView base = SERD_STRING("http://example.org/b/"); - SerdNode* const rel = serd_new_uri(SERD_STRING("rel")); - SerdEnv* const env = serd_env_new(base); - SerdNode* const rel_out = serd_env_expand_node(env, rel); + SerdWorld* const world = serd_world_new(); + SerdNode* const rel = serd_new_uri(SERD_STRING("rel")); + SerdEnv* const env = serd_env_new(world, base); + SerdNode* const rel_out = serd_env_expand_node(env, rel); assert(!strcmp(serd_node_string(rel_out), "http://example.org/b/rel")); serd_node_free(rel_out); serd_env_free(env); serd_node_free(rel); + serd_world_free(world); } static void test_expand_bad_uri(void) { - SerdNode* const bad_uri = serd_new_uri(SERD_STRING("rel")); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdNode* const bad_uri = serd_new_uri(SERD_STRING("rel")); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_expand_node(env, bad_uri)); serd_env_free(env); serd_node_free(bad_uri); + serd_world_free(world); } static void @@ -232,7 +252,8 @@ test_expand_curie(void) static const SerdStringView name = SERD_STRING("eg.1"); static const SerdStringView eg = SERD_STRING(NS_EG); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_set_prefix(env, name, eg)); @@ -244,12 +265,14 @@ test_expand_curie(void) serd_node_free(expanded); serd_env_free(env); + serd_world_free(world); } static void test_expand_bad_curie(void) { - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_expand_curie(NULL, SERD_EMPTY_STRING())); assert(!serd_env_expand_curie(NULL, SERD_STRING("what:ever"))); @@ -257,18 +280,21 @@ test_expand_bad_curie(void) assert(!serd_env_expand_curie(env, SERD_STRING("nocolon"))); serd_env_free(env); + serd_world_free(world); } static void test_expand_blank(void) { - SerdNode* const blank = serd_new_token(SERD_BLANK, SERD_STRING("b1")); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdWorld* const world = serd_world_new(); + SerdNode* const blank = serd_new_token(SERD_BLANK, SERD_STRING("b1")); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(!serd_env_expand_node(env, blank)); serd_env_free(env); serd_node_free(blank); + serd_world_free(world); } static void @@ -278,8 +304,9 @@ test_equals(void) static const SerdStringView base1 = SERD_STRING(NS_EG "b1/"); static const SerdStringView base2 = SERD_STRING(NS_EG "b2/"); - SerdEnv* const env1 = serd_env_new(base1); - SerdEnv* const env2 = serd_env_new(base2); + SerdWorld* const world = serd_world_new(); + SerdEnv* const env1 = serd_env_new(world, base1); + SerdEnv* const env2 = serd_env_new(world, base2); assert(!serd_env_equals(env1, NULL)); assert(!serd_env_equals(NULL, env1)); @@ -305,6 +332,7 @@ test_equals(void) serd_env_free(env1); serd_env_free(env2); + serd_world_free(world); } int diff --git a/test/test_model.c b/test/test_model.c index a64a7b7e..72db88ae 100644 --- a/test/test_model.c +++ b/test/test_model.c @@ -1053,7 +1053,7 @@ test_write_flat_range(SerdWorld* world, const unsigned n_quads) serd_model_add(model, b2, p, o, NULL); SerdBuffer buffer = {NULL, 0}; - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdOutputStream out = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, &out, 1); @@ -1124,7 +1124,7 @@ test_write_bad_list(SerdWorld* world, const unsigned n_quads) serd_model_add(model, norest, pfirst, val2, NULL); SerdBuffer buffer = {NULL, 0}; - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdOutputStream out = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, &out, 1); @@ -1186,7 +1186,7 @@ test_write_infinite_list(SerdWorld* world, const unsigned n_quads) serd_model_add(model, list2, prest, list1, NULL); SerdBuffer buffer = {NULL, 0}; - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdOutputStream out = serd_open_output_buffer(&buffer); SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0, env, &out, 1); @@ -1276,7 +1276,7 @@ test_write_error_in_list_subject(SerdWorld* world, const unsigned n_quads) serd_model_add(model, l2, rdf_rest, rdf_nil, NULL); serd_model_add(model, l1, p, o, NULL); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); for (size_t max_successes = 0; max_successes < 18; ++max_successes) { FailingWriteFuncState state = {0, max_successes}; @@ -1332,7 +1332,7 @@ test_write_error_in_list_object(SerdWorld* world, const unsigned n_quads) serd_model_add(model, l2, rdf_first, two, NULL); serd_model_add(model, l2, rdf_rest, rdf_nil, NULL); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); for (size_t max_successes = 0; max_successes < 21; ++max_successes) { FailingWriteFuncState state = {0, max_successes}; diff --git a/test/test_node_syntax.c b/test/test_node_syntax.c index 9875e656..d9b0afbb 100644 --- a/test/test_node_syntax.c +++ b/test/test_node_syntax.c @@ -20,13 +20,17 @@ #include #include -#include #include static bool -test(const SerdSyntax syntax, SerdNode* const node, const char* const expected) +check(SerdWorld* const world, + const SerdSyntax syntax, + SerdNode* const node, + const char* const expected) { - SerdEnv* const env = serd_env_new(SERD_STRING("http://example.org/base/")); + SerdEnv* const env = + serd_env_new(world, SERD_STRING("http://example.org/base/")); + char* const str = serd_node_to_syntax(node, syntax, env); SerdNode* const copy = serd_node_from_syntax(str, syntax, env); @@ -40,7 +44,7 @@ test(const SerdSyntax syntax, SerdNode* const node, const char* const expected) } static void -test_common(const SerdSyntax syntax) +test_common(SerdWorld* const world, const SerdSyntax syntax) { static const int data[] = {4, 2}; @@ -50,51 +54,66 @@ test_common(const SerdSyntax syntax) static const SerdStringView num_type = SERD_STRING("http://example.org/Decimal"); - assert(test(syntax, serd_new_string(SERD_STRING("node")), "\"node\"")); - - assert(test(syntax, - serd_new_literal( - SERD_STRING("hallo"), SERD_HAS_LANGUAGE, SERD_STRING("de")), - "\"hallo\"@de")); - - assert(test(syntax, - serd_new_literal(SERD_STRING("X"), SERD_HAS_DATATYPE, datatype), - "\"X\"^^")); - assert( - test(syntax, serd_new_token(SERD_BLANK, SERD_STRING("blank")), "_:blank")); - - assert(test(syntax, serd_new_token(SERD_BLANK, SERD_STRING("b0")), "_:b0")); - - assert(test( - syntax, serd_new_token(SERD_BLANK, SERD_STRING("named1")), "_:named1")); - - assert(test(syntax, - serd_new_uri(SERD_STRING("http://example.org/")), - "")); - - assert(test(syntax, - serd_new_double(1.25), - "\"1.25E0\"^^")); - - assert(test(syntax, - serd_new_float(1.25), - "\"1.25E0\"^^")); - - assert(test(syntax, - serd_new_integer(1234, num_type), - "\"1234\"^^")); + check(world, syntax, serd_new_string(SERD_STRING("node")), "\"node\"")); + + assert(check(world, + syntax, + serd_new_literal( + SERD_STRING("hallo"), SERD_HAS_LANGUAGE, SERD_STRING("de")), + "\"hallo\"@de")); + + assert(check(world, + syntax, + serd_new_literal(SERD_STRING("X"), SERD_HAS_DATATYPE, datatype), + "\"X\"^^")); + + assert(check(world, + syntax, + serd_new_token(SERD_BLANK, SERD_STRING("blank")), + "_:blank")); + + assert(check( + world, syntax, serd_new_token(SERD_BLANK, SERD_STRING("b0")), "_:b0")); + + assert(check(world, + syntax, + serd_new_token(SERD_BLANK, SERD_STRING("named1")), + "_:named1")); + + assert(check(world, + syntax, + serd_new_uri(SERD_STRING("http://example.org/")), + "")); + + assert(check(world, + syntax, + serd_new_double(1.25), + "\"1.25E0\"^^")); + + assert(check(world, + syntax, + serd_new_float(1.25), + "\"1.25E0\"^^")); + + assert(check(world, + syntax, + serd_new_integer(1234, num_type), + "\"1234\"^^")); assert( - test(syntax, - serd_new_base64(data, sizeof(data), SERD_EMPTY_STRING()), - "\"BAAAAAIAAAA=\"^^")); + check(world, + syntax, + serd_new_base64(data, sizeof(data), SERD_EMPTY_STRING()), + "\"BAAAAAIAAAA=\"^^")); } static void test_ntriples(void) { - test_common(SERD_NTRIPLES); + SerdWorld* const world = serd_world_new(); + + test_common(world, SERD_NTRIPLES); { // No relative URIs in NTriples, so converting one fails without an env @@ -103,11 +122,13 @@ test_ntriples(void) assert(!serd_node_from_syntax("", SERD_NTRIPLES, NULL)); // If a relative URI can be expanded then all's well - SerdEnv* const env = serd_env_new(SERD_STRING("http://example.org/base/")); - char* const str = serd_node_to_syntax(rel, SERD_NTRIPLES, env); + SerdEnv* const env = + serd_env_new(world, SERD_STRING("http://example.org/base/")); + char* const str = serd_node_to_syntax(rel, SERD_NTRIPLES, env); assert(!strcmp(str, "")); SerdNode* const copy = serd_node_from_syntax(str, SERD_NTRIPLES, env); + assert(!strcmp(serd_node_string(copy), "http://example.org/base/rel/uri")); serd_node_free(copy); @@ -116,21 +137,27 @@ test_ntriples(void) serd_node_free(rel); } - assert(test(SERD_NTRIPLES, - serd_new_decimal(1.25), - "\"1.25\"^^")); + assert(check(world, + SERD_NTRIPLES, + serd_new_decimal(1.25), + "\"1.25\"^^")); - assert(test(SERD_NTRIPLES, - serd_new_integer(1234, SERD_EMPTY_STRING()), - "\"1234\"^^")); + assert(check(world, + SERD_NTRIPLES, + serd_new_integer(1234, SERD_EMPTY_STRING()), + "\"1234\"^^")); - assert(test(SERD_NTRIPLES, - serd_new_boolean(true), - "\"true\"^^")); + assert(check(world, + SERD_NTRIPLES, + serd_new_boolean(true), + "\"true\"^^")); - assert(test(SERD_NTRIPLES, - serd_new_boolean(false), - "\"false\"^^")); + assert(check(world, + SERD_NTRIPLES, + serd_new_boolean(false), + "\"false\"^^")); + + serd_world_free(world); } static void @@ -139,19 +166,24 @@ test_turtle(void) static const SerdStringView xsd_integer = SERD_STRING("http://www.w3.org/2001/XMLSchema#integer"); - test_common(SERD_TURTLE); + SerdWorld* const world = serd_world_new(); + + test_common(world, SERD_TURTLE); + + check(world, SERD_TURTLE, serd_new_uri(SERD_STRING("rel/uri")), ""); - test(SERD_TURTLE, serd_new_uri(SERD_STRING("rel/uri")), ""); + assert(check(world, SERD_TURTLE, serd_new_decimal(1.25), "1.25")); - assert(test(SERD_TURTLE, serd_new_decimal(1.25), "1.25")); + assert(check( + world, SERD_TURTLE, serd_new_integer(1234, SERD_EMPTY_STRING()), "1234")); assert( - test(SERD_TURTLE, serd_new_integer(1234, SERD_EMPTY_STRING()), "1234")); + check(world, SERD_TURTLE, serd_new_integer(1234, xsd_integer), "1234")); - assert(test(SERD_TURTLE, serd_new_integer(1234, xsd_integer), "1234")); + assert(check(world, SERD_TURTLE, serd_new_boolean(true), "true")); + assert(check(world, SERD_TURTLE, serd_new_boolean(false), "false")); - assert(test(SERD_TURTLE, serd_new_boolean(true), "true")); - assert(test(SERD_TURTLE, serd_new_boolean(false), "false")); + serd_world_free(world); } int diff --git a/test/test_overflow.c b/test/test_overflow.c index 2aedc1bb..f7fdfa58 100644 --- a/test/test_overflow.c +++ b/test/test_overflow.c @@ -31,8 +31,8 @@ test_size(SerdWorld* const world, const SerdReaderFlags flags, const size_t stack_size) { - SerdSink* sink = serd_sink_new(NULL, NULL, NULL); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdSink* sink = serd_sink_new(world, NULL, NULL, NULL); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, syntax, flags, env, sink, stack_size); diff --git a/test/test_read_chunk.c b/test/test_read_chunk.c index a956a07d..59f99910 100644 --- a/test/test_read_chunk.c +++ b/test/test_read_chunk.c @@ -92,7 +92,7 @@ int main(void) { SerdWorld* world = serd_world_new(); - SerdSink* sink = serd_sink_new(NULL, on_event, NULL); + SerdSink* sink = serd_sink_new(world, NULL, on_event, NULL); static const char* const string = "@prefix eg: .\n" "@base .\n" @@ -104,7 +104,7 @@ main(void) "eg:s3 eg:p1 eg:o1 .\n" "eg:s4 eg:p1 [ eg:p3 eg:o1 ] .\n"; - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); assert(reader); diff --git a/test/test_reader.c b/test/test_reader.c index d9edc294..80d9533b 100644 --- a/test/test_reader.c +++ b/test/test_reader.c @@ -62,10 +62,12 @@ test_prepare_error(void) size_t n_statements = 0; FILE* const f = tmpfile(); - SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); + SerdSink* const sink = + serd_sink_new(world, &n_statements, count_statements, NULL); + assert(sink); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); @@ -94,10 +96,10 @@ test_read_string(void) SerdWorld* world = serd_world_new(); size_t n_statements = 0; - SerdSink* sink = serd_sink_new(&n_statements, count_statements, NULL); + SerdSink* sink = serd_sink_new(world, &n_statements, count_statements, NULL); assert(sink); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); @@ -196,8 +198,8 @@ test_read_eof_by_page(void) SerdWorld* world = serd_world_new(); size_t ignored = 0u; - SerdSink* sink = serd_sink_new(&ignored, count_statements, NULL); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); @@ -224,8 +226,8 @@ test_read_eof_by_byte(void) { SerdWorld* world = serd_world_new(); size_t ignored = 0u; - SerdSink* sink = serd_sink_new(&ignored, count_statements, NULL); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdSink* sink = serd_sink_new(world, &ignored, count_statements, NULL); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); @@ -255,10 +257,12 @@ test_read_chunks(void) FILE* const f = tmpfile(); static const char null = 0; - SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); + SerdSink* const sink = + serd_sink_new(world, &n_statements, count_statements, NULL); + assert(sink); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); @@ -324,10 +328,11 @@ test_read_empty(void) size_t n_statements = 0; FILE* const f = tmpfile(); - SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); + SerdSink* const sink = + serd_sink_new(world, &n_statements, count_statements, NULL); assert(sink); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, SERD_SYNTAX_EMPTY, 0, env, sink, 4096); @@ -374,8 +379,8 @@ test_error_cursor(void) { SerdWorld* world = serd_world_new(); bool called = false; - SerdSink* sink = serd_sink_new(&called, check_cursor, NULL); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdSink* sink = serd_sink_new(world, &called, check_cursor, NULL); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c index 8bb76083..52be8d74 100644 --- a/test/test_reader_writer.c +++ b/test/test_reader_writer.c @@ -36,11 +36,11 @@ count_statements(void* handle, const SerdEvent* event) static void test_writer(const char* const path) { - FILE* fd = fopen(path, "wb"); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + FILE* fd = fopen(path, "wb"); + SerdWorld* world = serd_world_new(); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); assert(fd); - SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); SerdOutputStream output = serd_open_output_file(path); @@ -133,12 +133,15 @@ test_writer(const char* const path) static void test_reader(const char* path) { - SerdWorld* world = serd_world_new(); - size_t n_statements = 0; - SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); + SerdWorld* world = serd_world_new(); + size_t n_statements = 0; + + SerdSink* const sink = + serd_sink_new(world, &n_statements, count_statements, NULL); + assert(sink); - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); assert(env); // Test that too little stack space fails gracefully diff --git a/test/test_sink.c b/test/test_sink.c index 8bbfbb2d..7c49cc04 100644 --- a/test/test_sink.c +++ b/test/test_sink.c @@ -97,6 +97,7 @@ on_event(void* const handle, const SerdEvent* const event) static void test_callbacks(void) { + SerdWorld* const world = serd_world_new(); SerdNodes* const nodes = serd_nodes_new(); const SerdNode* base = serd_nodes_uri(nodes, SERD_STRING(NS_EG)); @@ -104,7 +105,7 @@ test_callbacks(void) const SerdNode* uri = serd_nodes_uri(nodes, SERD_STRING(NS_EG "uri")); const SerdNode* blank = serd_nodes_blank(nodes, SERD_STRING("b1")); - SerdEnv* env = serd_env_new(serd_node_string_view(base)); + SerdEnv* env = serd_env_new(world, serd_node_string_view(base)); SerdStatement* const statement = serd_statement_new(base, uri, blank, NULL, NULL); @@ -118,7 +119,7 @@ test_callbacks(void) // Call functions on a sink with no functions set - SerdSink* null_sink = serd_sink_new(&state, NULL, NULL); + SerdSink* null_sink = serd_sink_new(world, &state, NULL, NULL); assert(!serd_sink_write_base(null_sink, base)); assert(!serd_sink_write_prefix(null_sink, name, uri)); @@ -141,7 +142,7 @@ test_callbacks(void) // Try again with a sink that has the event handler set - SerdSink* sink = serd_sink_new(&state, on_event, NULL); + SerdSink* sink = serd_sink_new(world, &state, on_event, NULL); assert(!serd_sink_write_base(sink, base)); assert(serd_node_equals(state.last_base, base)); @@ -164,6 +165,7 @@ test_callbacks(void) serd_statement_free(statement); serd_env_free(env); serd_nodes_free(nodes); + serd_world_free(world); } static void @@ -172,12 +174,16 @@ test_free(void) // Free of null should (as always) not crash serd_sink_free(NULL); + SerdWorld* const world = serd_world_new(); + // Set up a sink with dynamically allocated data and a free function uintptr_t* data = (uintptr_t*)calloc(1, sizeof(uintptr_t)); - SerdSink* sink = serd_sink_new(data, NULL, free); + SerdSink* sink = serd_sink_new(world, data, NULL, free); // Free the sink, which should free the data (rely on valgrind or sanitizers) serd_sink_free(sink); + + serd_world_free(world); } int diff --git a/test/test_terse_write.c b/test/test_terse_write.c index d9ce4d1b..02f6bebf 100644 --- a/test/test_terse_write.c +++ b/test/test_terse_write.c @@ -44,7 +44,7 @@ test(void) { SerdBuffer buffer = {NULL, 0}; SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdNodes* nodes = serd_nodes_new(); const SerdNode* b1 = serd_nodes_blank(nodes, SERD_STRING("b1")); diff --git a/test/test_writer.c b/test/test_writer.c index 6ffe5d0f..7e2386be 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -29,7 +29,7 @@ static void test_writer_new(void) { SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdBuffer buffer = {NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); @@ -43,7 +43,7 @@ static void test_write_bad_event(void) { SerdWorld* world = serd_world_new(); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdBuffer buffer = {NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); @@ -72,7 +72,7 @@ test_write_long_literal(void) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdBuffer buffer = {NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); @@ -128,7 +128,7 @@ test_writer_stack_overflow(void) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdOutputStream output = serd_open_output_stream(null_sink, NULL, NULL, NULL); @@ -180,7 +180,7 @@ test_strict_write(void) SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdOutputStream output = serd_open_output_file(path); assert(output.stream); @@ -233,7 +233,7 @@ test_write_error(void) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); const SerdNode* s = serd_nodes_uri(nodes, SERD_STRING("http://example.org/s")); @@ -279,7 +279,7 @@ test_write_empty_syntax(void) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); const SerdNode* s = serd_nodes_uri(nodes, SERD_STRING("http://example.org/s")); @@ -318,7 +318,7 @@ test_write_bad_uri(void) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); const SerdNode* s = serd_nodes_uri(nodes, SERD_STRING("http://example.org/s")); @@ -355,7 +355,7 @@ check_pname_escape(const char* const lname, const char* const expected) { SerdWorld* world = serd_world_new(); SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* env = serd_env_new(world, SERD_EMPTY_STRING()); SerdBuffer buffer = {NULL, 0}; SerdOutputStream output = serd_open_output_buffer(&buffer); diff --git a/tools/console.c b/tools/console.c index c6e55c17..c2166130 100644 --- a/tools/console.c +++ b/tools/console.c @@ -50,8 +50,8 @@ serd_tool_setup(SerdTool* const tool, // We have something to write to, so build the writing environment if (!(tool->world = serd_world_new()) || - !(tool->env = - serd_create_env(program, options.base_uri, options.out_filename)) || + !(tool->env = serd_create_env( + tool->world, program, options.base_uri, options.out_filename)) || !(tool->writer = serd_writer_new( tool->world, serd_choose_syntax( @@ -291,7 +291,8 @@ serd_parse_common_option(OptionIter* const iter, SerdCommonOptions* const opts) } SerdEnv* -serd_create_env(const char* const program, +serd_create_env(SerdWorld* const world, + const char* const program, const char* const base_string, const char* const out_filename) { @@ -302,10 +303,10 @@ serd_create_env(const char* const program, } if (base_string && serd_uri_string_has_scheme(base_string)) { - return serd_env_new(SERD_STRING(base_string)); + return serd_env_new(world, SERD_STRING(base_string)); } - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); serd_set_base_uri_from_path(env, is_rebase ? out_filename : base_string); return env; } diff --git a/tools/console.h b/tools/console.h index 43bc7a12..ef3d7b8d 100644 --- a/tools/console.h +++ b/tools/console.h @@ -109,7 +109,8 @@ SerdStatus serd_parse_common_option(OptionIter* iter, SerdCommonOptions* opts); SerdEnv* -serd_create_env(const char* program, +serd_create_env(SerdWorld* world, + const char* program, const char* base_string, const char* out_filename); diff --git a/tools/serd-filter.c b/tools/serd-filter.c index b172d05d..199125d5 100644 --- a/tools/serd-filter.c +++ b/tools/serd-filter.c @@ -71,9 +71,9 @@ parse_pattern(SerdWorld* const world, SerdInputStream* const in, const bool inclusive) { - SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdEnv* const env = serd_env_new(world, SERD_EMPTY_STRING()); FilterPattern pat = {NULL, NULL, NULL, NULL}; - SerdSink* in_sink = serd_sink_new(&pat, on_pattern_event, NULL); + SerdSink* in_sink = serd_sink_new(world, &pat, on_pattern_event, NULL); SerdReader* reader = serd_reader_new( world, SERD_NQUADS, SERD_READ_VARIABLES, env, in_sink, 4096); @@ -99,7 +99,7 @@ parse_pattern(SerdWorld* const world, } SerdSink* filter = - serd_filter_new(sink, pat.s, pat.p, pat.o, pat.g, inclusive); + serd_filter_new(world, sink, pat.s, pat.p, pat.o, pat.g, inclusive); serd_node_free(pat.s); serd_node_free(pat.p); -- cgit v1.2.1