summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--sord/sord.h12
-rw-r--r--src/sord.c51
-rw-r--r--wscript2
4 files changed, 55 insertions, 11 deletions
diff --git a/NEWS b/NEWS
index 32c4c78..a5b475d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,6 @@
sord (9999) unstable;
+ * Add error callback to world for custom error reporting
* sordmm.hpp: Add indices and graphs parameters to Model constructor
* sordmm.hpp: Remove overzealous URI scheme assertion
* sordmm.hpp: Correctly handle Sord::Node self-assignment
diff --git a/sord/sord.h b/sord/sord.h
index 8a800ff..8f1ef38 100644
--- a/sord/sord.h
+++ b/sord/sord.h
@@ -157,6 +157,18 @@ void
sord_world_free(SordWorld* world);
/**
+ Set a function to be called when errors occur.
+
+ The @p error_sink will be called with @p handle as its first argument. If
+ no error function is set, errors are printed to stderr.
+*/
+SORD_API
+void
+sord_world_set_error_sink(SordWorld* world,
+ SerdErrorSink error_sink,
+ void* handle);
+
+/**
@}
@name Node
@{
diff --git a/src/sord.c b/src/sord.c
index 087a0c0..5d7c075 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -102,10 +102,12 @@ static const int orderings[NUM_ORDERS][TUP_LEN] = {
/** World */
struct SordWorldImpl {
- ZixHash* names; ///< URI or blank node identifier string => ID
- ZixHash* langs; ///< Language tag => Interned language tag
- ZixHash* literals; ///< Literal => ID
- size_t n_nodes; ///< Number of nodes
+ ZixHash* names; ///< URI or blank node identifier string => ID
+ ZixHash* langs; ///< Language tag => Interned language tag
+ ZixHash* literals; ///< Literal => ID
+ size_t n_nodes; ///< Number of nodes
+ SerdErrorSink error_sink;
+ void* error_handle;
};
/** Store */
@@ -161,6 +163,21 @@ sord_literal_equal(const void* a, const void* b)
&& (a_node->datatype == b_node->datatype));
}
+static void
+error(SordWorld* world, SerdStatus st, const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ const SerdError e = { st, NULL, 0, 0, fmt, &args };
+ 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, fmt, args);
+ }
+ va_end(args);
+}
+
SordWorld*
sord_world_new(void)
{
@@ -201,6 +218,15 @@ sord_world_free(SordWorld* world)
free(world);
}
+void
+sord_world_set_error_sink(SordWorld* world,
+ SerdErrorSink error_sink,
+ void* handle)
+{
+ world->error_sink = error_sink;
+ world->error_handle = handle;
+}
+
/** Compare nodes, considering NULL a wildcard match. */
static inline int
sord_node_compare(const SordNode* a, const SordNode* b)
@@ -643,13 +669,15 @@ sord_node_free_internal(SordWorld* world, SordNode* node)
assert(node->refs == 0);
if (node->node.type == SERD_LITERAL) {
if (zix_hash_remove(world->literals, node)) {
- fprintf(stderr, "Failed to remove literal from hash.\n");
+ error(world, SERD_ERR_INTERNAL,
+ "failed to remove literal from hash\n");
return;
}
sord_node_free(world, node->datatype);
} else {
if (zix_hash_remove(world->names, node->node.buf)) {
- fprintf(stderr, "Failed to remove resource from hash.\n");
+ error(world, SERD_ERR_INTERNAL,
+ "failed to remove resource from hash\n");
return;
}
}
@@ -943,7 +971,7 @@ sord_node_get_type(const SordNode* node)
case SERD_URI:
return SORD_URI;
default:
- fprintf(stderr, "sord: error: Illegal node type.\n");
+ fprintf(stderr, "error: invalid node type\n");
return (SordNodeType)0;
}
}
@@ -996,7 +1024,8 @@ sord_new_uri_counted(SordWorld* world, const uint8_t* str,
size_t n_bytes, size_t n_chars, bool copy)
{
if (!serd_uri_string_has_scheme(str)) {
- fprintf(stderr, "Attempt to map invalid URI `%s'.\n", str);
+ error(world, SERD_ERR_BAD_ARG,
+ "attempt to map invalid URI `%s'\n", str);
return NULL; // Can't intern relative URIs
}
@@ -1154,7 +1183,8 @@ sord_node_from_serd_node(SordWorld* world,
SerdChunk uri_prefix;
SerdChunk uri_suffix;
if (serd_env_expand(env, sn, &uri_prefix, &uri_suffix)) {
- fprintf(stderr, "Failed to expand qname `%s'\n", sn->buf);
+ error(world, SERD_ERR_BAD_CURIE,
+ "failed to expand CURIE `%s'\n", sn->buf);
return NULL;
}
const size_t uri_len = uri_prefix.len + uri_suffix.len;
@@ -1213,7 +1243,8 @@ sord_add(SordModel* sord, const SordQuad tup)
{
SORD_WRITE_LOG("Add " TUP_FMT "\n", TUP_FMT_ARGS(tup));
if (!tup[0] || !tup[1] || !tup[2]) {
- fprintf(stderr, "Attempt to add quad with NULL field.\n");
+ error(sord->world, SERD_ERR_BAD_ARG,
+ "attempt to add quad with NULL field\n");
return false;
}
diff --git a/wscript b/wscript
index a0aae10..8133ea2 100644
--- a/wscript
+++ b/wscript
@@ -8,7 +8,7 @@ from waflib.extras import autowaf as autowaf
import waflib.Logs as Logs, waflib.Options as Options
# Version of this package (even if built as a child)
-SORD_VERSION = '0.8.1'
+SORD_VERSION = '0.9.0'
SORD_MAJOR_VERSION = '0'
# Library version (UNIX style major, minor, micro)