This source file includes following definitions.
- spell_decode_lang
- spell_available
- aspell_init
- aspell_clean
- aspell_get_lang_list
- aspell_array_clean
- aspell_get_lang
- aspell_set_lang
- aspell_check
- aspell_suggest
- aspell_add_to_dict
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 #include <config.h>
27
28 #include <stdlib.h>
29 #include <string.h>
30 #include <gmodule.h>
31 #include <aspell.h>
32
33 #ifdef HAVE_CHARSET
34 #include "lib/charsets.h"
35 #endif
36 #include "lib/strutil.h"
37
38 #include "src/setup.h"
39
40 #include "edit-impl.h"
41 #include "spell.h"
42
43
44
45
46
47
48
49 typedef struct aspell_struct
50 {
51 AspellConfig *config;
52 AspellSpeller *speller;
53 } spell_t;
54
55
56
57 static GModule *spell_module = NULL;
58 static spell_t *global_speller = NULL;
59
60 static AspellConfig *(*mc_new_aspell_config) (void);
61 static int (*mc_aspell_config_replace) (AspellConfig * ths, const char *key, const char *value);
62 static AspellCanHaveError *(*mc_new_aspell_speller) (AspellConfig * config);
63 static unsigned int (*mc_aspell_error_number) (const AspellCanHaveError * ths);
64 static const char *(*mc_aspell_speller_error_message) (const AspellSpeller * ths);
65 static const AspellError *(*mc_aspell_speller_error) (const AspellSpeller * ths);
66
67 static AspellSpeller *(*mc_to_aspell_speller) (AspellCanHaveError * obj);
68 static int (*mc_aspell_speller_check) (AspellSpeller * ths, const char *word, int word_size);
69 static const AspellWordList *(*mc_aspell_speller_suggest) (AspellSpeller * ths,
70 const char *word, int word_size);
71 static AspellStringEnumeration *(*mc_aspell_word_list_elements) (const struct AspellWordList * ths);
72 static const char *(*mc_aspell_config_retrieve) (AspellConfig * ths, const char *key);
73 static void (*mc_delete_aspell_speller) (AspellSpeller * ths);
74 static void (*mc_delete_aspell_config) (AspellConfig * ths);
75 static void (*mc_delete_aspell_can_have_error) (AspellCanHaveError * ths);
76 static const char *(*mc_aspell_error_message) (const AspellCanHaveError * ths);
77 static void (*mc_delete_aspell_string_enumeration) (AspellStringEnumeration * ths);
78 static AspellDictInfoEnumeration *(*mc_aspell_dict_info_list_elements)
79 (const AspellDictInfoList * ths);
80 static AspellDictInfoList *(*mc_get_aspell_dict_info_list) (AspellConfig * config);
81 static const AspellDictInfo *(*mc_aspell_dict_info_enumeration_next)
82 (AspellDictInfoEnumeration * ths);
83 static const char *(*mc_aspell_string_enumeration_next) (AspellStringEnumeration * ths);
84 static void (*mc_delete_aspell_dict_info_enumeration) (AspellDictInfoEnumeration * ths);
85 static unsigned int (*mc_aspell_word_list_size) (const AspellWordList * ths);
86 static const AspellError *(*mc_aspell_error) (const AspellCanHaveError * ths);
87 static int (*mc_aspell_speller_add_to_personal) (AspellSpeller * ths, const char *word,
88 int word_size);
89 static int (*mc_aspell_speller_save_all_word_lists) (AspellSpeller * ths);
90
91 static struct
92 {
93 const char *code;
94 const char *name;
95 } spell_codes_map[] =
96 {
97
98 {"br", N_("Breton")},
99 {"cs", N_("Czech")},
100 {"cy", N_("Welsh")},
101 {"da", N_("Danish")},
102 {"de", N_("German")},
103 {"el", N_("Greek")},
104 {"en", N_("English")},
105 {"en_GB", N_("British English")},
106 {"en_CA", N_("Canadian English")},
107 {"en_US", N_("American English")},
108 {"eo", N_("Esperanto")},
109 {"es", N_("Spanish")},
110 {"fo", N_("Faroese")},
111 {"fr", N_("French")},
112 {"it", N_("Italian")},
113 {"nl", N_("Dutch")},
114 {"no", N_("Norwegian")},
115 {"pl", N_("Polish")},
116 {"pt", N_("Portuguese")},
117 {"ro", N_("Romanian")},
118 {"ru", N_("Russian")},
119 {"sk", N_("Slovak")},
120 {"sv", N_("Swedish")},
121 {"uk", N_("Ukrainian")},
122 {NULL, NULL}
123
124 };
125
126
127
128
129
130
131
132
133
134
135 static const char *
136 spell_decode_lang (const char *code)
137 {
138 size_t i;
139
140 for (i = 0; spell_codes_map[i].code != NULL; i++)
141 {
142 if (strcmp (spell_codes_map[i].code, code) == 0)
143 return _(spell_codes_map[i].name);
144 }
145
146 return code;
147 }
148
149
150
151
152
153
154
155
156 static gboolean
157 spell_available (void)
158 {
159 gchar *spell_module_fname;
160 gboolean ret = FALSE;
161
162 if (spell_module != NULL)
163 return TRUE;
164
165 spell_module_fname = g_module_build_path (NULL, "libaspell");
166 spell_module = g_module_open (spell_module_fname, G_MODULE_BIND_LAZY);
167
168 g_free (spell_module_fname);
169
170 if (spell_module == NULL)
171 return FALSE;
172
173 if (!g_module_symbol (spell_module, "new_aspell_config", (void *) &mc_new_aspell_config))
174 goto error_ret;
175
176 if (!g_module_symbol (spell_module, "aspell_dict_info_list_elements",
177 (void *) &mc_aspell_dict_info_list_elements))
178 goto error_ret;
179
180 if (!g_module_symbol (spell_module, "aspell_dict_info_enumeration_next",
181 (void *) &mc_aspell_dict_info_enumeration_next))
182 goto error_ret;
183
184 if (!g_module_symbol (spell_module, "new_aspell_speller", (void *) &mc_new_aspell_speller))
185 goto error_ret;
186
187 if (!g_module_symbol (spell_module, "aspell_error_number", (void *) &mc_aspell_error_number))
188 goto error_ret;
189
190 if (!g_module_symbol (spell_module, "aspell_speller_error_message",
191 (void *) &mc_aspell_speller_error_message))
192 goto error_ret;
193
194 if (!g_module_symbol (spell_module, "aspell_speller_error", (void *) &mc_aspell_speller_error))
195 goto error_ret;
196
197 if (!g_module_symbol (spell_module, "aspell_error", (void *) &mc_aspell_error))
198 goto error_ret;
199
200 if (!g_module_symbol (spell_module, "to_aspell_speller", (void *) &mc_to_aspell_speller))
201 goto error_ret;
202
203 if (!g_module_symbol (spell_module, "aspell_speller_check", (void *) &mc_aspell_speller_check))
204 goto error_ret;
205
206 if (!g_module_symbol
207 (spell_module, "aspell_speller_suggest", (void *) &mc_aspell_speller_suggest))
208 goto error_ret;
209
210 if (!g_module_symbol
211 (spell_module, "aspell_word_list_elements", (void *) &mc_aspell_word_list_elements))
212 goto error_ret;
213
214 if (!g_module_symbol (spell_module, "aspell_string_enumeration_next",
215 (void *) &mc_aspell_string_enumeration_next))
216 goto error_ret;
217
218 if (!g_module_symbol
219 (spell_module, "aspell_config_replace", (void *) &mc_aspell_config_replace))
220 goto error_ret;
221
222 if (!g_module_symbol (spell_module, "aspell_error_message", (void *) &mc_aspell_error_message))
223 goto error_ret;
224
225 if (!g_module_symbol
226 (spell_module, "delete_aspell_speller", (void *) &mc_delete_aspell_speller))
227 goto error_ret;
228
229 if (!g_module_symbol (spell_module, "delete_aspell_config", (void *) &mc_delete_aspell_config))
230 goto error_ret;
231
232 if (!g_module_symbol (spell_module, "delete_aspell_string_enumeration",
233 (void *) &mc_delete_aspell_string_enumeration))
234 goto error_ret;
235
236 if (!g_module_symbol (spell_module, "get_aspell_dict_info_list",
237 (void *) &mc_get_aspell_dict_info_list))
238 goto error_ret;
239
240 if (!g_module_symbol (spell_module, "delete_aspell_can_have_error",
241 (void *) &mc_delete_aspell_can_have_error))
242 goto error_ret;
243
244 if (!g_module_symbol (spell_module, "delete_aspell_dict_info_enumeration",
245 (void *) &mc_delete_aspell_dict_info_enumeration))
246 goto error_ret;
247
248 if (!g_module_symbol
249 (spell_module, "aspell_config_retrieve", (void *) &mc_aspell_config_retrieve))
250 goto error_ret;
251
252 if (!g_module_symbol
253 (spell_module, "aspell_word_list_size", (void *) &mc_aspell_word_list_size))
254 goto error_ret;
255
256 if (!g_module_symbol (spell_module, "aspell_speller_add_to_personal",
257 (void *) &mc_aspell_speller_add_to_personal))
258 goto error_ret;
259
260 if (!g_module_symbol (spell_module, "aspell_speller_save_all_word_lists",
261 (void *) &mc_aspell_speller_save_all_word_lists))
262 goto error_ret;
263
264 ret = TRUE;
265
266 error_ret:
267 if (!ret)
268 {
269 g_module_close (spell_module);
270 spell_module = NULL;
271 }
272 return ret;
273 }
274
275
276
277
278
279
280
281
282 void
283 aspell_init (void)
284 {
285 AspellCanHaveError *error = NULL;
286
287 if (strcmp (spell_language, "NONE") == 0)
288 return;
289
290 if (global_speller != NULL)
291 return;
292
293 global_speller = g_try_malloc (sizeof (spell_t));
294 if (global_speller == NULL)
295 return;
296
297 if (!spell_available ())
298 {
299 MC_PTR_FREE (global_speller);
300 return;
301 }
302
303 global_speller->config = mc_new_aspell_config ();
304 global_speller->speller = NULL;
305
306 if (spell_language != NULL)
307 mc_aspell_config_replace (global_speller->config, "lang", spell_language);
308
309 error = mc_new_aspell_speller (global_speller->config);
310
311 if (mc_aspell_error_number (error) == 0)
312 global_speller->speller = mc_to_aspell_speller (error);
313 else
314 {
315 edit_error_dialog (_("Error"), mc_aspell_error_message (error));
316 mc_delete_aspell_can_have_error (error);
317 aspell_clean ();
318 }
319 }
320
321
322
323
324
325
326 void
327 aspell_clean (void)
328 {
329 if (global_speller == NULL)
330 return;
331
332 if (global_speller->speller != NULL)
333 mc_delete_aspell_speller (global_speller->speller);
334
335 if (global_speller->config != NULL)
336 mc_delete_aspell_config (global_speller->config);
337
338 MC_PTR_FREE (global_speller);
339
340 g_module_close (spell_module);
341 spell_module = NULL;
342 }
343
344
345
346
347
348
349
350
351
352 unsigned int
353 aspell_get_lang_list (GArray * lang_list)
354 {
355 AspellDictInfoList *dlist;
356 AspellDictInfoEnumeration *elem;
357 const AspellDictInfo *entry;
358 unsigned int i = 0;
359
360 if (spell_module == NULL)
361 return 0;
362
363
364 dlist = mc_get_aspell_dict_info_list (global_speller->config);
365 elem = mc_aspell_dict_info_list_elements (dlist);
366
367 while ((entry = mc_aspell_dict_info_enumeration_next (elem)) != NULL)
368 {
369 if (entry->name != NULL)
370 {
371 char *tmp;
372
373 tmp = g_strdup (entry->name);
374 g_array_append_val (lang_list, tmp);
375 i++;
376 }
377 }
378
379 mc_delete_aspell_dict_info_enumeration (elem);
380
381 return i;
382 }
383
384
385
386
387
388
389
390
391 void
392 aspell_array_clean (GArray * array)
393 {
394 if (array != NULL)
395 {
396 guint i = 0;
397
398 for (i = 0; i < array->len; ++i)
399 {
400 char *tmp;
401
402 tmp = g_array_index (array, char *, i);
403 g_free (tmp);
404 }
405 g_array_free (array, TRUE);
406 }
407 }
408
409
410
411
412
413
414
415
416 const char *
417 aspell_get_lang (void)
418 {
419 const char *code;
420
421 code = mc_aspell_config_retrieve (global_speller->config, "lang");
422 return spell_decode_lang (code);
423 }
424
425
426
427
428
429
430
431
432
433 gboolean
434 aspell_set_lang (const char *lang)
435 {
436 if (lang != NULL)
437 {
438 AspellCanHaveError *error;
439 const char *spell_codeset;
440
441 g_free (spell_language);
442 spell_language = g_strdup (lang);
443
444 #ifdef HAVE_CHARSET
445 if (mc_global.source_codepage > 0)
446 spell_codeset = get_codepage_id (mc_global.source_codepage);
447 else
448 #endif
449 spell_codeset = str_detect_termencoding ();
450
451 mc_aspell_config_replace (global_speller->config, "lang", lang);
452 mc_aspell_config_replace (global_speller->config, "encoding", spell_codeset);
453
454
455 if (global_speller->speller != NULL)
456 mc_delete_aspell_speller (global_speller->speller);
457
458 global_speller->speller = NULL;
459
460 error = mc_new_aspell_speller (global_speller->config);
461 if (mc_aspell_error (error) != 0)
462 {
463 mc_delete_aspell_can_have_error (error);
464 return FALSE;
465 }
466
467 global_speller->speller = mc_to_aspell_speller (error);
468 }
469 return TRUE;
470 }
471
472
473
474
475
476
477
478
479
480
481 gboolean
482 aspell_check (const char *word, const int word_size)
483 {
484 int res = 0;
485
486 if (word != NULL && global_speller != NULL && global_speller->speller != NULL)
487 res = mc_aspell_speller_check (global_speller->speller, word, word_size);
488
489 return (res == 1);
490 }
491
492
493
494
495
496
497
498
499
500
501
502 unsigned int
503 aspell_suggest (GArray * suggest, const char *word, const int word_size)
504 {
505 unsigned int size = 0;
506
507 if (word != NULL && global_speller != NULL && global_speller->speller != NULL)
508 {
509 const AspellWordList *wordlist;
510
511 wordlist = mc_aspell_speller_suggest (global_speller->speller, word, word_size);
512 if (wordlist != NULL)
513 {
514 AspellStringEnumeration *elements = NULL;
515 unsigned int i;
516
517 elements = mc_aspell_word_list_elements (wordlist);
518 size = mc_aspell_word_list_size (wordlist);
519
520 for (i = 0; i < size; i++)
521 {
522 const char *cur_sugg_word;
523
524 cur_sugg_word = g_strdup (mc_aspell_string_enumeration_next (elements));
525 if (cur_sugg_word != NULL)
526 g_array_append_val (suggest, cur_sugg_word);
527 }
528
529 mc_delete_aspell_string_enumeration (elements);
530 }
531 }
532
533 return size;
534 }
535
536
537
538
539
540
541
542
543
544 gboolean
545 aspell_add_to_dict (const char *word, int word_size)
546 {
547 mc_aspell_speller_add_to_personal (global_speller->speller, word, word_size);
548
549 if (mc_aspell_speller_error (global_speller->speller) != 0)
550 {
551 edit_error_dialog (_("Error"), mc_aspell_speller_error_message (global_speller->speller));
552 return FALSE;
553 }
554
555 mc_aspell_speller_save_all_word_lists (global_speller->speller);
556
557 if (mc_aspell_speller_error (global_speller->speller) != 0)
558 {
559 edit_error_dialog (_("Error"), mc_aspell_speller_error_message (global_speller->speller));
560 return FALSE;
561 }
562
563 return TRUE;
564 }
565
566