diff options
-rw-r--r-- | include/serd/env.h | 10 | ||||
-rw-r--r-- | src/env.c | 47 | ||||
-rw-r--r-- | test/test_env.c | 43 |
3 files changed, 100 insertions, 0 deletions
diff --git a/include/serd/env.h b/include/serd/env.h index 2b2982f3..404c96b6 100644 --- a/include/serd/env.h +++ b/include/serd/env.h @@ -10,6 +10,8 @@ #include "serd/status.h" #include "serd/string_view.h" +#include <stdbool.h> + SERD_BEGIN_DECLS /** @@ -25,6 +27,14 @@ typedef struct SerdEnvImpl SerdEnv; SERD_API SerdEnv* SERD_ALLOCATED serd_env_new(SerdStringView base_uri); +/// Copy an environment +SERD_API SerdEnv* SERD_ALLOCATED +serd_env_copy(const SerdEnv* SERD_NULLABLE env); + +/// Return true iff `a` is equal to `b` +SERD_PURE_API bool +serd_env_equals(const SerdEnv* SERD_NULLABLE a, const SerdEnv* SERD_NULLABLE b); + /// Free `env` SERD_API void serd_env_free(SerdEnv* SERD_NULLABLE env); @@ -37,6 +37,31 @@ serd_env_new(const SerdStringView base_uri) return env; } +SerdEnv* +serd_env_copy(const SerdEnv* const env) +{ + if (!env) { + return NULL; + } + + SerdEnv* copy = (SerdEnv*)calloc(1, sizeof(struct SerdEnvImpl)); + if (copy) { + copy->n_prefixes = env->n_prefixes; + copy->prefixes = (SerdPrefix*)malloc(copy->n_prefixes * sizeof(SerdPrefix)); + for (size_t i = 0; i < copy->n_prefixes; ++i) { + copy->prefixes[i].name = serd_node_copy(env->prefixes[i].name); + copy->prefixes[i].uri = serd_node_copy(env->prefixes[i].uri); + } + + const SerdNode* const base = serd_env_base_uri(env); + if (base) { + serd_env_set_base_uri(copy, serd_node_string_view(base)); + } + } + + return copy; +} + void serd_env_free(SerdEnv* const env) { @@ -53,6 +78,28 @@ serd_env_free(SerdEnv* const env) free(env); } +bool +serd_env_equals(const SerdEnv* const a, const SerdEnv* const b) +{ + if (!a || !b) { + return !a == !b; + } + + if (a->n_prefixes != b->n_prefixes || + !serd_node_equals(a->base_uri_node, b->base_uri_node)) { + return false; + } + + for (size_t i = 0; i < a->n_prefixes; ++i) { + if (!serd_node_equals(a->prefixes[i].name, b->prefixes[i].name) || + !serd_node_equals(a->prefixes[i].uri, b->prefixes[i].uri)) { + return false; + } + } + + return true; +} + SerdURIView serd_env_base_uri_view(const SerdEnv* const env) { diff --git a/test/test_env.c b/test/test_env.c index 4f947246..69b69061 100644 --- a/test/test_env.c +++ b/test/test_env.c @@ -13,6 +13,47 @@ #include <assert.h> #include <string.h> +static void +test_copy(void) +{ + assert(!serd_env_copy(NULL)); + + SerdEnv* const env = serd_env_new(serd_string("http://example.org/base/")); + + serd_env_set_prefix( + env, serd_string("eg"), serd_string("http://example.org/")); + + SerdEnv* const env_copy = serd_env_copy(env); + + assert(serd_env_equals(env, env_copy)); + + serd_env_set_prefix( + env_copy, serd_string("test"), serd_string("http://example.org/test")); + + assert(!serd_env_equals(env, env_copy)); + + serd_env_set_prefix( + env, serd_string("test2"), serd_string("http://example.org/test2")); + + assert(!serd_env_equals(env, env_copy)); + + serd_env_free(env_copy); + serd_env_free(env); +} + +static void +test_comparison(void) +{ + SerdEnv* const env = serd_env_new(serd_empty_string()); + + assert(!serd_env_equals(env, NULL)); + assert(!serd_env_equals(NULL, env)); + assert(serd_env_equals(NULL, NULL)); + assert(serd_env_equals(env, env)); + + serd_env_free(env); +} + static SerdStatus count_prefixes(void* handle, const SerdEvent* event) { @@ -118,6 +159,8 @@ test_env(void) int main(void) { + test_copy(); + test_comparison(); test_env(); return 0; } |