1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "fts-language.h"
#include "fts-filter-private.h"
#include "fts-common.h"
#include "unichar.h"
static int
fts_filter_contractions_create(const struct fts_language *lang,
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;
}
if (strcmp(lang->name, "fr") != 0) {
*error_r = t_strdup_printf("Unsupported language: %s", lang->name);
return -1;
}
filter = i_new(struct fts_filter, 1);
*filter = *fts_filter_contractions;
filter->token = str_new(default_pool, 64);
*filter_r = filter;
return 0;
}
static int
fts_filter_contractions_filter(struct fts_filter *filter ATTR_UNUSED,
const char **_token,
const char **error_r ATTR_UNUSED)
{
int char_size, pos = 0;
unichar_t apostrophe;
const char *token = *_token;
switch (token[pos]) {
case 'q':
pos++;
if (token[pos] == '\0' || token[pos] != 'u')
break;
/* fall through */
case 'c':
case 'd':
case 'j':
case 'l':
case 'm':
case 'n':
case 's':
case 't':
pos++;
if (token[pos] == '\0')
break;
char_size = uni_utf8_get_char(token + pos, &apostrophe);
i_assert(char_size > 0);
if (IS_APOSTROPHE(apostrophe)) {
pos += char_size;
*_token = token + pos;
}
if (token[pos] == '\0') /* nothing left */
return 0;
break;
default:
/* do nothing */
break;
}
return 1;
}
static const struct fts_filter fts_filter_contractions_real = {
.class_name = "contractions",
.v = {
fts_filter_contractions_create,
fts_filter_contractions_filter,
NULL
}
};
const struct fts_filter *fts_filter_contractions = &fts_filter_contractions_real;
|