Merge lp:~kamstrup/dee/icu-transliterators into lp:dee
- icu-transliterators
- Merge into trunk
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 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michal Hruby (community) | Approve | ||
Review via email: mp+90256@code.launchpad.net |
Commit message
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.
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 |
Great start of something magnificent! :)