]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-fts: Added "lowercase" filter.
authorTimo Sirainen <tss@iki.fi>
Sat, 9 May 2015 11:26:42 +0000 (14:26 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 9 May 2015 11:26:42 +0000 (14:26 +0300)
For now it handles only ASCII characters, but that's enough for our use.

src/lib-fts/Makefile.am
src/lib-fts/fts-filter-lowercase.c [new file with mode: 0644]
src/lib-fts/fts-filter.c
src/lib-fts/fts-filter.h
src/lib-fts/test-fts-filter.c

index e4a04f17c7a4acc6b45884f4f4c72490c1913ae1..a096de699ef49b9253d8d5c50c23cfe87060f819 100644 (file)
@@ -61,6 +61,7 @@ libfts_la_LIBADD = \
 
 libfts_la_SOURCES = \
        fts-filter.c \
+       fts-filter-lowercase.c \
        fts-filter-normalizer-icu.c \
        fts-filter-stopwords.c \
        fts-filter-stemmer-snowball.c \
diff --git a/src/lib-fts/fts-filter-lowercase.c b/src/lib-fts/fts-filter-lowercase.c
new file mode 100644 (file)
index 0000000..4074c84
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2015 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "str.h"
+#include "fts-filter.h"
+#include "fts-filter-private.h"
+#include "fts-language.h"
+
+static bool
+fts_filter_lowercase_supports(const struct fts_language *lang ATTR_UNUSED)
+{
+       return TRUE;
+}
+
+static void
+fts_filter_lowercase_destroy(struct fts_filter *filter)
+{
+       i_free(filter);
+}
+
+static int
+fts_filter_lowercase_create(const struct fts_language *lang ATTR_UNUSED,
+                           const char *const *settings,
+                           struct fts_filter **filter_r,
+                           const char **error_r)
+{
+       struct fts_filter *filter;
+
+       if (settings[0] != NULL) {
+               *error_r = t_strdup_printf("Unknown setting: %s", settings[0]);
+               return -1;
+       }
+       filter = i_new(struct fts_filter, 1);
+       *filter = *fts_filter_lowercase;
+
+       *filter_r = filter;
+       return 0;
+}
+
+static int
+fts_filter_lowercase_filter(struct fts_filter *_filter ATTR_UNUSED,
+                           const char **token,
+                           const char **error_r ATTR_UNUSED)
+{
+       *token = t_str_lcase(*token);
+       return 1;
+}
+
+static const struct fts_filter_vfuncs normalizer_filter_vfuncs = {
+       fts_filter_lowercase_supports,
+       fts_filter_lowercase_create,
+       fts_filter_lowercase_filter,
+       fts_filter_lowercase_destroy
+};
+
+static const struct fts_filter fts_filter_lowercase_real = {
+       .class_name = LOWERCASE_FILTER_NAME,
+       .v = &normalizer_filter_vfuncs
+};
+
+const struct fts_filter *fts_filter_lowercase = &fts_filter_lowercase_real;
index 2ffbfdb2c4c4950e029f25d678e402a6c484bcb2..74350dc7a63d50e253a31b3de09bd6e4afc03600 100644 (file)
@@ -15,6 +15,7 @@ void fts_filters_init(void)
        fts_filter_register(fts_filter_stopwords);
        fts_filter_register(fts_filter_stemmer_snowball);
        fts_filter_register(fts_filter_normalizer_icu);
+       fts_filter_register(fts_filter_lowercase);
 }
 
 void fts_filters_deinit(void)
index 07aa4bae2ba5b5a66c4ac2852ee8b48299136994..128a5b4f76282b39f5296560497ce7e78e4987de 100644 (file)
@@ -33,6 +33,10 @@ extern const struct fts_filter *fts_filter_stemmer_snowball;
 extern const struct fts_filter *fts_filter_normalizer_icu;
 #define ICU_NORMALIZER_FILTER_NAME "normalizer-icu"
 
+/* Lowecases the input. Currently only ASCII data is lowercased. */
+extern const struct fts_filter *fts_filter_lowercase;
+#define LOWERCASE_FILTER_NAME "lowercase"
+
 /* Register all built-in filters. */
 void fts_filters_init(void);
 void fts_filters_deinit(void);
index 867574344a1ce5001584f111754051e48d4550f5..e2e666ca9edf1a210eba845c666b78c1c82be3f1 100644 (file)
 static const char *const stopword_settings[] = {"stopwords_dir", TEST_STOPWORDS_DIR, NULL};
 static struct fts_language english_language = { .name = "en" };
 
+static void test_fts_filter_lowercase(void)
+{
+       struct {
+               const char *input;
+               const char *output;
+       } tests[] = {
+               { "foo", "foo" },
+               { "FOO", "foo" },
+               { "fOo", "foo" }
+       };
+       const struct fts_filter *filter_class;
+       struct fts_filter *filter;
+       const char *error;
+       const char *token;
+       unsigned int i;
+
+       test_begin("fts filter lowercase");
+       filter_class = fts_filter_find(LOWERCASE_FILTER_NAME);
+       test_assert(fts_filter_create(filter_class, NULL, &english_language, NULL, &filter, &error) == 0);
+
+       for (i = 0; i < N_ELEMENTS(tests); i++) {
+               token = tests[i].input;
+               test_assert_idx(fts_filter_filter(filter, &token, &error) > 0 &&
+                               strcmp(token, tests[i].output) == 0, 0);
+       }
+       fts_filter_unref(&filter);
+       test_end();
+}
+
 static void test_fts_filter_stopwords_eng(void)
 {
        const struct fts_filter *filter_class;
@@ -521,6 +550,7 @@ static void test_fts_filter_normalizer_stopwords_stemmer_eng(void)
 int main(void)
 {
        static void (*test_functions[])(void) = {
+               test_fts_filter_lowercase,
                test_fts_filter_stopwords_eng,
                test_fts_filter_stopwords_fin,
                test_fts_filter_stopwords_fra,