1 /* internal.h -- common header file for the internal CORE and SHELL APIs.
2 Copyright (C) 2003, 2004
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., 59 Temple Place, Suite 330, Boston, MA
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 mdebug_hook ();
34 /** Return with code RET while setting merror_code to ERR. */
36 #define MERROR(err, ret) \
38 merror_code = (err); \
44 #define MERROR_GOTO(err, label) \
47 merror_code = (err); \
53 #define MWARNING(err) \
60 #define M_CHECK_CHAR(c, ret) \
61 if ((c) < 0 || (c) > MCHAR_MAX) \
62 MERROR (MERROR_CHAR, (ret)); \
66 /** Memory allocation stuffs. */
68 /* Call a handler function for memory full situation with argument
69 ERR. ERR must be one of enum MErrorCode. By default, the
70 handler function just calls exit () with argument ERR. */
72 #define MEMORY_FULL(err) \
74 (*m17n_memory_full_handler) (err); \
79 /** The macro MTABLE_MALLOC () allocates memory (by malloc) for an
80 array of SIZE objects. The size of each object is determined by
81 the type of P. Then, it sets P to the allocated memory. ERR must
82 be one of enum MErrorCode. If the allocation fails, the macro
83 MEMORY_FULL () is called with argument ERR. */
85 #define MTABLE_MALLOC(p, size, err) \
87 int bytes = sizeof (*(p)) * (size); \
88 if (! ((p) = (void *) malloc (bytes))) \
93 /** The macro MTABLE_CALLOC() is like the macro MTABLE_MALLOC but use
94 calloc instead of malloc, thus the allocated memory are zero
97 #define MTABLE_CALLOC(p, size, err) \
99 if (! ((p) = (void *) calloc (sizeof (*(p)), size))) \
104 /** The macro MTABLE_REALLOC () changes the size of memory block
105 pointed to by P to a size suitable for an array of SIZE objects.
106 The size of each object is determined by the type of P. ERR must
107 be one of enum MErrorCode. If the allocation fails, the macro
108 MEMORY_FULL () is called with argument ERR. */
110 #define MTABLE_REALLOC(p, size, err) \
112 if (! ((p) = (void *) realloc ((p), sizeof (*(p)) * (size)))) \
117 /** The macro MTABLE_ALLOCA () allocates memory (by alloca) for an
118 array of SIZE objects. The size of each object is determined by
119 the type of P. Then, it sets P to the allocated memory. ERR must
120 be one of enum MErrorCode. If the allocation fails, the macro
121 MEMORY_FULL () is called with argument ERR. */
123 #define MTABLE_ALLOCA(p, size, err) \
125 int bytes = sizeof (*(p)) * (size); \
126 if (! ((p) = (void *) alloca (bytes))) \
128 memset ((p), 0, bytes); \
132 /** short description of MSTRUCT_MALLOC */
133 /** The macro MSTRUCT_MALLOC () allocates memory (by malloc) for an
134 object whose size is determined by the type of P, and sets P to
135 the allocated memory. ERR must be one of enum MErrorCode. If
136 the allocation fails, the macro MEMORY_FULL () is called with
139 #define MSTRUCT_MALLOC(p, err) \
141 if (! ((p) = (void *) malloc (sizeof (*(p))))) \
146 #define MSTRUCT_CALLOC(p, err) MTABLE_CALLOC ((p), 1, (err))
149 /** Extendable array. */
151 #define MLIST_RESET(list) \
155 #define MLIST_INIT1(list, mem, increment) \
157 (list)->size = (list)->used = 0; \
158 (list)->inc = (increment); \
159 (list)->mem = NULL; \
163 #define MLIST_APPEND1(list, mem, elt, err) \
165 if ((list)->inc <= 0) \
167 if ((list)->size == (list)->used) \
169 (list)->size += (list)->inc; \
170 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
172 (list)->mem[(list)->used++] = (elt); \
176 #define MLIST_PREPEND1(list, mem, elt, err) \
178 if ((list)->inc <= 0) \
180 if ((list)->size == (list)->used) \
182 (list)->size += (list)->inc; \
183 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
185 memmove ((list)->mem + 1, (list)->mem, \
186 sizeof *((list)->mem) * ((list)->used)); \
187 (list)->mem[0] = (elt); \
192 #define MLIST_INSERT1(list, mem, idx, len, err) \
194 while ((list)->used + (len) > (list)->size) \
196 (list)->size += (list)->inc; \
197 MTABLE_REALLOC ((list)->mem, (list)->size, (err)); \
199 memmove ((list)->mem + ((idx) + (len)), (list)->mem + (idx), \
200 (sizeof *((list)->mem)) * ((list)->used - (idx))); \
201 (list)->used += (len); \
205 #define MLIST_DELETE1(list, mem, idx, len) \
207 memmove ((list)->mem + (idx), (list)->mem + (idx) + (len), \
208 (sizeof *((list)->mem)) * ((list)->used - (idx) - (len))); \
209 (list)->used -= (len); \
213 #define MLIST_COPY1(list0, list1, mem, err) \
215 (list0)->size = (list0)->used = (list1)->used; \
217 MTABLE_MALLOC ((list0)->mem, (list0)->used, (err)); \
218 memcpy ((list0)->mem, (list1)->mem, \
219 (sizeof (list0)->mem) * (list0)->used); \
223 #define MLIST_FREE1(list, mem) \
226 free ((list)->mem); \
227 (list)->mem = NULL; \
228 (list)->size = (list)->used = 0; \
236 void (*freer) (void *);
243 /**en Reference count of the object. */
244 unsigned ref_count : 16;
246 unsigned ref_count_extended : 1;
248 /**en A flag bit used for various perpose. */
252 /**en If <ref_count_extended> is zero, a function to free the
254 void (*freer) (void *);
255 /**en If <ref_count_extended> is nonzero, a pointer to the
256 struct M17NObjectRecord. */
257 M17NObjectRecord *record;
262 /** Allocate a managed object OBJECT which has freer FREE_FUNC. */
264 #define M17N_OBJECT(object, free_func, err) \
266 MSTRUCT_CALLOC ((object), (err)); \
267 ((M17NObject *) (object))->ref_count = 1; \
268 ((M17NObject *) (object))->u.freer = free_func; \
272 /**en Increment the reference count of OBJECT if the count is not
275 #define M17N_OBJECT_REF(object) \
277 if (((M17NObject *) (object))->ref_count_extended) \
278 m17n_object_ref (object); \
279 else if (((M17NObject *) (object))->ref_count > 0) \
281 ((M17NObject *) (object))->ref_count++; \
282 if (! ((M17NObject *) (object))->ref_count) \
284 ((M17NObject *) (object))->ref_count--; \
285 m17n_object_ref (object); \
291 #define M17N_OBJECT_REF_NTIMES(object, n) \
295 if (((M17NObject *) (object))->ref_count_extended) \
296 for (i = 0; i < n; i++) \
297 m17n_object_ref (object); \
298 else if (((M17NObject *) (object))->ref_count > 0) \
300 int orig_ref_count = ((M17NObject *) (object))->ref_count; \
302 for (i = 0; i < n; i++) \
303 if (! ++((M17NObject *) (object))->ref_count) \
305 ((M17NObject *) (object))->ref_count = orig_ref_count; \
306 for (i = 0; i < n; i++) \
307 m17n_object_ref (object); \
313 /**en Decrement the reference count of OBJECT if the count is greater
314 than 0. In that case, if the count becomes 0, free OBJECT. */
316 #define M17N_OBJECT_UNREF(object) \
320 if (((M17NObject *) (object))->ref_count_extended) \
321 m17n_object_unref (object); \
322 else if (((M17NObject *) (object))->ref_count == 0) \
324 else if (((M17NObject *) (object))->ref_count > 1) \
325 ((M17NObject *) (object))->ref_count--; \
328 if (((M17NObject *) (object))->u.freer) \
329 (((M17NObject *) (object))->u.freer) (object); \
344 extern void mdebug__register_object (M17NObjectArray *array, void *object);
346 #define M17N_OBJECT_REGISTER(array, object) \
347 if (mdebug__flag & MDEBUG_FINI) \
348 mdebug__register_object (&array, object); \
351 extern void mdebug__unregister_object (M17NObjectArray *array, void *object);
353 #define M17N_OBJECT_UNREGISTER(array, object) \
354 if (mdebug__flag & MDEBUG_FINI) \
355 mdebug__unregister_object (&array, object); \
358 extern void mdebug__report_object (char *name, M17NObjectArray *array);
368 enum MTextFormat format;
370 /**en Number of characters in the M-text */
371 /**ja M-text Ãæ¤Îʸ»ú¿ô */
374 /**en Number of bytes used to represent the characters in the M-text. */
375 /**ja M-text Ãæ¤Îʸ»ú¤òɽ¤ï¤¹¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥Ð¥¤¥È¿ô */
378 /**en Character sequence of the M-text. */
379 /**ja M-text Ãæ¤Îʸ»úÎó */
382 /**en Number of bytes allocated for the @c data member. */
383 /**ja ¥á¥ó¥Ð @c data ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥Ð¥¤¥È¿ô */
386 /**en Pointer to the property list of the M-text. */
387 /**ja M-text ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ */
388 struct MTextPlist *plist;
390 /**en Caches of the character position and the corresponding byte position. */
391 /**ja ʸ»ú°ÌÃÖ¤ª¤è¤ÓÂбþ¤¹¤ë¥Ð¥¤¥È°ÌÃ֤Υ¥ã¥Ã¥·¥å */
392 int cache_char_pos, cache_byte_pos;
395 /** short description of M_CHECK_POS */
396 /** longer description of M_CHECK_POS */
398 #define M_CHECK_POS(mt, pos, ret) \
400 if ((pos) < 0 || (pos) >= (mt)->nchars) \
401 MERROR (MERROR_RANGE, (ret)); \
405 /** short description of M_CHECK_POS_X */
406 /** longer description of M_CHECK_POS_X */
408 #define M_CHECK_POS_X(mt, pos, ret) \
410 if ((pos) < 0 || (pos) > (mt)->nchars) \
411 MERROR (MERROR_RANGE, (ret)); \
415 /** short description of M_CHECK_RANGE */
416 /** longer description of M_CHECK_RANGE */
418 #define M_CHECK_RANGE(mt, from, to, ret, ret2) \
420 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
421 MERROR (MERROR_RANGE, (ret)); \
422 if ((from) == (to)) \
426 #define M_CHECK_RANGE_X(mt, from, to, ret) \
428 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
429 MERROR (MERROR_RANGE, (ret)); \
433 #define M_CHECK_POS_NCHARS(mt, pos, nchars, ret, ret2) \
435 int to = (pos) + (nchars); \
437 M_CHECK_RANGE ((mt), (pos), (to), (ret), (ret2)); \
441 #define MTEXT_READ_ONLY_P(mt) ((mt)->allocated < 0)
443 #define M_CHECK_READONLY(mt, ret) \
445 if ((mt)->allocated < 0) \
446 MERROR (MERROR_MTEXT, (ret)); \
449 #define mtext_nchars(mt) ((mt)->nchars)
451 #define mtext_nbytes(mt) ((mt)->nbytes)
453 #define mtext_allocated(mt) ((mt)->allocated)
455 #define mtext_reset(mt) (mtext_del ((mt), 0, (mt)->nchars))
463 MDEBUG_CHARSET = 0x04,
464 MDEBUG_CODING = 0x08,
465 MDEBUG_DATABASE = 0x10,
466 MDEBUG_FONT = 0x0100,
467 MDEBUG_FONT_FLT = 0x0200,
468 MDEBUG_FONT_OTF = 0x0400,
469 MDEBUG_INPUT = 0x0800,
473 extern int mdebug__flag;
474 extern void mdebug__push_time ();
475 extern void mdebug__pop_time ();
476 extern void mdebug__print_time ();
478 #define MDEBUG_PRINT(msg) \
480 if (mdebug__flag & mdebug_mask) \
481 fprintf (stderr, (msg)); \
484 #define MDEBUG_PRINT1(fmt, arg) \
486 if (mdebug__flag & mdebug_mask) \
487 fprintf (stderr, (fmt), (arg)); \
490 #define MDEBUG_PRINT2(fmt, arg1, arg2) \
492 if (mdebug__flag & mdebug_mask) \
493 fprintf (stderr, (fmt), (arg1), (arg2)); \
496 #define MDEBUG_PRINT3(fmt, arg1, arg2, arg3) \
498 if (mdebug__flag & mdebug_mask) \
499 fprintf (stderr, (fmt), (arg1), (arg2), (arg3)); \
502 #define MDEBUG_PRINT4(fmt, arg1, arg2, arg3, arg4) \
504 if (mdebug__flag & mdebug_mask) \
505 fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4)); \
508 #define MDEBUG_PRINT5(fmt, arg1, arg2, arg3, arg4, arg5) \
510 if (mdebug__flag & mdebug_mask) \
511 fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4), (arg5)); \
515 #define MDEBUG_PUSH_TIME() \
517 if (mdebug__flag & mdebug_mask) \
518 mdebug__push_time (); \
522 #define MDEBUG_POP_TIME() \
524 if (mdebug__flag & mdebug_mask) \
525 mdebug__pop_time (); \
529 #define MDEBUG_PRINT_TIME(tag, ARG_LIST) \
531 if (mdebug__flag & mdebug_mask) \
533 fprintf (stderr, " [%s] ", tag); \
534 mdebug__print_time (); \
536 fprintf (stderr, "\n"); \
541 #define SWAP_16(c) (((c) >> 8) | (((c) & 0xFF) << 8))
544 (((c) >> 24) | (((c) >> 8) & 0xFF00) \
545 | (((c) & 0xFF00) << 8) | (((c) & 0xFF) << 24))
548 extern void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2,
549 MSymbol tag3, MSymbol tag4);
550 extern void *(*mdatabase__loader) (void *);
552 /* Initialize/finalize function. */
554 extern int msymbol__init ();
555 extern void msymbol__fini ();
557 extern int mplist__init ();
558 extern void mplist__fini ();
560 extern int mtext__init ();
561 extern void mtext__fini ();
563 extern int mtext__prop_init ();
564 extern void mtext__prop_fini ();
566 extern int mchartable__init ();
567 extern void mchartable__fini ();
569 extern int mcharset__init ();
570 extern void mcharset__fini ();
572 extern int mcoding__init ();
573 extern void mcoding__fini ();
575 extern int mdatabase__init (void);
576 extern void mdatabase__fini (void);
578 extern int mchar__init ();
579 extern void mchar__fini ();
581 extern int mlang__init ();
582 extern void mlang__fini ();
584 extern int mlocale__init ();
585 extern void mlocale__fini ();
587 extern int minput__init ();
588 extern void minput__fini ();
590 #endif /* _M17N_INTERNAL_H_ */