diff options
-rw-r--r-- | src/read_turtle.c | 5 | ||||
-rw-r--r-- | src/reader.c | 17 | ||||
-rw-r--r-- | src/reader.h | 7 | ||||
-rw-r--r-- | test/test_reader.c | 56 |
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)); |