aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-04-05 18:28:27 -0400
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:07 -0500
commitee946a0de13a22ff83c288aa64ef3f4fd381da75 (patch)
treeab205c8c977203963eae308e6ec998f29e97a1e9
parentd62c7dc45af3256c6cd70d12a11e91b5b872c7db (diff)
downloadserd-ee946a0de13a22ff83c288aa64ef3f4fd381da75.tar.gz
serd-ee946a0de13a22ff83c288aa64ef3f4fd381da75.tar.bz2
serd-ee946a0de13a22ff83c288aa64ef3f4fd381da75.zip
Simplify statement flags
-rw-r--r--NEWS1
-rw-r--r--include/serd/statement.h14
-rw-r--r--src/n3.c34
-rw-r--r--src/reader.c2
-rw-r--r--src/writer.c41
-rw-r--r--test/test_writer.c4
6 files changed, 47 insertions, 49 deletions
diff --git a/NEWS b/NEWS
index 255f94dc..01a292fa 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ serd (1.1.1) unstable; urgency=medium
* Remove support for reading Turtle named inline nodes extension
* Remove useless character counting from API
* Rename SerdChunk to SerdStringView
+ * Simplify statement flags
* Simplify writer style options and write UTF-8 by default
* Use a fixed-size reader stack
* Use char* for strings in public API
diff --git a/include/serd/statement.h b/include/serd/statement.h
index eff7b796..aee632cb 100644
--- a/include/serd/statement.h
+++ b/include/serd/statement.h
@@ -29,14 +29,12 @@ typedef enum {
/// Flags indicating inline abbreviation information for a statement
typedef enum {
- SERD_EMPTY_S = 1U << 1U, ///< Empty blank node subject
- SERD_EMPTY_O = 1U << 2U, ///< Empty blank node object
- SERD_ANON_S_BEGIN = 1U << 3U, ///< Start of anonymous subject
- SERD_ANON_O_BEGIN = 1U << 4U, ///< Start of anonymous object
- SERD_ANON_CONT = 1U << 5U, ///< Continuation of anonymous node
- SERD_LIST_S_BEGIN = 1U << 6U, ///< Start of list subject
- SERD_LIST_O_BEGIN = 1U << 7U, ///< Start of list object
- SERD_LIST_CONT = 1U << 8U, ///< Continuation of list
+ SERD_EMPTY_S = 1U << 0U, ///< Empty blank node subject
+ SERD_EMPTY_O = 1U << 1U, ///< Empty blank node object
+ SERD_ANON_S = 1U << 2U, ///< Start of anonymous subject
+ SERD_ANON_O = 1U << 3U, ///< Start of anonymous object
+ SERD_LIST_S = 1U << 4U, ///< Start of list subject
+ SERD_LIST_O = 1U << 5U, ///< Start of list object
} SerdStatementFlag;
/// Bitwise OR of SerdStatementFlag values
diff --git a/src/n3.c b/src/n3.c
index 09f00c54..a82e37a0 100644
--- a/src/n3.c
+++ b/src/n3.c
@@ -1071,9 +1071,9 @@ read_anon(SerdReader* const reader,
const bool empty = peek_delim(reader, ']');
if (subject) {
- *ctx.flags |= empty ? SERD_EMPTY_S : SERD_ANON_S_BEGIN;
+ *ctx.flags |= empty ? SERD_EMPTY_S : SERD_ANON_S;
} else {
- *ctx.flags |= empty ? SERD_EMPTY_O : SERD_ANON_O_BEGIN;
+ *ctx.flags |= empty ? SERD_EMPTY_O : SERD_ANON_O;
}
if (!*dest) {
@@ -1091,20 +1091,16 @@ read_anon(SerdReader* const reader,
// Switch the subject to the anonymous node and read its description
ctx.subject = *dest;
if (!empty) {
- *ctx.flags &= ~(unsigned)SERD_LIST_CONT;
- if (!subject) {
- *ctx.flags |= SERD_ANON_CONT;
- }
-
bool ate_dot_in_list = false;
- TRY(st, read_predicateObjectList(reader, ctx, &ate_dot_in_list));
-
+ TRY_FAILING(st, read_predicateObjectList(reader, ctx, &ate_dot_in_list));
if (ate_dot_in_list) {
return r_err(reader, SERD_BAD_SYNTAX, "'.' inside blank\n");
}
+
read_ws_star(reader);
- serd_sink_write_end(reader->sink, *dest);
*ctx.flags = old_flags;
+
+ TRY(st, serd_sink_write_end(reader->sink, *dest));
}
return st > SERD_FAILURE ? st : eat_byte_check(reader, ']');
@@ -1288,10 +1284,8 @@ read_predicateObjectList(SerdReader* const reader,
}
static SerdStatus
-end_collection(SerdReader* const reader, ReadContext ctx, const SerdStatus st)
+end_collection(SerdReader* const reader, const SerdStatus st)
{
- *ctx.flags &= ~(unsigned)SERD_LIST_CONT;
-
return st ? st : eat_byte_check(reader, ')');
}
@@ -1310,16 +1304,15 @@ read_collection(SerdReader* const reader,
}
if (ctx.subject) { // Reading a collection object
- *ctx.flags |= (end ? 0 : SERD_LIST_O_BEGIN);
+ *ctx.flags |= (end ? 0 : SERD_LIST_O);
TRY(st, emit_statement(reader, ctx, *dest));
- *ctx.flags &= SERD_LIST_O_BEGIN;
- *ctx.flags |= SERD_LIST_CONT;
+ *ctx.flags &= ~((unsigned)SERD_LIST_O);
} else { // Reading a collection subject
- *ctx.flags |= (end ? 0 : SERD_LIST_S_BEGIN);
+ *ctx.flags |= (end ? 0 : SERD_LIST_S);
}
if (end) {
- return end_collection(reader, ctx, st);
+ return end_collection(reader, st);
}
/* The order of node allocation here is necessarily not in stack order,
@@ -1339,7 +1332,7 @@ read_collection(SerdReader* const reader,
ctx.predicate = reader->rdf_first;
bool ate_dot = false;
if ((st = read_object(reader, &ctx, true, &ate_dot)) || ate_dot) {
- return end_collection(reader, ctx, st);
+ return end_collection(reader, st);
}
if (!(end = peek_delim(reader, ')'))) {
@@ -1354,7 +1347,6 @@ read_collection(SerdReader* const reader,
}
// _:node rdf:rest _:rest
- *ctx.flags |= SERD_LIST_CONT;
ctx.predicate = reader->rdf_rest;
TRY(st, emit_statement(reader, ctx, (end ? reader->rdf_nil : rest)));
@@ -1363,7 +1355,7 @@ read_collection(SerdReader* const reader,
node = ctx.subject; // invariant
}
- return end_collection(reader, ctx, st);
+ return end_collection(reader, st);
}
static SerdStatus
diff --git a/src/reader.c b/src/reader.c
index 3c80c491..61da89ff 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -125,7 +125,7 @@ emit_statement(SerdReader* const reader,
const SerdStatus st =
serd_sink_write_statement(reader->sink, *ctx.flags, &statement);
- *ctx.flags &= SERD_ANON_CONT | SERD_LIST_CONT; // Preserve only cont flags
+ *ctx.flags = 0;
return st;
}
diff --git a/src/writer.c b/src/writer.c
index ca17bbd9..23b2c0bd 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -847,13 +847,13 @@ write_blank(SerdWriter* const writer,
const char* const node_str = serd_node_string(node);
if (supports_abbrev(writer)) {
- if ((field == SERD_SUBJECT && (flags & SERD_ANON_S_BEGIN)) ||
- (field == SERD_OBJECT && (flags & SERD_ANON_O_BEGIN))) {
+ if ((field == SERD_SUBJECT && (flags & SERD_ANON_S)) ||
+ (field == SERD_OBJECT && (flags & SERD_ANON_O))) {
return write_sep(writer, SEP_ANON_BEGIN);
}
- if ((field == SERD_SUBJECT && (flags & SERD_LIST_S_BEGIN)) ||
- (field == SERD_OBJECT && (flags & SERD_LIST_O_BEGIN))) {
+ if ((field == SERD_SUBJECT && (flags & SERD_LIST_S)) ||
+ (field == SERD_OBJECT && (flags & SERD_LIST_O))) {
return write_sep(writer, SEP_LIST_BEGIN);
}
@@ -954,11 +954,11 @@ terminate_context(SerdWriter* writer)
{
SerdStatus st = SERD_SUCCESS;
- if (writer->context.subject && writer->context.subject->type) {
+ if (ctx(writer, SERD_SUBJECT)) {
TRY(st, write_sep(writer, SEP_END_S));
}
- if (writer->context.graph && writer->context.graph->type) {
+ if (ctx(writer, SERD_GRAPH)) {
TRY(st, write_sep(writer, SEP_GRAPH_END));
}
@@ -970,13 +970,20 @@ serd_writer_write_statement(SerdWriter* const writer,
const SerdStatementFlags flags,
const SerdStatement* const statement)
{
+ assert(!((flags & SERD_ANON_S) && (flags & SERD_LIST_S)));
+ assert(!((flags & SERD_EMPTY_S) && (flags & SERD_LIST_S)));
+ assert(!((flags & SERD_ANON_O) && (flags & SERD_LIST_O)));
+ assert(!((flags & SERD_EMPTY_O) && (flags & SERD_LIST_O)));
+
SerdStatus st = SERD_SUCCESS;
const SerdNode* const subject = serd_statement_subject(statement);
const SerdNode* const predicate = serd_statement_predicate(statement);
const SerdNode* const object = serd_statement_object(statement);
const SerdNode* const graph = serd_statement_graph(statement);
- if (!is_resource(subject) || !is_resource(predicate) || !object) {
+ if (!is_resource(subject) || !is_resource(predicate) || !object ||
+ ((flags & SERD_ANON_S) && (flags & SERD_LIST_S)) ||
+ ((flags & SERD_ANON_O) && (flags & SERD_LIST_O))) {
return SERD_BAD_ARG;
}
@@ -1008,7 +1015,7 @@ serd_writer_write_statement(SerdWriter* const writer,
}
}
- if ((flags & SERD_LIST_CONT)) {
+ if (writer->context.type == CTX_LIST) {
// Continue a list
if (!strcmp(serd_node_string(predicate), NS_RDF "first") &&
!strcmp(serd_node_string(object), NS_RDF "nil")) {
@@ -1026,8 +1033,8 @@ serd_writer_write_statement(SerdWriter* const writer,
// Elide S P (write O)
const Sep last = writer->last_sep;
- const bool anon_o = flags & SERD_ANON_O_BEGIN;
- const bool list_o = flags & SERD_LIST_O_BEGIN;
+ const bool anon_o = flags & SERD_ANON_O;
+ const bool list_o = flags & SERD_LIST_O;
const bool open_o = anon_o || list_o;
const bool after_end = (last == SEP_ANON_END) || (last == SEP_LIST_END);
@@ -1039,7 +1046,7 @@ serd_writer_write_statement(SerdWriter* const writer,
} else {
// Elide S (write P and O)
- if (writer->context.comma_indented) {
+ if (writer->context.comma_indented && !(flags & SERD_ANON_S)) {
--writer->indent;
writer->context.comma_indented = false;
}
@@ -1063,7 +1070,7 @@ serd_writer_write_statement(SerdWriter* const writer,
}
TRY(st, write_node(writer, subject, SERD_SUBJECT, flags));
- if ((flags & (SERD_ANON_S_BEGIN | SERD_LIST_S_BEGIN))) {
+ if ((flags & (SERD_ANON_S | SERD_LIST_S))) {
TRY(st, write_sep(writer, SEP_ANON_S_P));
} else {
TRY(st, write_sep(writer, SEP_S_P));
@@ -1076,16 +1083,16 @@ serd_writer_write_statement(SerdWriter* const writer,
reset_context(writer, 0U);
serd_node_set(&writer->context.subject, subject);
- if (!(flags & SERD_LIST_S_BEGIN)) {
+ if (!(flags & SERD_LIST_S)) {
TRY(st, write_pred(writer, flags, predicate));
}
TRY(st, write_node(writer, object, SERD_OBJECT, flags));
}
- if (flags & (SERD_ANON_S_BEGIN | SERD_LIST_S_BEGIN)) {
+ if (flags & (SERD_ANON_S | SERD_LIST_S)) {
// Push context for anonymous or list subject
- const bool is_list = (flags & SERD_LIST_S_BEGIN);
+ const bool is_list = (flags & SERD_LIST_S);
TRY(st,
push_context(writer,
is_list ? CTX_LIST : CTX_BLANK,
@@ -1094,11 +1101,11 @@ serd_writer_write_statement(SerdWriter* const writer,
is_list ? NULL : predicate));
}
- if (flags & (SERD_ANON_O_BEGIN | SERD_LIST_O_BEGIN)) {
+ if (flags & (SERD_ANON_O | SERD_LIST_O)) {
// Push context for anonymous or list object if necessary
TRY(st,
push_context(writer,
- (flags & SERD_LIST_O_BEGIN) ? CTX_LIST : CTX_BLANK,
+ (flags & SERD_LIST_O) ? CTX_LIST : CTX_BLANK,
graph,
object,
NULL));
diff --git a/test/test_writer.c b/test/test_writer.c
index d2f59af0..e56dd789 100644
--- a/test/test_writer.c
+++ b/test/test_writer.c
@@ -137,7 +137,7 @@ test_writer_cleanup(void)
SerdNode* p = serd_new_uri(serd_string("http://example.org/p"));
SerdNode* o = serd_new_blank(serd_string("start"));
- st = serd_sink_write(sink, SERD_ANON_O_BEGIN, s, p, o, NULL);
+ st = serd_sink_write(sink, SERD_ANON_O, s, p, o, NULL);
assert(!st);
// Write the start of several nested anonymous objects
@@ -147,7 +147,7 @@ test_writer_cleanup(void)
SerdNode* next_o = serd_new_blank(serd_string(buf));
- st = serd_sink_write(sink, SERD_ANON_O_BEGIN, o, p, next_o, NULL);
+ st = serd_sink_write(sink, SERD_ANON_O, o, p, next_o, NULL);
serd_node_free(o);
o = next_o;