From 9fd4ff5a6470f58916d7cd8578bcb839f9b5feaa Mon Sep 17 00:00:00 2001
From: David Robillard <d@drobilla.net>
Date: Sun, 29 Apr 2018 15:24:05 +0200
Subject: Add SerdWorld for shared library state

---
 src/reader.c        | 14 +++-----------
 src/reader.h        |  3 ++-
 src/serd_internal.h |  8 +++++---
 src/serdi.c         | 14 ++++++++------
 src/world.c         | 40 ++++++++++++++++++++++++++++++++++++++++
 src/world.h         | 27 +++++++++++++++++++++++++++
 src/writer.c        | 16 +++++-----------
 7 files changed, 90 insertions(+), 32 deletions(-)
 create mode 100644 src/world.c
 create mode 100644 src/world.h

(limited to 'src')

diff --git a/src/reader.c b/src/reader.c
index fd7acd96..1c4c5104 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -35,7 +35,7 @@ r_err(SerdReader* reader, SerdStatus st, const char* fmt, ...)
 	va_start(args, fmt);
 	const Cursor* const cur = &reader->source.cur;
 	const SerdError e = { st, cur->filename, cur->line, cur->col, fmt, &args };
-	serd_error(reader->error_sink, reader->error_handle, &e);
+	serd_error(reader->world, &e);
 	va_end(args);
 	return 0;
 }
@@ -155,10 +155,11 @@ serd_reader_read_document(SerdReader* reader)
 }
 
 SerdReader*
-serd_reader_new(SerdSyntax syntax, const SerdSink* sink)
+serd_reader_new(SerdWorld* world, SerdSyntax syntax, const SerdSink* sink)
 {
 	SerdReader* me = (SerdReader*)calloc(1, sizeof(SerdReader));
 
+	me->world         = world;
 	me->sink          = sink;
 	me->default_graph = NULL;
 	me->stack         = serd_stack_new(SERD_PAGE_SIZE);
@@ -179,15 +180,6 @@ serd_reader_set_strict(SerdReader* reader, bool strict)
 	reader->strict = strict;
 }
 
