summaryrefslogtreecommitdiffstats
path: root/src/query.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/query.c')
-rw-r--r--src/query.c206
1 files changed, 95 insertions, 111 deletions
diff --git a/src/query.c b/src/query.c
index cf5e44f..3dd8eca 100644
--- a/src/query.c
+++ b/src/query.c
@@ -1,18 +1,5 @@
-/*
- Copyright 2007-2019 David Robillard <http://drobilla.net>
-
- Permission to use, copy, modify, and/or distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+// Copyright 2007-2019 David Robillard <d@drobilla.net>
+// SPDX-License-Identifier: ISC
#include "lilv_internal.h"
@@ -24,30 +11,32 @@
#include <string.h>
typedef enum {
- LILV_LANG_MATCH_NONE, ///< Language does not match at all
- LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match
- LILV_LANG_MATCH_EXACT ///< Exact (language and country) match
+ LILV_LANG_MATCH_NONE, ///< Language does not match at all
+ LILV_LANG_MATCH_PARTIAL, ///< Partial (language, but not country) match
+ LILV_LANG_MATCH_EXACT ///< Exact (language and country) match
} LilvLangMatch;
static LilvLangMatch
lilv_lang_matches(const char* a, const char* b)
{
- if (!a || !b) {
- return LILV_LANG_MATCH_NONE;
- } else if (!strcmp(a, b)) {
- return LILV_LANG_MATCH_EXACT;
- }
-
- const char* a_dash = strchr(a, '-');
- const size_t a_lang_len = a_dash ? (size_t)(a_dash - a) : strlen(a);
- const char* b_dash = strchr(b, '-');
- const size_t b_lang_len = b_dash ? (size_t)(b_dash - b) : strlen(b);
-
- if (a_lang_len == b_lang_len && !strncmp(a, b, a_lang_len)) {
- return LILV_LANG_MATCH_PARTIAL;
- }
-
- return LILV_LANG_MATCH_NONE;
+ if (!a || !b) {
+ return LILV_LANG_MATCH_NONE;
+ }
+
+ if (!strcmp(a, b)) {
+ return LILV_LANG_MATCH_EXACT;
+ }
+
+ const char* a_dash = strchr(a, '-');
+ const size_t a_lang_len = a_dash ? (size_t)(a_dash - a) : strlen(a);
+ const char* b_dash = strchr(b, '-');
+ const size_t b_lang_len = b_dash ? (size_t)(b_dash - b) : strlen(b);
+
+ if (a_lang_len == b_lang_len && !strncmp(a, b, a_lang_len)) {
+ return LILV_LANG_MATCH_PARTIAL;
+ }
+
+ return LILV_LANG_MATCH_NONE;
}
static LilvNodes*
@@ -55,66 +44,59 @@ lilv_nodes_from_stream_objects_i18n(LilvWorld* world,
SordIter* stream,
SordQuadIndex field)
{
- LilvNodes* values = lilv_nodes_new();
- const SordNode* nolang = NULL; // Untranslated value
- const SordNode* partial = NULL; // Partial language match
- char* syslang = lilv_get_lang();
- FOREACH_MATCH(stream) {
- const SordNode* value = sord_iter_get_node(stream, field);
- if (sord_node_get_type(value) == SORD_LITERAL) {
- const char* lang = sord_node_get_language(value);
-
- if (!lang) {
- nolang = value;
- } else {
- switch (lilv_lang_matches(lang, syslang)) {
- case LILV_LANG_MATCH_EXACT:
- // Exact language match, add to results
- zix_tree_insert((ZixTree*)values,
- lilv_node_new_from_node(world, value),
- NULL);
- break;
- case LILV_LANG_MATCH_PARTIAL:
- // Partial language match, save in case we find no exact
- partial = value;
- break;
- case LILV_LANG_MATCH_NONE:
- break;
- }
- }
- } else {
- zix_tree_insert((ZixTree*)values,
- lilv_node_new_from_node(world, value),
- NULL);
- }
- }
- sord_iter_free(stream);
- free(syslang);
-
- if (lilv_nodes_size(values) > 0) {
- return values;
- }
-
- const SordNode* best = nolang;
- if (syslang && partial) {
- // Partial language match for system language
- best = partial;
- } else if (!best) {
- // No languages matches at all, and no untranslated value
- // Use any value, if possible
- best = partial;
- }
-
- if (best) {
- zix_tree_insert(
- (ZixTree*)values, lilv_node_new_from_node(world, best), NULL);
- } else {
- // No matches whatsoever
- lilv_nodes_free(values);
- values = NULL;
- }
-
- return values;
+ LilvNodes* values = lilv_nodes_new();
+ const SordNode* nolang = NULL; // Untranslated value
+ const SordNode* partial = NULL; // Partial language match
+ char* syslang = lilv_get_lang();
+ FOREACH_MATCH (stream) {
+ const SordNode* value = sord_iter_get_node(stream, field);
+ if (sord_node_get_type(value) == SORD_LITERAL) {
+ const char* lang = sord_node_get_language(value);
+
+ if (!lang) {
+ nolang = value;
+ } else {
+ switch (lilv_lang_matches(lang, syslang)) {
+ case LILV_LANG_MATCH_EXACT:
+ // Exact language match, add to results
+ zix_tree_insert(
+ (ZixTree*)values, lilv_node_new_from_node(world, value), NULL);
+ break;
+ case LILV_LANG_MATCH_PARTIAL:
+ // Partial language match, save in case we find no exact
+ partial = value;
+ break;
+ case LILV_LANG_MATCH_NONE:
+ break;
+ }
+ }
+ } else {
+ zix_tree_insert(
+ (ZixTree*)values, lilv_node_new_from_node(world, value), NULL);
+ }
+ }
+ sord_iter_free(stream);
+ free(syslang);
+
+ if (lilv_nodes_size(values) > 0) {
+ return values;
+ }
+
+ const SordNode* best = nolang;
+ if ((syslang && partial) || !best) {
+ best = partial;
+ }
+
+ if (best) {
+ zix_tree_insert(
+ (ZixTree*)values, lilv_node_new_from_node(world, best), NULL);
+ } else {
+ // No matches whatsoever
+ lilv_nodes_free(values);
+ values = NULL;
+ }
+
+ return values;
}
LilvNodes*
@@ -122,21 +104,23 @@ lilv_nodes_from_stream_objects(LilvWorld* world,
SordIter* stream,
SordQuadIndex field)
{
- if (sord_iter_end(stream)) {
- sord_iter_free(stream);
- return NULL;
- } else if (world->opt.filter_language) {
- return lilv_nodes_from_stream_objects_i18n(world, stream, field);
- } else {
- LilvNodes* values = lilv_nodes_new();
- FOREACH_MATCH(stream) {
- const SordNode* value = sord_iter_get_node(stream, field);
- LilvNode* node = lilv_node_new_from_node(world, value);
- if (node) {
- zix_tree_insert((ZixTree*)values, node, NULL);
- }
- }
- sord_iter_free(stream);
- return values;
- }
+ if (sord_iter_end(stream)) {
+ sord_iter_free(stream);
+ return NULL;
+ }
+
+ if (world->opt.filter_language) {
+ return lilv_nodes_from_stream_objects_i18n(world, stream, field);
+ }
+
+ LilvNodes* values = lilv_nodes_new();
+ FOREACH_MATCH (stream) {
+ const SordNode* value = sord_iter_get_node(stream, field);
+ LilvNode* node = lilv_node_new_from_node(world, value);
+ if (node) {
+ zix_tree_insert((ZixTree*)values, node, NULL);
+ }
+ }
+ sord_iter_free(stream);
+ return values;
}