diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | include/serd/statement.h | 14 | ||||
-rw-r--r-- | src/n3.c | 34 | ||||
-rw-r--r-- | src/reader.c | 2 | ||||
-rw-r--r-- | src/writer.c | 41 | ||||
-rw-r--r-- | test/test_writer.c | 4 |
6 files changed, 47 insertions, 49 deletions
@@ -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 @@ -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; |