dee

Merge lp:~kamstrup/dee/icu-transliterators into lp:dee

Proposed by Mikkel Kamstrup Erlandsen
Status: Merged
Approved by: Michal Hruby
Approved revision: 345
Merged at revision: 338
Proposed branch: lp:~kamstrup/dee/icu-transliterators
Merge into: lp:dee
Diff against target: 744 lines (+572/-5)
14 files modified
Makefile.am (+5/-0)
configure.ac (+33/-1)
dee-1.0.pc.in (+1/-1)
dee-icu-1.0.pc.in (+11/-0)
doc/reference/dee-1.0/dee-1.0-docs.sgml (+1/-0)
src/Makefile.am (+6/-0)
src/dee-icu-term-filter.c (+279/-0)
src/dee-icu.h (+72/-0)
tests/Makefile.am (+4/-0)
tests/test-dee.c (+8/-0)
tests/test-icu.c (+122/-0)
vapi/Dee-1.0-custom.vala (+5/-0)
vapi/Dee-1.0.metadata (+2/-0)
vapi/dee-1.0.vapi (+23/-3)
To merge this branch: bzr merge lp:~kamstrup/dee/icu-transliterators
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Review via email: mp+90256@code.launchpad.net

Description of the change

Add advanced transliteration support using ICU. This is an optional dependency. Developers relying on this feature will have to check it with pkg-config on the module dee-icu-1.0 and include the header file dee-icu.h.

To post a comment you must log in.
Revision history for this message
Michal Hruby (mhr3) wrote :

