1 /* database.c -- database module.
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
24 @addtogroup m17nDatabase
25 @brief The m17n database and API for it.
27 The m17n library dynamically acquires various kinds of information
28 in need from data in the <i> m17n database</i>. Application
29 programs can also add/load their original data to/from the m17n
30 database. The m17n database contains multiple heterogeneous data,
31 and each data is identified by four tags; TAG0, TAG1, TAG2, TAG3.
32 Each tag must be a symbol.
34 TAG0 specifies the type of data stored in the database as below.
37 If TAG0 is #Mchar_table, the data is of the @e chartable @e
38 type and provides information about each character. In this case,
39 TAG1 specifies the type of the information and must be #Msymbol,
40 #Minteger, #Mstring, #Mtext, or #Mplist. TAG2 and TAG3 can be any
44 If TAG0 is #Mcharset, the data is of the @e charset @e type
45 and provides a decode/encode mapping table for a charset. In this
46 case, TAG1 must be a symbol representing a charset. TAG2 and TAG3
50 If TAG0 is neither #Mchar_table nor #Mcharset, the data is of
51 the @e plist @e type. See the documentation of the
52 mdatabase_load () function for the details.
53 In this case, TAG1, TAG2, and TAG3 can be any symbols.
55 The notation \<TAG0, TAG1, TAG2, TAG3\> means a data with those
58 Application programs first calls the mdatabase_find () function to
59 get a pointer to an object of the type #MDatabase. That object
60 holds information about the specified data. When it is
61 successfully returned, the mdatabase_load () function loads the
62 data. The implementation of the structure #MDatabase is
63 concealed from application programs.
67 @addtogroup m17nDatabase
68 @brief m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤È¤½¤ì¤Ë´Ø¤¹¤ë API.
70 m17n ¥é¥¤¥Ö¥é¥ê¤ÏɬÍפ˱þ¤¸¤ÆưŪ¤Ë @e m17n @e ¥Ç¡¼¥¿¥Ù¡¼¥¹ ¤«¤é¾ð
71 Êó¤ò¼èÆÀ¤¹¤ë¡£¤Þ¤¿¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤âÆȼ«¤Î¥Ç¡¼¥¿¤ò
72 m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÄɲä·¡¢¤½¤ì¤òưŪ¤Ë¼èÆÀ¤¹¤ë¤³¤È¤¬¤Ç¤¤ë¡£m17n
73 ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ë¤ÏÊ£¿ô¤Î¿Íͤʥǡ¼¥¿¤¬´Þ¤Þ¤ì¤Æ¤ª¤ê¡¢³Æ¥Ç¡¼¥¿¤Ï£´¤Ä¤Î
74 ¥¿¥° TAG0, TAG1, TAG2, TAG3¡Ê¤¹¤Ù¤Æ¥·¥ó¥Ü¥ë¡Ë¤Ë¤è¤Ã¤Æ¼±Ê̤µ¤ì¤ë¡£
76 TAG0 ¤Ï¥Ç¡¼¥¿¥Ù¡¼¥¹Æâ¤Î¥Ç¡¼¥¿¤Î¥¿¥¤¥×¤ò°Ê²¼¤Î¤è¤¦¤Ë»ØÄꤹ¤ë¡£
79 TAG0 ¤¬ #Mchar_table ¤Ç¤¢¤ë¥Ç¡¼¥¿¤Ï @e chartable¥¿¥¤¥× ¤È¸Æ¤Ð¤ì¡¢
80 ³Æʸ»ú¤Ë´Ø¤¹¤ë¾ðÊó¤òÄ󶡤¹¤ë¡£¤³¤Î¾ì¹ç TAG1 ¤Ï¾ðÊó¤Î¼ïÎà¤ò»ØÄꤹ¤ë
81 ¥·¥ó¥Ü¥ë¤Ç¤¢¤ê¡¢#Msymbol, #Minteger, #Mstring, #Mtext, #Mplist ¤Î
82 ¤¤¤º¤ì¤«¤Ç¤¢¤ë¡£TAG2 ¤È TAG3 ¤ÏǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
85 TAG0 ¤¬ #Mcharset ¤Ç¤¢¤ë¥Ç¡¼¥¿¤Ï @e charset¥¿¥¤¥× ¤È¸Æ¤Ð¤ì¡¢Ê¸
86 »ú¥»¥Ã¥ÈÍѤΥǥ³¡¼¥É¡¿¥¨¥ó¥³¡¼¥É¥Þ¥Ã¥×¤òÄ󶡤¹¤ë¡£¤³¤Î¾ì¹ç TAG1 ¤Ï
87 ʸ»ú¥»¥Ã¥È¤Î¥·¥ó¥Ü¥ë¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£TAG2 ¤È TAG3 ¤ÏǤ°Õ¤Î¥·¥ó
91 TAG0 ¤¬ #Mchar_table ¤Ç¤â #Mcharset ¤Ç¤â¤Ê¤¤¾ì¹ç¡¢¤½¤Î¥Ç¡¼¥¿¤Ï @e
92 plist¥¿¥¤¥× ¤Ç¤¢¤ë¡£¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï´Ø¿ô mdatabase_load () ¤ÎÀâÌÀ¤ò
93 »²¾È¤Î¤³¤È¡£¤³¤Î¾ì¹ç TAG1¡¢TAG2¡¢TAG3 ¤ÏǤ°Õ¤Î¥·¥ó¥Ü¥ë¤Ç¤è¤¤¡£
95 ÆÃÄê¤Î¥¿¥°¤ò»ý¤Ä¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò \<TAG0, TAG1, TAG2, TAG3\> ¤È¤¤¤¦·Á
98 ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤Ï¡¢¤Þ¤º´Ø¿ô mdatabase_find () ¤ò»È¤Ã¤Æ¥Ç¡¼
99 ¥¿¥Ù¡¼¥¹¤Ë´Ø¤¹¤ë¾ðÊó¤òÊÝ»ý¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¡Ê#MDatabase ·¿¡Ë¤Ø¤Î
100 ¥Ý¥¤¥ó¥¿¤òÆÀ¤ë¡£¤½¤ì¤ËÀ®¸ù¤·¤¿¤é¡¢ mdatabase_load () ¤Ë¤è¤Ã¤Æ¼ÂºÝ
101 ¤Ë¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥í¡¼¥É¤¹¤ë¡£¹½Â¤ÂÎ #MDatabase ¼«¿È¤¬¤É¤¦¼ÂÁõ¤µ¤ì
102 ¤Æ¤¤¤ë¤«¤Ï¡¢¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¤¡£
104 @latexonly \IPAlabel{database} @endlatexonly
109 #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE)
110 /*** @addtogroup m17nInternal
118 #include <sys/types.h>
119 #include <sys/stat.h>
124 #include "m17n-misc.h"
125 #include "internal.h"
127 #include "character.h"
129 #include "database.h"
133 /** The file containing a list of databases. */
134 #define MDB_DIR "mdb.dir"
135 #define MDB_DIR_LEN 8
137 /** Structure for a data in the m17n database. */
141 /** Tags to identify the data. <tag>[0] specifies the type of
142 database. If it is #Mchar_table, the type is @e chartable, if
143 it is #Mcharset, the type is @e charset, otherwise the type is
147 void *(*loader) (MSymbol *tags, void *extra_info);
149 /** The meaning of the value is dependent on <loader>. If <loader>
150 is load_database (), the value is a string of the file name that
151 contains the data. */
155 /** List of all data. */
162 static struct MDatabaseList mdb_list;
166 read_number (char *buf, int *i)
175 while (c && isspace (c)) c = buf[idx++];
181 for (idx++, c = 0; (n = hex_mnemonic[(unsigned) buf[idx]]) < 16;
195 n = escape_mnemonic[c];
199 while (buf[idx] && buf[idx++] != '\'');
203 else if (hex_mnemonic[c] < 10)
208 while ((n = hex_mnemonic[(unsigned) buf[idx]]) < 10)
209 c = (c * 10) + n, idx++;
215 /** Load a data of type @c chartable from the file FD, and return the
216 newly created chartable. */
219 load_chartable (FILE *fp, MSymbol type)
227 MERROR (MERROR_DB, NULL);
229 table = mchartable (type, (type == Msymbol ? (void *) Mnil
230 : type == Minteger ? (void *) -1
237 for (len = 0; len < 1023 && (c = getc (fp)) != EOF && c != '\n'; len++)
240 if (hex_mnemonic[(unsigned) buf[0]] >= 10)
241 /* skip comment/invalid line */
244 from = read_number (buf, &i);
246 i++, to = read_number (buf, &i);
249 if (from < 0 || to < 0)
252 while (buf[i] && isspace ((unsigned) buf[i])) i++;
259 /* VAL is a C-string. */
260 if (! (val = strdup (buf + i)))
261 MEMORY_FULL (MERROR_DB);
263 else if (type == Minteger)
265 /* VAL is an integer. */
271 n = read_number (buf, &i);
274 val = (void *) (n * positive);
276 else if (type == Mtext)
278 /* VAL is an M-text. */
281 mt = mconv_decode_buffer (Mcoding_utf_8,
282 (unsigned char *) (buf + i),
287 while ((c = read_number (buf, &i)) >= 0)
288 mt = mtext_cat_char (mt, c);
292 else if (type == Msymbol)
294 if (! strcmp (buf + i, "nil"))
297 val = (void *) msymbol (buf + i);
299 else if (type == Mplist)
301 val = (void *) mplist__from_string ((unsigned char *) buf + i,
308 mchartable_set (table, from, val);
310 mchartable_set_range (table, from, to, val);
315 M17N_OBJECT_UNREF (table);
316 MERROR (MERROR_DB, NULL);
320 /** Load a data of type @c charset from the file FD. */
323 load_charset (FILE *fp, MSymbol charset_name)
325 MCharset *charset = MCHARSET (charset_name);
334 MERROR (MERROR_DB, NULL);
335 size = (charset->code_range[15]
336 - (charset->min_code - charset->code_range_min_code));
337 MTABLE_MALLOC (decoder, size, MERROR_DB);
338 for (i = 0; i < size; i++)
340 encoder = mchartable (Minteger, (void *) MCHAR_INVALID_CODE);
342 while ((c = getc (fp)) != EOF)
344 unsigned code1, code2, c1, c2;
349 fgets (buf, 256, fp);
352 if (sscanf (buf, "0x%x-0x%x 0x%x", &code1, &code2, &c1) == 3)
354 idx1 = CODE_POINT_TO_INDEX (charset, code1);
357 idx2 = CODE_POINT_TO_INDEX (charset, code2);
360 c2 = c1 + (idx2 - idx1);
362 else if (sscanf (buf, "0x%x 0x%x", &code1, &c1) == 2)
364 idx1 = idx2 = CODE_POINT_TO_INDEX (charset, code1);
371 if (idx1 >= 0 && idx2 >= 0)
374 mchartable_set (encoder, c1, (void *) code1);
375 for (idx1++, c1++; idx1 <= idx2; idx1++, c1++)
377 code1 = INDEX_TO_CODE_POINT (charset, idx1);
379 mchartable_set (encoder, c1, (void *) code1);
389 M17N_OBJECT_UNREF (encoder);
393 mplist_add (plist, Mt, decoder);
394 mplist_add (plist, Mt, encoder);
399 gen_database_name (char *buf, MSymbol *tags)
403 strcpy (buf, msymbol_name (tags[0]));
404 for (i = 1; i < 4; i++)
407 strcat (buf, msymbol_name (tags[i]));
413 get_database_stream (char *filename)
417 if (filename[0] == '/')
418 fp = fopen (filename, "r");
424 MPLIST_DO (plist, mdatabase__dir_list)
426 strcpy (path, (char *) MPLIST_VAL (plist));
427 strcat (path, filename);
428 fp = fopen (path, "r");
437 load_database (MSymbol *tags, void *extra_info)
439 FILE *fp = get_database_stream ((char *) extra_info);
443 MERROR (MERROR_DB, NULL);
445 if (tags[0] == Mchar_table)
446 value = load_chartable (fp, tags[1]);
447 else if (tags[0] == Mcharset)
448 value = load_charset (fp, tags[1]);
450 value = mplist__from_file (fp, NULL);
454 MERROR (MERROR_DB, NULL);
459 /** Copy DIRNAME to a newly allocated memory and return it. If
460 DIRNAME does not end with a slash, append a slash to the new memory. */
463 duplicate_dirname (char *dirname)
470 || stat (dirname, &buf) < 0)
473 len = strlen (dirname);
474 MTABLE_MALLOC (str, len + 2, MERROR_DB);
475 memcpy (str, dirname, len + 1);
476 if (str[len - 1] != '/')
487 /** List of database directories. */
488 MPlist *mdatabase__dir_list;
490 MSymbol M_database_hook;
500 Mchar_table = msymbol ("char-table");
501 M_database_hook = msymbol (" database-hook");
503 mdatabase__dir_list = mplist ();
504 /** The macro M17NDIR specifies a directory where the system-wide
505 MDB_DIR file exists. */
506 if ((dir = duplicate_dirname (M17NDIR)))
507 mplist_set (mdatabase__dir_list, Mt, dir);
509 /* The variable mdatabase_dir specifies a directory where an
510 application program specific MDB_DIR file exists. */
511 if ((dir = duplicate_dirname (mdatabase_dir)))
512 mplist_push (mdatabase__dir_list, Mt, dir);
514 /* The environment variable M17NDIR (if non-NULL) specifies a
515 directory where a user specific MDB_DIR file exists. */
516 if ((dir = duplicate_dirname (getenv ("M17NDIR"))))
517 mplist_push (mdatabase__dir_list, Mt, dir);
519 MLIST_INIT1 (&mdb_list, mdbs, 256);
520 MPLIST_DO (plist, mdatabase__dir_list)
526 dir = (char *) MPLIST_VAL (plist);
528 if (len + MDB_DIR_LEN >= PATH_MAX)
530 memcpy (path, dir, len);
531 memcpy (path + len, MDB_DIR, MDB_DIR_LEN);
532 if (! (fp = fopen (path, "r")))
534 pl = mplist__from_file (fp, NULL);
544 if (! MPLIST_PLIST_P (p))
546 for (i = 0, p1 = MPLIST_PLIST (p);
547 i < 4 && MPLIST_KEY (p1) == Msymbol;
548 i++, p1 = MPLIST_NEXT (p1))
549 mdb.tag[i] = MPLIST_SYMBOL (p1);
551 || ! MPLIST_MTEXT_P (p1))
555 if (mdatabase_find (mdb.tag[0], mdb.tag[1],
556 mdb.tag[2], mdb.tag[3]))
559 mdb.loader = load_database;
560 nbytes = mconv_encode_buffer (Mcoding_utf_8, MPLIST_MTEXT (p1),
561 (unsigned char *) path, PATH_MAX);
562 if (nbytes < 0 || nbytes >= PATH_MAX)
564 path[nbytes++] = '\0';
565 mdb.extra_info = (void *) strdup (path);
566 MLIST_APPEND1 (&mdb_list, mdbs, mdb, MERROR_DB);
568 M17N_OBJECT_UNREF (pl);
571 mdatabase__finder = ((void *(*) (MSymbol, MSymbol, MSymbol, MSymbol))
573 mdatabase__loader = (void *(*) (void *)) mdatabase_load;
579 mdatabase__fini (void)
584 MPLIST_DO (plist, mdatabase__dir_list)
585 free (MPLIST_VAL (plist));
586 M17N_OBJECT_UNREF (mdatabase__dir_list);
588 for (i = 0; i < mdb_list.used; i++)
590 MDatabase *mdb = mdb_list.mdbs + i;
592 if (mdb->loader == load_database)
593 free (mdb->extra_info);
595 MLIST_FREE1 (&mdb_list, mdbs);
599 mdatabase__load_for_keys (MDatabase *mdb, MPlist *keys)
601 int mdebug_mask = MDEBUG_DATABASE;
606 if (mdb->loader != load_database
607 || mdb->tag[0] == Mchar_table
608 || mdb->tag[0] == Mcharset)
609 MERROR (MERROR_DB, NULL);
610 MDEBUG_PRINT1 (" [DATABASE] loading <%s>.\n",
611 gen_database_name (buf, mdb->tag));
612 fp = get_database_stream ((char *) mdb->extra_info);
614 MERROR (MERROR_DB, NULL);
615 plist = mplist__from_file (fp, keys);
622 #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */
627 /*** @addtogroup m17nDatabase */
632 @brief Directory for application specific data.
634 If an application program wants to provide a data specific to the
635 program or a data overriding what supplied by the m17n database,
636 it must set this variable to a name of directory that contains the
637 data files before it calls the macro M17N_INIT (). The directory
638 may contain a file "mdb.dir" which contains a list of data
639 definitions in the format described in @ref mdbDir "mdbDir(5)".
641 The default value is NULL. */
643 @brief ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇͤΥǡ¼¥¿Íѥǥ£¥ì¥¯¥È¥ê.
645 ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥×¥í¥°¥é¥à¤¬¡¢¤½¤Î¥×¥í¥°¥é¥à¸ÇͤΥǡ¼¥¿¤ä m17n ¥Ç¡¼
646 ¥¿¥Ù¡¼¥¹¤ò¾å½ñ¤¤¹¤ë¥Ç¡¼¥¿¤òÄ󶡤¹¤ë¾ì¹ç¤Ë¤Ï¡¢¥Þ¥¯¥í M17N_INIT ()
647 ¤ò¸Æ¤ÖÁ°¤Ë¤³¤ÎÊÑ¿ô¤ò¥Ç¡¼¥¿¥Õ¥¡¥¤¥ë¤ò´Þ¤à¥Ç¥£¥ì¥¯¥È¥ê̾¤Ë¥»¥Ã¥È¤·¤Ê
648 ¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¡£¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤Ï "mdb.dir" ¥Õ¥¡¥¤¥ë¤ò¤ª¤¯¤³¤È¤¬¤Ç
649 ¤¤ë¡£¤½¤Î"mdb.dir"¥Õ¥¡¥¤¥ë¤Ë¤Ï¡¢ @ref mdbDir "mdbDir(5)" ¤ÇÀâÌÀ¤µ
650 ¤ì¤Æ¤¤¤ë¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç¥Ç¡¼¥¿ÄêµÁ¤Î¥ê¥¹¥È¤òµ½Ò¤¹¤ë¡£
652 ¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ¤Ï NULL ¤Ç¤¢¤ë¡£ */
658 @brief Look for a data in the database.
660 The mdatabase_find () function searches the m17n database for a
661 data who has tags $TAG0 through $TAG3, and returns a pointer to
662 the data. If such a data is not found, it returns @c NULL. */
665 @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Î¥Ç¡¼¥¿¤òõ¤¹.
667 ´Ø¿ô mdatabase_find () ¤Ï¡¢ m17n ¸À¸ì¾ðÊó¥Ù¡¼¥¹Ãæ¤Ç $TAG0 ¤«¤é
668 $TAG3 ¤Þ¤Ç¤Î¥¿¥°¤ò»ý¤Ä¥Ç¡¼¥¿¤òõ¤·¡¢¤½¤ì¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤½¤Î¤è
669 ¤¦¤Ê¥Ç¡¼¥¿¤¬¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
671 @latexonly \IPAlabel{mdatabase_find} @endlatexonly */
674 mdatabase_find (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
677 MDatabaseHookFunc func
678 = (MDatabaseHookFunc) msymbol_get (tag0, M_database_hook);
681 func (tag0, tag1, tag2, tag3);
683 for (i = 0; i < mdb_list.used; i++)
685 MDatabase *mdb = mdb_list.mdbs + i;
687 if (tag0 == mdb->tag[0]
688 && tag1 == mdb->tag[1]
689 && tag2 == mdb->tag[2]
690 && tag3 == mdb->tag[3])
698 @brief Return a data list of the m17n database.
700 The mdatabase_list () function searches the m17n database for data
701 who have tags $TAG0 through $TAG3, and returns their list by a
702 plist. The value #Mnil in $TAGn means a wild card that matches
703 any tag. Each element of the plist has key #Mt and value a
704 pointer to type #MDatabase. */
706 @brief m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥Ç¡¼¥¿¥ê¥¹¥È¤òÊÖ¤¹.
708 ´Ø¿ô mdatabase_list () ¤Ï m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹Ã椫¤é $TAG0 ¤«¤é$TAG3
709 ¤Þ¤Ç¤Î¥¿¥°¤ò»ý¤Ä¥Ç¡¼¥¿¤òõ¤·¡¢¤½¤Î¥ê¥¹¥È¤òplist ¤È¤·¤ÆÊÖ¤¹¡£ $TAGn
710 ¤¬ #Mnil ¤Ç¤¢¤Ã¤¿¾ì¹ç¤Ë¤Ï¡¢Ç¤°Õ¤Î¥¿¥°¤Ë¥Þ¥Ã¥Á¤¹¤ë¥ï¥¤¥ë¥É¥«¡¼¥É¤È
711 ¤·¤Æ¼è¤ê°·¤ï¤ì¤ë¡£ÊÖ¤µ¤ì¤ë plist ¤Î³ÆÍ×ÁǤϥ¡¼ ¤È¤·¤Æ #Mt ¤ò¡¢ÃÍ
712 ¤È¤·¤Æ #MDatabase ·¿¤Ø¤Î¥Ý¥¤¥ó¥¿¤ò»ý¤Ä¡£ */
716 mdatabase_list (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
719 MPlist *plist = NULL, *pl;
720 MDatabaseHookFunc func
721 = (MDatabaseHookFunc) msymbol_get (tag0, M_database_hook);
724 func (tag0, tag1, tag2, tag3);
726 for (i = 0; i < mdb_list.used; i++)
728 MDatabase *mdb = mdb_list.mdbs + i;
730 if ((tag0 == Mnil || tag0 == mdb->tag[0])
731 && (tag1 == Mnil || tag1 == mdb->tag[1])
732 && (tag2 == Mnil || tag2 == mdb->tag[2])
733 && (tag3 == Mnil || tag3 == mdb->tag[3]))
736 plist = pl = mplist ();
737 pl = mplist_add (pl, Mt, mdb);
747 @brief Define a data of the m17n database.
749 The mdatabase_define () function defines a data that has tags
750 $TAG0 through $TAG3 and additional information $EXTRA_INFO.
752 $LOADER is a pointer to a function that loads the data from the
753 database. This function is called from the mdatabase_load ()
754 function with the two arguments $TAGS and $EXTRA_INFO. Here,
755 $TAGS is the array of $TAG0 through $TAG3.
757 If $LOADER is @c NULL, the default loader of the m17n library is
758 used. In this case, $EXTRA_INFO must be a string specifying a
759 filename that contains the data.
762 If the operation was successful, mdatabase_define () returns a
763 pointer to the defined data, which can be used as an argument to
764 mdatabase_load (). Otherwise, it returns @c NULL. */
767 @brief m17n ¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥Ç¡¼¥¿¤òÄêµÁ¤¹¤ë.
769 ´Ø¿ô mdatabase_define () ¤Ï $TAG0 ¤«¤é $TAG3 ¤Þ¤Ç¤Î¥¿¥°¤ª¤è¤ÓÉÕ²Ã
770 ¾ðÊó $EXTRA_INFO ¤ò»ý¤Ä¥Ç¡¼¥¿¤òÄêµÁ¤¹¤ë¡£
772 $LOADER ¤Ï¤½¤Î¥Ç¡¼¥¿¤Î¥í¡¼¥É¤ËÍѤ¤¤é¤ì¤ë´Ø¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç¤¢¤ë¡£¤³
773 ¤Î´Ø¿ô¤Ï mdatabase_load () ¤«¤é $TAGS ¤È $EXTRA_INFO ¤È¤¤¤¦2 ¤Ä¤Î
774 °ú¿ôÉÕ¤¤Ç¸Æ¤Ó½Ð¤µ¤ì¤ë¡£¤³¤³¤Ç $TAGS ¤Ï $TAG0 ¤«¤é $TAG3 ¤Þ¤Ç¤ÎÇÛ
777 ¤â¤· $LOADER ¤¬ @c NULL ¤Ê¤é¡¢m17n ¥é¥¤¥Ö¥é¥êɸ½à¤Î¥í¡¼¥À¤¬»È¤ï¤ì
778 ¤ë¡£¤³¤Î¾ì¹ç¤Ë¤Ï $EXTRA_INFO ¤Ï¥Ç¡¼¥¿¤ò´Þ¤à¥Õ¥¡¥¤¥ë̾¤Ç¤Ê¤¯¤Æ¤Ï¤Ê
782 ½èÍý¤ËÀ®¸ù¤¹¤ì¤Ð mdatabase_define () ¤ÏÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿¥Ù¡¼
783 ¥¹¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£¤³¤Î¥Ý¥¤¥ó¥¿¤Ï´Ø¿ô mdatabase_load () ¤Î°ú¿ô
784 ¤È¤·¤ÆÍѤ¤¤ë¤³¤È¤¬¤Ç¤¤ë¡£¤½¤¦¤Ç¤Ê¤±¤ì¤Ð @c NULL ¤òÊÖ¤¹¡£
786 @latexonly \IPAlabel{mdatabase_define} @endlatexonly */
790 mdatabase_load (), mdatabase_define () */
793 mdatabase_define (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3,
794 void *(*loader) (MSymbol *, void *),
798 MDatabaseHookFunc func
799 = (MDatabaseHookFunc) msymbol_get (tag0, M_database_hook);
802 func (tag0, tag1, tag2, tag3);
804 mdb = mdatabase_find (tag0, tag1, tag2, tag3);
809 template.tag[0] = tag0, template.tag[1] = tag1;
810 template.tag[2] = tag2, template.tag[3] = tag3;
811 template.extra_info = NULL;
812 MLIST_APPEND1 (&mdb_list, mdbs, template, MERROR_DB);
813 mdb = mdb_list.mdbs + (mdb_list.used - 1);
815 mdb->loader = loader ? loader : load_database;
816 if (mdb->loader == load_database)
819 free (mdb->extra_info);
820 mdb->extra_info = strdup ((char *) extra_info);
823 mdb->extra_info = extra_info;
824 return (&(mdb_list.mdbs[mdb_list.used - 1]));
829 @brief Load a data from the database.
831 The mdatabase_load () function loads a data specified in $MDB and
832 returns the contents. The type of contents depends on the type of
835 If the data is of the @e plist @e type, this function returns a
838 If the database is of the @e chartable @e type, it returns a
839 chartable. The default value of the chartable is set according to
840 the second tag of the data as below:
842 @li If the tag is #Msymbol, the default value is #Mnil.
843 @li If the tag is #Minteger, the default value is -1.
844 @li Otherwise, the default value is @c NULL.
846 If the data is of the @e charset @e type, it returns a plist of length 2
847 (keys are both #Mt). The value of the first element is an array
848 of integers that maps code points to the corresponding character
849 codes. The value of the second element is a chartable of integers
850 that does the reverse mapping. The charset must be defined in
855 @brief ¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤é¥Ç¡¼¥¿¤ò¥í¡¼¥É¤¹¤ë.
857 ´Ø¿ô mdatabase_load () ¤Ï $MDB ¤¬»Ø¤¹¥Ç¡¼¥¿¤ò¥í¡¼¥É¤·¡¢¤½¤Î
858 Ãæ¿È¤òÊÖ¤¹¡£ÊÖ¤µ¤ì¤ë¤â¤Î¤Ï¥Ç¡¼¥¿¤Î¥¿¥¤¥×¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë¡£
860 ¥Ç¡¼¥¿¤¬ @e plist¥¿¥¤¥× ¤Ê¤é¤Ð¡¢ @e plist ¤Ø¤Î¥Ý¥¤¥ó¥¿¤òÊÖ¤¹¡£
862 ¥Ç¡¼¥¿¤¬ @e chartable¥¿¥¤¥× ¤Ê¤é¤Ðʸ»ú¥Æ¡¼¥Ö¥ë¤òÊÖ¤¹¡£Ê¸»ú¥Æ¡¼¥Ö¥ë
863 ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤϡ¢¥Ç¡¼¥¿¤ÎÂè2¥¿¥°¤Ë¤è¤Ã¤Æ°Ê²¼¤Î¤è¤¦¤Ë·è¤Þ¤ë¡£
865 @li ¥¿¥°¤¬ #Msymbol ¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï #Mnil
866 @li ¥¿¥°¤¬ #Minteger ¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï -1
867 @li ¤½¤ì°Ê³°¤Ê¤é¡¢¥Ç¥Õ¥©¥ë¥ÈÃÍ¤Ï @c NULL
869 ¥Ç¡¼¥¿¤¬ @e charset¥¿¥¤¥× ¤Ê¤é¤ÐŤµ 2 ¤Î plist ¤òÊÖ¤¹¡Ê¥¡¼¤Ï¶¦¤Ë
870 #Mt ¡Ë¡£ºÇ½é¤ÎÍ×ÁǤÎÃͤϥ³¡¼¥É¥Ý¥¤¥ó¥È¤òÂбþ¤¹¤ëʸ»ú¥³¡¼¥É¤Ë¥Þ¥Ã¥×
871 ¤¹¤ëÀ°¿ô¤ÎÇÛÎó¤Ç¤¢¤ë¡££²ÈÖÌܤÎÍ×ÁǤÎÃͤϵդΥޥåפò¤¹¤ëʸ»ú¥Æ¡¼¥Ö
872 ¥ë¤Ç¤¢¤ë¡£¤³¤Îʸ»ú¥»¥Ã¥È¤Ïͽ¤áÄêµÁ¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
874 @latexonly \IPAlabel{mdatabase_load} @endlatexonly
879 mdatabase_load (), mdatabase_define () */
882 mdatabase_load (MDatabase *mdb)
884 int mdebug_mask = MDEBUG_DATABASE;
887 MDEBUG_PRINT1 (" [DATABASE] loading <%s>.\n",
888 gen_database_name (buf, mdb->tag));
889 return (*mdb->loader) (mdb->tag, mdb->extra_info);
894 @brief Get tags of a data.
896 The mdatabase_tag () function returns an array of tags (symbols)
897 that identify the data in $MDB. The length of the array is
901 @brief ¥Ç¡¼¥¿¤Î¥¿¥°¤òÆÀ¤ë.
903 ´Ø¿ô mdatabase_tag () ¤Ï¡¢¥Ç¡¼¥¿ $MDB ¤Î¥¿¥°¡Ê¥·¥ó¥Ü¥ë¡Ë¤ÎÇÛÎó¤òÊÖ
904 ¤¹¡£ÇÛÎó¤ÎŤµ¤Ï 4 ¤Ç¤¢¤ë¡£
906 @latexonly \IPAlabel{mdatabase_tag} @endlatexonly */
909 mdatabase_tag (MDatabase *mdb)