9a67711e3aa4e2d6ad21990416edfa6c7b340b8c
[m17n/m17n-lib.git] / src / internal.h
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
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., 59 Temple Place, Suite 330, Boston, MA
21    02111-1307, USA.  */
22
23 #ifndef _M17N_INTERNAL_H_
24 #define _M17N_INTERNAL_H_
25
26 /** @file internal.h
27     @brief a documentation for internal.h
28
29     longer version of internal.h description 
30 */
31
32 extern int m17n__core_initialized;
33 extern int m17n__shell_initialized;
34 extern int m17n__gui_initialized;
35
36 extern int mdebug_hook ();
37
38 /** Return with code RET while setting merror_code to ERR.  */
39
40 #define MERROR(err, ret)        \
41   do {                          \
42     merror_code = (err);        \
43     mdebug_hook ();             \
44     return (ret);               \
45   } while (0)
46
47
48 #define MERROR_GOTO(err, label) \
49   do {                          \
50     if ((err))                  \
51       merror_code = (err);      \
52     mdebug_hook ();             \
53     goto label;                 \
54   } while (0)
55
56
57 #define MWARNING(err)   \
58   do {                  \
59     mdebug_hook ();     \
60     goto warning;       \
61   } while (0)
62
63 #define MFATAL(err)     \
64   do {                  \
65     mdebug_hook ();     \
66     exit (err);         \
67   } while (0)
68
69 #define M_CHECK_CHAR(c, ret)            \
70   if ((c) < 0 || (c) > MCHAR_MAX)       \
71     MERROR (MERROR_CHAR, (ret));        \
72   else
73
74 \f
75 /** Memory allocation stuffs.  */
76
77 /* Call a handler function for memory full situation with argument
78    ERR.  ERR must be one of enum MErrorCode.  By default, the
79    handler function just calls exit () with argument ERR.  */
80
81 #define MEMORY_FULL(err)                \
82   do {                                  \
83     (*m17n_memory_full_handler) (err);  \
84     exit (err);                         \
85   } while (0)
86
87
88 /** The macro MTABLE_MALLOC () allocates memory (by malloc) for an
89     array of SIZE objects.  The size of each object is determined by
90     the type of P.  Then, it sets P to the allocated memory.  ERR must
91     be one of enum MErrorCode.  If the allocation fails, the macro
92     MEMORY_FULL () is called with argument ERR.  */
93
94 #define MTABLE_MALLOC(p, size, err)                             \
95   do {                                                          \
96     if (! ((p) = (void *) malloc (sizeof (*(p)) * (size))))     \
97       MEMORY_FULL (err);                                        \
98   } while (0)
99
100
101 /** The macro MTABLE_CALLOC() is like the macro MTABLE_MALLOC but use
102     calloc instead of malloc, thus the allocated memory are zero
103     cleared.  */
104
105 #define MTABLE_CALLOC(p, size, err)                             \
106   do {                                                          \
107     if (! ((p) = (void *) calloc (sizeof (*(p)), size)))        \
108       MEMORY_FULL (err);                                        \
109   } while (0)
110
111
112 /** The macro MTABLE_REALLOC () changes the size of memory block
113     pointed to by P to a size suitable for an array of SIZE objects.
114     The size of each object is determined by the type of P.  ERR must
115     be one of enum MErrorCode.  If the allocation fails, the macro
116     MEMORY_FULL () is called with argument ERR.  */
117
118 #define MTABLE_REALLOC(p, size, err)                                    \
119   do {                                                                  \
120     if (! ((p) = (void *) realloc ((p), sizeof (*(p)) * (size))))       \
121       MEMORY_FULL (err);                                                \
122   } while (0)
123
124
125 /** The macro MTABLE_ALLOCA () allocates memory (by alloca) for an
126     array of SIZE objects.  The size of each object is determined by
127     the type of P.  Then, it sets P to the allocated memory.  ERR must
128     be one of enum MErrorCode.  If the allocation fails, the macro
129     MEMORY_FULL () is called with argument ERR.  */
130
131 #define MTABLE_ALLOCA(p, size, err)             \
132   do {                                          \
133     int allocasize = sizeof (*(p)) * (size);    \
134     if (! ((p) = (void *) alloca (allocasize))) \
135       MEMORY_FULL (err);                        \
136     memset ((p), 0, allocasize);                \
137   } while (0)
138
139
140 /** short description of MSTRUCT_MALLOC */
141 /** The macro MSTRUCT_MALLOC () allocates memory (by malloc) for an
142     object whose size is determined by the type of P, and sets P to
143     the allocated memory.  ERR must be one of enum MErrorCode.  If
144     the allocation fails, the macro MEMORY_FULL () is called with
145     argument ERR.  */
146
147 #define MSTRUCT_MALLOC(p, err)                          \
148   do {                                                  \
149     if (! ((p) = (void *) malloc (sizeof (*(p)))))      \
150       MEMORY_FULL (err);                                \
151   } while (0)
152
153
154 #define MSTRUCT_CALLOC(p, err) MTABLE_CALLOC ((p), 1, (err))
155
156 #define USE_SAFE_ALLOCA \
157   int sa_must_free = 0, sa_size = 0
158
159 /* P must be the same in all calls to SAFE_ALLOCA and SAFE_FREE in a
160    function.  */
161
162 #define SAFE_ALLOCA(P, SIZE)            \
163   do {                                  \
164     if (sa_size < (SIZE))               \
165       {                                 \
166         if (sa_must_free)               \
167           (P) = realloc ((P), (SIZE));  \
168         else                            \
169           {                             \
170             (P) = alloca ((SIZE));      \
171             if (! (P))                  \
172               {                         \
173                 (P) = malloc (SIZE);    \
174                 sa_must_free = 1;       \
175               }                         \
176           }                             \
177         if (! (P))                      \
178           MEMORY_FULL (1);              \
179         sa_size = (SIZE);               \
180       }                                 \
181   } while (0)
182
183 #define SAFE_FREE(P)                    \
184   do {                                  \
185     if (sa_must_free && sa_size > 0)    \
186       {                                 \
187         free ((P));                     \
188         sa_must_free = sa_size = 0;     \
189       }                                 \
190   } while (0)
191
192 \f
193 /** Extendable array.  */
194
195 #define MLIST_RESET(list)       \
196   ((list)->used = 0)
197
198
199 #define MLIST_INIT1(list, mem, increment)       \
200   do {                                          \
201     (list)->size = (list)->used = 0;            \
202     (list)->inc = (increment);                  \
203     (list)->mem = NULL;                         \
204   } while (0)
205
206
207 #define MLIST_APPEND1(list, mem, elt, err)                      \
208   do {                                                          \
209     if ((list)->inc <= 0)                                       \
210       mdebug_hook ();                                           \
211     if ((list)->size == (list)->used)                           \
212       {                                                         \
213         (list)->size += (list)->inc;                            \
214         MTABLE_REALLOC ((list)->mem, (list)->size, (err));      \
215       }                                                         \
216     (list)->mem[(list)->used++] = (elt);                        \
217   } while (0)
218
219
220 #define MLIST_PREPEND1(list, mem, elt, err)                     \
221   do {                                                          \
222     if ((list)->inc <= 0)                                       \
223       mdebug_hook ();                                           \
224     if ((list)->size == (list)->used)                           \
225       {                                                         \
226         (list)->size += (list)->inc;                            \
227         MTABLE_REALLOC ((list)->mem, (list)->size, (err));      \
228       }                                                         \
229     memmove ((list)->mem + 1, (list)->mem,                      \
230              sizeof *((list)->mem) * ((list)->used));           \
231     (list)->mem[0] = (elt);                                     \
232     (list)->used++;                                             \
233   } while (0)
234
235
236 #define MLIST_INSERT1(list, mem, idx, len, err)                         \
237   do {                                                                  \
238     while ((list)->used + (len) > (list)->size)                         \
239       {                                                                 \
240         (list)->size += (list)->inc;                                    \
241         MTABLE_REALLOC ((list)->mem, (list)->size, (err));              \
242       }                                                                 \
243     memmove ((list)->mem + ((idx) + (len)), (list)->mem + (idx),        \
244              (sizeof *((list)->mem)) * ((list)->used - (idx)));         \
245     (list)->used += (len);                                              \
246   } while (0)
247
248
249 #define MLIST_DELETE1(list, mem, idx, len)                              \
250   do {                                                                  \
251     memmove ((list)->mem + (idx), (list)->mem + (idx) + (len),          \
252              (sizeof *((list)->mem)) * ((list)->used - (idx) - (len))); \
253     (list)->used -= (len);                                              \
254   } while (0)
255
256
257 #define MLIST_COPY1(list0, list1, mem, err)                     \
258   do {                                                          \
259     (list0)->size = (list0)->used = (list1)->used;              \
260     (list0)->inc = 1;                                           \
261     MTABLE_MALLOC ((list0)->mem, (list0)->used, (err));         \
262     memcpy ((list0)->mem, (list1)->mem,                         \
263             (sizeof (list0)->mem) * (list0)->used);             \
264   } while (0)
265
266
267 #define MLIST_FREE1(list, mem)          \
268   if ((list)->size)                     \
269     {                                   \
270       free ((list)->mem);               \
271       (list)->mem = NULL;               \
272       (list)->size = (list)->used = 0;  \
273     }                                   \
274   else
275
276 \f
277
278 typedef struct
279 {
280   void (*freer) (void *);
281   int size, inc, used;
282   unsigned *counts;
283 } M17NObjectRecord;
284
285 typedef struct
286 {
287   /**en Reference count of the object.  */
288   /**ja ¥ª¥Ö¥¸¥§¥¯¥È¤Î»²¾È¿ô.  */
289   unsigned ref_count : 16;
290
291   unsigned ref_count_extended : 1;
292
293   /**en A flag bit used for various perpose.  */
294   /**ja ¤µ¤Þ¤¶¤Þ¤ÊÌÜŪ¤ËÍѤ¤¤é¤ì¤ë¥Õ¥é¥°¥Ó¥Ã¥È.  */
295   unsigned flag : 15;
296
297   union {
298     /**en If <ref_count_extended> is zero, a function to free the
299        object.  */
300     /**ja <ref_count_extended> ¤¬ 0 ¤Ê¤é¤Ð¥ª¥Ö¥¸¥§¥¯¥È¤ò²òÊü¤¹¤ë´Ø¿ô.  */
301     void (*freer) (void *);
302     /**en If <ref_count_extended> is nonzero, a pointer to the
303        struct M17NObjectRecord.  */
304     /**ja <ref_count_extended> ¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð¹½Â¤ÂΠM17NObjectRecord ¤Ø¤Î¥Ý¥¤¥ó¥¿.  */
305     M17NObjectRecord *record;
306   } u;
307 } M17NObject;
308
309
310 /** Allocate a managed object OBJECT which has freer FREE_FUNC.  */
311
312 #define M17N_OBJECT(object, free_func, err)             \
313   do {                                                  \
314     MSTRUCT_CALLOC ((object), (err));                   \
315     ((M17NObject *) (object))->ref_count = 1;           \
316     ((M17NObject *) (object))->u.freer = free_func;     \
317   } while (0)
318
319
320 /**en Increment the reference count of OBJECT if the count is not
321    0.  */
322 /**ja OBJECT ¤Î»²¾È¿ô¤¬ 0 ¤Ç¤Ê¤±¤ì¤Ð 1 Áý¤ä¤¹.  */
323
324 #define M17N_OBJECT_REF(object)                         \
325   do {                                                  \
326     if (((M17NObject *) (object))->ref_count_extended)  \
327       m17n_object_ref (object);                         \
328     else if (((M17NObject *) (object))->ref_count > 0)  \
329       {                                                 \
330         ((M17NObject *) (object))->ref_count++;         \
331         if (! ((M17NObject *) (object))->ref_count)     \
332           {                                             \
333             ((M17NObject *) (object))->ref_count--;     \
334             m17n_object_ref (object);                   \
335           }                                             \
336       }                                                 \
337   } while (0)
338
339
340 #define M17N_OBJECT_REF_NTIMES(object, n)                               \
341   do {                                                                  \
342     int i;                                                              \
343                                                                         \
344     if (((M17NObject *) (object))->ref_count_extended)                  \
345       for (i = 0; i < n; i++)                                           \
346         m17n_object_ref (object);                                       \
347     else if (((M17NObject *) (object))->ref_count > 0)                  \
348       {                                                                 \
349         int orig_ref_count = ((M17NObject *) (object))->ref_count;      \
350                                                                         \
351         for (i = 0; i < n; i++)                                         \
352           if (! ++((M17NObject *) (object))->ref_count)                 \
353             {                                                           \
354               ((M17NObject *) (object))->ref_count = orig_ref_count;    \
355               for (i = 0; i < n; i++)                                   \
356                 m17n_object_ref (object);                               \
357             }                                                           \
358       }                                                                 \
359   } while (0)
360
361
362 /**en Decrement the reference count of OBJECT if the count is greater
363       than 0.  In that case, if the count becomes 0, free OBJECT.  */
364 /**ja OBJECT ¤Î»²¾È¿ô¤¬ 0 ¤è¤êÂ礭¤±¤ì¤Ð 1 ¸º¤é¤¹¡£¸º¤é¤·¤Æ 0 ¤Ë¤Ê¤ì¤Ð
365       OBJECT ¤ò²òÊü¤¹¤ë.  */
366
367 #define M17N_OBJECT_UNREF(object)                                       \
368   do {                                                                  \
369     if (object)                                                         \
370       {                                                                 \
371         if (((M17NObject *) (object))->ref_count_extended)              \
372           m17n_object_unref (object);                                   \
373         else if (((M17NObject *) (object))->ref_count == 0)             \
374           break;                                                        \
375         else                                                            \
376           {                                                             \
377             ((M17NObject *) (object))->ref_count--;                     \
378             if (((M17NObject *) (object))->ref_count == 0)              \
379               {                                                         \
380                 if (((M17NObject *) (object))->u.freer)                 \
381                   (((M17NObject *) (object))->u.freer) (object);        \
382                 else                                                    \
383                   free (object);                                        \
384                 (object) = NULL;                                        \
385               }                                                         \
386           }                                                             \
387       }                                                                 \
388   } while (0)
389
390 typedef struct _M17NObjectArray M17NObjectArray;
391
392 struct _M17NObjectArray
393 {
394   char *name;
395   int count;
396   int size, inc, used;
397   void **objects;
398   M17NObjectArray *next;
399 };
400
401 extern void mdebug__add_object_array (M17NObjectArray *array, char *name);
402
403 #define M17N_OBJECT_ADD_ARRAY(array, name)      \
404   if (mdebug__flag & MDEBUG_FINI)               \
405     mdebug__add_object_array (&array, name);    \
406   else
407
408 extern void mdebug__register_object (M17NObjectArray *array, void *object);
409
410 #define M17N_OBJECT_REGISTER(array, object)     \
411   if (mdebug__flag & MDEBUG_FINI)               \
412     mdebug__register_object (&array, object);   \
413   else
414
415 extern void mdebug__unregister_object (M17NObjectArray *array, void *object);
416
417 #define M17N_OBJECT_UNREGISTER(array, object)   \
418   if (mdebug__flag & MDEBUG_FINI)               \
419     mdebug__unregister_object (&array, object); \
420   else
421
422 \f
423
424 struct MTextPlist;
425
426 enum MTextCoverage
427   {
428     MTEXT_COVERAGE_ASCII,
429     MTEXT_COVERAGE_UNICODE,
430     MTEXT_COVERAGE_FULL
431   };
432
433 struct MText
434 {
435   M17NObject control;
436
437   enum MTextFormat format : 16;
438   enum MTextCoverage coverage : 16;
439
440   /**en Number of characters in the M-text */
441   /**ja M-text Ãæ¤Îʸ»ú¿ô */
442   int nchars;
443
444   /**en Number of bytes used to represent the characters in the M-text. */
445   /**ja M-text Ãæ¤Îʸ»ú¤òɽ¤ï¤¹¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥Ð¥¤¥È¿ô */
446   int nbytes;
447
448   /**en Character sequence of the M-text. */
449   /**ja M-text Ãæ¤Îʸ»úÎó */
450   unsigned char *data;
451
452   /**en Number of bytes allocated for the @c data member. */
453   /**ja ¥á¥ó¥Ð @c data ¤Ë³ä¤êÅö¤Æ¤é¤ì¤¿¥Ð¥¤¥È¿ô */
454   int allocated;
455
456   /**en Pointer to the property list of the M-text. */
457   /**ja M-text ¤Î¥×¥í¥Ñ¥Æ¥£¥ê¥¹¥È¤Ø¤Î¥Ý¥¤¥ó¥¿ */
458   struct MTextPlist *plist;
459
460   /**en Caches of the character position and the corresponding byte position. */
461   /**ja Ê¸»ú°ÌÃÖ¤ª¤è¤ÓÂбþ¤¹¤ë¥Ð¥¤¥È°ÌÃ֤Υ­¥ã¥Ã¥·¥å */
462   int cache_char_pos, cache_byte_pos;
463 };
464
465 /** short description of M_CHECK_POS */
466 /** longer description of M_CHECK_POS */
467
468 #define M_CHECK_POS(mt, pos, ret)               \
469   do {                                          \
470     if ((pos) < 0 || (pos) >= (mt)->nchars)     \
471       MERROR (MERROR_RANGE, (ret));             \
472   } while (0)
473
474
475 /** short description of M_CHECK_POS_X */
476 /** longer description of M_CHECK_POS_X */
477
478 #define M_CHECK_POS_X(mt, pos, ret)             \
479   do {                                          \
480     if ((pos) < 0 || (pos) > (mt)->nchars)      \
481       MERROR (MERROR_RANGE, (ret));             \
482   } while (0)
483
484
485 /** short description of M_CHECK_RANGE */
486 /** longer description of M_CHECK_RANGE */
487
488 #define M_CHECK_RANGE(mt, from, to, ret, ret2)                  \
489   do {                                                          \
490     if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars)     \
491       MERROR (MERROR_RANGE, (ret));                             \
492     if ((from) == (to))                                         \
493       return (ret2);                                            \
494   } while (0)
495
496 #define M_CHECK_RANGE_X(mt, from, to, ret)                      \
497   do {                                                          \
498     if ((from) < 0 || (to) < (from) || (to) > (mt)->nchars)     \
499       MERROR (MERROR_RANGE, (ret));                             \
500   } while (0)
501
502
503 #define M_CHECK_POS_NCHARS(mt, pos, nchars, ret, ret2)  \
504   do {                                                  \
505     int to = (pos) + (nchars);                  \
506                                                         \
507     M_CHECK_RANGE ((mt), (pos), (to), (ret), (ret2));   \
508   } while (0)
509
510
511 #define MTEXT_READ_ONLY_P(mt) ((mt)->allocated < 0)
512
513 #define M_CHECK_READONLY(mt, ret)       \
514   do {                                  \
515     if ((mt)->allocated < 0)            \
516       MERROR (MERROR_MTEXT, (ret));     \
517   } while (0)
518
519 #define mtext_nchars(mt) ((mt)->nchars)
520
521 #define mtext_nbytes(mt) ((mt)->nbytes)
522
523 #define mtext_allocated(mt) ((mt)->allocated)
524
525 #define mtext_reset(mt) (mtext_del ((mt), 0, (mt)->nchars))
526
527 \f
528
529 enum MDebugMaskBit
530   {
531     MDEBUG_INIT =       0x01,
532     MDEBUG_FINI =       0x02,
533     MDEBUG_CHARSET =    0x04,
534     MDEBUG_CODING =     0x08,
535     MDEBUG_DATABASE =   0x10,
536     MDEBUG_FONT =       0x0100,
537     MDEBUG_FONT_FLT =   0x0200,
538     MDEBUG_FONT_OTF =   0x0400,
539     MDEBUG_INPUT =      0x0800,
540     MDEBUG_MAX
541   };
542
543 extern int mdebug__flag;
544 extern void mdebug__push_time ();
545 extern void mdebug__pop_time ();
546 extern void mdebug__print_time ();
547
548 #define MDEBUG_PRINT(msg)               \
549   do {                                  \
550     if (mdebug__flag & mdebug_mask)     \
551       fprintf (stderr, (msg));          \
552   } while (0)
553
554 #define MDEBUG_PRINT1(fmt, arg)         \
555   do {                                  \
556     if (mdebug__flag & mdebug_mask)     \
557       fprintf (stderr, (fmt), (arg));   \
558   } while (0)
559
560 #define MDEBUG_PRINT2(fmt, arg1, arg2)          \
561   do {                                          \
562     if (mdebug__flag & mdebug_mask)             \
563       fprintf (stderr, (fmt), (arg1), (arg2));  \
564   } while (0)
565
566 #define MDEBUG_PRINT3(fmt, arg1, arg2, arg3)            \
567   do {                                                  \
568     if (mdebug__flag & mdebug_mask)                     \
569       fprintf (stderr, (fmt), (arg1), (arg2), (arg3));  \
570   } while (0)
571
572 #define MDEBUG_PRINT4(fmt, arg1, arg2, arg3, arg4)              \
573   do {                                                          \
574     if (mdebug__flag & mdebug_mask)                             \
575       fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4));  \
576   } while (0)
577
578 #define MDEBUG_PRINT5(fmt, arg1, arg2, arg3, arg4, arg5)                \
579   do {                                                                  \
580     if (mdebug__flag & mdebug_mask)                                     \
581       fprintf (stderr, (fmt), (arg1), (arg2), (arg3), (arg4), (arg5));  \
582   } while (0)
583
584
585 #define MDEBUG_PUSH_TIME()              \
586   do {                                  \
587     if (mdebug__flag & mdebug_mask)     \
588       mdebug__push_time ();             \
589   } while (0)
590
591
592 #define MDEBUG_POP_TIME()               \
593   do {                                  \
594     if (mdebug__flag & mdebug_mask)     \
595       mdebug__pop_time ();              \
596   } while (0)
597
598
599 #define MDEBUG_PRINT_TIME(tag, ARG_LIST)        \
600   do {                                          \
601     if (mdebug__flag & mdebug_mask)             \
602       {                                         \
603         fprintf (stderr, " [%s] ", tag);        \
604         mdebug__print_time ();                  \
605         fprintf ARG_LIST;                       \
606         fprintf (stderr, "\n");                 \
607       }                                         \
608   } while (0)
609
610
611 #define SWAP_16(c) (((c) >> 8) | (((c) & 0xFF) << 8))
612
613 #define SWAP_32(c)                      \
614   (((c) >> 24) | (((c) >> 8) & 0xFF00)  \
615    | (((c) & 0xFF00) << 8) | (((c) & 0xFF) << 24))
616
617
618 extern void *(*mdatabase__finder) (MSymbol tag1, MSymbol tag2,
619                                    MSymbol tag3, MSymbol tag4);
620 extern void *(*mdatabase__loader) (void *);
621
622 /* Initialize/finalize function.  */
623
624 extern int msymbol__init ();
625 extern void msymbol__fini ();
626
627 extern int mplist__init ();
628 extern void mplist__fini ();
629
630 extern int mtext__init ();
631 extern void mtext__fini ();
632
633 extern int mtext__prop_init ();
634 extern void mtext__prop_fini ();
635
636 extern int mchartable__init ();
637 extern void mchartable__fini ();
638
639 extern int mcharset__init ();
640 extern void mcharset__fini ();
641
642 extern int mcoding__init ();
643 extern void mcoding__fini ();
644
645 extern int mdatabase__init (void);
646 extern void mdatabase__fini (void);
647
648 extern int mchar__init ();
649 extern void mchar__fini ();
650
651 extern int mlang__init ();
652 extern void mlang__fini ();
653
654 extern int mlocale__init ();
655 extern void mlocale__fini ();
656
657 extern int minput__init ();
658 extern void minput__fini ();
659
660 #endif /* _M17N_INTERNAL_H_ */
661
662 /*
663   Local Variables:
664   coding: euc-japan
665   End:
666 */