aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/read_turtle.c5
-rw-r--r--src/reader.c17
-rw-r--r--src/reader.h7
-rw-r--r--test/test_reader.c56
4 files changed, 80 insertions, 5 deletions
diff --git a/src/read_turtle.c b/src/read_turtle.c
index 027f0918..c3970a1e 100644
--- a/src/read_turtle.c
+++ b/src/read_turtle.c
@@ -13,6 +13,7 @@
#include "try.h"
#include "turtle.h"
+#include "serd/caret.h"
#include "serd/node.h"
#include "serd/reader.h"
#include "serd/sink.h"
@@ -610,6 +611,7 @@ read_object(SerdReader* const reader,
bool* const ate_dot)
{
const size_t orig_stack_size = reader->stack.size;
+ SerdCaret orig_caret = reader->source->caret;
assert(ctx->subject);
@@ -660,6 +662,7 @@ read_object(SerdReader* const reader,
break;
case '\"':
case '\'':
+ ++orig_caret.col;
st = read_literal(reader, &o, ate_dot);
break;
default:
@@ -668,7 +671,7 @@ read_object(SerdReader* const reader,
}
if (!st && simple && o) {
- st = emit_statement(reader, *ctx, o);
+ st = emit_statement_at(reader, *ctx, o, &orig_caret);
}
serd_stack_pop_to(&reader->stack, orig_stack_size);
diff --git a/src/reader.c b/src/reader.c
index f34f7974..7e0864cc 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -162,9 +162,10 @@ tokcmp(const SerdNode* const node, const char* const tok, const size_t n)
}
SerdStatus
-emit_statement(SerdReader* const reader,
- const ReadContext ctx,
- SerdNode* const o)
+emit_statement_at(SerdReader* const reader,
+ const ReadContext ctx,
+ SerdNode* const o,
+ SerdCaret* const caret)
{
if (reader->stack.size + (2 * sizeof(SerdNode)) > reader->stack.buf_size) {
return SERD_BAD_STACK;
@@ -175,7 +176,7 @@ emit_statement(SerdReader* const reader,
serd_node_zero_pad(o);
const SerdStatement statement = {{ctx.subject, ctx.predicate, o, ctx.graph},
- &reader->source->caret};
+ caret};
const SerdStatus st =
serd_sink_write_statement(reader->sink, *ctx.flags, &statement);
@@ -185,6 +186,14 @@ emit_statement(SerdReader* const reader,
}
SerdStatus
+emit_statement(SerdReader* const reader,
+ const ReadContext ctx,
+ SerdNode* const o)
+{
+ return emit_statement_at(reader, ctx, o, &reader->source->caret);
+}
+
+SerdStatus
serd_reader_read_document(SerdReader* const reader)
{
assert(reader);
diff --git a/src/reader.h b/src/reader.h
index 601453b0..132d038e 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -10,6 +10,7 @@
#include "try.h"
#include "serd/attributes.h"
+#include "serd/caret.h"
#include "serd/node.h"
#include "serd/reader.h"
#include "serd/sink.h"
@@ -85,6 +86,12 @@ void
set_blank_id(SerdReader* reader, SerdNode* node, size_t buf_size);
SerdStatus
+emit_statement_at(SerdReader* reader,
+ ReadContext ctx,
+ SerdNode* o,
+ SerdCaret* caret);
+
+SerdStatus
emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o);
static inline int
diff --git a/test/test_reader.c b/test/test_reader.c
index dd090d83..b5cefbe1 100644
--- a/test/test_reader.c
+++ b/test/test_reader.c
@@ -3,12 +3,16 @@
#undef NDEBUG
+#include "serd/caret.h"
#include "serd/event.h"
#include "serd/input_stream.h"
+#include "serd/node.h"
#include "serd/reader.h"
#include "serd/sink.h"
+#include "serd/statement.h"
#include "serd/status.h"
#include "serd/stream.h"
+#include "serd/string_view.h"
#include "serd/syntax.h"
#include "serd/world.h"
#include "zix/allocator.h"
@@ -21,6 +25,7 @@
#endif
#include <assert.h>
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -486,6 +491,56 @@ test_read_empty(const char* const path)
serd_world_free(world);
}
+static SerdStatus
+check_cursor(void* handle, const SerdEvent* event)
+{
+ bool* const called = (bool*)handle;
+
+ if (event->type == SERD_STATEMENT) {
+ const SerdCaret* const caret =
+ serd_statement_caret(event->statement.statement);
+ assert(caret);
+
+ assert(!strcmp(serd_node_string(serd_caret_document(caret)), "string"));
+ assert(serd_caret_line(caret) == 1);
+ assert(serd_caret_column(caret) == 47);
+ }
+
+ *called = true;
+ return SERD_SUCCESS;
+}
+
+static void
+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);
+ assert(sink);
+ assert(reader);
+
+ static const char* const string =
+ "<http://example.org/s> <http://example.org/p> "
+ "<http://example.org/o> .";
+
+ SerdNode* const string_name = serd_new_string(serd_string("string"));
+ const char* position = string;
+ SerdInputStream in = serd_open_input_string(&position);
+
+ SerdStatus st = serd_reader_start(reader, &in, string_name, 1);
+ assert(!st);
+ assert(serd_reader_read_document(reader) == SERD_SUCCESS);
+ assert(!serd_reader_finish(reader));
+ assert(called);
+ assert(!serd_close_input(&in));
+
+ serd_node_free(string_name);
+ serd_reader_free(reader);
+ serd_sink_free(sink);
+ serd_world_free(world);
+}
+
int
main(void)
{
@@ -504,6 +559,7 @@ main(void)
test_read_nquads_chunks(nq_path);
test_read_turtle_chunks(ttl_path);
test_read_empty(ttl_path);
+ test_error_cursor();
assert(!zix_remove(dir));