aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-04-05 08:58:15 -0400
committerDavid Robillard <d@drobilla.net>2023-12-02 18:49:08 -0500
commita1b677851274b7e5295962658e723cab007f9b85 (patch)
treebb9de8a1addaa32f0e973e382b16b4c46b64e0de
parentb5956c4dc6b065d664908104d5fc6752a87e3364 (diff)
downloadserd-a1b677851274b7e5295962658e723cab007f9b85.tar.gz
serd-a1b677851274b7e5295962658e723cab007f9b85.tar.bz2
serd-a1b677851274b7e5295962658e723cab007f9b85.zip
Add SERD_READ_ORDERED to preserve blank node ordering in models
-rw-r--r--doc/man/serd-pipe.14
-rw-r--r--include/serd/reader.h10
-rw-r--r--src/reader.c16
-rw-r--r--test/extra/pretty/manifest.ttl14
-rw-r--r--test/extra/syntactic/inline-blank-subject.ttl (renamed from test/extra/pretty/inline-blank-subject.ttl)0
-rw-r--r--test/extra/syntactic/inline-blanks-and-lists.ttl (renamed from test/extra/pretty/inline-blanks-and-lists.ttl)0
-rw-r--r--test/extra/syntactic/manifest.ttl24
-rw-r--r--test/meson.build5
-rw-r--r--tools/console.c1
9 files changed, 55 insertions, 19 deletions
diff --git a/doc/man/serd-pipe.1 b/doc/man/serd-pipe.1
index a2ce86eb..a5dbd328 100644
--- a/doc/man/serd-pipe.1
+++ b/doc/man/serd-pipe.1
@@ -148,6 +148,10 @@ to prevent labels in different files from clashing.
This option disables that,
so blank node labels will be passed through without any added prefix.
Note that this may corrupt the output by merging distinct blank nodes.
+.It Cm ordered
+Generate blank node labels with suffixes left-padded with zeros.
+This generates IDs like "_:b0000000123" that sort in numerical order,
+which can be useful to preserve statement ordering.
.El
.It Fl O Ar syntax
Set an output syntax or option.
diff --git a/include/serd/reader.h b/include/serd/reader.h
index a2bde202..78b51d00 100644
--- a/include/serd/reader.h
+++ b/include/serd/reader.h
@@ -91,6 +91,16 @@ typedef enum {
the input document.
*/
SERD_READ_GENERATED = 1U << 4U,
+
+ /**
+ Generate blank node labels with suffixes left-padded with zeros.
+
+ This is useful because it makes generated blank node IDs like
+ "_:b0000000123" match the numerical order when compared as strings (or as
+ nodes). In particular, this can be used to preserve blank node ordering
+ from documents when the statements are sorted, such as in a model.
+ */
+ SERD_READ_ORDERED = 1U << 5U,
} SerdReaderFlag;
/// Bitwise OR of SerdReaderFlag values
diff --git a/src/reader.c b/src/reader.c
index 5ce81962..ce87a6f0 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -68,16 +68,22 @@ set_blank_id(SerdReader* const reader,
SerdNode* const node,
const size_t buf_size)
{
- char* const buf = (char*)(node + 1);
-
- node->length = (size_t)snprintf(
- buf, buf_size, "%sb%u", reader->bprefix, reader->next_id++);
+ char* const buf = (char*)(node + 1);
+ const unsigned id = reader->next_id++;
+
+ if ((reader->flags & SERD_READ_ORDERED)) {
+ node->length =
+ (size_t)snprintf(buf, buf_size, "%sb%09u", reader->bprefix, id);
+ } else {
+ node->length =
+ (size_t)snprintf(buf, buf_size, "%sb%u", reader->bprefix, id);
+ }
}
size_t
genid_length(const SerdReader* const reader)
{
- return reader->bprefix_len + 10; // + "b" + UINT32_MAX
+ return reader->bprefix_len + 11;
}
bool
diff --git a/test/extra/pretty/manifest.ttl b/test/extra/pretty/manifest.ttl
index 6422c9e0..71968ae9 100644
--- a/test/extra/pretty/manifest.ttl
+++ b/test/extra/pretty/manifest.ttl
@@ -18,8 +18,6 @@
<#empty-list-subject>
<#empty-list-subject-and-object>
<#graph-abbreviation>
- <#inline-blank-subject>
- <#inline-blanks-and-lists>
<#inline-list-subject>
<#langtags>
<#list-in-object>
@@ -106,18 +104,6 @@
mf:name "graph-abbreviation" ;
mf:result <graph-abbreviation.trig> .
-<#inline-blank-subject>
- a rdft:TestTurtleEval ;
- mf:action <inline-blank-subject.ttl> ;
- mf:name "inline-blank-subject" ;
- mf:result <inline-blank-subject.ttl> .
-
-<#inline-blanks-and-lists>
- a rdft:TestTurtleEval ;
- mf:action <inline-blanks-and-lists.ttl> ;
- mf:name "inline-blanks-and-lists" ;
- mf:result <inline-blanks-and-lists.ttl> .
-
<#inline-list-subject>
a rdft:TestTurtleEval ;
mf:action <inline-list-subject.ttl> ;
diff --git a/test/extra/pretty/inline-blank-subject.ttl b/test/extra/syntactic/inline-blank-subject.ttl
index 87ea8051..87ea8051 100644
--- a/test/extra/pretty/inline-blank-subject.ttl
+++ b/test/extra/syntactic/inline-blank-subject.ttl
diff --git a/test/extra/pretty/inline-blanks-and-lists.ttl b/test/extra/syntactic/inline-blanks-and-lists.ttl
index 3fdfa4ee..3fdfa4ee 100644
--- a/test/extra/pretty/inline-blanks-and-lists.ttl
+++ b/test/extra/syntactic/inline-blanks-and-lists.ttl
diff --git a/test/extra/syntactic/manifest.ttl b/test/extra/syntactic/manifest.ttl
new file mode 100644
index 00000000..22507130
--- /dev/null
+++ b/test/extra/syntactic/manifest.ttl
@@ -0,0 +1,24 @@
+@prefix mf: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix rdft: <http://www.w3.org/ns/rdftest#> .
+@prefix serd: <http://drobilla.net/ns/serd#> .
+
+<>
+ a mf:Manifest ;
+ rdfs:comment "Serd syntactic (non-model) pretty-printing test cases" ;
+ mf:entries (
+ <#inline-blank-subject>
+ <#inline-blanks-and-lists>
+ ) .
+
+<#inline-blank-subject>
+ a rdft:TestTurtleEval ;
+ mf:action <inline-blank-subject.ttl> ;
+ mf:name "inline-blank-subject" ;
+ mf:result <inline-blank-subject.ttl> .
+
+<#inline-blanks-and-lists>
+ a rdft:TestTurtleEval ;
+ mf:action <inline-blanks-and-lists.ttl> ;
+ mf:name "inline-blanks-and-lists" ;
+ mf:result <inline-blanks-and-lists.ttl> .
diff --git a/test/meson.build b/test/meson.build
index 8e0688f6..1f736afc 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -664,6 +664,10 @@ test_suites = {
files('extra/pretty/manifest.ttl'),
ns_serdtest + 'pretty/',
],
+ 'syntactic': [
+ files('extra/pretty/manifest.ttl'),
+ ns_serdtest + 'pretty/',
+ ],
'qualify': [
files('extra/qualify/manifest.ttl'),
ns_serdtest + 'qualify/',
@@ -712,6 +716,7 @@ if is_variable('serd_sort')
'pattern',
'perfect_forward',
'perfect_reverse',
+ 'pretty',
'qualify',
'terse',
]
diff --git a/tools/console.c b/tools/console.c
index 0aef9c01..2a396af0 100644
--- a/tools/console.c
+++ b/tools/console.c
@@ -273,6 +273,7 @@ serd_set_input_option(const SerdStringView name,
{"relative", SERD_READ_RELATIVE},
{"global", SERD_READ_GLOBAL},
{"generated", SERD_READ_GENERATED},
+ {"ordered", SERD_READ_ORDERED},
{NULL, SERD_READ_LAX},
};