~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/lib-fts/fts-filter.c

  • Committer: Package Import Robot
  • Author(s): Jelmer Vernooij
  • Date: 2015-05-24 15:01:19 UTC
  • mto: (4.1.53 sid)
  • mto: This revision was merged to the branch mainline in revision 102.
  • Revision ID: package-import@ubuntu.com-20150524150119-hsh6cbr1fqseapga
Tags: upstream-2.2.18
ImportĀ upstreamĀ versionĀ 2.2.18

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2014-2015 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "lib.h"
 
4
#include "array.h"
 
5
#include "fts-language.h"
 
6
#include "fts-filter.h"
 
7
#include "fts-filter-private.h"
 
8
 
 
9
static ARRAY(const struct fts_filter *) fts_filter_classes;
 
10
 
 
11
void fts_filters_init(void)
 
12
{
 
13
        i_array_init(&fts_filter_classes, FTS_FILTER_CLASSES_NR);
 
14
 
 
15
        fts_filter_register(fts_filter_stopwords);
 
16
        fts_filter_register(fts_filter_stemmer_snowball);
 
17
        fts_filter_register(fts_filter_normalizer_icu);
 
18
        fts_filter_register(fts_filter_lowercase);
 
19
}
 
20
 
 
21
void fts_filters_deinit(void)
 
22
{
 
23
        array_free(&fts_filter_classes);
 
24
}
 
25
 
 
26
void fts_filter_register(const struct fts_filter *filter_class)
 
27
{
 
28
        i_assert(fts_filter_find(filter_class->class_name) == NULL);
 
29
 
 
30
        array_append(&fts_filter_classes, &filter_class, 1);
 
31
}
 
32
 
 
33
const struct fts_filter *fts_filter_find(const char *name)
 
34
{
 
35
        const struct fts_filter *const *fp = NULL;
 
36
 
 
37
        array_foreach(&fts_filter_classes, fp) {
 
38
                if (strcmp((*fp)->class_name, name) == 0)
 
39
                        return *fp;
 
40
        }
 
41
        return NULL;
 
42
}
 
43
 
 
44
int fts_filter_create(const struct fts_filter *filter_class,
 
45
                      struct fts_filter *parent,
 
46
                      const struct fts_language *lang,
 
47
                      const char *const *settings,
 
48
                      struct fts_filter **filter_r,
 
49
                      const char **error_r)
 
50
{
 
51
        struct fts_filter *fp;
 
52
        const char *empty_settings = NULL;
 
53
 
 
54
        i_assert(settings == NULL || str_array_length(settings) % 2 == 0);
 
55
 
 
56
        if (settings == NULL)
 
57
                settings = &empty_settings;
 
58
 
 
59
        if (filter_class->v->create(lang, settings, &fp, error_r) < 0) {
 
60
                *filter_r = NULL;
 
61
                return -1;
 
62
        }
 
63
        fp->refcount = 1;
 
64
        fp->parent = parent;
 
65
        if (parent != NULL) {
 
66
                fts_filter_ref(parent);
 
67
        }
 
68
        *filter_r = fp;
 
69
        return 0;
 
70
}
 
71
void fts_filter_ref(struct fts_filter *fp)
 
72
{
 
73
        i_assert(fp->refcount > 0);
 
74
 
 
75
        fp->refcount++;
 
76
}
 
77
 
 
78
void fts_filter_unref(struct fts_filter **_fpp)
 
79
{
 
80
        struct fts_filter *fp = *_fpp;
 
81
 
 
82
        i_assert(fp->refcount > 0);
 
83
        *_fpp = NULL;
 
84
 
 
85
        if (--fp->refcount > 0)
 
86
                return;
 
87
 
 
88
        if (fp->parent != NULL)
 
89
                fts_filter_unref(&fp->parent);
 
90
        fp->v->destroy(fp);
 
91
}
 
92
 
 
93
int fts_filter_filter(struct fts_filter *filter, const char **token,
 
94
                      const char **error_r)
 
95
{
 
96
        int ret = 0;
 
97
 
 
98
        i_assert((*token)[0] != '\0');
 
99
 
 
100
        /* Recurse to parent. */
 
101
        if (filter->parent != NULL)
 
102
                ret = fts_filter_filter(filter->parent, token, error_r);
 
103
 
 
104
        /* Parent returned token or no parent. */
 
105
        if (ret > 0 || filter->parent == NULL)
 
106
                ret = filter->v->filter(filter, token, error_r);
 
107
 
 
108
        if (ret <= 0)
 
109
                *token = NULL;
 
110
        else {
 
111
                i_assert(*token != NULL);
 
112
                i_assert((*token)[0] != '\0');
 
113
        }
 
114
        return ret;
 
115
}