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