aboutsummaryrefslogtreecommitdiffstats
path: root/src/read_turtle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/read_turtle.c')
-rw-r--r--src/read_turtle.c107
1 files changed, 58 insertions, 49 deletions
diff --git a/src/read_turtle.c b/src/read_turtle.c
index c6982327..a041e873 100644
--- a/src/read_turtle.c
+++ b/src/read_turtle.c
@@ -2,7 +2,8 @@
// SPDX-License-Identifier: ISC
#include "read_turtle.h"
-#include "byte_source.h"
+
+#include "caret.h"
#include "env.h"
#include "namespaces.h"
#include "node.h"
@@ -14,7 +15,6 @@
#include "try.h"
#include "turtle.h"
-#include "serd/caret.h"
#include "serd/env.h"
#include "serd/node.h"
#include "serd/reader.h"
@@ -49,12 +49,14 @@ read_predicateObjectList(SerdReader* reader, ReadContext ctx, bool* ate_dot);
static SerdStatus
read_whitespace(SerdReader* const reader)
{
- switch (peek_byte(reader)) {
+ const int c = peek_byte(reader);
+
+ switch (c) {
case '\t':
case '\n':
case '\r':
case ' ':
- return serd_byte_source_advance(reader->source);
+ return skip_byte(reader, c);
case '#':
return read_comment(reader);
default:
@@ -338,7 +340,7 @@ resolve_IRIREF(SerdReader* const reader,
}
// Push a new temporary node for constructing the resolved URI
- SerdNode* const temp = push_node(reader, SERD_URI, "", 0);
+ SerdNode* const temp = push_node_head(reader, SERD_URI);
if (!temp) {
return SERD_BAD_STACK;
}
@@ -346,10 +348,12 @@ resolve_IRIREF(SerdReader* const reader,
// Write resolved URI to the temporary node
WriteNodeContext ctx = {reader, temp, SERD_SUCCESS};
temp->length = serd_write_uri(uri, write_to_stack, &ctx);
+
if (!ctx.status) {
// Replace the destination with the new expanded node
memmove(dest, temp, sizeof(SerdNode) + serd_node_pad_length(temp->length));
serd_stack_pop_to(&reader->stack, string_start_offset + dest->length);
+ TRY(ctx.status, push_node_tail(reader));
}
return ctx.status;
@@ -361,7 +365,7 @@ read_IRIREF(SerdReader* const reader, SerdNode** const dest)
SerdStatus st = SERD_SUCCESS;
TRY(st, eat_byte_check(reader, '<'));
- if (!(*dest = push_node(reader, SERD_URI, "", 0))) {
+ if (!(*dest = push_node_head(reader, SERD_URI))) {
return SERD_BAD_STACK;
}
@@ -372,8 +376,10 @@ read_IRIREF(SerdReader* const reader, SerdNode** const dest)
return st;
}
+ TRY(st, push_node_tail(reader));
+
return (reader->flags & SERD_READ_RELATIVE)
- ? SERD_SUCCESS
+ ? st
: resolve_IRIREF(reader, *dest, string_start_offset);
}
@@ -411,7 +417,7 @@ read_PrefixedName(SerdReader* const reader,
return st;
}
- return SERD_SUCCESS;
+ return push_node_tail(reader);
}
static SerdStatus
@@ -439,12 +445,11 @@ read_number(SerdReader* const reader,
#define XSD_DOUBLE NS_XSD "double"
#define XSD_INTEGER NS_XSD "integer"
- *dest = push_node(reader, SERD_LITERAL, "", 0);
-
SerdStatus st = SERD_SUCCESS;
int c = peek_byte(reader);
bool has_decimal = false;
- if (!*dest) {
+
+ if (!(*dest = push_node_head(reader, SERD_LITERAL))) {
return SERD_BAD_STACK;
}
@@ -467,8 +472,8 @@ read_number(SerdReader* const reader,
skip_byte(reader, c);
c = peek_byte(reader);
if (!is_digit(c) && c != 'e' && c != 'E') {
- *ate_dot = true; // Force caller to deal with stupid grammar
- return SERD_SUCCESS; // Next byte is not a number character
+ *ate_dot = true; // Force caller to deal with stupid grammar
+ return push_node_tail(reader); // Next byte is not a number character
}
TRY(st, push_byte(reader, *dest, '.'));
@@ -491,12 +496,13 @@ read_number(SerdReader* const reader,
break;
}
TRY(st, read_0_9(reader, *dest, true));
+ TRY(st, push_node_tail(reader));
meta = push_node(reader, SERD_URI, XSD_DOUBLE, sizeof(XSD_DOUBLE) - 1);
- (*dest)->flags |= SERD_HAS_DATATYPE;
} else if (has_decimal) {
+ TRY(st, push_node_tail(reader));
meta = push_node(reader, SERD_URI, XSD_DECIMAL, sizeof(XSD_DECIMAL) - 1);
- (*dest)->flags |= SERD_HAS_DATATYPE;
} else {
+ TRY(st, push_node_tail(reader));
meta = push_node(reader, SERD_URI, XSD_INTEGER, sizeof(XSD_INTEGER) - 1);
}
@@ -513,11 +519,14 @@ read_turtle_iri(SerdReader* const reader,
return read_IRIREF(reader, dest);
}
- if (!(*dest = push_node(reader, SERD_LITERAL, "", 0))) {
+ if (!(*dest = push_node_head(reader, SERD_LITERAL))) {
return SERD_BAD_STACK;
}
- return read_PrefixedName(reader, *dest, true, ate_dot, reader->stack.size);
+ const SerdStatus st =
+ read_PrefixedName(reader, *dest, true, ate_dot, reader->stack.size);
+
+ return st;
}
static SerdStatus
@@ -525,14 +534,14 @@ read_literal(SerdReader* const reader,
SerdNode** const dest,
bool* const ate_dot)
{
- if (!(*dest = push_node(reader, SERD_LITERAL, "", 0))) {
+ SerdStatus st = SERD_SUCCESS;
+
+ if (!(*dest = push_node_head(reader, SERD_LITERAL))) {
return SERD_BAD_STACK;
}
- SerdStatus st = read_String(reader, *dest);
- if (st) {
- return st;
- }
+ TRY(st, read_String(reader, *dest));
+ TRY(st, push_node_tail(reader));
SerdNode* datatype = NULL;
switch (peek_byte(reader)) {
@@ -546,9 +555,11 @@ read_literal(SerdReader* const reader,
TRY(st, eat_byte_check(reader, '^'));
(*dest)->flags |= SERD_HAS_DATATYPE;
TRY(st, read_turtle_iri(reader, &datatype, ate_dot));
+ assert(datatype == serd_node_meta_c(*dest));
break;
}
- return SERD_SUCCESS;
+
+ return st;
}
static SerdStatus
@@ -567,7 +578,7 @@ read_verb(SerdReader* reader, SerdNode** const dest)
/* Either a qname, or "a". Read the prefix first, and if it is in fact
"a", produce that instead.
*/
- if (!(*dest = push_node(reader, SERD_URI, "", 0))) {
+ if (!(*dest = push_node_head(reader, SERD_URI))) {
return SERD_BAD_STACK;
}
@@ -593,7 +604,7 @@ read_verb(SerdReader* reader, SerdNode** const dest)
reader, st > SERD_FAILURE ? st : SERD_BAD_SYNTAX, "expected verb");
}
- return SERD_SUCCESS;
+ return SERD_SUCCESS; // push_node_tail(reader);
}
static SerdStatus
@@ -670,7 +681,7 @@ read_named_object(SerdReader* const reader,
Deal with this here by trying to read a prefixed node, then if it turns
out to actually be "true" or "false", switch it to a boolean literal. */
- if (!(*dest = push_node(reader, SERD_URI, "", 0))) {
+ if (!(*dest = push_node_head(reader, SERD_URI))) {
return SERD_BAD_STACK;
}
@@ -685,6 +696,7 @@ read_named_object(SerdReader* const reader,
node_has_string(node, false_string))) {
node->flags = SERD_HAS_DATATYPE;
node->type = SERD_LITERAL;
+ TRY(st, push_node_tail(reader));
return push_node(reader, SERD_URI, XSD_BOOLEAN, XSD_BOOLEAN_LEN)
? SERD_SUCCESS
: SERD_BAD_STACK;
@@ -696,7 +708,7 @@ read_named_object(SerdReader* const reader,
return r_err(reader, st, "expected prefixed name or boolean");
}
- return SERD_SUCCESS;
+ return SERD_SUCCESS; // push_node_tail(reader);
}
// Read an object and emit statements, possibly recursively
@@ -705,8 +717,8 @@ read_object(SerdReader* const reader,
ReadContext* const ctx,
bool* const ate_dot)
{
- const size_t orig_stack_size = reader->stack.size;
- SerdCaret orig_caret = reader->source->caret;
+ const size_t orig_stack_size = reader->stack.size;
+ struct SerdCaretImpl orig_caret = reader->source.caret;
assert(ctx->subject);
@@ -809,7 +821,7 @@ read_predicateObjectList(SerdReader* const reader,
int c = 0;
do {
read_turtle_ws_star(reader);
- switch (c = peek_byte(reader)) {
+ switch ((c = peek_byte(reader))) {
case EOF:
serd_stack_pop_to(&reader->stack, orig_stack_size);
return r_err(reader, SERD_BAD_SYNTAX, "unexpected end of file");
@@ -869,11 +881,9 @@ read_collection(SerdReader* const reader,
/* The order of node allocation here is necessarily not in stack order,
so we create two nodes and recycle them throughout. */
- SerdNode* n1 =
- push_node_padded(reader, genid_length(reader), SERD_BLANK, "", 0);
-
+ SerdNode* n1 = push_node_padding(reader, SERD_BLANK, genid_length(reader));
SerdNode* node = n1;
- SerdNode* rest = 0;
+ SerdNode* rest = NULL;
if (!n1) {
return SERD_BAD_STACK;
@@ -985,7 +995,6 @@ read_turtle_base(SerdReader* const reader, const bool sparql, const bool token)
return SERD_BAD_STACK;
}
- 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));
@@ -1012,25 +1021,22 @@ read_turtle_prefixID(SerdReader* const reader,
}
read_turtle_ws_star(reader);
- SerdNode* name = push_node(reader, SERD_LITERAL, "", 0);
+
+ SerdNode* const name = push_node_head(reader, SERD_LITERAL);
if (!name) {
return SERD_BAD_STACK;
}
+ // Read (possibly empty) name node
TRY_LAX(st, read_PN_PREFIX(reader, name));
+ TRY(st, push_node_tail(reader));
TRY(st, eat_byte_check(reader, ':'));
read_turtle_ws_star(reader);
+ // Read URI node
SerdNode* uri = NULL;
TRY(st, read_IRIREF(reader, &uri));
- if (reader->stack.size + sizeof(SerdNode) > reader->stack.buf_size) {
- return SERD_BAD_STACK;
- }
-
- 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)));
@@ -1064,11 +1070,15 @@ read_turtle_directive(SerdReader* const reader)
static SerdStatus
read_sparql_directive(SerdReader* const reader, const SerdNode* const token)
{
+ SerdStatus st = SERD_SUCCESS;
+
if (!tokcmp(token, "base", 4)) {
+ TRY(st, push_node_tail(reader));
return read_turtle_base(reader, true, false);
}
if (!tokcmp(token, "prefix", 6)) {
+ TRY(st, push_node_tail(reader));
return read_turtle_prefixID(reader, true, false);
}
@@ -1078,11 +1088,10 @@ read_sparql_directive(SerdReader* const reader, const SerdNode* const token)
static SerdStatus
read_block(SerdReader* const reader, ReadContext* const ctx)
{
- SerdStatus st = SERD_SUCCESS;
-
// Try to read a subject, though it may actually be a directive or graph name
- SerdNode* token = NULL;
- int s_type = 0;
+ SerdNode* token = NULL;
+ SerdStatus st = SERD_SUCCESS;
+ int s_type = 0;
TRY_LAX(st, read_turtle_subject(reader, *ctx, &token, &s_type));
// Try to interpret as a SPARQL "PREFIX" or "BASE" directive
@@ -1121,7 +1130,7 @@ read_turtle_statement(SerdReader* const reader)
return SERD_FAILURE;
case '\0':
- eat_byte(reader);
+ skip_byte(reader, '\0');
return SERD_FAILURE;
case '@':
@@ -1138,7 +1147,7 @@ read_turtle_statement(SerdReader* const reader)
SerdStatus
read_turtleDoc(SerdReader* const reader)
{
- while (!reader->source->eof) {
+ while (!reader->source.eof) {
const size_t orig_stack_size = reader->stack.size;
const SerdStatus st = read_turtle_statement(reader);