Mercurial > dovecot > core-2.2
changeset 18555:230698a51fbb
fts: Improve filter error handling.
In lib-fts:
Move error storage to the generic filter struct level. Change make_utf8
helper to void also.
In fts:
Add the error argument to _filter() calls.
author | Teemu Huovila <teemu.huovila@dovecot.fi> |
---|---|
date | Sat, 09 May 2015 11:13:49 +0300 |
parents | 8c33d375c73e |
children | a45a328c5019 |
files | src/lib-fts/fts-filter-normalizer-icu.c src/lib-fts/fts-filter-private.h src/lib-fts/fts-filter.c src/lib-fts/fts-filter.h src/lib-fts/test-fts-filter.c src/plugins/fts/fts-build-mail.c src/plugins/fts/fts-search-args.c |
diffstat | 7 files changed, 49 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fts/fts-filter-normalizer-icu.c Sat May 09 11:10:31 2015 +0300 +++ b/src/lib-fts/fts-filter-normalizer-icu.c Sat May 09 11:13:49 2015 +0300 @@ -16,7 +16,6 @@ struct fts_filter_normalizer { struct fts_filter filter; - const char *error; pool_t pool; const char *transliterator_id; UTransliterator *transliterator; @@ -97,7 +96,7 @@ i_assert(ustr_len == ustr_len_actual); } -static int make_utf8(const UChar *src, const char **_dst, const char **error_r) +static void make_utf8(const UChar *src, const char **_dst) { char *dst; char *retp = NULL; @@ -133,14 +132,11 @@ dsize_actual, dsize); } if (0 != sub_num) { - fts_filter_normalizer_icu_error(error_r, "UTF8 string not well formed." - " Substitutions (%d) were made.", sub_num); - return -1; + i_panic("UTF8 string not well formed. " + "Substitutions (%d) were made.", sub_num); } i_assert(retp == dst); - *_dst = dst; - return 0; } static bool fts_filter_normalizer_icu_supports(const struct fts_language *lang) @@ -208,11 +204,11 @@ NULL, 0, &perr, &err); if (U_FAILURE(err)) { if (perr.line >= 1) { - fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.", + fts_filter_normalizer_icu_error(&np->filter.error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.", np->transliterator_id, u_errorName(err), perr.line, perr.offset); } else { - fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s.", + fts_filter_normalizer_icu_error(&np->filter.error, "Failed to open transliterator for id: %s. Lib ICU error: %s.", np->transliterator_id, u_errorName(err)); } return -1; @@ -231,10 +227,6 @@ struct fts_filter_normalizer *np = (struct fts_filter_normalizer *)filter; - /* TODO: fix error handling */ - if (np->error != NULL) - goto err_exit; - if (np->transliterator == NULL) if (fts_filter_normalizer_icu_create_trans(np) < 0) goto err_exit; @@ -262,15 +254,13 @@ } if (U_FAILURE(err)) { - icu_error(&np->error, err, "utrans_transUChars()"); + icu_error(&np->filter.error, err, "utrans_transUChars()"); goto err_exit; } - if (make_utf8(utext, token, &np->error) < 0) { - goto err_exit; - } + make_utf8(utext, token); + return 1; - return 1; err_exit: *token = NULL; return -1;
--- a/src/lib-fts/fts-filter-private.h Sat May 09 11:10:31 2015 +0300 +++ b/src/lib-fts/fts-filter-private.h Sat May 09 11:13:49 2015 +0300 @@ -18,12 +18,14 @@ struct fts_filter **filter_r, const char **error_r); int (*filter)(struct fts_filter *filter, const char **token); + void (*destroy)(struct fts_filter *filter); }; struct fts_filter { const char *class_name; /* name of the class this is based on */ const struct fts_filter_vfuncs *v; + const char *error; int refcount; struct fts_filter *parent; };
--- a/src/lib-fts/fts-filter.c Sat May 09 11:10:31 2015 +0300 +++ b/src/lib-fts/fts-filter.c Sat May 09 11:13:49 2015 +0300 @@ -93,18 +93,27 @@ /* TODO: Avoid multiple allocations by using a buffer in v->filter? Do this non-recursively? */ int -fts_filter_filter(struct fts_filter *filter, const char **token) +fts_filter_filter(struct fts_filter *filter, const char **token, + const char **error_r) { - int ret; + int ret = 0; - if (filter->parent == NULL) - return filter->v->filter(filter, token); + if (filter->error != NULL) { + *error_r = filter->error; + return -1; + } - ret = fts_filter_filter(filter->parent, token); + /* Recurse to parent. */ + if (filter->parent != NULL) + ret = fts_filter_filter(filter->parent, token, error_r); - if(ret > 0) - return filter->v->filter(filter, token); + /* Parent returned token or no parent. */ + if(ret > 0 || filter->parent == NULL) + ret = filter->v->filter(filter, token); + + if (filter->error != NULL) + *error_r = filter->error; return ret; }
--- a/src/lib-fts/fts-filter.h Sat May 09 11:10:31 2015 +0300 +++ b/src/lib-fts/fts-filter.h Sat May 09 11:13:49 2015 +0300 @@ -63,6 +63,7 @@ Input is also given via *token. */ int -fts_filter_filter(struct fts_filter *filter, const char **token); +fts_filter_filter(struct fts_filter *filter, const char **token, + const char **error_r); #endif
--- a/src/lib-fts/test-fts-filter.c Sat May 09 11:10:31 2015 +0300 +++ b/src/lib-fts/test-fts-filter.c Sat May 09 11:13:49 2015 +0300 @@ -35,7 +35,7 @@ op = output; while (*ip != NULL) { token = *ip; - ret = fts_filter_filter(filter, &token); + ret = fts_filter_filter(filter, &token, &error); test_assert(ret >= 0); if (ret == 0) test_assert(*op == NULL); @@ -79,7 +79,7 @@ op = output; while (*ip != NULL) { token = *ip; - ret = fts_filter_filter(filter, &token); + ret = fts_filter_filter(filter, &token, &error); test_assert(ret >= 0); if (ret == 0) test_assert(*op == NULL); @@ -100,7 +100,7 @@ op = output2; while (*ip != NULL) { token = *ip; - ret = fts_filter_filter(filter, &token); + ret = fts_filter_filter(filter, &token, &error); if (ret == 0) test_assert(*op == NULL); else { @@ -143,7 +143,7 @@ op = output; while (*ip != NULL) { token = *ip; - ret = fts_filter_filter(filter, &token); + ret = fts_filter_filter(filter, &token, &error); test_assert(ret >= 0); if (ret == 0) test_assert(*op == NULL); @@ -207,7 +207,7 @@ bpp = bases; for (tpp=tokens; *tpp != NULL; tpp++) { token = *tpp; - ret = fts_filter_filter(stemmer, &token); + ret = fts_filter_filter(stemmer, &token, &error); test_assert(token != NULL); test_assert(null_strcmp(token, *bpp) == 0); bpp++; @@ -242,7 +242,7 @@ bpp = bases; for (tpp=tokens; *tpp != NULL; tpp++) { token = *tpp; - ret = fts_filter_filter(stemmer, &token); + ret = fts_filter_filter(stemmer, &token, &error); test_assert(token != NULL); test_assert(null_strcmp(token, *bpp) == 0); bpp++; @@ -289,7 +289,7 @@ bpp = bases; for (tpp=tokens; *tpp != NULL; tpp++) { token = *tpp; - ret = fts_filter_filter(stemmer, &token); + ret = fts_filter_filter(stemmer, &token, &error); if (ret == 0) test_assert(*bpp == NULL); else { @@ -344,7 +344,7 @@ for (i = 0; i < N_ELEMENTS(input); i++) { if (input[i] != NULL) { token = input[i]; - test_assert_idx(fts_filter_filter(norm, &token) == 1, i); + test_assert_idx(fts_filter_filter(norm, &token, &error) == 1, i); test_assert_idx(null_strcmp(token, expected_output[i]) == 0, i); } } @@ -389,7 +389,7 @@ for (i = 0; i < N_ELEMENTS(input); i++) { if (input[i] != NULL) { token = input[i]; - test_assert_idx(fts_filter_filter(norm, &token) == 1, i); + test_assert_idx(fts_filter_filter(norm, &token, &error) == 1, i); test_assert_idx(null_strcmp(token, expected_output[i]) == 0, i); } } @@ -437,7 +437,7 @@ sha512_init(&ctx); while (NULL != fgets(buf, sizeof(buf), input)) { tokens = buf; - if (fts_filter_filter(norm, &tokens) != 1){ + if (fts_filter_filter(norm, &tokens, &error) != 1){ break; } sha512_loop(&ctx, tokens, strlen(tokens)); @@ -466,8 +466,8 @@ filter_class = fts_filter_find(ICU_NORMALIZER_FILTER_NAME); ret = fts_filter_create(filter_class, NULL, NULL, settings, &norm, &error); test_assert(ret == 0 && error == NULL); - ret = fts_filter_filter(norm, &token); - test_assert(ret < 0); + ret = fts_filter_filter(norm, &token, &error); + test_assert(ret < 0 && error != NULL); test_end(); } @@ -517,7 +517,7 @@ bpp = bases; for (tpp = tokens; *tpp != NULL; tpp++) { token = *tpp; - ret = fts_filter_filter(stemmer, &token); + ret = fts_filter_filter(stemmer, &token, &error); if (ret == 0) test_assert(*bpp == NULL); else {
--- a/src/plugins/fts/fts-build-mail.c Sat May 09 11:10:31 2015 +0300 +++ b/src/plugins/fts/fts-build-mail.c Sat May 09 11:13:49 2015 +0300 @@ -244,12 +244,13 @@ struct fts_tokenizer *tokenizer; struct fts_filter *filter = ctx->cur_user_lang->filter; const char *token; + const char *error; int ret; tokenizer = fts_user_get_index_tokenizer(ctx->update_ctx->backend->ns->user); while ((ret = fts_tokenizer_next(tokenizer, data, size, &token)) > 0) { if (filter != NULL) { - ret = fts_filter_filter(filter, &token); + ret = fts_filter_filter(filter, &token, &error); if (ret == 0) continue; if (ret < 0) @@ -260,6 +261,8 @@ strlen(token)) < 0) return -1; } + if (ret < 0) + i_error("fts: Couldn't create indexable tokens: %s", error); return ret; }
--- a/src/plugins/fts/fts-search-args.c Sat May 09 11:10:31 2015 +0300 +++ b/src/plugins/fts/fts-search-args.c Sat May 09 11:13:49 2015 +0300 @@ -63,7 +63,7 @@ struct mail_search_arg *arg; struct fts_user_language *const *langp; ARRAY_TYPE(const_string) tokens; - const char *token2; + const char *token2, *error; int ret; t_array_init(&tokens, 4); @@ -76,11 +76,13 @@ array_foreach(languages, langp) { token2 = t_strdup(token); if ((*langp)->filter != NULL) - ret = fts_filter_filter((*langp)->filter, &token2); + ret = fts_filter_filter((*langp)->filter, &token2, &error); if (ret > 0) { token2 = t_strdup(token2); array_append(&tokens, &token2, 1); } + else if (ret < 0) + i_error("fts: Couldn't create search tokens: %s", error); } array_sort(&tokens, i_strcmp_p); strings_deduplicate(&tokens);