1 /* m17n-core.c -- body of the CORE API.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
5
6 This file is part of the m17n library.
7
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
12
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301 USA. */
22
23 /***en
24 @addtogroup m17nIntro
25 @brief Introduction to the m17n library.
26
27 <em>API LEVELS</em>
28
29 The API of the m17n library is divided into these five.
30
31 <ol>
32 <li> CORE API
33
34 It provides basic modules to handle M-texts. To use this API, an
35 application program must include <m17n-core<EM></EM>.h> and be
36 linked with -lm17n-core.
37
38 <li> SHELL API
39
40 It provides modules for character properties, character set
41 handling, code conversion, etc. They load various kinds of
42 data from the database on demand. To use this API, an application
43 program must include <m17n<EM></EM>.h> and be linked with
44 -lm17n-core -lm17n.
45
46 When you use this API, CORE API is also available.
47
48 <li> FLT API
49
50 It provides modules for text shaping using @ref mdbFLT. To use
51 this API, an application program must include <m17n<EM></EM>.h>
52 and be linked with -lm17n-core -lm17n-flt.
53
54 When you use this API, CORE API is also available.
55
56 <li> GUI API
57
58 It provides GUI modules such as drawing and inputting M-texts on a
59 graphic device. This API itself is independent of graphic
60 devices, but most functions require an argument MFrame that is
61 created for a specific type of graphic devices. The currently
62 supported graphic devices are null device, the X Window System,
63 and image data (gdImagePtr) of the GD library.
64
65 On a frame of a null device, you cannot draw text nor use input
66 methods. However, functions like mdraw_glyph_list (), etc. are
67 available.
68
69 On a frame of the X Window System, you can use the whole GUI API.
70
71 On a frame of the GD library, you can use all drawing API but
72 cannot use input methods.
73
74 To use this API, an application program must include
75 <m17n-gui<EM></EM>.h> and be linked with -lm17n-core -lm17n
76 -lm17n-gui.
77
78 When you use this API, CORE, SHELL, and FLT APIs are also
79 available.
80
81 <li> MISC API
82
83 It provides miscellaneous functions to support error handling and
84 debugging. This API cannot be used standalone; it must be used
85 with one or more APIs listed above. To use this API, an
86 application program must include <m17n-misc<EM></EM>.h> in
87 addition to one of the header files described above.
88
89 </ol>
90
91 See also the section @ref m17n-config "m17n-config(1)".
92
93 <em>ENVIRONMENT VARIABLES</em>
94
95 The m17n library pays attention to the following environment
96 variables.
97
98 <ul>
99 <li> @c M17NDIR
100
101 The name of the directory that contains data of the m17n database.
102 See @ref m17nDatabase for details.
103
104 <li> @c MDEBUG_XXX
105
106 Environment variables whose names start with "MDEBUG_" control
107 debug information output. See @ref m17nDebug for details.
108
109 </ul>
110
111 <em>API NAMING CONVENTION</em>
112
113 The m17n library exports functions, variables, macros, and types.
114 All of them start with the letter 'm' or 'M', and are followed by
115 an object name (e.g. "symbol", "plist") or a module name
116 (e.g. draw, input). Note that the name of M-text objects start
117 with "mtext" and not with "mmtext".
118
119 <ul>
120
121 <li> functions -- mobject () or mobject_xxx ()
122
123 They start with 'm' and are followed by an object name in lower
124 case. Words are separated by '_'. For example, msymbol (),
125 mtext_ref_char (), mdraw_text ().
126
127 <li> non-symbol variables -- mobject, or mobject_xxx
128
129 The naming convention is the same as functions (e.g. mface_large).
130
131 <li> symbol variables -- Mname
132
133 Variables of the type MSymbol start with 'M' and are followed by
134 their names. Words are separated by '_'. For example, Mlanguage
135 (the name is "language"), Miso_2022 (the name is "iso-2022").
136
137 <li> macros -- MOBJECT_XXX
138
139 They start with 'M' and are followed by an object name in upper
140 case. Words are separated by '_'.
141
142 <li> types -- MObject or MObjectXxx
143
144 They start with 'M' and are followed by capitalized object names.
145 Words are concatenated directly and no '_' are used. For example,
146 MConverter, MInputDriver.
147
148 </ul>
149
150 */
151
152 /***ja
153 @addtogroup m17nIntro
154 @brief m17n �饤�֥�� ����ȥ���������.
155
156 @em API�Υ�٥�
157
158 m17n �饤�֥��� API �ϰʲ��Σ����ʬ�व��Ƥ��롣
159
160 <ol>
161 <li> ���� API
162
163 M-text ������δ���Ū�ʥ⥸�塼������롣
164 ���� API �����Ѥ��뤿��ˤϡ����ץꥱ�������ץ�����
165 <m17n-core<EM></EM>.h> �� include ���� -lm17n-core
166 �ǥ����ʤ��ƤϤʤ�ʤ���
167
168 <li> ������ API
169
170 ʸ���ץ�ѥƥ���ʸ���������������Ѵ����Τ���Υ⥸�塼������롣
171 �����Υ⥸�塼��ϡ��ǡ����١�������ɬ�פ˱�����¿�ͤʥǡ�������ɤ��롣
172 ���� API �����Ѥ��뤿��ˤϡ����ץꥱ�������ץ�����
173 <m17n<EM></EM>.h> �� include ���� -lm17n-core -lm17n
174 �ǥ����ʤ��ƤϤʤ�ʤ���
175
176 ���� API ����Ѥ���С����� API �⼫ưŪ�˻��Ѳ�ǽ�Ȥʤ롣
177
178 <li> FLT API
179
180 ʸ����ɽ���� @ref mdbFLT ���Ѥ���⥸�塼������롣���� API
181 �����Ѥ��뤿��ˤϡ����ץꥱ�������ץ����� <m17n<EM></EM>.h>
182 �� include ���� -lm17n-core -lm17n-flt �ǥ����ʤ��ƤϤʤ�ʤ���
183
184 ���� API ����Ѥ���С����� API �⼫ưŪ�˻��Ѳ�ǽ�Ȥʤ롣
185
186 <li> GUI API
187
188 ����ե��å��ǥХ������ M-text ��ɽ�����������Ϥ����ꤹ�뤿���
189 GUI �⥸�塼������롣���� API
190 ���Τϥ���ե��å��ǥХ����Ȥ���Ω�Ǥ��뤬��
191 ¿���δؿ�������Υ���ե��å��ǥХ����Ѥ˺������줿
192 MFrame ������˼�롣
193 �������ǥ��ݡ��Ȥ���Ƥ��륰��ե��å��ǥХ����ϡ��̥�ǥХ�����X
194 ������ɥ������ƥࡢ����� GD �饤�֥��Υ�����ǡ���
195 (gdImagePtr) �Ǥ��롣
196
197 �̥�ǥХ����Υե졼���Ǥ�ɽ�������Ϥ�Ǥ��ʤ���������
198 mdraw_glyph_list () �ʤɤδؿ��ϻ��Ѳ�ǽ�Ǥ��롣
199
200 X ������ɥ������ƥ�Υե졼���ǤϤ��٤Ƥ� GUI API �����ѤǤ��롣
201
202 GD �饤�֥��Υե졼���Ǥϡ������Ѥ� API
203 �Ϥ��٤ƻ��ѤǤ��뤬�����ϤϤǤ��ʤ���
204
205 ���� API ����Ѥ��뤿��ˤϡ����ץꥱ�������ץ�����
206 <m17n-gui<EM></EM>.h> �� include ����-lm17n-core -lm17n -lm17n-gui
207 �ǥ����ʤ��ƤϤʤ�ʤ���
208
209 ���� API ����Ѥ���С����� API�������� API������� FLT API
210 �⼫ưŪ�˻��Ѳ�ǽ�Ȥʤ롣
211
212 <li> ����¾�� API
213
214 ���顼�������ǥХå��ѤΤ���¾�δؿ������롣���� API
215 �Ϥ�������Ǥϻ��ѤǤ������嵭��¾�� API
216 �ȶ��˻Ȥ������Ѥ��뤿��ˤϡ��嵭�Τ����줫��include
217 �ե�����˲ä��ơ� <m17n-misc<EM></EM>.h> ��include
218 ���ʤ��ƤϤʤ�ʤ���
219
220 </ol>
221
222 @ref m17n-config "m17n-config(1)" ��⻲�ȡ�
223
224 @em �Ķ��ѿ�
225
226 m17n �饤�֥��ϰʲ��δĶ��ѿ��Ȥ��롣
227
228 <ul>
229 <li> @c M17NDIR
230
231 m17n �ǡ����١����Υǡ������Ǽ�����ǥ��쥯�ȥ��̾�����ܺ٤� @ref
232 m17nDatabase ���ȡ�
233
234 <li> @c MDEBUG_XXX
235
236 "MDEBUG_" �ǻϤޤ�̾������ĴĶ��ѿ��ϥǥХå�����ν��Ϥ����椹�롣
237 �ܺ٤� @ref m17nDebug ���ȡ�
238
239 </ul>
240
241 @em API @em ��̿̾��§
242
243 m17n �饤�֥��ϡ��ؿ����ѿ����ޥ������� export ���롣������ 'm'
244 �ޤ��� 'M' �Τ��Ȥ˥��֥�������̾ ("symbol"��"plist" �ʤ�)
245 �ޤ��ϥ⥸�塼��̾ (draw, input �ʤ�) ��³������ΤǤ��롣
246 M-text ���֥������Ȥ�̾���� "mmtext" �ǤϤʤ��� "mtext"
247 �ǻϤޤ뤳�Ȥ���ա�
248
249 <ul>
250
251 <li> �ؿ� -- mobject () �ޤ��� mobject_xxx ()
252
253 'm' �Τ��Ȥ˾�ʸ���ǥ��֥�������̾��³����ñ��֤� '_'
254 �Ƕ��ڤ��롣���Ȥ��С�msymbol (),
255 mtext_ref_char (), mdraw_text () �ʤɡ�
256
257 <li> ����ܥ�Ǥʤ��ѿ� -- mobject, �ޤ��� mobject_xxx
258
259 �ؿ���Ʊ��̿̾��§�˽��������Ȥ��� mface_large �ʤɡ�
260
261 <li> ����ܥ��ѿ� -- Mname
262
263 MSymbol ���ѿ��ϡ�'M' �θ��̾����³����ñ��֤� '_'
264 �Ƕ��ڤ��롣���Ȥ��� Mlanguage (̾���� "language"), Miso_2022
265 (̾����"iso-2022") �ʤɡ�
266
267 <li> �ޥ��� -- MOBJECT_XXX
268
269 'M' �θ����ʸ���ǥ��֥�������̾��³����ñ��֤� '_' �Ƕ��ڤ��롣
270
271 <li> ������ -- MObject �ޤ��� MObjectXxx
272
273 'M' �θ����ʸ���ǻϤޤ륪�֥�������̾��³����ñ���Ϣ³���ƽ졢
274 '_' ���Ѥ����ʤ������Ȥ��� MConverter, MInputDriver �ʤɡ�
275
276 </ul>
277
278 */
279 /*=*/
280 /*** @{ */
281 #ifdef FOR_DOXYGEN
282 /***en
283 The #M17NLIB_MAJOR_VERSION macro gives the major version number
284 of the m17n library. */
285 /***ja
286 �ޥ��� #M17NLIB_MAJOR_VERSION �� m17n
287 �饤�֥��Υ�㡼�С�������ֹ��Ϳ����. */
288
289 #define M17NLIB_MAJOR_VERSION
290
291 /*=*/
292
293 /***en
294 The #M17NLIB_MINOR_VERSION macro gives the minor version number
295 of the m17n library. */
296
297 /***ja
298 �ޥ��� #M17NLIB_MINOR_VERSION �� m17n
299 �饤�֥��Υޥ��ʡ��С�������ֹ��Ϳ����. */
300
301 #define M17NLIB_MINOR_VERSION
302
303 /*=*/
304
305 /***en
306 The #M17NLIB_PATCH_LEVEL macro gives the patch level number
307 of the m17n library. */
308
309 /***ja
310 �ޥ��� #M17NLIB_PATCH_LEVEL �� m17n
311 �饤�֥��Υѥå���٥��ֹ��Ϳ����. */
312
313 #define M17NLIB_PATCH_LEVEL
314
315 /*=*/
316
317 /***en
318 The #M17NLIB_VERSION_NAME macro gives the version name of the
319 m17n library as a string. */
320
321 /***ja
322 �ޥ��� #M17NLIB_VERSION_NAME �� m17n
323 �饤�֥��ΥС������̾��ʸ����Ȥ���Ϳ����. */
324
325 #define M17NLIB_VERSION_NAME
326
327 /*=*/
328
329 /***en
330 @brief Initialize the m17n library.
331
332 The macro M17N_INIT () initializes the m17n library. This macro
333 must be called before any m17n functions are used.
334
335 It is safe to call this macro multiple times, but in that case,
336 the macro M17N_FINI () must be called the same times to free the
337 memory.
338
339 If the initialization was successful, the external variable
340 #merror_code is set to 0. Otherwise it is set to -1.
341
342 @seealso
343 M17N_FINI (), m17n_status () */
344
345 /***ja
346 @brief m17n �饤�֥�����������.
347
348 �ޥ��� M17N_INIT () �� m17n �饤�֥����������롣m17n
349 �δؿ������Ѥ������ˡ����Υޥ����ޤ��ƤФʤ��ƤϤʤ�ʤ���
350
351 ���Υޥ����ʣ����Ƥ�Ǥ�����Ǥ��뤬�����ξ������������뤿��˥ޥ���
352 M17N_FINI () ��Ʊ������Ƥ�ɬ�פ����롣
353
354 �����ѿ� #merror_code �ϡ����������������� 0 �ˡ������Ǥʤ����
355 -1 �����ꤵ��롣
356
357 @seealso
358 M17N_FINI (), m17n_status () */
359
360 #define M17N_INIT()
361
362 /*=*/
363
364 /***en
365 @brief Finalize the m17n library.
366
367 The macro M17N_FINI () finalizes the m17n library. It frees all the
368 memory area used by the m17n library. Once this macro is
369 called, no m17n functions should be used until the
370 macro M17N_INIT () is called again.
371
372 If the macro M17N_INIT () was called N times, the Nth call of this
373 macro actually free the memory.
374
375 @seealso
376 M17N_INIT (), m17n_status () */
377 /***ja
378 @brief m17n �饤�֥���λ����.
379
380 �ޥ��� M17N_FINI () �� m17n �饤�֥���λ���롣m17n
381 �饤�֥�꤬�Ȥä����ƤΥ����ΰ�ϲ�������롣���٤��Υޥ����ƤФ줿�顢�ޥ���
382 M17N_INIT () �����ٸƤФ��ޤ� m17n �ؿ��ϻȤ��٤��Ǥʤ���
383
384 �ޥ��� M17N_INIT () �� N ��ƤФ�Ƥ������ˤϡ����Υޥ��� N
385 ��ƤФ�ƽ��ƥ��꤬��������롣
386
387 @seealso
388 M17N_INIT (), m17n_status () */
389
390 #define M17N_FINI()
391 #endif /* FOR_DOXYGEN */
392 /*=*/
393 /*** @} */
394 /*=*/
395
396 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
397 /*** @addtogroup m17nInternal
398 @{ */
399
400 #include <config.h>
401 #include <stdio.h>
402 #include <stdlib.h>
403 #include <string.h>
404 #include <sys/time.h>
405 #include <sys/resource.h>
406 #include <unistd.h>
407
408 #include "m17n-core.h"
409 #include "m17n-misc.h"
410 #include "internal.h"
411 #include "symbol.h"
412
413 static void
default_error_handler(enum MErrorCode err)414 default_error_handler (enum MErrorCode err)
415 {
416 exit (err);
417 }
418
419 static struct timeval time_stack[16];
420 static int time_stack_index;
421
422 static M17NObjectArray *object_array_root;
423
424 static void
report_object_array()425 report_object_array ()
426 {
427 fprintf (mdebug__output, "%16s %7s %7s %7s\n",
428 "object", "created", "freed", "alive");
429 fprintf (mdebug__output, "%16s %7s %7s %7s\n",
430 "------", "-------", "-----", "-----");
431 for (; object_array_root; object_array_root = object_array_root->next)
432 {
433 M17NObjectArray *array = object_array_root;
434
435 fprintf (mdebug__output, "%16s %7d %7d %7d\n", array->name,
436 array->used, array->used - array->count, array->count);
437 if (array->count > 0)
438 {
439 int i;
440 for (i = 0; i < array->used && ! array->objects[i]; i++);
441
442 if (strcmp (array->name, "M-text") == 0)
443 {
444 MText *mt = (MText *) array->objects[i];
445
446 if (mt->format <= MTEXT_FORMAT_UTF_8)
447 fprintf (mdebug__output, "\t\"%s\"\n", (char *) mt->data);
448 }
449 else if (strcmp (array->name, "Plist") == 0)
450 {
451 MPlist *plist = (MPlist *) array->objects[i];
452
453 mdebug_dump_plist (plist, 8);
454 fprintf (mdebug__output, "\n");
455 }
456 }
457
458 if (array->objects != NULL)
459 {
460 free (array->objects);
461 array->count = array->used = 0;
462 }
463 }
464 }
465
466
467
468 /* Internal API */
469
470 int m17n__core_initialized;
471 int m17n__shell_initialized;
472 int m17n__gui_initialized;
473
474 int mdebug__flags[MDEBUG_MAX];
475 FILE *mdebug__output;
476
477 void
mdebug__push_time()478 mdebug__push_time ()
479 {
480 struct timezone tz;
481
482 gettimeofday (time_stack + time_stack_index++, &tz);
483 }
484
485 void
mdebug__pop_time()486 mdebug__pop_time ()
487 {
488 time_stack_index--;
489 }
490
491 void
mdebug__print_time()492 mdebug__print_time ()
493 {
494 struct timeval tv;
495 struct timezone tz;
496 long diff;
497
498 gettimeofday (&tv, &tz);
499 diff = ((tv.tv_sec - time_stack[time_stack_index - 1].tv_sec) * 1000000
500 + (tv.tv_usec - time_stack[time_stack_index - 1].tv_usec));
501 fprintf (mdebug__output, "%8ld ms.", diff);
502 time_stack[time_stack_index - 1] = tv;
503 }
504
505 static void
SET_DEBUG_FLAG(char * env_name,enum MDebugFlag flag)506 SET_DEBUG_FLAG (char *env_name, enum MDebugFlag flag)
507 {
508 char *env_value = getenv (env_name);
509
510 if (env_value)
511 {
512 int int_value = atoi (env_value);
513
514 if (flag == MDEBUG_ALL)
515 {
516 int i;
517 for (i = 0; i < MDEBUG_MAX; i++)
518 mdebug__flags[i] = int_value;
519 }
520 else
521 mdebug__flags[flag] = int_value;
522 }
523 }
524
525 void
mdebug__add_object_array(M17NObjectArray * array,char * name)526 mdebug__add_object_array (M17NObjectArray *array, char *name)
527 {
528 array->name = name;
529 array->count = 0;
530 array->next = object_array_root;
531 object_array_root = array;
532 }
533
534
535 void
mdebug__register_object(M17NObjectArray * array,void * object)536 mdebug__register_object (M17NObjectArray *array, void *object)
537 {
538 if (array->objects == NULL)
539 MLIST_INIT1 (array, objects, 256);
540 array->count++;
541 MLIST_APPEND1 (array, objects, object, MERROR_OBJECT);
542 }
543
544 void
mdebug__unregister_object(M17NObjectArray * array,void * object)545 mdebug__unregister_object (M17NObjectArray *array, void *object)
546 {
547 array->count--;
548 if (array->count >= 0)
549 {
550 int i;
551
552 for (i = array->used - 1; i >= 0 && array->objects[i] != object; i--);
553 if (i >= 0)
554 {
555 if (i == array->used - 1)
556 array->used--;
557 array->objects[i] = NULL;
558 }
559 else
560 mdebug_hook ();
561 }
562 else \
563 mdebug_hook ();
564 }
565
566
567 /* External API */
568
569 /* The following two are actually not exposed to a user but concealed
570 by the macro M17N_INIT (). */
571
572 void
m17n_init_core(void)573 m17n_init_core (void)
574 {
575 int mdebug_flag = MDEBUG_INIT;
576
577 merror_code = MERROR_NONE;
578 if (m17n__core_initialized++)
579 return;
580
581 m17n_memory_full_handler = default_error_handler;
582
583 SET_DEBUG_FLAG ("MDEBUG_ALL", MDEBUG_ALL);
584 SET_DEBUG_FLAG ("MDEBUG_INIT", MDEBUG_INIT);
585 SET_DEBUG_FLAG ("MDEBUG_FINI", MDEBUG_FINI);
586 SET_DEBUG_FLAG ("MDEBUG_CHARSET", MDEBUG_CHARSET);
587 SET_DEBUG_FLAG ("MDEBUG_CODING", MDEBUG_CODING);
588 SET_DEBUG_FLAG ("MDEBUG_DATABASE", MDEBUG_DATABASE);
589 SET_DEBUG_FLAG ("MDEBUG_FONT", MDEBUG_FONT);
590 SET_DEBUG_FLAG ("MDEBUG_FLT", MDEBUG_FLT);
591 SET_DEBUG_FLAG ("MDEBUG_FONTSET", MDEBUG_FONTSET);
592 SET_DEBUG_FLAG ("MDEBUG_INPUT", MDEBUG_INPUT);
593 /* for backward compatibility... */
594 SET_DEBUG_FLAG ("MDEBUG_FONT_FLT", MDEBUG_FLT);
595 SET_DEBUG_FLAG ("MDEBUG_FONT_OTF", MDEBUG_FLT);
596 {
597 char *env_value = getenv ("MDEBUG_OUTPUT_FILE");
598
599 mdebug__output = NULL;
600 if (env_value)
601 {
602 if (strcmp (env_value, "stdout") == 0)
603 mdebug__output = stdout;
604 else
605 mdebug__output = fopen (env_value, "a");
606 }
607 if (! mdebug__output)
608 mdebug__output = stderr;
609 }
610
611 MDEBUG_PUSH_TIME ();
612 MDEBUG_PUSH_TIME ();
613 if (msymbol__init () < 0)
614 goto err;
615 MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize symbol module."));
616 if (mplist__init () < 0)
617 goto err;
618 MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize plist module."));
619 if (mchar__init () < 0)
620 goto err;
621 MDEBUG_PRINT_TIME ("INIT",
622 (mdebug__output, " to initialize character module."));
623 if (mchartable__init () < 0)
624 goto err;
625 MDEBUG_PRINT_TIME ("INIT",
626 (mdebug__output, " to initialize chartable module."));
627 if (mtext__init () < 0 || mtext__prop_init () < 0)
628 goto err;
629 MDEBUG_PRINT_TIME ("INIT", (mdebug__output, " to initialize mtext module."));
630 if (mdatabase__init () < 0)
631 goto err;
632 MDEBUG_PRINT_TIME ("INIT",
633 (mdebug__output, " to initialize database module."));
634
635 #if ENABLE_NLS
636 bindtextdomain ("m17n-lib", GETTEXTDIR);
637 bindtextdomain ("m17n-db", GETTEXTDIR);
638 bindtextdomain ("m17n-contrib", GETTEXTDIR);
639 bind_textdomain_codeset ("m17n-lib", "UTF-8");
640 bind_textdomain_codeset ("m17n-db", "UTF-8");
641 bind_textdomain_codeset ("m17n-contrib", "UTF-8");
642 #endif
643
644 err:
645 MDEBUG_POP_TIME ();
646 MDEBUG_PRINT_TIME ("INIT",
647 (mdebug__output, " to initialize the core modules."));
648 MDEBUG_POP_TIME ();
649 }
650
651 void
m17n_fini_core(void)652 m17n_fini_core (void)
653 {
654 int mdebug_flag = MDEBUG_FINI;
655
656 if (m17n__core_initialized == 0
657 || --m17n__core_initialized > 0)
658 return;
659
660 MDEBUG_PUSH_TIME ();
661 MDEBUG_PUSH_TIME ();
662 mchartable__fini ();
663 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize chartable module."));
664 mtext__fini ();
665 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize mtext module."));
666 msymbol__fini ();
667 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize symbol module."));
668 mplist__fini ();
669 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize plist module."));
670 /* We must call this after the aboves because it frees interval
671 pools. */
672 mtext__prop_fini ();
673 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize textprop module."));
674 MDEBUG_POP_TIME ();
675 MDEBUG_PRINT_TIME ("FINI", (mdebug__output, " to finalize the core modules."));
676 MDEBUG_POP_TIME ();
677 if (mdebug__flags[MDEBUG_FINI])
678 report_object_array ();
679 msymbol__free_table ();
680 if (mdebug__output != stderr)
681 fclose (mdebug__output);
682 }
683
684 /*** @} */
685 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
686 /*=*/
687
688 /*** @addtogroup m17nIntro */
689
690 /*** @{ */
691 /*=*/
692
693 /***en
694 @brief Report which part of the m17n library is initialized.
695
696 The m17n_status () function returns one of these values depending
697 on which part of the m17n library is initialized:
698
699 #M17N_NOT_INITIALIZED, #M17N_CORE_INITIALIZED,
700 #M17N_SHELL_INITIALIZED, #M17N_GUI_INITIALIZED */
701
702 /***ja
703 @brief m17n �饤�֥��Τɤ���ʬ����������줿�����.
704
705 �ؿ� m17n_status () ��
706 m17n �饤�֥��Τɤ���ʬ����������줿���˱����ơ��ʲ����ͤΤ����줫���֤���
707
708 #M17N_NOT_INITIALIZED, #M17N_CORE_INITIALIZED,
709 #M17N_SHELL_INITIALIZED, #M17N_GUI_INITIALIZED */
710
711 enum M17NStatus
m17n_status(void)712 m17n_status (void)
713 {
714 return (m17n__gui_initialized ? M17N_GUI_INITIALIZED
715 : m17n__shell_initialized ? M17N_SHELL_INITIALIZED
716 : m17n__core_initialized ? M17N_CORE_INITIALIZED
717 : M17N_NOT_INITIALIZED);
718 }
719
720 /*** @} */
721
722 /*=*/
723 /***en
724 @addtogroup m17nObject
725 @brief Managed objects are objects managed by the reference count.
726
727 There are some types of m17n objects that are managed by their
728 reference count. Those objects are called @e managed @e objects.
729 When created, the reference count of a managed object is
730 initialized to one. The m17n_object_ref () function increments
731 the reference count of a managed object by one, and the
732 m17n_object_unref () function decrements by one. A managed
733 object is automatically freed when its reference count becomes
734 zero.
735
736 A property whose key is a managing key can have only a managed
737 object as its value. Some functions, for instance msymbol_put ()
738 and mplist_put (), pay special attention to such a property.
739
740 In addition to the predefined managed object types, users can
741 define their own managed object types. See the documentation of
742 the m17n_object () for more details. */
743 /***ja
744 @addtogroup m17nObject
745 @brief ���������֥������ȤȤϻ��ȿ��ˤ�äƴ�������Ƥ��륪�֥������ȤǤ���.
746
747 m17n ���֥������ȤΤ��뷿�Τ�Τϡ����ȿ��ˤ�äƴ�������Ƥ��롣
748 �����Υ��֥������Ȥ� @e ���������֥������� �ȸƤФ�롣�������줿�����Ǥλ��ȿ���
749 1 �˽��������Ƥ��롣�ؿ� m17n_object_ref () �ϴ��������֥������Ȥλ��ȿ���
750 1 ���䤷���ؿ�m17n_object_unref () �� 1 ���餹�����ȿ���
751 0 �ˤʤä����������֥������Ȥϼ�ưŪ�˲�������롣
752
753 ���������������Ǥ���ץ�ѥƥ��ϡ��ͤȤ��ƴ��������֥������Ȥ������롣
754 �ؿ� msymbol_put () �� mplist_put () �ʤɤϤ����Υץ�ѥƥ������̰������롣
755
756 ����Ѥߴ��������֥������ȥ����פ�¾�ˡ��桼����ɬ�פʴ��������֥������ȥ����פ�ʬ��������뤳�Ȥ��Ǥ��롣�ܺ٤�
757 m17n_object () �������ȡ� */
758
759 /*** @{ */
760 /*=*/
761 /***en
762 @brief Allocate a managed object.
763
764 The m17n_object () function allocates a new managed object of
765 $SIZE bytes and sets its reference count to 1. $FREER is the
766 function that is used to free the object when the reference count
767 becomes 0. If $FREER is NULL, the object is freed by the free ()
768 function.
769
770 The heading bytes of the allocated object is occupied by
771 #M17NObjectHead. That area is reserved for the m17n library and
772 application programs should never touch it.
773
774 @return
775 This function returns a newly allocated object.
776
777 @errors
778 This function never fails. */
779
780 /***ja
781 @brief ���������֥������Ȥ������Ƥ�.
782
783 �ؿ� m17n_object () ��$SIZE �Х��Ȥο��������������֥������Ȥ������ơ����λ��ȿ���
784 1 �Ȥ��롣 $FREER �ϻ��ȿ��� 0
785 �ˤʤä��ݤˤ��Υ��֥������Ȥ�������뤿����Ѥ�����ؿ��Ǥ��롣$FREER
786 �� NULL�ʤ�С����֥������Ȥϴؿ� free () �ˤ�äƲ�������롣
787
788 ������Ƥ�줿���֥���������Ƭ�ΥХ��Ȥϡ�#M17NObjectHead
789 �����롣�����ΰ�� m17n �饤�֥�꤬���Ѥ���Τǡ����ץꥱ�������ץ����Ͽ���ƤϤʤ�ʤ���
790
791 @return
792 ���δؿ��Ͽ�����������Ƥ�줿���֥������Ȥ��֤���
793
794 @errors
795 ���δؿ��ϼ��Ԥ��ʤ��� */
796
797 #if EXAMPLE_CODE
798 typedef struct
799 {
800 M17NObjectHead head;
801 int mem1;
802 char *mem2;
803 } MYStruct;
804
805 void
my_freer(void * obj)806 my_freer (void *obj)
807 {
808 free (((MYStruct *) obj)->mem2);
809 free (obj);
810 }
811
812 void
my_func(MText * mt,MSymbol key,int num,char * str)813 my_func (MText *mt, MSymbol key, int num, char *str)
814 {
815 MYStruct *st = m17n_object (sizeof (MYStruct), my_freer);
816
817 st->mem1 = num;
818 st->mem2 = strdup (str);
819 /* KEY must be a managing key. */
820 mtext_put_prop (mt, 0, mtext_len (mt), key, st);
821 /* This sets the reference count of ST back to 1. */
822 m17n_object_unref (st);
823 }
824 #endif
825
826 void *
m17n_object(int size,void (* freer)(void *))827 m17n_object (int size, void (*freer) (void *))
828 {
829 M17NObject *obj = malloc (size);
830
831 obj->ref_count = 1;
832 obj->ref_count_extended = 0;
833 obj->flag = 0;
834 obj->u.freer = freer;
835 return obj;
836 }
837
838 /*=*/
839
840 /***en
841 @brief Increment the reference count of a managed object.
842
843 The m17n_object_ref () function increments the reference count of
844 the managed object pointed to by $OBJECT.
845
846 @return
847 This function returns the resulting reference count if it fits in
848 a 16-bit unsigned integer (i.e. less than 0x10000). Otherwise, it
849 return -1.
850
851 @errors
852 This function never fails. */
853 /***ja
854 @brief ���������֥������Ȥλ��ȿ��� 1 ���䤹.
855
856 �ؿ� m17n_object_ref () �� $OBJECT
857 �ǻؤ������������֥������Ȥλ��ȿ��� 1 ���䤹��
858
859 @return
860 ���δؿ��ϡ����䤷�����ȿ��� 16 �ӥåȤ����̵��������(���ʤ��
861 0x10000 ̤��)�ˤ����ޤ�С�������֤��������Ǥʤ���� -1 ���֤���
862
863 @errors
864 ���δؿ��ϼ��Ԥ��ʤ��� */
865
866 int
m17n_object_ref(void * object)867 m17n_object_ref (void *object)
868 {
869 M17NObject *obj = (M17NObject *) object;
870 M17NObjectRecord *record;
871 unsigned *count;
872
873 if (! obj->ref_count_extended)
874 {
875 if (++obj->ref_count)
876 return (int) obj->ref_count;
877 MSTRUCT_MALLOC (record, MERROR_OBJECT);
878 record->freer = obj->u.freer;
879 MLIST_INIT1 (record, counts, 1);
880 MLIST_APPEND1 (record, counts, 0, MERROR_OBJECT);
881 obj->u.record = record;
882 obj->ref_count_extended = 1;
883 }
884 else
885 record = obj->u.record;
886
887 count = record->counts;
888 while (*count == 0xFFFFFFFF)
889 *(count++) = 0;
890 (*count)++;
891 if (*count == 0xFFFFFFFF)
892 MLIST_APPEND1 (record, counts, 0, MERROR_OBJECT);
893 return -1;
894 }
895
896 /*=*/
897
898 /***en
899 @brief Decrement the reference count of a managed object.
900
901 The m17n_object_unref () function decrements the reference count
902 of the managed object pointed to by $OBJECT. When the reference
903 count becomes zero, the object is freed by its freer function.
904
905 @return
906 This function returns the resulting reference count if it fits in
907 a 16-bit unsigned integer (i.e. less than 0x10000). Otherwise, it
908 returns -1. Thus, the return value zero means that $OBJECT is
909 freed.
910
911 @errors
912 This function never fails. */
913 /***ja
914 @brief ���������֥������Ȥλ��ȿ��� 1 ���餹.
915
916 �ؿ� m17n_object_unref () �� $OBJECT �ǻؤ������������֥������Ȥλ��ȿ���
917 1 ���餹�����ȿ��� 0 �ˤʤ�С����֥������Ȥϲ����ؿ��ˤ�äƲ�������롣
918
919 @return
920 ���δؿ��ϡ����餷�����ȿ��� 16 �ӥåȤ����̵��������(���ʤ��
921 0x10000 ̤��)�ˤ����ޤ�С�������֤��������Ǥʤ���� -1
922 ���֤����Ĥޤꡢ0 ���֤ä��褿����$OBJECT �ϲ�������Ƥ��롣
923
924 @errors
925 ���δؿ��ϼ��Ԥ��ʤ��� */
926 int
m17n_object_unref(void * object)927 m17n_object_unref (void *object)
928 {
929 M17NObject *obj = (M17NObject *) object;
930 M17NObjectRecord *record;
931 unsigned *count;
932
933 if (! obj->ref_count_extended)
934 {
935 if (! --obj->ref_count)
936 {
937 if (obj->u.freer)
938 (obj->u.freer) (object);
939 else
940 free (object);
941 return 0;
942 }
943 return (int) obj->ref_count;
944 }
945
946 record = obj->u.record;
947 count = record->counts;
948 while (! *count)
949 *(count++) = 0xFFFFFFFF;
950 (*count)--;
951 if (! record->counts[0])
952 {
953 obj->ref_count_extended = 0;
954 obj->ref_count--;
955 obj->u.freer = record->freer;
956 MLIST_FREE1 (record, counts);
957 free (record);
958 }
959 return -1;
960 }
961
962 /*=*/
963
964 /*** @} */
965
966 /***en
967 @addtogroup m17nError Error Handling
968 @brief Error handling of the m17n library.
969
970 There are two types of errors that may happen in a function of
971 the m17n library.
972
973 The first type is argument errors. When a library function is
974 called with invalid arguments, it returns a value that indicates
975 error and at the same time sets the external variable #merror_code
976 to a non-zero integer.
977
978 The second type is memory allocation errors. When the required
979 amount of memory is not available on the system, m17n library
980 functions call a function pointed to by the external variable @c
981 m17n_memory_full_handler. The default value of the variable is a
982 pointer to the default_error_handle () function, which just calls
983 <tt> exit ()</tt>. */
984
985 /***ja
986 @addtogroup m17nError ���顼����
987 @brief m17n �饤�֥��Υ��顼����.
988
989 m17n �饤�֥��δؿ��Ǥϡ����Ĥμ���Υ��顼�����������롣
990
991 ��Ĥϰ����Υ��顼�Ǥ��롣
992 �饤�֥��δؿ��������Ǥʤ������ȤȤ�˸ƤФ줿��硢���δؿ��ϥ��顼���̣�����ͤ��֤���Ʊ���˳����ѿ�
993 #merror_code �˥���Ǥʤ������åȤ��롣
994
995 �⤦��Ĥμ���ϥ�������ƥ��顼�Ǥ��롣
996 �����ƥबɬ�פ��̤Υ��������Ƥ뤳�Ȥ��Ǥ��ʤ���硢�饤�֥��ؿ��ϳ����ѿ�
997 @c m17n_memory_full_handler ���ؤ��ؿ���Ƥ֡��ǥե���ȤǤϡ��ؿ�
998 default_error_handle () ��ؤ��Ƥ��ꡢ���δؿ���ñ�� <tt>exit
999 ()</tt> ��Ƥ֡�
1000 */
1001
1002 /*** @{ */
1003
1004 /*=*/
1005
1006 /***en
1007 @brief External variable to hold error code of the m17n library.
1008
1009 The external variable #merror_code holds an error code of the
1010 m17n library. When a library function is called with an invalid
1011 argument, it sets this variable to one of @c enum #MErrorCode.
1012
1013 This variable initially has the value 0. */
1014
1015 /***ja
1016 @brief m17n �饤�֥��Υ��顼�����ɤ��ݻ����볰���ѿ�.
1017
1018 �����ѿ� #merror_code �ϡ�m17n �饤�֥��Υ��顼�����ɤ��ݻ����롣
1019 �饤�֥��ؿ��������Ǥʤ������ȤȤ�˸ƤФ줿�ݤˤϡ������ѿ���
1020 @c enum #MErrorCode �ΰ�Ĥ˥��åȤ��롣
1021
1022 �����ѿ��ν���ͤ� 0 �Ǥ��롣 */
1023
1024 int merror_code;
1025
1026 /*=*/
1027
1028 /***en
1029 @brief Memory allocation error handler.
1030
1031 The external variable #m17n_memory_full_handler holds a pointer
1032 to the function to call when a library function failed to allocate
1033 memory. $ERR is one of @c enum #MErrorCode indicating in which
1034 function the error occurred.
1035
1036 This variable initially points a function that simply calls the
1037 <tt>exit </tt>() function with $ERR as an argument.
1038
1039 An application program that needs a different error handling can
1040 change this variable to point a proper function. */
1041
1042 /***ja
1043 @brief ��������ƥ��顼�ϥ�ɥ�.
1044
1045 �ѿ� #m17n_memory_full_handler
1046 �ϡ��饤�֥��ؿ�����������Ƥ˼��Ԥ����ݤ˸Ƥ֤٤��ؿ��ؤΥݥ��Ǥ��롣
1047 $ERR �� @c enum #MErrorCode
1048 �Τ����Τ����줫�Ǥ��ꡢ�ɤΥ饤�֥��ؿ��ǥ��顼�����ä�������
1049
1050 @anchor test
1051
1052 �������Ǥϡ������ѿ���ñ�� <tt>exit ()</tt> �� $ERR
1053 ������Ȥ��ƸƤִؿ���ؤ��Ƥ��롣
1054
1055 ����Ȥϰۤʤ륨�顼������ɬ�פȤ��륢�ץꥱ�������ϡ������ѿ���Ŭ���ʴؿ������ꤹ�뤳�Ȥǡ���Ū��ã���Ǥ��롣 */
1056
1057 void (*m17n_memory_full_handler) (enum MErrorCode err);
1058
1059 /*** @} */
1060
1061 /*=*/
1062
1063 /***en
1064 @addtogroup m17nDebug
1065 @brief Support for m17n library users to debug their programs.
1066
1067 The m17n library provides the following facilities to support the
1068 library users to debug their programs.
1069
1070 <ul>
1071
1072 <li> Environment variables to control printing of various
1073 information to stderr.
1074
1075 <ul>
1076
1077 <li> MDEBUG_INIT -- If set to 1, print information about the
1078 library initialization on the call of M17N_INIT ().
1079
1080 <li> MDEBUG_FINI -- If set to 1, print counts of objects that are
1081 not yet freed on the call of M17N_FINI ().
1082
1083 <li> MDEBUG_CHARSET -- If set to 1, print information about
1084 charsets being loaded from the m17n database.
1085
1086 <li> MDEBUG_CODING -- If set to 1, print information about coding
1087 systems being loaded from the m17n database.
1088
1089 <li> MDEBUG_DATABASE -- If set to 1, print information about
1090 data being loaded from the m17n database.
1091
1092 <li> MDEBUG_FONT -- If set to 1, print information about fonts
1093 being selected and opened.
1094
1095 <li> MDEBUG_FLT -- If set to 1, 2, or 3, print information about
1096 which command of Font Layout Table are being executed. The bigger
1097 number prints the more detailed information.
1098
1099 <li> MDEBUG_INPUT -- If set to 1, print information about how an
1100 input method is running.
1101
1102 <li> MDEBUG_ALL -- Setting this variable to 1 is equivalent to
1103 setting all the above variables to 1.
1104
1105 <li> MDEBUG_OUTPUT_FILE -- If set to a file name, the above
1106 debugging information is appended to the file. If set to
1107 "stdout", the information is printed to stdout.
1108
1109 </ul>
1110
1111 <li> Functions to print various objects in a human readable way.
1112 See the documentation of mdebug_dump_XXXX () functions.
1113
1114 <li> The hook function called on an error. See the documentation
1115 of mdebug_hook ().
1116
1117 </ul>
1118 */
1119 /***ja
1120 @addtogroup m17nDebug
1121 @brief m17n �饤�֥��桼���Τ���Υץ����ǥХå����ݡ���.
1122
1123 m17n �饤�֥��ϡ����Υ桼������ʬ�Υץ�����ǥХå����뤿��ˡ��ʲ��ε�ǽ�ݡ��Ȥ��Ƥ��롣
1124
1125 <ul>
1126
1127 <li> ���ޤ��ޤʾ����ɸ�२�顼���ϤؤΥץ��Ȥ����椹��Ķ��ѿ���
1128
1129 <ul>
1130
1131 <li> MDEBUG_INIT -- 1 �ʤ�С�M17N_INIT ()
1132 ���ƤФ줿�����ǡ��饤�֥��ν�����˴ؤ�������ץ��Ȥ��롣
1133
1134 <li> MDEBUG_FINI -- 1 �ʤ�С�M17N_FINI ()
1135 ���ƤФ줿�����ǡ��ޤ���������Ƥ��ʤ����֥������Ȥλ��ȿ���ץ��Ȥ��롣
1136
1137 <li> MDEBUG_CHARSET -- 1 �ʤ�С�m17n
1138 �ǡ����١���������ɤ��줿ʸ�����åȤˤĤ��Ƥξ����ץ��Ȥ��롣
1139
1140 <li> MDEBUG_CODING -- 1 �ʤ�С�m17n
1141 �ǡ����١���������ɤ��줿�����ɷϤˤĤ��Ƥξ����ץ��Ȥ��롣
1142
1143 <li> MDEBUG_DATABASE -- 1 �ʤ�С�m17n
1144 �ǡ����١���������ɤ��줿�ǡ����ˤĤ��Ƥξ����ץ��Ȥ��롣
1145
1146 <li> MDEBUG_FONT -- 1 �ʤ�С�����ƥ����ץ줿�ե���Ȥˤ�
1147 ���Ƥξ����ץ��Ȥ��롣
1148
1149 <li> MDEBUG_FLT -- 1��2���⤷���� 3 �ʤ�С�Font Layout Table �Τ�
1150 �Υ��ޥ�ɤ��¹��椫�ˤĤ��ƤΤ�ץ��Ȥ��롣����礭����������
1151 ���������ץ��Ȥ��롣
1152
1153 <li> MDEBUG_INPUT -- 1 �ʤ�С��¹�������ϥ�åɤξ��֤��դ��Ƥ�
1154 �����ץ��Ȥ��롣
1155
1156 <li> MDEBUG_ALL -- 1 �ʤ�С��嵭���٤Ƥ��ѿ��� 1
1157 �ˤ����Τ�Ʊ�����̤���ġ�
1158
1159 <li> MDEBUG_OUTPUT_FILE -- �⤷�ե�����̾�ʤ顢�嵭�ǥХå�����Ϥ�
1160 �Υե�������ɲä���롣�⤷ "stdout" �ʤ餽�ξ����ɸ����Ϥ˽���
1161 ����롣
1162
1163 </ul>
1164
1165 <li> ��Υ��֥������Ȥ�ʹ֤˲��ɤʷ��ǥץ��Ȥ���ؿ����ܺ٤ϴؿ�
1166 mdebug_dump_XXXX () ���������ȡ�
1167
1168 <li> ���顼ȯ�����˸ƤФ��եå��ؿ���mdebug_hook () ���������ȡ�
1169
1170 </ul>
1171 */
1172
1173 /*=*/
1174 /*** @{ */
1175 /*=*/
1176
1177 /***en
1178 @brief Hook function called on an error.
1179
1180 The mdebug_hook () function is called when an error happens. It
1181 returns -1 without doing anything. It is useful to set a break
1182 point on this function in a debugger. */
1183 /***ja
1184 @brief ���顼�κݤ˸ƤФ��եå��ؿ�.
1185
1186 �ؿ� mdebug_hook () �ϥ��顼�������ä��ݤ˸ƤФ졢���⤻����-1
1187 ���֤����ǥХå���ǥ֥졼���ݥ���Ȥ����ꤹ�뤿����Ѥ��뤳�Ȥ��Ǥ��롣
1188 */
1189
1190 int
mdebug_hook()1191 mdebug_hook ()
1192 {
1193 return -1;
1194 }
1195
1196 /*=*/
1197
1198 /*** @} */
1199
1200 /*
1201 Local Variables:
1202 coding: euc-japan
1203 End:
1204 */
1205