aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/n3.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/src/n3.c b/src/n3.c
index a82e37a0..f583a9fa 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -998,6 +998,24 @@ read_verb(SerdReader* const reader, SerdNode** const dest)
}
static SerdStatus
+adjust_blank_id(SerdReader* const reader, char* const buf)
+{
+ if (fancy_syntax(reader) && is_digit(buf[reader->bprefix_len + 1])) {
+ const char tag = buf[reader->bprefix_len];
+ if (tag == 'b') {
+ buf[reader->bprefix_len] = 'B'; // Prevent clash
+ reader->seen_genid = true;
+ } else if (tag == 'B' && reader->seen_genid) {
+ return r_err(reader,
+ SERD_BAD_LABEL,
+ "found both 'b' and 'B' blank IDs, prefix required\n");
+ }
+ }
+
+ return SERD_SUCCESS;
+}
+
+static SerdStatus
read_BLANK_NODE_LABEL(SerdReader* const reader,
SerdNode** const dest,
bool* const ate_dot)
@@ -1014,8 +1032,9 @@ read_BLANK_NODE_LABEL(SerdReader* const reader,
return SERD_BAD_STACK;
}
- SerdNode* n = *dest;
- int c = peek_byte(reader); // First: (PN_CHARS | '_' | [0-9])
+ // Read first: (PN_CHARS | '_' | [0-9])
+ SerdNode* const n = *dest;
+ int c = peek_byte(reader);
if (is_digit(c) || c == '_') {
TRY(st, push_byte(reader, n, eat_byte_safe(reader, c)));
} else if ((st = read_PN_CHARS(reader, n))) {
@@ -1023,7 +1042,8 @@ read_BLANK_NODE_LABEL(SerdReader* const reader,
return r_err(reader, st, "invalid name start\n");
}
- while ((c = peek_byte(reader))) { // Middle: (PN_CHARS | '.')*
+ // Read middle: (PN_CHARS | '.')*
+ while ((c = peek_byte(reader))) {
if (c == '.') {
TRY(st, push_byte(reader, n, eat_byte_safe(reader, c)));
} else if ((st = read_PN_CHARS(reader, n))) {
@@ -1035,28 +1055,18 @@ read_BLANK_NODE_LABEL(SerdReader* const reader,
return st;
}
- char* buf = serd_node_buffer(n);
+ // Deal with annoying edge case of having eaten the trailing dot
+ char* const buf = serd_node_buffer(n);
if (buf[n->length - 1] == '.' && read_PN_CHARS(reader, n)) {
- // Ate trailing dot, pop it from stack/node and inform caller
--n->length;
serd_stack_pop(&reader->stack, 1);
*ate_dot = true;
}
- if (fancy_syntax(reader)) {
- if (is_digit(buf[reader->bprefix_len + 1])) {
- if ((buf[reader->bprefix_len]) == 'b') {
- buf[reader->bprefix_len] = 'B'; // Prevent clash
- reader->seen_genid = true;
- } else if (reader->seen_genid && buf[reader->bprefix_len] == 'B') {
- return r_err(reader,
- SERD_BAD_LABEL,
- "found both 'b' and 'B' blank IDs, prefix required\n");
- }
- }
- }
+ // Adjust ID to avoid clashes with generated IDs if necessary
+ st = adjust_blank_id(reader, buf);
- return SERD_SUCCESS;
+ return st;
}
static SerdStatus