~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/anthy-utf8.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2008-06-25 19:56:33 UTC
  • mfrom: (3.1.18 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080625195633-8jljph4rfq00l8o7
Tags: 1:1.5.1-2
* uim-tcode: provide tutcode-custom.scm, tutcode-bushudic.scm
  and tutcode-rule.scm (Closes: #482659)
* Fix FTBFS: segv during compile (Closes: #483078).
  I personally think this bug is not specific for uim but is a optimization
  problem on gcc-4.3.1. (https://bugs.freedesktop.org/show_bug.cgi?id=16477)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
  Copyright (c) 2003-2008 uim Project http://code.google.com/p/uim/
 
4
 
 
5
  All rights reserved.
 
6
 
 
7
  Redistribution and use in source and binary forms, with or without
 
8
  modification, are permitted provided that the following conditions
 
9
  are met:
 
10
 
 
11
  1. Redistributions of source code must retain the above copyright
 
12
     notice, this list of conditions and the following disclaimer.
 
13
  2. Redistributions in binary form must reproduce the above copyright
 
14
     notice, this list of conditions and the following disclaimer in the
 
15
     documentation and/or other materials provided with the distribution.
 
16
  3. Neither the name of authors nor the names of its contributors
 
17
     may be used to endorse or promote products derived from this software
 
18
     without specific prior written permission.
 
19
 
 
20
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
 
21
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
22
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
23
  ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
 
24
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
25
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
26
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
27
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
28
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
29
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
30
  SUCH DAMAGE.
 
31
*/
 
32
 
 
33
#include <config.h>
 
34
 
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <ctype.h>
 
38
 
 
39
#include <anthy/anthy.h>
 
40
 
 
41
#include "uim.h"
 
42
#include "uim-scm.h"
 
43
#include "uim-scm-abbrev.h"
 
44
#include "uim-util.h"
 
45
#include "plugin.h"
 
46
 
 
47
 
 
48
#ifdef ENABLE_ANTHY_UTF8_STATIC
 
49
void uim_anthy_utf8_plugin_instance_init(void);
 
50
void uim_anthy_utf8_plugin_instance_quit(void);
 
51
#endif
 
52
 
 
53
static uim_bool initialized;
 
54
static uim_lisp context_list;
 
55
 
 
56
static void *iconv_cd_e2u;
 
57
static void *iconv_cd_u2e;
 
58
 
 
59
static void
 
60
validate_segment_index(anthy_context_t ac, int i)
 
61
{
 
62
  int err;
 
63
  struct anthy_conv_stat cs;
 
64
 
 
65
  err = anthy_get_stat(ac, &cs);
 
66
  if (err)
 
67
    uim_fatal_error("anthy_get_stat() failed");
 
68
  if (!(0 <= i && i < cs.nr_segment))
 
69
    ERROR_OBJ("invalid segment index", MAKE_INT(i));
 
70
}
 
71
 
 
72
static anthy_context_t
 
73
get_anthy_context(uim_lisp ac_)
 
74
{
 
75
  anthy_context_t ac;
 
76
 
 
77
  ac = C_PTR(ac_);
 
78
  if (!ac)
 
79
    uim_fatal_error("NULL anthy_context_t");
 
80
 
 
81
  return ac;
 
82
}
 
83
 
 
84
static uim_lisp
 
85
anthy_version()
 
86
{
 
87
  return MAKE_STR(anthy_get_version_string());
 
88
}
 
89
 
 
90
static uim_lisp
 
91
init_anthy_lib(void)
 
92
{
 
93
  if (!initialized) {
 
94
    if (anthy_init() == -1)
 
95
      uim_fatal_error("anthy_init() failed");
 
96
 
 
97
    initialized = UIM_TRUE;
 
98
  }
 
99
 
 
100
  return uim_scm_t();
 
101
}
 
102
 
 
103
static uim_lisp
 
104
create_context(uim_lisp encoding_)
 
105
{
 
106
  anthy_context_t ac;
 
107
  uim_lisp ac_;
 
108
  int encoding;
 
109
 
 
110
  /* 0: compiled, 1: EUC-JP, 2: UTF-8 */
 
111
  encoding = C_INT(encoding_);
 
112
 
 
113
  if (!iconv_cd_e2u)
 
114
    iconv_cd_e2u = uim_iconv->create("UTF-8", "EUC-JP");
 
115
 
 
116
  if (!iconv_cd_u2e)
 
117
    iconv_cd_u2e = uim_iconv->create("EUC-JP", "UTF-8");
 
118
 
 
119
  ac = anthy_create_context();
 
120
  if (!ac)
 
121
    uim_fatal_error("anthy_create_context() failed");
 
122
 
 
123
  anthy_context_set_encoding(ac, encoding);
 
124
  ac_ = MAKE_PTR(ac);
 
125
  context_list = uim_scm_callf("cons", "oo", ac_, context_list);
 
126
 
 
127
  return ac_;
 
128
}
 
129
 
 
130
 
 
131
static uim_lisp
 
132
release_context(uim_lisp ac_)
 
133
{
 
134
  anthy_context_t ac;
 
135
 
 
136
  context_list = uim_scm_callf("delete!", "oo", ac_, context_list);
 
137
 
 
138
  ac = get_anthy_context(ac_);
 
139
  anthy_release_context(ac);
 
140
  uim_scm_nullify_c_ptr(ac_);
 
141
 
 
142
  return uim_scm_f();
 
143
}
 
144
 
 
145
static uim_lisp
 
146
set_string(uim_lisp ac_, uim_lisp str_)
 
147
{
 
148
  anthy_context_t ac;
 
149
  const char *str;
 
150
 
 
151
  ac = get_anthy_context(ac_);
 
152
  str = REFER_C_STR(str_);
 
153
  anthy_set_string(ac, str);
 
154
 
 
155
  return uim_scm_f();
 
156
}
 
157
 
 
158
static uim_lisp
 
159
get_nr_segments(uim_lisp ac_)
 
160
{
 
161
  anthy_context_t ac;
 
162
  struct anthy_conv_stat cs;
 
163
  int err;
 
164
 
 
165
  ac = get_anthy_context(ac_);
 
166
  err = anthy_get_stat(ac, &cs);
 
167
  if (err)
 
168
    uim_fatal_error("anthy_get_stat() failed");
 
169
 
 
170
  return MAKE_INT(cs.nr_segment);
 
171
}
 
172
 
 
173
static uim_lisp
 
174
get_nr_candidates(uim_lisp ac_, uim_lisp seg_)
 
175
{
 
176
  anthy_context_t ac;
 
177
  int seg, err;
 
178
  struct anthy_segment_stat ss;
 
179
 
 
180
  ac = get_anthy_context(ac_);
 
181
  seg = C_INT(seg_);
 
182
 
 
183
  validate_segment_index(ac, seg);
 
184
 
 
185
  err = anthy_get_segment_stat(ac, seg, &ss);
 
186
  if (err)
 
187
    uim_fatal_error("anthy_get_segment_stat() failed");
 
188
 
 
189
  return MAKE_INT(ss.nr_candidate);
 
190
}
 
191
 
 
192
static uim_lisp
 
193
get_nth_candidate(uim_lisp ac_, uim_lisp seg_, uim_lisp nth_)
 
194
{
 
195
  anthy_context_t ac;
 
196
  int seg, nth, buflen;
 
197
  char *buf;
 
198
  uim_lisp buf_;
 
199
  
 
200
  ac = get_anthy_context(ac_);
 
201
  seg = C_INT(seg_);
 
202
  nth  = C_INT(nth_);
 
203
 
 
204
  buflen = anthy_get_segment(ac, seg, nth, NULL, 0);
 
205
  if (buflen == -1)
 
206
    uim_fatal_error("anthy_get_segment() failed");
 
207
 
 
208
  buf = uim_malloc(buflen + 1);
 
209
  buflen = anthy_get_segment(ac, seg, nth, buf, buflen + 1);
 
210
  if (buflen == -1) {
 
211
    free(buf);
 
212
    uim_fatal_error("anthy_get_segment() failed");
 
213
  }
 
214
  buf_ = MAKE_STR_DIRECTLY(buf);
 
215
 
 
216
  return buf_;
 
217
}
 
218
 
 
219
static uim_lisp
 
220
get_unconv_candidate(uim_lisp ac_, uim_lisp seg_)
 
221
{
 
222
  uim_lisp nth_;
 
223
 
 
224
  nth_ = MAKE_INT(NTH_UNCONVERTED_CANDIDATE);
 
225
  return get_nth_candidate(ac_, seg_, nth_);
 
226
}
 
227
 
 
228
static uim_lisp
 
229
get_segment_length(uim_lisp ac_, uim_lisp seg_)
 
230
{
 
231
  anthy_context_t ac;
 
232
  int seg, err;
 
233
  struct anthy_segment_stat ss;
 
234
 
 
235
  ac = get_anthy_context(ac_);
 
236
  seg = C_INT(seg_);
 
237
 
 
238
  validate_segment_index(ac, seg);
 
239
 
 
240
  err = anthy_get_segment_stat(ac, seg, &ss);
 
241
  if (err)
 
242
    uim_fatal_error("anthy_get_segment_stat() failed");
 
243
 
 
244
  return MAKE_INT(ss.seg_len);
 
245
}
 
246
 
 
247
static uim_lisp
 
248
resize_segment(uim_lisp ac_, uim_lisp seg_, uim_lisp delta_)
 
249
{
 
250
  anthy_context_t ac;
 
251
  int seg, delta;
 
252
 
 
253
  ac = get_anthy_context(ac_);
 
254
  seg = C_INT(seg_);
 
255
  delta = C_INT(delta_);
 
256
 
 
257
  anthy_resize_segment(ac, seg, delta);
 
258
  return uim_scm_f();
 
259
}
 
260
 
 
261
static uim_lisp
 
262
commit_segment(uim_lisp ac_, uim_lisp seg_, uim_lisp nth_)
 
263
{
 
264
  anthy_context_t ac;
 
265
  int seg, nth;
 
266
 
 
267
  ac = get_anthy_context(ac_);
 
268
  seg = C_INT(seg_);
 
269
  nth = C_INT(nth_);
 
270
 
 
271
  anthy_commit_segment(ac, seg, nth);
 
272
  return uim_scm_f();
 
273
}
 
274
 
 
275
static uim_lisp
 
276
set_prediction_src_string(uim_lisp ac_, uim_lisp str_)
 
277
{
 
278
#ifdef HAS_ANTHY_PREDICTION
 
279
  anthy_context_t ac;
 
280
  const char *str;
 
281
 
 
282
  ac = get_anthy_context(ac_);
 
283
  str = REFER_C_STR(str_);
 
284
 
 
285
  anthy_set_prediction_string(ac, str);
 
286
#endif
 
287
  return uim_scm_f();
 
288
}
 
289
 
 
290
static uim_lisp
 
291
get_nr_predictions(uim_lisp ac_)
 
292
{
 
293
#ifdef HAS_ANTHY_PREDICTION
 
294
  anthy_context_t ac;
 
295
  struct anthy_prediction_stat ps;
 
296
  int err;
 
297
 
 
298
  ac = get_anthy_context(ac_);
 
299
 
 
300
  err = anthy_get_prediction_stat(ac, &ps);
 
301
  if (err)
 
302
    uim_fatal_error("anthy_get_prediction_stat() failed");
 
303
  return MAKE_INT(ps.nr_prediction);
 
304
#else
 
305
  return uim_scm_f();
 
306
#endif
 
307
}
 
308
 
 
309
static uim_lisp
 
310
get_nth_prediction(uim_lisp ac_, uim_lisp nth_)
 
311
{
 
312
#ifdef HAS_ANTHY_PREDICTION
 
313
  anthy_context_t ac;
 
314
  int nth, buflen;
 
315
  char *buf;
 
316
  uim_lisp buf_;
 
317
 
 
318
  ac = get_anthy_context(ac_);
 
319
  nth = C_INT(nth_); 
 
320
 
 
321
  buflen = anthy_get_prediction(ac, nth, NULL, 0);
 
322
  if (buflen == -1)
 
323
    uim_fatal_error("anthy_get_prediction() failed");
 
324
 
 
325
  buf = uim_malloc(buflen + 1);
 
326
  buflen = anthy_get_prediction(ac, nth, buf, buflen + 1);
 
327
  if (buflen == -1) {
 
328
    free(buf);
 
329
    uim_fatal_error("anthy_get_prediction() failed");
 
330
  }
 
331
  buf_ = MAKE_STR_DIRECTLY(buf);
 
332
 
 
333
  return buf_;
 
334
#else
 
335
  return uim_scm_f();
 
336
#endif
 
337
}
 
338
 
 
339
static uim_lisp
 
340
commit_nth_prediction(uim_lisp ac_, uim_lisp nth_)
 
341
{
 
342
#ifdef HAS_ANTHY_COMMIT_PREDICTION
 
343
  anthy_context_t ac;
 
344
  int nth, err;
 
345
 
 
346
  ac = get_anthy_context(ac_);
 
347
  nth = C_INT(nth_); 
 
348
 
 
349
  err = anthy_commit_prediction(ac, nth);
 
350
 
 
351
  return MAKE_BOOL(!err);
 
352
#else
 
353
  return uim_scm_f();
 
354
#endif
 
355
}
 
356
 
 
357
static uim_lisp
 
358
eucjp_to_utf8(uim_lisp str_)
 
359
{
 
360
  const char *str;
 
361
  char *convstr;
 
362
  uim_lisp utf8_;
 
363
 
 
364
  if (!iconv_cd_e2u)
 
365
    return MAKE_STR("〓");
 
366
 
 
367
  str = REFER_C_STR(str_);
 
368
  convstr = uim_iconv->convert(iconv_cd_e2u, str);
 
369
  utf8_ = MAKE_STR(convstr);
 
370
  free(convstr);
 
371
 
 
372
  return utf8_;
 
373
}
 
374
 
 
375
static uim_lisp
 
376
utf8_to_eucjp(uim_lisp str_)
 
377
{
 
378
  const char *str;
 
379
  char *convstr;
 
380
  uim_lisp eucjp_;
 
381
 
 
382
  if (!iconv_cd_u2e)
 
383
    return MAKE_STR("");
 
384
 
 
385
  str = REFER_C_STR(str_);
 
386
  convstr = uim_iconv->convert(iconv_cd_u2e, str);
 
387
  eucjp_ = MAKE_STR(convstr);
 
388
  free(convstr);
 
389
 
 
390
  return eucjp_;
 
391
}
 
392
 
 
393
#ifndef ENABLE_ANTHY_UTF8_STATIC
 
394
void
 
395
uim_plugin_instance_init(void)
 
396
#else
 
397
void
 
398
uim_anthy_utf8_plugin_instance_init(void)
 
399
#endif
 
400
{
 
401
  context_list = uim_scm_null();
 
402
  uim_scm_gc_protect(&context_list);
 
403
 
 
404
  uim_scm_eval_c_string("(require-extension (srfi 1))"); /* for delete! */
 
405
 
 
406
  uim_scm_init_proc0("anthy-utf8-lib-init", init_anthy_lib);
 
407
  uim_scm_init_proc1("anthy-utf8-lib-alloc-context", create_context);
 
408
  uim_scm_init_proc1("anthy-utf8-lib-free-context", release_context);
 
409
  uim_scm_init_proc2("anthy-utf8-lib-set-string", set_string);
 
410
  uim_scm_init_proc1("anthy-utf8-lib-get-nr-segments",get_nr_segments);
 
411
  uim_scm_init_proc2("anthy-utf8-lib-get-nr-candidates", get_nr_candidates);
 
412
  uim_scm_init_proc3("anthy-utf8-lib-get-nth-candidate", get_nth_candidate);
 
413
  uim_scm_init_proc2("anthy-utf8-lib-get-unconv-candidate", get_unconv_candidate);
 
414
  uim_scm_init_proc2("anthy-utf8-lib-get-segment-length", get_segment_length);
 
415
  uim_scm_init_proc3("anthy-utf8-lib-resize-segment", resize_segment);
 
416
  uim_scm_init_proc3("anthy-utf8-lib-commit-segment", commit_segment);
 
417
  uim_scm_init_proc0("anthy-utf8-lib-get-anthy-version", anthy_version);
 
418
  uim_scm_init_proc2("anthy-utf8-lib-set-prediction-src-string", set_prediction_src_string);
 
419
  uim_scm_init_proc1("anthy-utf8-lib-get-nr-predictions", get_nr_predictions);
 
420
  uim_scm_init_proc2("anthy-utf8-lib-get-nth-prediction", get_nth_prediction);
 
421
  uim_scm_init_proc2("anthy-utf8-lib-commit-nth-prediction",
 
422
                     commit_nth_prediction);
 
423
  uim_scm_init_proc1("anthy-utf8-lib-eucjp-to-utf8", eucjp_to_utf8);
 
424
  uim_scm_init_proc1("anthy-utf8-lib-utf8-to-eucjp", utf8_to_eucjp);
 
425
}
 
426
 
 
427
#ifndef ENABLE_ANTHY_UTF8_STATIC
 
428
void
 
429
uim_plugin_instance_quit(void)
 
430
#else
 
431
void
 
432
uim_anthy_utf8_plugin_instance_quit(void)
 
433
#endif
 
434
{
 
435
  if (initialized) {
 
436
    uim_scm_callf("for-each", "vo",
 
437
                  "anthy-utf8-lib-free-context", context_list);
 
438
    context_list = uim_scm_null();
 
439
    uim_scm_gc_unprotect(&context_list);
 
440
 
 
441
    anthy_quit();
 
442
    initialized = UIM_FALSE;
 
443
 
 
444
    if (iconv_cd_e2u) {
 
445
      uim_iconv->release(iconv_cd_e2u);
 
446
      iconv_cd_e2u = NULL;
 
447
    }
 
448
    if (iconv_cd_u2e) {
 
449
      uim_iconv->release(iconv_cd_u2e);
 
450
      iconv_cd_u2e = NULL;
 
451
    }
 
452
  }
 
453
}