aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-03-27 05:39:26 -0400
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:08 -0500
commit7ffa2c0488fcd96c3c12713e5650633eb03e91f7 (patch)
tree9ca96bb40f71b6c37789ae641af75e39a2751c18
parent5e4538756d601e6a941c5290777af95ea8848e1a (diff)
downloadserd-7ffa2c0488fcd96c3c12713e5650633eb03e91f7.tar.gz
serd-7ffa2c0488fcd96c3c12713e5650633eb03e91f7.tar.bz2
serd-7ffa2c0488fcd96c3c12713e5650633eb03e91f7.zip
[WIP] 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.
-rw-r--r--include/serd/reader.h2
-rw-r--r--include/serd/writer.h2
-rw-r--r--src/read_turtle.c7
-rw-r--r--src/reader.c3
-rw-r--r--src/reader.h2
-rw-r--r--src/writer.c21
-rw-r--r--test/test_overflow.c4
-rw-r--r--test/test_reader.c49
-rw-r--r--test/test_reader_writer.c11
-rw-r--r--test/test_writer.c32
-rw-r--r--tools/serd-pipe.c9
11 files changed, 76 insertions, 66 deletions
diff --git a/include/serd/reader.h b/include/serd/reader.h
index 040f3398..658193fb 100644
--- a/include/serd/reader.h
+++ b/include/serd/reader.h
@@ -5,6 +5,7 @@
#define SERD_READER_H
#include "serd/attributes.h"
+#include "serd/env.h"
#include "serd/input_stream.h"
#include "serd/node.h"
#include "serd/sink.h"
@@ -41,6 +42,7 @@ SERD_API SerdReader* ZIX_ALLOCATED
serd_reader_new(SerdWorld* ZIX_NONNULL world,
SerdSyntax syntax,
SerdReaderFlags flags,
+ SerdEnv* ZIX_NONNULL env,
const SerdSink* ZIX_NONNULL sink);
/**
diff --git a/include/serd/writer.h b/include/serd/writer.h
index 41ffb8cd..b85c7b82 100644
--- a/include/serd/writer.h
+++ b/include/serd/writer.h
@@ -51,7 +51,7 @@ SERD_API SerdWriter* ZIX_ALLOCATED
serd_writer_new(SerdWorld* ZIX_NONNULL world,
SerdSyntax syntax,
SerdWriterFlags flags,
- SerdEnv* ZIX_NONNULL env,
+ const SerdEnv* ZIX_NONNULL env,
SerdOutputStream* ZIX_NONNULL output,
size_t block_size);
diff --git a/src/read_turtle.c b/src/read_turtle.c
index 22269741..8d9ec78a 100644
--- a/src/read_turtle.c
+++ b/src/read_turtle.c
@@ -14,6 +14,7 @@
#include "turtle.h"
#include "serd/caret.h"
+#include "serd/env.h"
#include "serd/node.h"
#include "serd/reader.h"
#include "serd/sink.h"
@@ -891,6 +892,7 @@ read_turtle_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_turtle_ws_star(reader);
@@ -934,6 +936,11 @@ read_turtle_prefixID(SerdReader* const reader,
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 7e0864cc..8b74836f 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -229,9 +229,11 @@ SerdReader*
serd_reader_new(SerdWorld* const world,
const SerdSyntax syntax,
const SerdReaderFlags flags,
+ SerdEnv* const env,
const SerdSink* const sink)
{
assert(world);
+ assert(env);
assert(sink);
const size_t stack_size = world->limits.reader_stack_size;
@@ -243,6 +245,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 132d038e..302f8c6f 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -11,6 +11,7 @@
#include "serd/attributes.h"
#include "serd/caret.h"
+#include "serd/env.h"
#include "serd/node.h"
#include "serd/reader.h"
#include "serd/sink.h"
@@ -40,6 +41,7 @@ struct SerdReaderImpl {
SerdNode* rdf_rest;
SerdNode* rdf_nil;
SerdByteSource* source;
+ SerdEnv* env;
SerdStack stack;
SerdSyntax syntax;
SerdReaderFlags flags;
diff --git a/src/writer.c b/src/writer.c
index 329a29ad..05be0500 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -131,7 +131,7 @@ struct SerdWriterImpl {
SerdSink iface;
SerdSyntax syntax;
SerdWriterFlags flags;
- SerdEnv* env;
+ const SerdEnv* env;
SerdNode* root_node;
SerdURIView root_uri;
WriteContext* anon_stack;
@@ -1367,7 +1367,7 @@ SerdWriter*
serd_writer_new(SerdWorld* world,
SerdSyntax syntax,
SerdWriterFlags flags,
- SerdEnv* env,
+ const SerdEnv* env,
SerdOutputStream* output,
size_t block_size)
{
@@ -1426,20 +1426,15 @@ serd_writer_set_base_uri(SerdWriter* writer, const SerdNode* uri)
{
assert(writer);
+ SerdStatus st = SERD_SUCCESS;
+
if (uri && serd_node_type(uri) != SERD_URI) {
return SERD_BAD_ARG;
}
- if (serd_node_equals(serd_env_base_uri(writer->env), uri)) {
- return SERD_SUCCESS;
- }
-
const SerdStringView uri_string =
uri ? serd_node_string_view(uri) : serd_empty_string();
- SerdStatus st = SERD_SUCCESS;
- TRY(st, serd_env_set_base_uri(writer->env, uri_string));
-
if (uri && (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG)) {
TRY(st, terminate_context(writer));
TRY(st, esink("@base <", 7, writer));
@@ -1476,16 +1471,16 @@ serd_writer_set_prefix(SerdWriter* writer,
{
SerdStatus st = SERD_SUCCESS;
- TRY(st,
- serd_env_set_prefix(
- writer->env, serd_node_string_view(name), serd_node_string_view(uri)));
+ if (name->type != SERD_LITERAL || uri->type != SERD_URI) {
+ return SERD_BAD_ARG;
+ }
if (writer->syntax == SERD_TURTLE || writer->syntax == SERD_TRIG) {
TRY(st, terminate_context(writer));
TRY(st, esink("@prefix ", 8, writer));
TRY(st, esink(serd_node_string(name), name->length, writer));
TRY(st, esink(": <", 3, writer));
- TRY(st, ewrite_uri(writer, serd_node_string(uri), uri->length));
+ TRY(st, write_uri_from_node(writer, uri));
TRY(st, esink(">", 1, writer));
writer->last_sep = SEP_NODE;
TRY(st, write_sep(writer, writer->context.flags, SEP_END_DIRECT));
diff --git a/test/test_overflow.c b/test/test_overflow.c
index b81d4367..db20f734 100644
--- a/test/test_overflow.c
+++ b/test/test_overflow.c
@@ -23,7 +23,8 @@ test_size(SerdWorld* const world,
serd_world_set_limits(world, limits);
SerdSink* sink = serd_sink_new(NULL, NULL, NULL);
- SerdReader* const reader = serd_reader_new(world, syntax, flags, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ SerdReader* const reader = serd_reader_new(world, syntax, flags, env, sink);
if (!reader) {
return SERD_BAD_STACK;
}
@@ -38,6 +39,7 @@ test_size(SerdWorld* const world,
serd_close_input(&in);
serd_node_free(string_name);
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
return st;
diff --git a/test/test_reader.c b/test/test_reader.c
index b5cefbe1..f1ec1d35 100644
--- a/test/test_reader.c
+++ b/test/test_reader.c
@@ -4,6 +4,7 @@
#undef NDEBUG
#include "serd/caret.h"
+#include "serd/env.h"
#include "serd/event.h"
#include "serd/input_stream.h"
#include "serd/node.h"
@@ -96,7 +97,9 @@ test_prepare_error(const char* const path)
SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
- SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, env, sink);
+
assert(reader);
SerdInputStream in =
@@ -111,6 +114,7 @@ test_prepare_error(const char* const path)
serd_close_input(&in);
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
fclose(f);
@@ -125,7 +129,9 @@ test_read_string(void)
SerdSink* sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
- SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
+
assert(reader);
static const char* const string1 =
@@ -162,6 +168,7 @@ test_read_string(void)
assert(!serd_close_input(&in));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
}
@@ -221,11 +228,11 @@ test_read_eof_by_page(const char* const path)
fflush(f);
fseek(f, 0L, SEEK_SET);
- SerdWorld* world = serd_world_new();
- ReaderTest ignored = {0, 0, 0, 0};
- SerdSink* sink = serd_sink_new(&ignored, test_sink, NULL);
- SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, sink);
-
+ SerdWorld* world = serd_world_new();
+ ReaderTest ignored = {0, 0, 0, 0};
+ SerdSink* sink = serd_sink_new(&ignored, test_sink, NULL);
+ SerdEnv* env = serd_env_new(serd_empty_string());
+ SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
SerdInputStream in =
serd_open_input_stream((SerdReadFunc)fread, (SerdErrorFunc)ferror, NULL, f);
@@ -237,6 +244,7 @@ test_read_eof_by_page(const char* const path)
assert(!serd_close_input(&in));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
fclose(f);
@@ -250,7 +258,8 @@ test_read_eof_by_byte(void)
SerdWorld* world = serd_world_new();
ReaderTest ignored = {0, 0, 0, 0};
SerdSink* sink = serd_sink_new(&ignored, test_sink, NULL);
- SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, sink);
+ SerdEnv* env = serd_env_new(serd_empty_string());
+ SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
size_t n_reads = 0U;
SerdInputStream in = serd_open_input_stream(
@@ -265,6 +274,7 @@ test_read_eof_by_byte(void)
assert(!serd_close_input(&in));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
}
@@ -300,7 +310,10 @@ test_read_nquads_chunks(const char* const path)
SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
- SerdReader* const reader = serd_reader_new(world, SERD_NQUADS, 0U, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ assert(env);
+
+ SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
assert(reader);
SerdInputStream in =
@@ -353,6 +366,7 @@ test_read_nquads_chunks(const char* const path)
assert(!serd_close_input(&in));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
fclose(f);
@@ -382,7 +396,10 @@ test_read_turtle_chunks(const char* const path)
SerdSink* sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
- SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ assert(env);
+
+ SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
assert(reader);
SerdInputStream in =
@@ -451,6 +468,7 @@ test_read_turtle_chunks(const char* const path)
assert(!serd_close_input(&in));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
fclose(f);
@@ -467,7 +485,11 @@ test_read_empty(const char* const path)
SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
- SerdReader* const reader = serd_reader_new(world, SERD_SYNTAX_EMPTY, 0, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ assert(env);
+
+ SerdReader* const reader =
+ serd_reader_new(world, SERD_SYNTAX_EMPTY, 0U, env, sink);
assert(reader);
FILE* const f = fopen(path, "w+b");
@@ -487,6 +509,7 @@ test_read_empty(const char* const path)
fclose(f);
assert(!zix_remove(path));
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
}
@@ -516,7 +539,8 @@ test_error_cursor(void)
SerdWorld* world = serd_world_new();
bool called = false;
SerdSink* sink = serd_sink_new(&called, check_cursor, NULL);
- SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0, sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ SerdReader* const reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
assert(sink);
assert(reader);
@@ -537,6 +561,7 @@ test_error_cursor(void)
serd_node_free(string_name);
serd_reader_free(reader);
+ serd_env_free(env);
serd_sink_free(sink);
serd_world_free(world);
}
diff --git a/test/test_reader_writer.c b/test/test_reader_writer.c
index df2c3957..3a20bb7a 100644
--- a/test/test_reader_writer.c
+++ b/test/test_reader_writer.c
@@ -117,7 +117,8 @@ test_write_errors(void)
serd_writer_new(world, syntax, 0U, env, &out, 1U);
const SerdSink* const sink = serd_writer_sink(writer);
- SerdReader* const reader = serd_reader_new(world, SERD_TRIG, 0U, sink);
+ SerdReader* const reader =
+ serd_reader_new(world, SERD_TRIG, 0U, env, sink);
const char* position = doc_string;
SerdInputStream in = serd_open_input_string(&position);
@@ -251,16 +252,19 @@ test_reader(const char* path)
SerdSink* const sink = serd_sink_new(&rt, test_sink, NULL);
assert(sink);
+ SerdEnv* const env = serd_env_new(serd_empty_string());
+ assert(env);
+
// Test that too little stack space fails gracefully
const SerdLimits old_limits = serd_world_limits(world);
SerdLimits limits = old_limits;
limits.reader_stack_size = 32U;
serd_world_set_limits(world, limits);
- assert(!serd_reader_new(world, SERD_TURTLE, 0U, sink));
+ assert(!serd_reader_new(world, SERD_TURTLE, 0U, env, sink));
// Restore limits and successfully create reader
serd_world_set_limits(world, old_limits);
- SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, sink);
+ SerdReader* reader = serd_reader_new(world, SERD_TURTLE, 0U, env, sink);
assert(reader);
assert(serd_reader_read_chunk(reader) == SERD_BAD_CALL);
@@ -285,6 +289,7 @@ test_reader(const char* path)
serd_close_input(&in);
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 9ce69c55..f76cc800 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -66,37 +66,6 @@ test_write_bad_event(void)
}
static void
-test_write_bad_prefix(void)
-{
- SerdWorld* world = serd_world_new();
- SerdEnv* env = serd_env_new(serd_empty_string());
- SerdBuffer buffer = {NULL, 0};
- SerdOutputStream output = serd_open_output_buffer(&buffer);
- SerdWriter* writer =
- serd_writer_new(world, SERD_TURTLE, 0U, env, &output, 1U);
-
- assert(writer);
-
- SerdNode* name = serd_new_string(serd_string("eg"));
- SerdNode* uri = serd_new_uri(serd_string("rel"));
-
- assert(serd_sink_write_prefix(serd_writer_sink(writer), name, uri) ==
- SERD_BAD_ARG);
-
- serd_buffer_close(&buffer);
-
- char* const out = (char*)buffer.buf;
- assert(!strcmp(out, ""));
- serd_free(out);
-
- serd_node_free(uri);
- serd_node_free(name);
- serd_writer_free(writer);
- serd_env_free(env);
- serd_world_free(world);
-}
-
-static void
test_write_long_literal(void)
{
SerdWorld* world = serd_world_new();
@@ -442,7 +411,6 @@ main(void)
{
test_writer_new();
test_write_bad_event();
- test_write_bad_prefix();
test_write_long_literal();
test_writer_cleanup();
test_strict_write();
diff --git a/tools/serd-pipe.c b/tools/serd-pipe.c
index 734d02f4..8bf26f2a 100644
--- a/tools/serd-pipe.c
+++ b/tools/serd-pipe.c
@@ -72,6 +72,7 @@ static SerdStatus
read_file(SerdWorld* const world,
const SerdSyntax syntax,
const SerdReaderFlags flags,
+ SerdEnv* const env,
const SerdSink* const sink,
const size_t stack_size,
const char* const filename,
@@ -86,12 +87,10 @@ read_file(SerdWorld* const world,
return SERD_BAD_STREAM;
}
- SerdLimits limits = serd_world_limits(world);
- limits.reader_stack_size = stack_size;
+ const SerdLimits limits = {stack_size, MAX_DEPTH};
serd_world_set_limits(world, limits);
- SerdReader* reader = serd_reader_new(world, syntax, flags, sink);
-
+ SerdReader* reader = serd_reader_new(world, syntax, flags, env, sink);
serd_reader_add_blank_prefix(reader, add_prefix);
SerdStatus st = serd_reader_start(reader, &in, NULL, block_size);
@@ -315,6 +314,7 @@ main(int argc, char** argv)
serd_reader_new(world,
input_syntax ? input_syntax : SERD_TRIG,
reader_flags,
+ env,
serd_writer_sink(writer));
serd_reader_add_blank_prefix(reader, add_prefix);
@@ -349,6 +349,7 @@ main(int argc, char** argv)
if ((st = read_file(world,
serd_choose_syntax(world, input_syntax, inputs[i]),
reader_flags,
+ env,
serd_writer_sink(writer),
stack_size,
inputs[i],