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); \
345 #define M17N_OBJECT_REGISTER(array, object) \
346 if (mdebug__flag & MDEBUG_FINI) \
348 if ((array).count == 0) \
349 MLIST_INIT1 (&(array), objects, 256); \
351 MLIST_APPEND1 (&(array), objects, object, MERROR_OBJECT); \
355 #define M17N_OBJECT_UNREGISTER(array, object) \
356 if (mdebug__flag & MDEBUG_FINI) \
359 if ((array).count >= 0) \
363 while (i < (array).used && (array).objects[i] != object) i++; \
364 if (i < (array).used) \
365 (array).objects[i] = NULL; \
375 extern void mdebug__report_object (char *name, M17NObjectArray *array);
385 enum MTextFormat format;
387 /**en Number of characters in the M-text */
388 /**ja M-text Ãæ¤Îʸ»ú¿ô */
391 /**en Number of bytes used to represent the characters in the M-text. */
392 /**ja M-text Ãæ¤Îʸ»ú¤òɽ¤ï¤¹¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥Ð¥¤¥È¿ô */
395 /**en Character sequence of the M-text. */
396 /**ja M-text Ãæ¤Îʸ»úÎó */
399 /**en Number of bytes allocated for the @c data member. */
400 /**ja ¥á¥ó¥Ð @c data ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥Ð¥¤¥È¿ô */
403 /**en Pointer to the property list of the M-text. */
404 /**ja M-text ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ */
405 struct MTextPlist *plist;
407 /**en Caches of the character position and the corresponding byte position. */
408 /**ja ʸ»ú°ÌÃÖ¤ª¤è¤ÓÂбþ¤¹¤ë¥Ð¥¤¥È°ÌÃ֤Υ¥ã¥Ã¥·¥å */
409 int cache_char_pos, cache_byte_pos;
412 /** short description of M_CHECK_POS */
413 /** longer description of M_CHECK_POS */
415 #define M_CHECK_POS(mt, pos, ret) \
417 if ((pos) < 0 || (pos) >= (mt)->nchars) \
418 MERROR (MERROR_RANGE, (ret)); \
422 /** short description of M_CHECK_POS_X */
423 /** longer description of M_CHECK_POS_X */
425 #define M_CHECK_POS_X(mt, pos, ret) \
427 if ((pos) < 0 || (pos) > (mt)->nchars) \
428 MERROR (MERROR_RANGE, (ret)); \
432 /** short description of M_CHECK_RANGE */
433 /** longer description of M_CHECK_RANGE */
435 #define M_CHECK_RANGE(mt, from, to, ret, ret2) \
437 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
438 MERROR (MERROR_RANGE, (ret)); \
439 if ((from) == (to)) \
443 #define M_CHECK_RANGE_X(mt, from, to, ret) \
445 if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars) \
446 MERROR (MERROR_RANGE, (ret)); \
450 #define M_CHECK_POS_NCHARS(mt, pos, nchars, ret, ret2) \
452 int to = (pos) + (nchars); \
454 M_CHECK_RANGE ((mt), (pos), (to), (ret), (ret2)); \
458 #define M_CHECK_READONLY(mt, ret) \
460 if ((mt)->allocated < 0) \
461 MERROR (MERROR_MTEXT, (ret)); \
464 #define mtext_nchars(mt) ((mt)->nchars)
466 #define mtext_nbytes(mt) ((mt)->nbytes)
468 #define mtext_allocated(mt) ((mt)->allocated)
470 #define mtext_reset(mt) (mtext_del ((mt), 0, (mt)->nchars))
478 MDEBUG_CHARSET = 0x04,
479 MDEBUG_CODING = 0x08,
480 MDEBUG_DATABASE = 0x10,
481 MDEBUG_FONT = 0x0100,
482 MDEBUG_FONT_FLT = 0x0200,
483 MDEBUG_FONT_OTF = 0x0400,
484 MDEBUG_INPUT = 0x0800,
488 extern int mdebug__flag;
489 extern void mdebug__push_time ();
490 extern void mdebug__pop_time ();
491 extern void mdebug__print_time ();
493 #define MDEBUG_PRINT(msg) \
495 if (mdebug__flag & mdebug_mask) \
496 fprintf (stderr, (msg)); \
499 #define MDEBUG_PRINT1(fmt, arg) \
501 if (mdebug__flag & mdebug_mask) \
502 fprintf (stderr, (fmt), (arg)); \
505 #define MDEBUG_PRINT2(fmt, arg1, arg2) \
507 if (mdebug__flag & mdebug_mask) \
508 fprintf (stderr, (fmt), (arg1), (arg2)); \
511 #define MDEBUG_PRINT3(fmt, arg1, arg2, arg3) \
513 if (mdebug__flag & mdebug_mask) \
514 fprintf (stderr, (fmt), (arg1), (arg2), (arg3)); \
517 #define MDEBUG_PRINT4(fmt, arg1, arg2, arg3, arg4) \
519 if (mdebug__flag & mdebug_mask) \
520 fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4)); \
524 #define MDEBUG_PUSH_TIME() \
526 if (mdebug__flag & mdebug_mask) \
527 mdebug__push_time (); \
531 #define MDEBUG_POP_TIME() \
533 if (mdebug__flag & mdebug_mask) \
534 mdebug__pop_time (); \
538 #define MDEBUG_PRINT_TIME(tag, ARG_LIST) \
540 if (mdebug__flag & mdebug_mask) \
542 fprintf (stderr, " [%s] ", tag); \
543 mdebug__print_time (); \
545 fprintf (stderr, "\n"); \
550 #define SWAP_16(c) (((c) >> 8) | (((c) & 0xFF) << 8))
553 (((c) >> 24) | (((c) >> 8) & 0xFF00) \
554 | (((c) & 0xFF00) << 8) | (((c) & 0xFF) << 24))
557 extern void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2,
558 MSymbol tag3, MSymbol tag4);
559 extern void *(*mdatabase__loader) (void *);
561 /* Initialize/finalize function. */
563 extern int msymbol__init ();
564 extern void msymbol__fini ();
566 extern int mplist__init ();
567 extern void mplist__fini ();
569 extern int mtext__init ();
570 extern void mtext__fini ();
572 extern int mtext__prop_init ();
573 extern void mtext__prop_fini ();
575 extern int mchartable__init ();
576 extern void mchartable__fini ();
578 extern int mcharset__init ();
579 extern void mcharset__fini ();
581 extern int mcoding__init ();
582 extern void mcoding__fini ();
584 extern int mdatabase__init (void);
585 extern void mdatabase__fini (void);
587 extern int mchar__init ();
588 extern void mchar__fini ();
590 extern int mlang__init ();
591 extern void mlang__fini ();
593 extern int mlocale__init ();
594 extern void mlocale__fini ();
596 extern int minput__init ();
597 extern void minput__fini ();
599 #endif /* _M17N_INTERNAL_H_ */