-void
-serd_reader_set_error_sink(SerdReader*   reader,
-                           SerdErrorSink error_sink,
-                           void*         error_handle)
-{
-	reader->error_sink   = error_sink;
-	reader->error_handle = error_handle;
-}
-
 void
 serd_reader_free(SerdReader* reader)
 {
diff --git a/src/reader.h b/src/reader.h
index b4109eea..05a5de6a 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -46,7 +46,8 @@ typedef struct {
 } ReadContext;
 
 struct SerdReaderImpl {
-	const SerdSink* sink;
+	SerdWorld*               world;
+	const SerdSink*          sink;
 	SerdErrorSink            error_sink;
 	void*                    error_handle;
 	Ref                      rdf_first;
diff --git a/src/serd_internal.h b/src/serd_internal.h
index fbf493e9..172343b8 100644
--- a/src/serd_internal.h
+++ b/src/serd_internal.h
@@ -27,6 +27,8 @@
 #include "serd/serd.h"
 #include "serd_config.h"
 
+#include "world.h"
+
 #if defined(HAVE_POSIX_FADVISE) && defined(HAVE_FILENO)
 #   include <fcntl.h>
 #endif
@@ -68,10 +70,10 @@ serd_bufalloc(size_t size)
 }
 
 static inline void
-serd_error(SerdErrorSink error_sink, void* handle, const SerdError* e)
+serd_error(const SerdWorld* world, const SerdError* e)
 {
-	if (error_sink) {
-		error_sink(handle, e);
+	if (world->error_sink) {
+		world->error_sink(world->error_handle, e);
 	} else {
 		fprintf(stderr, "error: %s:%u:%u: ", e->filename, e->line, e->col);
 		vfprintf(stderr, e->fmt, *e->args);
diff --git a/src/serdi.c b/src/serdi.c
index 697f1217..c132eaf8 100644
--- a/src/serdi.c
+++ b/src/serdi.c
@@ -254,8 +254,9 @@ main(int argc, char** argv)
 		base = serd_node_new_file_uri(input, NULL, &base_uri, true);
 	}
 
-	FILE*    out_fd = stdout;
-	SerdEnv* env    = serd_env_new(base);
+	FILE*      out_fd = stdout;
+	SerdWorld* world  = serd_world_new();
+	SerdEnv*   env    = serd_env_new(base);
 
 	int output_style = 0;
 	if (output_syntax == SERD_NTRIPLES || ascii) {
@@ -277,7 +278,8 @@ main(int argc, char** argv)
 		output_style |= SERD_STYLE_BULK;
 	}
 
-	SerdWriter* writer = serd_writer_new(output_syntax,
+	SerdWriter* writer = serd_writer_new(world,
+	                                     output_syntax,
 	                                     (SerdStyle)output_style,
 	                                     env,
 	                                     &base_uri,
@@ -285,12 +287,11 @@ main(int argc, char** argv)
 	                                     out_fd);
 
 	SerdReader* reader =
-		serd_reader_new(input_syntax, serd_writer_get_sink(writer));
+		serd_reader_new(world, input_syntax, serd_writer_get_sink(writer));
 
 	serd_reader_set_strict(reader, !lax);
 	if (quiet) {
-		serd_reader_set_error_sink(reader, quiet_error_sink, NULL);
-		serd_writer_set_error_sink(writer, quiet_error_sink, NULL);
+		serd_world_set_error_sink(world, quiet_error_sink, NULL);
 	}
 
 	SerdNode* root = serd_node_new_string(SERD_URI, root_uri);
@@ -321,6 +322,7 @@ main(int argc, char** argv)
 	serd_writer_free(writer);
 	serd_env_free(env);
 	serd_node_free(base);
+	serd_world_free(world);
 	free(input_path);
 
 	if (from_file) {
diff --git a/src/world.c b/src/world.c
new file mode 100644
index 00000000..07439137
--- /dev/null
+++ b/src/world.c
@@ -0,0 +1,40 @@
+/*
+  Copyright 2011-2018 David Robillard <http://drobilla.net>
+
+  Permission to use, copy, modify, and/or distribute this software for any
+  purpose with or without fee is hereby granted, provided that the above
+  copyright notice and this permission notice appear in all copies.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#include "serd_internal.h"
+
+#include "world.h"
+
+SerdWorld*
+serd_world_new(void)
+{
+	return (SerdWorld*)calloc(1, sizeof(SerdWorld));
+}
+
+void
+serd_world_free(SerdWorld* world)
+{
+	free(world);
+}
+
+void
+serd_world_set_error_sink(SerdWorld*    world,
+                          SerdErrorSink error_sink,
+                          void*         handle)
+{
+	world->error_sink   = error_sink;
+	world->error_handle = handle;
+}
diff --git a/src/world.h b/src/world.h
new file mode 100644
index 00000000..88241b0e
--- /dev/null
+++ b/src/world.h
@@ -0,0 +1,27 @@
+/*
+  Copyright 2011-2018 David Robillard <http://drobilla.net>
+
+  Permission to use, copy, modify, and/or distribute this software for any
+  purpose with or without fee is hereby granted, provided that the above
+  copyright notice and this permission notice appear in all copies.
+
+  THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+
+#ifndef SERD_WORLD_H
+#define SERD_WORLD_H
+
+#include "serd_internal.h"
+
+struct SerdWorldImpl {
+	SerdErrorSink error_sink;
+	void*         error_handle;
+};
+
+#endif  // SERD_WORLD_H
diff --git a/src/writer.c b/src/writer.c
index 11ef0692..7bdc05f3 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -89,6 +89,7 @@ static const SepRule rules[] = {
 };
 
 struct SerdWriterImpl {
+	SerdWorld*    world;
 	SerdSink      iface;
 	SerdSyntax    syntax;
 	SerdStyle     style;
@@ -144,7 +145,7 @@ w_err(SerdWriter* writer, SerdStatus st, const char* fmt, ...)
 	va_list args;
 	va_start(args, fmt);
 	const SerdError e = { st, NULL, 0, 0, fmt, &args };
-	serd_error(writer->error_sink, writer->error_handle, &e);
+	serd_error(writer->world, &e);
 	va_end(args);
 }
 
@@ -874,7 +875,8 @@ serd_writer_finish(SerdWriter* writer)
 }
 
 SerdWriter*
-serd_writer_new(SerdSyntax     syntax,
+serd_writer_new(SerdWorld*     world,
+                SerdSyntax     syntax,
                 SerdStyle      style,
                 SerdEnv*       env,
                 const SerdURI* base_uri,
@@ -883,6 +885,7 @@ serd_writer_new(SerdSyntax     syntax,
 {
 	const WriteContext context = WRITE_CONTEXT_NULL;
 	SerdWriter*        writer  = (SerdWriter*)calloc(1, sizeof(SerdWriter));
+	writer->world        = world;
 	writer->syntax       = syntax;
 	writer->style        = style;
 	writer->env          = env;
@@ -905,15 +908,6 @@ serd_writer_new(SerdSyntax     syntax,
 	return writer;
 }
 
-void
-serd_writer_set_error_sink(SerdWriter*   writer,
-                           SerdErrorSink error_sink,
-                           void*         error_handle)
-{
-	writer->error_sink   = error_sink;
-	writer->error_handle = error_handle;
-}
-
 void
 serd_writer_chop_blank_prefix(SerdWriter* writer,
                               const char* prefix)
-- 
cgit v1.2.1