From c857c0ae873ea7558e8d702ae4c588a21c220409 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 11 Jul 2021 16:26:18 -0400 Subject: Move SerdEnv mutation from writer to reader Writing having side-effects seems questionable in general, and this prepares things for expanding URIs in the reader. --- include/serd/serd.h | 11 +++++---- src/n3.c | 6 +++++ src/reader.c | 2 ++ src/reader.h | 1 + src/serdi.c | 6 ++++- src/writer.c | 58 ++++++++++++++++++++++------------------------- test/test_overflow.c | 4 +++- test/test_read_chunk.c | 4 +++- test/test_reader.c | 39 ++++++++++++++++++++++--------- test/test_reader_writer.c | 9 +++++--- test/test_writer.c | 30 ------------------------ 11 files changed, 87 insertions(+), 83 deletions(-) diff --git a/include/serd/serd.h b/include/serd/serd.h index 403e637c..0db6205f 100644 --- a/include/serd/serd.h +++ b/include/serd/serd.h @@ -1750,6 +1750,7 @@ SerdReader* SERD_ALLOCATED serd_reader_new(SerdWorld* SERD_NONNULL world, SerdSyntax syntax, SerdReaderFlags flags, + SerdEnv* SERD_NONNULL env, const SerdSink* SERD_NONNULL sink, size_t stack_size); @@ -1915,11 +1916,11 @@ typedef uint32_t SerdWriterFlags; /// Create a new RDF writer SERD_API SerdWriter* SERD_ALLOCATED -serd_writer_new(SerdWorld* SERD_NONNULL world, - SerdSyntax syntax, - SerdWriterFlags flags, - SerdEnv* SERD_NONNULL env, - SerdByteSink* SERD_NONNULL byte_sink); +serd_writer_new(SerdWorld* SERD_NONNULL world, + SerdSyntax syntax, + SerdWriterFlags flags, + const SerdEnv* SERD_NONNULL env, + SerdByteSink* SERD_NONNULL byte_sink); /// Free `writer` SERD_API diff --git a/src/n3.c b/src/n3.c index c91303d9..145a0400 100644 --- a/src/n3.c +++ b/src/n3.c @@ -1511,6 +1511,7 @@ read_base(SerdReader* const reader, const bool sparql, const bool token) } serd_node_zero_pad(uri); + TRY(st, serd_env_set_base_uri(reader->env, serd_node_string_view(uri))); TRY(st, serd_sink_write_base(reader->sink, uri)); read_ws_star(reader); @@ -1557,6 +1558,11 @@ read_prefixID(SerdReader* const reader, const bool sparql, const bool token) serd_node_zero_pad(name); serd_node_zero_pad(uri); + + TRY(st, + serd_env_set_prefix( + reader->env, serd_node_string_view(name), serd_node_string_view(uri))); + st = serd_sink_write_prefix(reader->sink, name, uri); if (!sparql) { diff --git a/src/reader.c b/src/reader.c index c2962bdb..f2d929ac 100644 --- a/src/reader.c +++ b/src/reader.c @@ -184,6 +184,7 @@ SerdReader* serd_reader_new(SerdWorld* const world, const SerdSyntax syntax, const SerdReaderFlags flags, + SerdEnv* const env, const SerdSink* const sink, const size_t stack_size) { @@ -195,6 +196,7 @@ serd_reader_new(SerdWorld* const world, me->world = world; me->sink = sink; + me->env = env; me->stack = serd_stack_new(stack_size, serd_node_align); me->syntax = syntax; me->flags = flags; diff --git a/src/reader.h b/src/reader.h index cc8656d3..2374d7de 100644 --- a/src/reader.h +++ b/src/reader.h @@ -45,6 +45,7 @@ struct SerdReaderImpl { SerdNode* rdf_rest; SerdNode* rdf_nil; SerdByteSource* source; + SerdEnv* env; SerdStack stack; SerdSyntax syntax; SerdReaderFlags flags; diff --git a/src/serdi.c b/src/serdi.c index 28cf870d..2acae921 100644 --- a/src/serdi.c +++ b/src/serdi.c @@ -89,6 +89,7 @@ static SerdStatus read_file(SerdWorld* const world, SerdSyntax syntax, const SerdReaderFlags flags, + SerdEnv* const env, const SerdSink* const sink, const size_t stack_size, const char* const filename, @@ -118,7 +119,8 @@ read_file(SerdWorld* const world, return SERD_ERR_UNKNOWN; } - SerdReader* reader = serd_reader_new(world, syntax, flags, sink, stack_size); + SerdReader* reader = + serd_reader_new(world, syntax, flags, env, sink, stack_size); serd_reader_add_blank_prefix(reader, add_prefix); @@ -346,6 +348,7 @@ main(int argc, char** argv) serd_reader_new(world, input_syntax ? input_syntax : SERD_TRIG, reader_flags, + env, serd_writer_sink(writer), stack_size); @@ -390,6 +393,7 @@ main(int argc, char** argv) if ((st = read_file(world, input_syntax, reader_flags, + env, serd_writer_sink(writer), stack_size, inputs[i], diff --git a/src/writer.c b/src/writer.c index 3d4cad19..a0e5f3a3 100644 --- a/src/writer.c +++ b/src/writer.c @@ -120,7 +120,7 @@ struct SerdWriterImpl { SerdSink iface; SerdSyntax syntax; SerdWriterFlags flags; - SerdEnv* env; + const SerdEnv* env; SerdNode* root_node; SerdURIView root_uri; WriteContext* anon_stack; @@ -1315,7 +1315,7 @@ SerdWriter* serd_writer_new(SerdWorld* world, SerdSyntax syntax, SerdWriterFlags flags, - SerdEnv* env, + const SerdEnv* env, SerdByteSink* byte_sink) { const WriteContext context = WRITE_CONTEXT_NULL; @@ -1362,23 +1362,22 @@ serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri) return SERD_ERR_BAD_ARG; } - SerdStatus st = - serd_env_set_base_uri(writer->env, serd_node_string_view(uri)); + SerdStatus st = SERD_SUCCESS; - if (!st) { - if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) { - if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) { - TRY(st, esink(" .\n\n", 4, writer)); - reset_context(writer, true); - } - TRY(st, esink("@base <", 7, writer)); - TRY(st, esink(serd_node_string(uri), uri->length, writer)); - TRY(st, esink("> .\n", 4, writer)); + if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) { + if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) { + TRY(st, esink(" .\n\n", 4, writer)); + reset_context(writer, true); } - writer->indent = 0; - reset_context(writer, true); + + TRY(st, esink("@base <", 7, writer)); + TRY(st, esink(serd_node_string(uri), uri->length, writer)); + TRY(st, esink("> .\n", 4, writer)); } + writer->indent = 0; + reset_context(writer, true); + return st; } @@ -1406,27 +1405,24 @@ serd_writer_set_prefix(SerdWriter* writer, return SERD_ERR_BAD_ARG; } - SerdStatus st = serd_env_set_prefix( - writer->env, serd_node_string_view(name), serd_node_string_view(uri)); - - if (!st) { - if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) { - if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) { - TRY(st, esink(" .\n\n", 4, writer)); - reset_context(writer, true); - } + SerdStatus st = SERD_SUCCESS; - TRY(st, esink("@prefix ", 8, writer)); - TRY(st, esink(serd_node_string(name), name->length, writer)); - TRY(st, esink(": <", 3, writer)); - TRY(st, write_uri_from_node(writer, uri)); - TRY(st, esink("> .\n", 4, writer)); + if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) { + if (ctx(writer, SERD_GRAPH) || ctx(writer, SERD_SUBJECT)) { + TRY(st, esink(" .\n\n", 4, writer)); + reset_context(writer, true); } - writer->indent = 0; - reset_context(writer, true); + TRY(st, esink("@prefix ", 8, writer)); + TRY(st, esink(serd_node_string(name), name->length, writer)); + TRY(st, esink(": <", 3, writer)); + TRY(st, write_uri_from_node(writer, uri)); + TRY(st, esink("> .\n", 4, writer)); } + writer->indent = 0; + reset_context(writer, true); + return st; } diff --git a/test/test_overflow.c b/test/test_overflow.c index 335cd5c7..7f08112d 100644 --- a/test/test_overflow.c +++ b/test/test_overflow.c @@ -33,14 +33,16 @@ test_size(SerdWorld* const world, { SerdSink* sink = serd_sink_new(NULL, NULL, NULL); SerdByteSource* byte_source = serd_byte_source_new_string(str, NULL); + SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); SerdReader* const reader = - serd_reader_new(world, syntax, flags, sink, stack_size); + serd_reader_new(world, syntax, flags, env, sink, stack_size); assert(reader); serd_reader_start(reader, byte_source); const SerdStatus st = serd_reader_read_document(reader); serd_reader_free(reader); + serd_env_free(env); serd_byte_source_free(byte_source); serd_sink_free(sink); diff --git a/test/test_read_chunk.c b/test/test_read_chunk.c index f2681e32..52bb7804 100644 --- a/test/test_read_chunk.c +++ b/test/test_read_chunk.c @@ -106,7 +106,8 @@ main(void) "eg:s4 eg:p1 [ eg:p3 eg:o1 ] .\n", NULL); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0, sink, 4096); + SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); assert(reader); assert(!serd_reader_start(reader, byte_source)); @@ -123,6 +124,7 @@ main(void) assert(!serd_reader_finish(reader)); serd_reader_free(reader); + serd_env_free(env); serd_byte_source_free(byte_source); serd_sink_free(sink); serd_world_free(world); diff --git a/test/test_reader.c b/test/test_reader.c index 7bc8ab48..5cc8d634 100644 --- a/test/test_reader.c +++ b/test/test_reader.c @@ -64,7 +64,10 @@ test_prepare_error(void) SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, sink, 4096); + SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdReader* const reader = + serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); + assert(reader); SerdByteSource* byte_source = serd_byte_source_new_function( @@ -77,6 +80,7 @@ test_prepare_error(void) serd_byte_source_free(byte_source); serd_reader_free(reader); + serd_env_free(env); serd_sink_free(sink); serd_world_free(world); } @@ -90,7 +94,10 @@ test_read_string(void) SerdSink* sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, sink, 4096); + SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + SerdReader* const reader = + serd_reader_new(world, SERD_TURTLE, 0, env, sink, 4096); + assert(reader); SerdByteSource* byte_source = @@ -119,6 +126,7 @@ test_read_string(void) assert(!serd_reader_finish(reader)); serd_reader_free(reader); + serd_env_free(env); serd_byte_source_free(byte_source); serd_sink_free(sink); serd_world_free(world); @@ -179,10 +187,12 @@ test_read_eof_by_page(void) fflush(temp); fseek(temp, 0L, SEEK_SET); - SerdWorld* world = serd_world_new(); - size_t ignored = 0u; - SerdSink* sink = serd_sink_new(&ignored, count_statements, NULL); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, sink, 4096); + 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()); + + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); SerdByteSource* byte_source = serd_byte_source_new_function( (SerdReadFunc)fread, (SerdStreamErrorFunc)ferror, NULL, temp, NULL, 4096); @@ -195,6 +205,7 @@ test_read_eof_by_page(void) serd_byte_source_free(byte_source); serd_reader_free(reader); + serd_env_free(env); serd_sink_free(sink); serd_world_free(world); fclose(temp); @@ -204,10 +215,12 @@ test_read_eof_by_page(void) static void test_read_eof_by_byte(void) { - SerdWorld* world = serd_world_new(); - size_t ignored = 0u; - SerdSink* sink = serd_sink_new(&ignored, count_statements, NULL); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, sink, 4096); + 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()); + + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); size_t n_reads = 0u; SerdByteSource* byte_source = @@ -227,6 +240,7 @@ test_read_eof_by_byte(void) serd_byte_source_free(byte_source); serd_reader_free(reader); + serd_env_free(env); serd_sink_free(sink); serd_world_free(world); } @@ -242,8 +256,10 @@ test_read_chunks(void) SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); + SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); SerdReader* const reader = - serd_reader_new(world, SERD_TURTLE, 0u, sink, 4096); + serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); + assert(reader); SerdByteSource* byte_source = serd_byte_source_new_function( @@ -292,6 +308,7 @@ test_read_chunks(void) serd_byte_source_free(byte_source); serd_reader_free(reader); + serd_env_free(env); serd_sink_free(sink); fclose(f); serd_world_free(world); diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c index 3a9bf7c9..0124784c 100644 --- a/test/test_reader_writer.c +++ b/test/test_reader_writer.c @@ -142,10 +142,12 @@ test_reader(const char* path) SerdSink* const sink = serd_sink_new(&n_statements, count_statements, NULL); assert(sink); - // Test that too little stack space fails gracefully - assert(!serd_reader_new(world, SERD_TURTLE, 0u, sink, 32)); + SerdEnv* const env = serd_env_new(SERD_EMPTY_STRING()); + assert(env); - SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, sink, 4096); + // Test that too little stack space fails gracefully + assert(!serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 32)); + SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0u, env, sink, 4096); assert(reader); assert(serd_reader_read_document(reader) == SERD_ERR_BAD_CALL); @@ -170,6 +172,7 @@ test_reader(const char* path) serd_byte_source_free(byte_source); serd_reader_free(reader); + serd_env_free(env); serd_sink_free(sink); serd_world_free(world); } diff --git a/test/test_writer.c b/test/test_writer.c index df8ba520..dc1ebfcb 100644 --- a/test/test_writer.c +++ b/test/test_writer.c @@ -50,35 +50,6 @@ test_write_bad_event(void) serd_world_free(world); } -static void -test_write_bad_prefix(void) -{ - SerdWorld* world = serd_world_new(); - SerdNodes* nodes = serd_world_nodes(world); - SerdEnv* env = serd_env_new(SERD_EMPTY_STRING()); - SerdBuffer buffer = {NULL, 0}; - SerdByteSink* byte_sink = serd_byte_sink_new_buffer(&buffer); - - SerdWriter* writer = serd_writer_new(world, SERD_TURTLE, 0u, env, byte_sink); - assert(writer); - - const SerdNode* name = serd_nodes_string(nodes, SERD_STRING("eg")); - const SerdNode* uri = serd_nodes_uri(nodes, SERD_STRING("rel")); - - assert(serd_sink_write_prefix(serd_writer_sink(writer), name, uri) == - SERD_ERR_BAD_ARG); - - char* const out = serd_buffer_sink_finish(&buffer); - - assert(!strcmp(out, "")); - serd_free(out); - - serd_writer_free(writer); - serd_byte_sink_free(byte_sink); - serd_env_free(env); - serd_world_free(world); -} - static void test_write_long_literal(void) { @@ -319,7 +290,6 @@ int main(void) { test_write_bad_event(); - test_write_bad_prefix(); test_write_long_literal(); test_writer_stack_overflow(); test_strict_write(); -- cgit v1.2.1