aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2014-12-16 17:18:24 +0000
committerDavid Robillard <d@drobilla.net>2014-12-16 17:18:24 +0000
commitb0de506d2d55627ffc4120a25d1016b1a59849bb (patch)
tree1f80987c236d450f9b97629038d79ceda159004b
parentd51be9b8d97791bff796d046d10fe16fd4e41311 (diff)
downloadserd-b0de506d2d55627ffc4120a25d1016b1a59849bb.tar.gz
serd-b0de506d2d55627ffc4120a25d1016b1a59849bb.tar.bz2
serd-b0de506d2d55627ffc4120a25d1016b1a59849bb.zip
Fix reading statements ending with a blank then dot with no space (#989).
git-svn-id: http://svn.drobilla.net/serd/trunk@481 490d8e77-9747-427b-9fa3-0b8f29cee8a0
-rw-r--r--NEWS3
-rw-r--r--src/reader.c24
2 files changed, 15 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index bc8ae2f8..3bcb4bfe 100644
--- a/NEWS
+++ b/NEWS
@@ -4,10 +4,11 @@ serd (0.21.1) unstable;
* Fix serd_reader_read_file() for URIs with escaped characters (spaces)
* Add serd_reader_set_strict() and -l (lax) option to serdi to tolerate
parsing URIs with escaped characters
+ * Fix reading statements ending with a blank then dot with no space
* Report errors for invalid IRI characters and missing terminators
* Fix warnings when building with ISO C++ compilers
- -- David Robillard <d@drobilla.net> Wed, 10 Dec 2014 15:49:04 -0500
+ -- David Robillard <d@drobilla.net> Tue, 16 Dec 2014 12:17:44 -0500
serd (0.20.0) stable;
diff --git a/src/reader.c b/src/reader.c
index 8dddb568..d5c29c04 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -1002,7 +1002,7 @@ read_verb(SerdReader* reader, Ref* dest)
}
static Ref
-read_BLANK_NODE_LABEL(SerdReader* reader)
+read_BLANK_NODE_LABEL(SerdReader* reader, bool* ate_dot)
{
eat_byte_safe(reader, '_');
eat_byte_check(reader, ':');
@@ -1026,10 +1026,12 @@ read_BLANK_NODE_LABEL(SerdReader* reader)
}
}
- const SerdNode* n = deref(reader, ref);
+ SerdNode* n = deref(reader, ref);
if (n->buf[n->n_bytes - 1] == '.' && !read_PN_CHARS(reader, ref)) {
- r_err(reader, SERD_ERR_BAD_SYNTAX, "name ends with `.'\n");
- return pop_node(reader, ref);
+ // Ate trailing dot, pop it from stack/node and inform caller
+ --n->n_bytes;
+ serd_stack_pop(&reader->stack, 1);
+ *ate_dot = true;
}
if (reader->syntax == SERD_TURTLE) {
@@ -1071,13 +1073,13 @@ blank_id(SerdReader* reader)
}
static bool
-read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest)
+read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest, bool* ate_dot)
{
const SerdStatementFlags old_flags = *ctx.flags;
bool empty;
switch (peek_byte(reader)) {
case '_':
- return (*dest = read_BLANK_NODE_LABEL(reader));
+ return (*dest = read_BLANK_NODE_LABEL(reader, ate_dot));
case '[':
eat_byte_safe(reader, '[');
if ((empty = peek_delim(reader, ']'))) {
@@ -1097,9 +1099,9 @@ read_blank(SerdReader* reader, ReadContext ctx, bool subject, Ref* dest)
if (!subject) {
*ctx.flags |= SERD_ANON_CONT;
}
- bool ate_dot = false;
- read_predicateObjectList(reader, ctx, &ate_dot);
- if (ate_dot) {
+ bool ate_dot_in_list = false;
+ read_predicateObjectList(reader, ctx, &ate_dot_in_list);
+ if (ate_dot_in_list) {
return r_err(reader, SERD_ERR_BAD_SYNTAX, "`.' inside blank\n");
}
read_ws_star(reader);
@@ -1143,7 +1145,7 @@ read_object(SerdReader* reader, ReadContext ctx, bool* ate_dot)
emit = false;
// fall through
case '_':
- TRY_THROW(ret = read_blank(reader, ctx, false, &o));
+ TRY_THROW(ret = read_blank(reader, ctx, false, &o, ate_dot));
break;
case '<': case ':':
TRY_THROW(ret = read_iri(reader, &o, ate_dot));
@@ -1312,7 +1314,7 @@ read_subject(SerdReader* reader, ReadContext ctx, bool* nested)
*nested = true;
// nobreak
case '_':
- read_blank(reader, ctx, true, &subject);
+ read_blank(reader, ctx, true, &subject, &ate_dot);
break;
default:
read_iri(reader, &subject, &ate_dot);