1 /* internal.h -- common header file for the internal CORE and SHELL APIs.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
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.
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.
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,
23 #ifndef _M17N_INTERNAL_H_
24 #define _M17N_INTERNAL_H_
27 @brief a documentation for internal.h
29 longer version of internal.h description
32 extern int m17n__core_initialized;
33 extern int m17n__shell_initialized;
34 extern int m17n__gui_initialized;
36 extern int mdebug_hook ();
40 #define _(String) dgettext ("m17n-lib", String)
42 #define _(String) (String)
45 /** Return with code RET while setting merror_code to ERR. */
47 #define MERROR(err, ret) \
49 merror_code = (err); \
55 #define MERROR_GOTO(err, label) \
58 merror_code = (err); \
64 #define MWARNING(err) \
76 #define MFAILP(cond) ((cond) ? 0 : mdebug_hook ())
78 #define M_CHECK_CHAR(c, ret) \
79 if ((c) < 0 || (c) > MCHAR_MAX) \
80 MERROR (MERROR_CHAR, (ret)); \
84 /** Memory allocation stuffs. */
86 /* Call a handler function for memory full situation with argument
87 ERR. ERR must be one of enum MErrorCode. By default, the
88 handler function just calls exit () with argument ERR. */
90 #define MEMORY_FULL(err) \
92 (*m17n_memory_full_handler) (err); \
97 /** The macro MTABLE_MALLOC () allocates memory (by malloc) for an
98 array of SIZE objects. The size of each object is determined by
99 the type of P. Then, it sets P to the allocated memory. ERR must
100 be one of enum MErrorCode. If the allocation fails, the macro
101 MEMORY_FULL () is called with argument ERR. */
103 #define MTABLE_MALLOC(p, size, err) \
105 if (! ((p) = (void *) malloc (sizeof (*(p)) * (size)))) \
110 /** The macro MTABLE_CALLOC() is like the macro MTABLE_MALLOC but use
111 calloc instead of malloc, thus the allocated memory are zero
114 #define MTABLE_CALLOC(p, size, err) \
116 if (! ((p) = (void *) calloc (sizeof (*(p)), size))) \
120 #define MTABLE_CALLOC_SAFE(p, size) \
121 ((p) = (void *) calloc (sizeof (*(p)), (size)))
124 /** The macro MTABLE_REALLOC () changes the size of memory block
125 pointed to by P to a size suitable for an array of SIZE objects.
126 The size of each object is determined by the type of P. ERR must
127 be one of enum MErrorCode. If the allocation fails, the macro
128 MEMORY_FULL () is called with argument ERR. */
130 #define MTABLE_REALLOC(p, size, err) \
132 if (! ((p) = (void *) realloc ((p), sizeof (*(p)) * (size)))) \
137 /** The macro MTABLE_ALLOCA () allocates memory (by alloca) for an
138 array of SIZE objects. The size of each object is determined by
139 the type of P. Then, it sets P to the allocated memory. ERR must
140 be one of enum MErrorCode. If the allocation fails, the macro
141 MEMORY_FULL () is called with argument ERR. */
143 #define MTABLE_ALLOCA(p, size, err) \
145 int allocasize = sizeof (*(p)) * (size); \
146 if (! ((p) = (void *) alloca (allocasize))) \
148 memset ((p), 0, allocasize); \
152 /** short description of MSTRUCT_MALLOC */
153 /** The macro MSTRUCT_MALLOC () allocates memory (by malloc) for an
154 object whose size is determined by the type of P, and sets P to
155 the allocated memory. ERR must be one of enum MErrorCode. If
156 the allocation fails, the macro MEMORY_FULL () is called with
159 #define MSTRUCT_MALLOC(p, err) \
161 if (! ((p) = (void *) malloc (sizeof (*(p))))) \
166 #define MSTRUCT_CALLOC(p, err) MTABLE_CALLOC ((p), 1, (err))
168 #define MSTRUCT_CALLOC_SAFE(p) MTABLE_CALLOC_SAFE ((p), 1)
170 #define USE_SAFE_ALLOCA \
171 int sa_must_free = 0, sa_size = 0
173 /* P must be the same in all calls to SAFE_ALLOCA and SAFE_FREE in a
176 #define SAFE_ALLOCA(P, SIZE) \
178 if (sa_size < (SIZE)) \
181 (P) = realloc ((P), (SIZE)); \
184 (P) = alloca ((SIZE)); \
187 (P) = malloc (SIZE); \
197 #define SAFE_FREE(P) \
199 if (sa_must_free && sa_size > 0) \
202 sa_must_free = sa_size = 0; \
207 /** Extendable array. */
209 #define MLIST_RESET(list) \
213 #define MLIST_INIT1(list, mem, increment) \
215 (list)->size = (list)->used = 0; \
216 (list)->inc = (increment); \
217 (list)->mem = NULL; \
221 #define MLIST_APPEND1(list, mem, elt, err) \
223 if ((list)->inc <= 0) \
225 if ((list)->size == (list)->used) \
227 (list)->size += (list)->inc; \
228 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
230 (list)->mem[(list)->used++] = (elt); \
234 #define MLIST_PREPEND1(list, mem, elt, err) \
236 if ((list)->inc <= 0) \
238 if ((list)->size == (list)->used) \
240 (list)->size += (list)->inc; \
241 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
243 memmove ((list)->mem + 1, (list)->mem, \
244 sizeof *((list)->mem) * ((list)->used)); \
245 (list)->mem[0] = (elt); \
250 #define MLIST_INSERT1(list, mem, idx, len, err) \
252 while ((list)->used + (len) > (list)->size) \
254 (list)->size += (list)->inc; \
255 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
257 memmove ((list)->mem + ((idx) + (len)), (list)->mem + (idx), \
258 (sizeof *((list)->mem)) * ((list)->used - (idx))); \
259 (list)->used += (len); \
263 #define MLIST_DELETE1(list, mem, idx, len) \
265 memmove ((list)->mem + (idx), (list)->mem + (idx) + (len), \
266 (sizeof *((list)->mem)) * ((list)->used - (idx) - (len))); \
267 (list)->used -= (len); \
271 #define MLIST_COPY1(list0, list1, mem, err) \
273 (list0)->size = (list0)->used = (list1)->used; \
275 MTABLE_MALLOC ((list0)->mem, (list0)->used, (err)); \
276 memcpy ((list0)->mem, (list1)->mem, \
277 (sizeof (list0)->mem) * (list0)->used); \
281 #define MLIST_FREE1(list, mem) \
284 free ((list)->mem); \
285 (list)->mem = NULL; \
286 (list)->size = (list)->used = 0; \
294 void (*freer) (void *);
301 /**en Reference count of the object. */
302 /**ja ¥ª¥Ö¥¸¥§¥¯¥È¤Î»²¾È¿ô. */
303 unsigned ref_count : 16;
305 unsigned ref_count_extended : 1;
307 /**en A flag bit used for various perpose. */
308 /**ja ¤µ¤Þ¤¶¤Þ¤ÊÌÜŪ¤ËÍѤ¤¤é¤ì¤ë¥Õ¥é¥°¥Ó¥Ã¥È. */
312 /**en If <ref_count_extended> is zero, a function to free the
314 /**ja <ref_count_extended> ¤¬ 0 ¤Ê¤é¤Ð¥ª¥Ö¥¸¥§¥¯¥È¤ò²òÊü¤¹¤ë´Ø¿ô. */
315 void (*freer) (void *);
316 /**en If <ref_count_extended> is nonzero, a pointer to the
317 struct M17NObjectRecord. */
318 /**ja <ref_count_extended> ¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð¹½Â¤ÂÎ M17NObjectRecord ¤Ø¤Î¥Ý¥¤¥ó¥¿. */
319 M17NObjectRecord *record;
324 /** Allocate a managed object OBJECT which has freer FREE_FUNC. */
326 #define M17N_OBJECT(object, free_func, err) \
328 MSTRUCT_CALLOC ((object), (err)); \
329 ((M17NObject *) (object))->ref_count = 1; \
330 ((M17NObject *) (object))->u.freer = free_func; \
334 /**en Increment the reference count of OBJECT if the count is not
336 /**ja OBJECT ¤Î»²¾È¿ô¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð 1 Áý¤ä¤¹. */
338 #define M17N_OBJECT_REF(object) \
340 if (((M17NObject *) (object))->ref_count_extended) \
341 m17n_object_ref (object); \
342 else if (((M17NObject *) (object))->ref_count > 0) \
344 ((M17NObject *) (object))->ref_count++; \
345 if (! ((M17NObject *) (object))->ref_count) \
347 ((M17NObject *) (object))->ref_count--; \
348 m17n_object_ref (object); \
354 #define M17N_OBJECT_REF_NTIMES(object, n) \
358 if (((M17NObject *) (object))->ref_count_extended) \
359 for (i = 0; i < n; i++) \
360 m17n_object_ref (object); \
361 else if (((M17NObject *) (object))->ref_count > 0) \
363 int orig_ref_count = ((M17NObject *) (object))->ref_count; \
365 for (i = 0; i < n; i++) \
366 if (! ++((M17NObject *) (object))->ref_count) \
368 ((M17NObject *) (object))->ref_count = orig_ref_count; \
369 for (i = 0; i < n; i++) \
370 m17n_object_ref (object); \
376 /**en Decrement the reference count of OBJECT if the count is greater
377 than 0. In that case, if the count becomes 0, free OBJECT. */
378 /**ja OBJECT ¤Î»²¾È¿ô¤¬ 0 ¤è¤êÂ礤±¤ì¤Ð 1 ¸º¤é¤¹¡£¸º¤é¤·¤Æ 0 ¤Ë¤Ê¤ì¤Ð
379 OBJECT ¤ò²òÊü¤¹¤ë. */
381 #define M17N_OBJECT_UNREF(object) \
385 if (((M17NObject *) (object))->ref_count_extended) \
386 m17n_object_unref (object); \
387 else if (((M17NObject *) (object))->ref_count == 0) \
391 ((M17NObject *) (object))->ref_count--; \
392 if (((M17NObject *) (object))->ref_count == 0) \
394 if (((M17NObject *) (object))->u.freer) \
395 (((M17NObject *) (object))->u.freer) (object); \
404 typedef struct _M17NObjectArray M17NObjectArray;
406 struct _M17NObjectArray
412 M17NObjectArray *next;
415 extern void mdebug__add_object_array (M17NObjectArray *array, char *name);
417 #define M17N_OBJECT_ADD_ARRAY(array, name) \
418 if (mdebug__flags[MDEBUG_FINI]) \
419 mdebug__add_object_array (&array, name); \
422 extern void mdebug__register_object (M17NObjectArray *array, void *object);
424 #define M17N_OBJECT_REGISTER(array, object) \
425 if (mdebug__flags[MDEBUG_FINI]) \
426 mdebug__register_object (&array, object); \
429 extern void mdebug__unregister_object (M17NObjectArray *array, void *object);
431 #define M17N_OBJECT_UNREGISTER(array, object) \
432 if (mdebug__flags[MDEBUG_FINI]) \
433 mdebug__unregister_object (&array, object); \
442 MTEXT_COVERAGE_ASCII,
443 MTEXT_COVERAGE_UNICODE,
451 unsigned format : 16;
452 unsigned coverage : 16;
454 /**en Number of characters in the M-text */
455 /**ja M-text Ãæ¤Îʸ»ú¿ô */
458 /**en Number of bytes used to represent the characters in the M-text. */
459 /**ja M-text Ãæ¤Îʸ»ú¤òɽ¤ï¤¹¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥Ð¥¤¥È¿ô */
462 /**en Character sequence of the M-text. */
463 /**ja M-text Ãæ¤Îʸ»úÎó */
466 /**en Number of bytes allocated for the @c data member. */
467 /**ja ¥á¥ó¥Ð @c data ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥Ð¥¤¥È¿ô */
470 /**en Pointer to the property list of the M-text. */
471 /**ja M-text ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ */
472 struct MTextPlist *plist;
474 /**en Caches of the character position and the corresponding byte position. */
475 /**ja ʸ»ú°ÌÃÖ¤ª¤è¤ÓÂбþ¤¹¤ë¥Ð¥¤¥È°ÌÃ֤Υ¥ã¥Ã¥·¥å */
476 int cache_char_pos, cache_byte_pos;
479 /** short description of M_CHECK_POS */
480 /** longer description of M_CHECK_POS */
482 #define M_CHECK_POS(mt, pos, ret) \
484 if ((pos) < 0 || (pos) >= (mt)->nchars) \
485 MERROR (MERROR_RANGE, (ret)); \
489 /** short description of M_CHECK_POS_X */
490 /** longer description of M_CHECK_POS_X */
492 #define M_CHECK_POS_X(mt, pos, ret) \
494 if ((pos) < 0 || (pos) > (mt)->nchars) \
495 MERROR (MERROR_RANGE, (ret)); \
499 /** short description of M_CHECK_RANGE */
500 /** longer description of M_CHECK_RANGE */
502 #define M_CHECK_RANGE(mt, from, to, ret, ret2) \
504 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
505 MERROR (MERROR_RANGE, (ret)); \
506 if ((from) == (to)) \
510 #define M_CHECK_RANGE_X(mt, from, to, ret) \
512 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
513 MERROR (MERROR_RANGE, (ret)); \
517 #define M_CHECK_POS_NCHARS(mt, pos, nchars, ret, ret2) \
519 int to = (pos) + (nchars); \
521 M_CHECK_RANGE ((mt), (pos), (to), (ret), (ret2)); \
525 #define MTEXT_READ_ONLY_P(mt) ((mt)->allocated < 0)
527 #define M_CHECK_READONLY(mt, ret) \
529 if ((mt)->allocated < 0) \
530 MERROR (MERROR_MTEXT, (ret)); \
533 #define mtext_nchars(mt) ((mt)->nchars)
535 #define mtext_nbytes(mt) ((mt)->nbytes)
537 #define mtext_allocated(mt) ((mt)->allocated)
539 #define mtext_reset(mt) (mtext_del ((mt), 0, (mt)->nchars))
555 MDEBUG_MAX = MDEBUG_ALL
558 extern int mdebug__flags[MDEBUG_MAX];
559 extern FILE *mdebug__output;
560 extern void mdebug__push_time ();
561 extern void mdebug__pop_time ();
562 extern void mdebug__print_time ();
564 #define MDEBUG_FLAG() mdebug__flags[mdebug_flag]
566 #define MDEBUG_PRINT0(FPRINTF) \
568 if (MDEBUG_FLAG ()) \
571 fflush (mdebug__output); \
575 #define MDEBUG_PRINT(msg) \
576 MDEBUG_PRINT0 (fprintf (mdebug__output, "%s", (msg)))
578 #define MDEBUG_PRINT1(fmt, arg) \
579 MDEBUG_PRINT0 (fprintf (mdebug__output, (fmt), (arg)))
581 #define MDEBUG_PRINT2(fmt, arg1, arg2) \
582 MDEBUG_PRINT0 (fprintf (mdebug__output, (fmt), (arg1), (arg2)))
584 #define MDEBUG_PRINT3(fmt, arg1, arg2, arg3) \
585 MDEBUG_PRINT0 (fprintf (mdebug__output, (fmt), (arg1), (arg2), (arg3)))
587 #define MDEBUG_PRINT4(fmt, arg1, arg2, arg3, arg4) \
588 MDEBUG_PRINT0 (fprintf (mdebug__output, (fmt), (arg1), (arg2), (arg3), (arg4)))
590 #define MDEBUG_PRINT5(fmt, arg1, arg2, arg3, arg4, arg5) \
591 MDEBUG_PRINT0 (fprintf (mdebug__output, (fmt), (arg1), (arg2), (arg3), (arg4), (arg5)))
593 #define MDEBUG_DUMP(prefix, postfix, call) \
595 if (MDEBUG_FLAG ()) \
597 fprintf (mdebug__output, "%s", prefix); \
599 fprintf (mdebug__output, "%s", postfix); \
600 fflush (mdebug__output); \
604 #define MDEBUG_PUSH_TIME() \
606 if (MDEBUG_FLAG ()) \
607 mdebug__push_time (); \
611 #define MDEBUG_POP_TIME() \
613 if (MDEBUG_FLAG ()) \
614 mdebug__pop_time (); \
618 #define MDEBUG_PRINT_TIME(tag, ARG_LIST) \
620 if (MDEBUG_FLAG ()) \
622 fprintf (mdebug__output, " [%s] ", tag); \
623 mdebug__print_time (); \
625 fprintf (mdebug__output, "\n"); \
630 #define SWAP_16(c) (((c) >> 8) | (((c) & 0xFF) << 8))
633 (((c) >> 24) | (((c) >> 8) & 0xFF00) \
634 | (((c) & 0xFF00) << 8) | (((c) & 0xFF) << 24))
637 /* Initialize/finalize function. */
639 extern int msymbol__init ();
640 extern void msymbol__fini ();
642 extern int mplist__init ();
643 extern void mplist__fini ();
645 extern int mtext__init ();
646 extern void mtext__fini ();
648 extern int mtext__prop_init ();
649 extern void mtext__prop_fini ();
651 extern int mchartable__init ();
652 extern void mchartable__fini ();
654 extern int mcharset__init ();
655 extern void mcharset__fini ();
657 extern int mcoding__init ();
658 extern void mcoding__fini ();
660 extern int mdatabase__init (void);
661 extern void mdatabase__fini (void);
663 extern int mchar__init ();
664 extern void mchar__fini ();
666 extern int mlang__init ();
667 extern void mlang__fini ();
669 extern int mlocale__init ();
670 extern void mlocale__fini ();
672 extern int minput__init ();
673 extern void minput__fini ();
675 #endif /* _M17N_INTERNAL_H_ */