aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-07-10 22:01:30 -0400
committerDavid Robillard <d@drobilla.net>2022-01-14 19:37:51 -0500
commit07b716c38625dd954be279e3476164b5bb1d6293 (patch)
tree3b2d75ab74dad40c7d54d2dbee2fcad3d54f6935
parent94eeeadeb5be3d9c9266bed5d3c32c6ff29695b4 (diff)
downloadserd-07b716c38625dd954be279e3476164b5bb1d6293.tar.gz
serd-07b716c38625dd954be279e3476164b5bb1d6293.tar.bz2
serd-07b716c38625dd954be279e3476164b5bb1d6293.zip
Add serd_statement_matches()
-rw-r--r--include/serd/serd.h14
-rw-r--r--src/node.h8
-rw-r--r--src/statement.c14
-rw-r--r--test/test_statement.c9
4 files changed, 45 insertions, 0 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index 5d0f7290..cec77649 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -1177,6 +1177,20 @@ serd_statement_equals(const SerdStatement* SERD_NULLABLE a,
const SerdStatement* SERD_NULLABLE b);
/**
+ Return true iff the statement matches the given pattern.
+
+ Nodes match if they are equivalent, or if one of them is NULL. The
+ statement matches if every node matches.
+*/
+SERD_PURE_API
+bool
+serd_statement_matches(const SerdStatement* SERD_NONNULL statement,
+ const SerdNode* SERD_NULLABLE subject,
+ const SerdNode* SERD_NULLABLE predicate,
+ const SerdNode* SERD_NULLABLE object,
+ const SerdNode* SERD_NULLABLE graph);
+
+/**
@}
@defgroup serd_world World
@{
diff --git a/src/node.h b/src/node.h
index 29164dc2..e064e96b 100644
--- a/src/node.h
+++ b/src/node.h
@@ -20,6 +20,7 @@
#include "exess/exess.h"
#include "serd/serd.h"
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
@@ -49,6 +50,13 @@ serd_node_string_i(const SerdNode* const SERD_NONNULL node)
return (const char*)(node + 1);
}
+static inline bool
+serd_node_pattern_match(const SerdNode* SERD_NULLABLE a,
+ const SerdNode* SERD_NULLABLE b)
+{
+ return !a || !b || serd_node_equals(a, b);
+}
+
SerdNode* SERD_ALLOCATED
serd_node_malloc(size_t length, SerdNodeFlags flags, SerdNodeType type);
diff --git a/src/statement.c b/src/statement.c
index f3034566..d6571c6c 100644
--- a/src/statement.c
+++ b/src/statement.c
@@ -17,6 +17,7 @@
#include "statement.h"
#include "caret.h"
+#include "node.h"
#include <assert.h>
#include <stdbool.h>
@@ -132,3 +133,16 @@ serd_statement_equals(const SerdStatement* const a,
serd_node_equals(a->nodes[2], b->nodes[2]) &&
serd_node_equals(a->nodes[3], b->nodes[3])));
}
+
+bool
+serd_statement_matches(const SerdStatement* const statement,
+ const SerdNode* const subject,
+ const SerdNode* const predicate,
+ const SerdNode* const object,
+ const SerdNode* const graph)
+{
+ return (serd_node_pattern_match(statement->nodes[0], subject) &&
+ serd_node_pattern_match(statement->nodes[1], predicate) &&
+ serd_node_pattern_match(statement->nodes[2], object) &&
+ serd_node_pattern_match(statement->nodes[3], graph));
+}
diff --git a/test/test_statement.c b/test/test_statement.c
index 6f92513f..45605dd1 100644
--- a/test/test_statement.c
+++ b/test/test_statement.c
@@ -84,6 +84,15 @@ test_fields(void)
assert(serd_statement_graph(statement) == g);
assert(serd_statement_caret(statement) != caret);
assert(serd_caret_equals(serd_statement_caret(statement), caret));
+ assert(serd_statement_matches(statement, s, p, o, g));
+ assert(serd_statement_matches(statement, NULL, p, o, g));
+ assert(serd_statement_matches(statement, s, NULL, o, g));
+ assert(serd_statement_matches(statement, s, p, NULL, g));
+ assert(serd_statement_matches(statement, s, p, o, NULL));
+ assert(!serd_statement_matches(statement, o, NULL, NULL, NULL));
+ assert(!serd_statement_matches(statement, NULL, o, NULL, NULL));
+ assert(!serd_statement_matches(statement, NULL, NULL, s, NULL));
+ assert(!serd_statement_matches(statement, NULL, NULL, NULL, s));
SerdStatement* const diff_s = serd_statement_new(o, p, o, g, caret);
assert(!serd_statement_equals(statement, diff_s));