diff options
author | David Robillard <d@drobilla.net> | 2019-03-10 22:50:31 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2019-12-20 10:26:55 -0500 |
commit | 0474b622e7fb5b58268bd7064f054a75d1e3a550 (patch) | |
tree | 81f3a335e979818f5b32c656ef9955ab4103883b /src/writer.c | |
parent | 56d89f80566dbcf4089d1b08a0361aaef97de380 (diff) | |
download | serd-0474b622e7fb5b58268bd7064f054a75d1e3a550.tar.gz serd-0474b622e7fb5b58268bd7064f054a75d1e3a550.tar.bz2 serd-0474b622e7fb5b58268bd7064f054a75d1e3a550.zip |
Add support for writing terse collections
Diffstat (limited to 'src/writer.c')
-rw-r--r-- | src/writer.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/writer.c b/src/writer.c index 15b527a2..037454eb 100644 --- a/src/writer.c +++ b/src/writer.c @@ -61,8 +61,11 @@ typedef enum { SEP_ANON_S_P, ///< Between start of anonymous node and predicate SEP_ANON_END, ///< End of anonymous node (']') SEP_LIST_BEGIN, ///< Start of list ('(') - SEP_LIST_SEP, ///< List separator (whitespace) + SEP_LIST_SEP, ///< List separator (newline) SEP_LIST_END, ///< End of list (')') + SEP_TLIST_BEGIN, ///< Start of terse list ('(') + SEP_TLIST_SEP, ///< Terse list separator (space) + SEP_TLIST_END, ///< End of terse list (')') SEP_GRAPH_BEGIN, ///< Start of graph ('{') SEP_GRAPH_END, ///< End of graph ('}') } Sep; @@ -89,12 +92,15 @@ static const SepRule rules[] = { {",", 1, +0, SEP_ALL, SEP_NONE, ~(M(SEP_ANON_END) | M(SEP_LIST_END))}, {"", 0, +1, SEP_NONE, SEP_NONE, SEP_ALL}, {" ", 1, +0, SEP_NONE, SEP_NONE, SEP_NONE}, - {"[", 1, +1, M(SEP_END_O), SEP_NONE, SEP_NONE}, + {"[", 1, +1, M(SEP_END_O), M(SEP_TLIST_BEGIN)|M(SEP_TLIST_SEP), SEP_NONE}, {"", 0, +0, SEP_NONE, SEP_ALL, SEP_NONE}, {"]", 1, -1, SEP_NONE, ~M(SEP_ANON_BEGIN), SEP_NONE}, {"(", 1, +1, M(SEP_END_O), SEP_NONE, SEP_ALL}, {"", 0, +0, SEP_NONE, SEP_ALL, SEP_NONE}, {")", 1, -1, SEP_NONE, SEP_ALL, SEP_NONE}, + {"(", 1, +1, SEP_NONE, SEP_NONE, SEP_NONE}, + {"", 0, +0, SEP_ALL, SEP_NONE, SEP_NONE}, + {")", 1, -1, SEP_NONE, SEP_NONE, SEP_NONE}, {"{", 1, +1, SEP_ALL, SEP_NONE, SEP_NONE}, {"}", 1, -1, SEP_NONE, SEP_NONE, SEP_ALL}, {"<", 1, +0, SEP_NONE, SEP_NONE, SEP_NONE}, @@ -378,9 +384,9 @@ uri_sink(const void* buf, size_t size, size_t nmemb, void* stream) } static void -write_newline(SerdWriter* writer) +write_newline(SerdWriter* writer, bool terse) { - if (writer->flags & SERD_WRITE_TERSE) { + if (terse || (writer->flags & SERD_WRITE_TERSE)) { sink(" ", 1, writer); } else { sink("\n", 1, writer); @@ -394,16 +400,19 @@ static void write_top_level_sep(SerdWriter* writer) { if (!writer->empty && !(writer->flags & SERD_WRITE_TERSE)) { - write_newline(writer); + write_newline(writer, false); } } static bool write_sep(SerdWriter* writer, const SerdStatementFlags flags, Sep sep) { - (void)flags; - - const SepRule* rule = &rules[sep]; + const SepRule* rule = &rules[sep]; + const bool terse = (((flags & SERD_TERSE_S) && (flags & SERD_LIST_S)) || + ((flags & SERD_TERSE_O) && (flags & SERD_LIST_O))); + if (terse && sep >= SEP_LIST_BEGIN && sep <= SEP_LIST_END) { + sep = (Sep)((int)sep + 3); // Switch to corresponding terse separator + } // Adjust indent, but tolerate if it would become negative writer->indent = @@ -413,7 +422,7 @@ write_sep(SerdWriter* writer, const SerdStatementFlags flags, Sep sep) // Write newline or space before separator if necessary if (rule->pre_line_after & (1u << writer->last_sep)) { - write_newline(writer); + write_newline(writer, terse); } else if (rule->pre_space_after & (1u << writer->last_sep)) { sink(" ", 1, writer); } @@ -423,7 +432,7 @@ write_sep(SerdWriter* writer, const SerdStatementFlags flags, Sep sep) // Write newline after separator if necessary if (rule->post_line_after & (1u << writer->last_sep)) { - write_newline(writer); + write_newline(writer, terse); } writer->last_sep = sep; @@ -758,8 +767,10 @@ serd_writer_write_statement(SerdWriter* writer, const SerdNode* const graph = serd_statement_get_graph(statement); if (!is_resource(subject) || !is_resource(predicate) || !object || - ((flags & SERD_ANON_S) && (flags & SERD_LIST_S)) || - ((flags & SERD_ANON_O) && (flags & SERD_LIST_O))) { + ((flags & SERD_ANON_S) && (flags & SERD_LIST_S)) || // Nonsense + ((flags & SERD_ANON_O) && (flags & SERD_LIST_O)) || // Nonsense + ((flags & SERD_ANON_S) && (flags & SERD_TERSE_S)) || // Unsupported + ((flags & SERD_ANON_O) && (flags & SERD_TERSE_O))) { // Unsupported return SERD_ERR_BAD_ARG; } |