Great start of something magnificent! :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2012-01-02 12:40:15 +0000
3+++ Makefile.am 2012-01-26 12:28:22 +0000
4@@ -3,6 +3,10 @@
5 pkgconfigdir = $(libdir)/pkgconfig
6 pkgconfig_DATA = dee-1.0.pc
7
8+if HAVE_ICU
9+pkgconfig_DATA += dee-icu-1.0.pc
10+endif
11+
12 if WANT_TESTS
13 SUBDIRS += tests
14
15@@ -17,6 +21,7 @@
16 EXTRA_DIST = \
17 autogen.sh \
18 dee-1.0.pc.in \
19+ dee-icu-1.0.pc.in \
20 COPYING.GPL
21
22 DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc --enable-introspection=no
23
24=== modified file 'configure.ac'
25--- configure.ac 2012-01-02 12:40:15 +0000
26+++ configure.ac 2012-01-26 12:28:22 +0000
27@@ -155,6 +155,36 @@
28 AC_PATH_PROG([VALA_API_GEN], [vapigen])
29 AM_CONDITIONAL([HAVE_VAPIGEN], [test "x$VALA_API_GEN" != "x"])
30
31+dnl = Check for ICU ====================================
32+AC_ARG_ENABLE([icu],
33+ AS_HELP_STRING([--enable-icu=@<:@no/yes@:>@],[build with advanced unicode text handling (requires ICU >= 4.8) @<:@default=yes@:>@]),,
34+ [enable_icu=yes])
35+
36+if test "x$enable_icu" = "xyes"; then
37+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
38+ #include "unicode/uvernum.h"
39+ #if U_ICU_VERSION_MAJOR_NUM < 4
40+ #error Dee ICU requires at least ICU v4.8
41+ #elif U_ICU_VERSION_MAJOR_NUM == 4 && U_ICU_VERSION_MINOR_NUM < 8
42+ #error Dee ICU requires at least ICU v4.8
43+ #endif]], [[]])],
44+ [icu_available=yes],
45+ [icu_available=no])
46+
47+ if test "x$icu_available" = "xyes"; then
48+ AC_DEFINE(HAVE_ICU, 1, [Define to 1 if we have ICU])
49+ ICU_CFLAGS="$(icu-config --cflags)"
50+ ICU_LIBS="$(icu-config --ldflags-libsonly)"
51+ AC_SUBST(ICU_CFLAGS)
52+ AC_SUBST(ICU_LIBS)
53+ AC_OUTPUT([dee-icu-1.0.pc])
54+ else
55+ AC_MSG_ERROR([Dee ICU support requires ICU >= 4.8])
56+ fi
57+fi
58+
59+AM_CONDITIONAL(HAVE_ICU, test "x$enable_icu" = "xyes")
60+
61 dnl ===========================================================================
62 AC_OUTPUT([
63 Makefile
64@@ -171,7 +201,7 @@
65 tools/Makefile
66 examples/Makefile
67 vapi/Makefile
68-])
69+])
70
71 dnl Output the results
72 AC_MSG_NOTICE([
73@@ -181,6 +211,8 @@
74
75 Prefix : ${prefix}
76
77+ ICU support : ${enable_icu}
78+
79 Documentation : ${enable_gtk_doc}
80 Introspection : ${enable_introspection}
81
82
83=== modified file 'dee-1.0.pc.in'
84--- dee-1.0.pc.in 2010-05-06 14:37:39 +0000
85+++ dee-1.0.pc.in 2012-01-26 12:28:22 +0000
86@@ -8,4 +8,4 @@
87 Version: @VERSION@
88 Libs: -L${libdir} -ldee-1.0
89 Cflags: -I${includedir}/dee-1.0
90-Requires: glib-2.0 gthread-2.0 gobject-2.0 gio-2.0 gio-unix-2.0 dbus-glib-1
91+Requires: glib-2.0 gthread-2.0 gobject-2.0 gio-2.0 gio-unix-2.0
92
93=== added file 'dee-icu-1.0.pc.in'
94--- dee-icu-1.0.pc.in 1970-01-01 00:00:00 +0000
95+++ dee-icu-1.0.pc.in 2012-01-26 12:28:22 +0000
96@@ -0,0 +1,11 @@
97+prefix=@prefix@
98+exec_prefix=@exec_prefix@
99+libdir=@libdir@
100+includedir=@includedir@
101+
102+Name: @PACKAGE_NAME@
103+Description: Dee ICU integration
104+Version: @VERSION@
105+Libs: -L${libdir} -ldee-1.0
106+Cflags: -I${includedir}/dee-1.0
107+Requires: glib-2.0 gthread-2.0 gobject-2.0 gio-2.0 gio-unix-2.0
108
109=== modified file 'doc/reference/dee-1.0/dee-1.0-docs.sgml'
110--- doc/reference/dee-1.0/dee-1.0-docs.sgml 2012-01-10 07:43:54 +0000
111+++ doc/reference/dee-1.0/dee-1.0-docs.sgml 2012-01-26 12:28:22 +0000
112@@ -38,6 +38,7 @@
113 <xi:include href="xml/dee-term-list.xml"/>
114 <xi:include href="xml/dee-text-analyzer.xml"/>
115 <xi:include href="xml/dee-tree-index.xml"/>
116+ <xi:include href="xml/dee-icu.xml"/>
117 </chapter>
118
119 <chapter>
120
121=== modified file 'src/Makefile.am'
122--- src/Makefile.am 2012-01-02 10:44:20 +0000
123+++ src/Makefile.am 2012-01-26 12:28:22 +0000
124@@ -118,6 +118,12 @@
125 $(DEE_CFLAGS) \
126 $(MAINTAINER_CFLAGS)
127
128+if HAVE_ICU
129+devel_headers += dee-icu.h
130+libdee_1_0_la_SOURCES += dee-icu-term-filter.c
131+libdee_1_0_la_LIBADD += $(ICU_LIBS)
132+endif
133+
134 ##
135 # If trace logging is not enabled
136 # all the macros are removed by the preprocessor
137
138=== added file 'src/dee-icu-term-filter.c'
139--- src/dee-icu-term-filter.c 1970-01-01 00:00:00 +0000
140+++ src/dee-icu-term-filter.c 2012-01-26 12:28:22 +0000
141@@ -0,0 +1,279 @@
142+/*
143+ * Copyright (C) 2012 Canonical, Ltd.
144+ *
145+ * This library is free software; you can redistribute it and/or modify
146+ * it under the terms of the GNU Lesser General Public License
147+ * version 3.0 as published by the Free Software Foundation.
148+ *
149+ * This library is distributed in the hope that it will be useful,
150+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
151+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
152+ * GNU Lesser General Public License version 3.0 for more details.
153+ *
154+ * You should have received a copy of the GNU Lesser General Public
155+ * License along with this library. If not, see
156+ * <http://www.gnu.org/licenses/>.
157+ *
158+ * Authored by Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
159+ */
160+
161+#include <unicode/utypes.h>
162+#include <unicode/localpointer.h>
163+#include <unicode/urep.h>
164+#include <unicode/parseerr.h>
165+#include <unicode/uenum.h>
166+#include <unicode/utrans.h>
167+#include <unicode/ustring.h>
168+
169+#include <string.h>
170+
171+#include "dee-icu.h"
172+
173+/**
174+ * SECTION:dee-icu
175+ * @title: Dee ICU Extensions
176+ * @short_description: A suite of #DeeTermFilter<!-- -->s based on ICU
177+ * @include: dee-icu.h
178+ *
179+ * This module allows developers to easily construct powerful
180+ * #DeeTermFilter<!-- -->s with ease. The filters leverage the ICU
181+ * framework to provide world class transliteration features.
182+ *
183+ * The filters can be employed manually by calling dee_icu_term_filter_apply()
184+ * or installed in a #DeeAnalyzer by calling dee_analyzer_add_term_filter()
185+ * passing the term filter instance as the user data and
186+ * dee_icu_term_filter_destroy() as the #GDestroyNotify.
187+ */
188+
189+struct _DeeICUTermFilter {
190+ UTransliterator *transliterator;
191+};
192+
193+static UChar*
194+gchar2uchar (const gchar *string, int32_t *u_len)
195+{
196+ int32_t len;
197+ UChar *u_string;
198+ UErrorCode u_error_code = U_ZERO_ERROR;
199+
200+ if (string == NULL)
201+ {
202+ *u_len = -1;
203+ return NULL;
204+ }
205+
206+
207+ len = strlen (string) * 2;
208+ u_string = g_new(UChar, 2*len + 1);
209+ u_string[2*len] = '\0';
210+
211+ u_strFromUTF8Lenient (u_string, len, u_len, string, -1, &u_error_code);
212+
213+ if (U_FAILURE(u_error_code))
214+ {
215+ g_critical ("Failed to convert string '%s' into UTF-16: %s",
216+ string, u_errorName(u_error_code));
217+ return NULL;
218+ }
219+
220+ return u_string;
221+}
222+
223+static gchar*
224+print_error (const gchar *system_id,
225+ const gchar *rules,
226+ UParseError *u_parse_error,
227+ UErrorCode u_error_code)
228+{
229+ GString *str;
230+ gchar *msg;
231+
232+ str = g_string_new ("");
233+
234+ g_string_append_printf (str, "[%s]: Error creating transliterator "
235+ "for system id '%s' and rules '%s'.",
236+ u_errorName (u_error_code), system_id, rules);
237+
238+ if (u_parse_error->line >= 0)
239+ g_string_append_printf(str, " On line %i.", u_parse_error->line);
240+
241+ if (u_parse_error->offset >= 0)
242+ g_string_append_printf(str, " Offset %i.", u_parse_error->offset);
243+
244+ msg = str->str;
245+ g_string_free (str, FALSE);
246+
247+ return msg;
248+}
249+
250+static DeeICUError
251+get_error_code (UErrorCode u_error_code)
252+{
253+ /* The ICU error codes are quite tangled up,
254+ * so excuse the spaghetti logic please :-)
255+ */
256+
257+ if ( ! (u_error_code > U_PARSE_ERROR_START &&
258+ u_error_code < U_PARSE_ERROR_LIMIT) &&
259+ u_error_code != U_ILLEGAL_ARGUMENT_ERROR)
260+ {
261+ return DEE_ICU_ERROR_UNKNOWN;
262+ }
263+
264+ switch (u_error_code)
265+ {
266+ case U_INVALID_ID:
267+ case U_INVALID_FUNCTION:
268+ return DEE_ICU_ERROR_BAD_ID;
269+ case U_ILLEGAL_ARGUMENT_ERROR:
270+ default:
271+ return DEE_ICU_ERROR_BAD_RULE;
272+ }
273+}
274+
275+
276+/**
277+ * dee_icu_term_filter_new:
278+ * @system_id: A system id for the transliterator to use.
279+ * See <link anchor="http://userguide.icu-project.org/transforms/general">userguide.icu-project.org/transforms/general</link>
280+ * @rules: (allow-none): A set of transliteration rules to use.
281+ * See <link anchor="http://userguide.icu-project.org/transforms/general/rules">userguide.icu-project.org/transforms/general/rules</link>
282+ * @error: (allow-none) (error-domains Dee.ICUError): A place to return a #GError, or %NULL to ignore errors
283+ *
284+ * Create a new #DeeICUTermFilter for a given ICU transliterator system id
285+ * and/or set of transliteration rules.
286+ *
287+ * Returns: (transfer full): A newly allocated #DeeICUTermFilter.
288+ * Free with dee_icu_term_filter_destroy().
289+ */
290+DeeICUTermFilter*
291+dee_icu_term_filter_new (const gchar *system_id,
292+ const gchar *rules,
293+ GError **error)
294+{
295+ DeeICUTermFilter *self;
296+ UChar *u_rules, *u_id;
297+ int32_t u_rules_len, u_id_len;
298+ UErrorCode u_error_code = 0;
299+ UParseError u_parse_error = { 0 };
300+
301+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
302+
303+ self = g_new0 (DeeICUTermFilter, 1);
304+ u_id = gchar2uchar (system_id, &u_id_len);
305+ u_rules = gchar2uchar (rules, &u_rules_len);
306+
307+ self->transliterator = utrans_openU (u_id, u_id_len,
308+ UTRANS_FORWARD,
309+ u_rules, u_rules_len,
310+ &u_parse_error, &u_error_code);
311+
312+ if (U_FAILURE(u_error_code))
313+ {
314+ DeeICUError error_code;
315+ gchar *msg;
316+
317+ error_code = get_error_code (u_error_code);
318+ msg = print_error (system_id, rules, &u_parse_error, u_error_code);
319+
320+ g_set_error_literal (error, DEE_ICU_ERROR, error_code, msg);
321+ g_free (msg);
322+
323+ return NULL;
324+ }
325+
326+ g_free (u_rules);
327+ g_free (u_id);
328+
329+ return self;
330+}
331+
332+/**
333+ * dee_icu_term_filter_new_ascii_folder:
334+ *
335+ * Construct a term filter that folds any UTF-8 string into ASCII.
336+ *
337+ * Returns: (transfer full): A newly allocated #DeeICUTermFilter. Free with
338+ * dee_icu_term_filter_destroy().
339+ */
340+DeeICUTermFilter*
341+dee_icu_term_filter_new_ascii_folder ()
342+{
343+ return dee_icu_term_filter_new ("Latin; Latin-ASCII;", NULL, NULL);
344+}
345+
346+/**
347+ * dee_icu_term_filter_apply:
348+ * @self: The filter to apply
349+ * @text: The text to apply the filter on
350+ *
351+ * Apply a #DeeICUTermFilter on a piece of UTF-8 text.
352+ *
353+ * Returns: (transfer full): A newly allocated string. Free with g_free().
354+ */
355+gchar*
356+dee_icu_term_filter_apply (DeeICUTermFilter *self,
357+ const gchar *text)
358+{
359+ UChar *u_text;
360+ int32_t u_cap, u_len, u_limit;
361+ UErrorCode u_error_code = U_ZERO_ERROR;
362+ gchar *result;
363+
364+ g_return_val_if_fail (self != NULL, NULL);
365+ g_return_val_if_fail (text != NULL, NULL);
366+
367+ u_cap = strlen (text) * 4 + 1;
368+ u_text = g_new (UChar, u_cap);
369+ u_text[u_cap - 1] = '\0';
370+
371+ u_strFromUTF8Lenient (u_text, u_cap, &u_len, text, -1, &u_error_code);
372+
373+ if (U_FAILURE(u_error_code))
374+ {
375+ g_critical ("Failed to convert string '%s' into UTF-16: %s",
376+ text, u_errorName(u_error_code));
377+ return NULL;
378+ }
379+
380+ u_limit = u_len;
381+ utrans_transUChars (self->transliterator,
382+ u_text, &u_len, u_cap,
383+ 0, &u_limit,
384+ &u_error_code);
385+
386+ if (U_FAILURE(u_error_code))
387+ {
388+ g_critical ("Failed to transliterate '%s': %s",
389+ text, u_errorName(u_error_code));
390+ g_free (u_text);
391+ return NULL;
392+ }
393+
394+ result = g_utf16_to_utf8(u_text, u_len, NULL, NULL, NULL);
395+
396+ g_free (u_text);
397+ return result;
398+}
399+
400+/**
401+ * dee_icu_term_filter_destroy:
402+ * @filter: The filter to free
403+ *
404+ * Free all resources allocated by a #DeeICUTermFilter.
405+ */
406+void
407+dee_icu_term_filter_destroy (DeeICUTermFilter *filter)
408+{
409+ g_return_if_fail (filter != NULL);
410+
411+ utrans_close (filter->transliterator);
412+
413+ g_free (filter);
414+}
415+
416+GQuark
417+dee_icu_error_quark (void)
418+{
419+ return g_quark_from_static_string ("dee-icu-error-quark");
420+}
421
422=== added file 'src/dee-icu.h'
423--- src/dee-icu.h 1970-01-01 00:00:00 +0000
424+++ src/dee-icu.h 2012-01-26 12:28:22 +0000
425@@ -0,0 +1,72 @@
426+/*
427+ * Copyright (C) 2012 Canonical, Ltd.
428+ *
429+ * This library is free software; you can redistribute it and/or modify
430+ * it under the terms of the GNU Lesser General Public License
431+ * version 3.0 as published by the Free Software Foundation.
432+ *
433+ * This library is distributed in the hope that it will be useful,
434+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
435+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
436+ * GNU Lesser General Public License version 3.0 for more details.
437+ *
438+ * You should have received a copy of the GNU Lesser General Public
439+ * License along with this library. If not, see
440+ * <http://www.gnu.org/licenses/>.
441+ *
442+ * Authored by Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
443+ */
444+
445+#ifndef _HAVE_DEE_ICU_H
446+#define _HAVE_DEE_ICU_H
447+
448+#include <glib.h>
449+#include <glib-object.h>
450+#include <dee-analyzer.h>
451+#include <dee-term-list.h>
452+
453+G_BEGIN_DECLS
454+
455+/**
456+ * DEE_ICU_ERROR:
457+ *
458+ * Error domain for the ICU extension to Dee. Error codes will be from the
459+ * #DeeICUError enumeration
460+ */
461+#define DEE_ICU_ERROR dee_icu_error_quark()
462+
463+/**
464+ * DeeICUError:
465+ *
466+ * Error codes for the ICU extension to Dee. These codes will be set when the
467+ * error domain is #DEE_ICU_ERROR.
468+ *
469+ * @DEE_ICU_ERROR_BAD_RULE: Error parsing a transliteration rule
470+ * @DEE_ICU_ERROR_BAD_ID: Error parsing a transliterator system id
471+ * @DEE_ICU_ERROR_UNKNOWN: The ICU subsystem returned an error that is not
472+ * handled in Dee
473+ */
474+typedef enum {
475+ DEE_ICU_ERROR_BAD_RULE,
476+ DEE_ICU_ERROR_BAD_ID,
477+ DEE_ICU_ERROR_UNKNOWN
478+} DeeICUError;
479+
480+typedef struct _DeeICUTermFilter DeeICUTermFilter;
481+
482+DeeICUTermFilter* dee_icu_term_filter_new (const gchar* system_id,
483+ const gchar *rules,
484+ GError **error);
485+
486+DeeICUTermFilter* dee_icu_term_filter_new_ascii_folder ();
487+
488+gchar* dee_icu_term_filter_apply (DeeICUTermFilter *self,
489+ const gchar *text);
490+
491+void dee_icu_term_filter_destroy (DeeICUTermFilter *filter);
492+
493+GQuark dee_icu_error_quark (void);
494+
495+G_END_DECLS
496+
497+#endif /* _HAVE_DEE_ICU_H */
498
499=== modified file 'tests/Makefile.am'
500--- tests/Makefile.am 2012-01-02 12:40:15 +0000
501+++ tests/Makefile.am 2012-01-26 12:28:22 +0000
502@@ -44,6 +44,10 @@
503
504 test_dee_LDADD = $(top_builddir)/src/libdee-1.0.la $(DEE_LIBS)
505
506+if HAVE_ICU
507+test_dee_SOURCES += test-icu.c
508+endif
509+
510 if HAVE_GTX
511 test_dee_SOURCES += test-model-interactions.c
512 test_dee_SOURCES += test-peer-interactions.c
513
514=== modified file 'tests/test-dee.c'
515--- tests/test-dee.c 2011-12-15 13:41:06 +0000
516+++ tests/test-dee.c 2012-01-26 12:28:22 +0000
517@@ -43,6 +43,10 @@
518 void test_client_server_interactions_create_suite(void);
519 #endif /* HAVE_GTX */
520
521+#ifdef HAVE_ICU
522+void test_icu_create_suite(void);
523+#endif /* HAVE_ICU */
524+
525 gint
526 main (gint argc, gchar *argv[])
527 {
528@@ -75,5 +79,9 @@
529 g_message ("Interactions' test suite disabled. GTX not found. You can download GTX from https://launchpad.net/gtx");
530 #endif /* HAVE_GTX */
531
532+#ifdef HAVE_ICU
533+ test_icu_create_suite ();
534+#endif
535+
536 return g_test_run ();
537 }
538
539=== added file 'tests/test-icu.c'
540--- tests/test-icu.c 1970-01-01 00:00:00 +0000
541+++ tests/test-icu.c 2012-01-26 12:28:22 +0000
542@@ -0,0 +1,122 @@
543+/*
544+ * Copyright (C) 2012 Canonical, Ltd.
545+ *
546+ * This library is free software; you can redistribute it and/or modify
547+ * it under the terms of the GNU Lesser General Public License
548+ * version 3.0 as published by the Free Software Foundation.
549+ *
550+ * This library is distributed in the hope that it will be useful,
551+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
552+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
553+ * GNU Lesser General Public License version 3.0 for more details.
554+ *
555+ * You should have received a copy of the GNU Lesser General Public
556+ * License along with this library. If not, see
557+ * <http://www.gnu.org/licenses/>.
558+ *
559+ * Authored by Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
560+ */
561+
562+#include <dee.h>
563+#include <dee-icu.h>
564+
565+typedef struct
566+{
567+ DeeICUTermFilter *filter;
568+} Fixture;
569+
570+static void setup (Fixture *fix, gconstpointer data);
571+static void teardown (Fixture *fix, gconstpointer data);
572+
573+static void
574+setup (Fixture *fix, gconstpointer data)
575+{
576+ fix->filter = NULL;
577+}
578+
579+static void
580+teardown (Fixture *fix, gconstpointer data)
581+{
582+ if (fix->filter)
583+ dee_icu_term_filter_destroy (fix->filter);
584+}
585+
586+static void
587+test_ascii_folder (Fixture *fix, gconstpointer data)
588+{
589+ gchar *result;
590+
591+ fix->filter = dee_icu_term_filter_new_ascii_folder();
592+
593+ result = dee_icu_term_filter_apply (fix->filter, "Hello world");
594+ g_assert_cmpstr (result, ==, "Hello world");
595+ g_free (result);
596+
597+ result = dee_icu_term_filter_apply (fix->filter, "øöô");
598+ g_assert_cmpstr (result, ==, "ooo");
599+ g_free (result);
600+
601+ result = dee_icu_term_filter_apply (fix->filter, "Θεοδωράτου, Ελένη");
602+ g_assert_cmpstr (result, ==, "Theodoratou, Elene");
603+ g_free (result);
604+
605+ result = dee_icu_term_filter_apply (fix->filter, "Догилева, Татьяна");
606+ g_assert_cmpstr (result, ==, "Dogileva, Tatʹana");
607+ g_free (result);
608+
609+ result = dee_icu_term_filter_apply (fix->filter, "김, 국삼");
610+ g_assert_cmpstr (result, ==, "gim, gugsam");
611+ g_free (result);
612+
613+ result = dee_icu_term_filter_apply (fix->filter, "たけだ, まさゆき");
614+ g_assert_cmpstr (result, ==, "takeda, masayuki");
615+ g_free (result);
616+
617+ /* One last time to honor the French ;-) */
618+ result = dee_icu_term_filter_apply (fix->filter, "Est-ce que tes enfants sont de bons élèves? Ça va pour eux?");
619+ g_assert_cmpstr (result, ==, "Est-ce que tes enfants sont de bons eleves? Ca va pour eux?");
620+ g_free (result);
621+}
622+
623+static void
624+test_bad_id (Fixture *fix, gconstpointer data)
625+{
626+ GError *error = NULL;
627+
628+ fix->filter = dee_icu_term_filter_new ("*-sad ???", NULL, &error);
629+
630+ g_assert (fix->filter == NULL);
631+ g_assert (error != NULL);
632+ g_assert_cmpint (error->domain, ==, DEE_ICU_ERROR);
633+ g_assert_cmpint (error->code, ==, DEE_ICU_ERROR_BAD_ID);
634+
635+ g_error_free (error);
636+}
637+
638+static void
639+test_bad_rule (Fixture *fix, gconstpointer data)
640+{
641+ GError *error = NULL;
642+
643+ fix->filter = dee_icu_term_filter_new (NULL, "*-sad ???", &error);
644+
645+ g_assert (fix->filter == NULL);
646+ g_assert (error != NULL);
647+ g_assert_cmpint (error->domain, ==, DEE_ICU_ERROR);
648+ g_assert_cmpint (error->code, ==, DEE_ICU_ERROR_BAD_RULE);
649+
650+ g_error_free (error);
651+}
652+
653+void
654+test_icu_create_suite (void)
655+{
656+#define DOMAIN "/ICU/TermFilter"
657+
658+ g_test_add (DOMAIN"/Default/AsciiFolder", Fixture, 0,
659+ setup, test_ascii_folder, teardown);
660+ g_test_add (DOMAIN"/Default/BadId", Fixture, 0,
661+ setup, test_bad_id, teardown);
662+ g_test_add (DOMAIN"/Default/BadRule", Fixture, 0,
663+ setup, test_bad_rule, teardown);
664+}
665
666=== modified file 'vapi/Dee-1.0-custom.vala'
667--- vapi/Dee-1.0-custom.vala 2012-01-16 08:18:04 +0000
668+++ vapi/Dee-1.0-custom.vala 2012-01-26 12:28:22 +0000
669@@ -36,4 +36,9 @@
670 [CCode (returns_floating_reference = true)]
671 public GLib.Variant externalize ();
672 }
673+
674+ [CCode (cheader_filename = "dee-icu.h", free_function = "dee_icu_term_filter_destroy")]
675+ [Compact]
676+ public class ICUTermFilter {
677+ }
678 }
679
680=== modified file 'vapi/Dee-1.0.metadata'
681--- vapi/Dee-1.0.metadata 2012-01-16 08:18:04 +0000
682+++ vapi/Dee-1.0.metadata 2012-01-26 12:28:22 +0000
683@@ -32,6 +32,8 @@
684 SharedModelError errordomain
685 .shared_model_error_leader_invalidated name="LEADER_INVALIDATED"
686
687+ICUError cheader_filename="dee-icu.h"
688+
689 // why does gir add these twice?
690 resource_manager_get_default skip
691 serializable_parse skip
692
693=== modified file 'vapi/dee-1.0.vapi'
694--- vapi/dee-1.0.vapi 2012-01-16 08:18:04 +0000
695+++ vapi/dee-1.0.vapi 2012-01-26 12:28:22 +0000
696@@ -48,6 +48,12 @@
697 [CCode (has_construct_function = false)]
698 public HashIndex (Dee.Model model, Dee.Analyzer analyzer, Dee.ModelReader reader);
699 }
700+ [CCode (cheader_filename = "dee-icu.h", free_function = "dee_icu_term_filter_destroy")]
701+ [Compact]
702+ public class ICUTermFilter {
703+ public string apply (string text);
704+ public void destroy ();
705+ }
706 [CCode (cheader_filename = "dee.h", type_id = "dee_index_get_type ()")]
707 public abstract class Index : GLib.Object {
708 [CCode (has_construct_function = false)]
709@@ -291,18 +297,32 @@
710 public static Dee.ModelReader new_for_uint32_column (uint column);
711 public string read (Dee.Model model, Dee.ModelIter iter);
712 }
713- [CCode (cheader_filename = "dee.h", cprefix = "DEE_TERM_MATCH_")]
714+ [CCode (cheader_filename = "dee.h")]
715 [Flags]
716 public enum TermMatchFlag {
717+ [CCode (cname = "DEE_TERM_MATCH_EXACT")]
718 EXACT,
719+ [CCode (cname = "DEE_TERM_MATCH_PREFIX")]
720 PREFIX
721 }
722- [CCode (cheader_filename = "dee.h", cprefix = "DEE_TRANSACTION_ERROR_")]
723+ [CCode (cheader_filename = "dee.h")]
724 public enum TransactionError {
725+ [CCode (cname = "DEE_TRANSACTION_ERROR_CONCURRENT_MODIFICATION")]
726 CONCURRENT_MODIFICATION,
727+ [CCode (cname = "DEE_TRANSACTION_ERROR_COMMITTED")]
728 COMMITTED
729 }
730- [CCode (cheader_filename = "dee.h", cprefix = "DEE_SHARED_MODEL_ERROR_LEADER_")]
731+ [CCode (cheader_filename = "dee-icu.h")]
732+ public errordomain ICUError {
733+ [CCode (cname = "DEE_ICU_ERROR_BAD_RULE")]
734+ BAD_RULE,
735+ [CCode (cname = "DEE_ICU_ERROR_BAD_ID")]
736+ BAD_ID,
737+ [CCode (cname = "DEE_ICU_ERROR_UNKNOWN")]
738+ UNKNOWN;
739+ public static GLib.Quark quark ();
740+ }
741+ [CCode (cheader_filename = "dee.h")]
742 public errordomain SharedModelError {
743 [CCode (cname = "DEE_SHARED_MODEL_ERROR_LEADER_INVALIDATED")]
744 LEADER_INVALIDATED

Subscribers

People subscribed via source and target branches