/* character.c -- character module. Copyright (C) 2003, 2004 National Institute of Advanced Industrial Science and Technology (AIST) Registration Number H15PRO112 This file is part of the m17n library. The m17n library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The m17n library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the m17n library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 02111-1307, USA. */ /***en @addtogroup m17nCharacter @brief Character objects and API for them. The m17n library represents a @e character by a character code (an integer). The minimum character code is @c 0. The maximum character code is defined by the macro #MCHAR_MAX. It is assured that #MCHAR_MAX is not smaller than @c 0x3FFFFF (22 bits). Characters @c 0 to @c 0x10FFFF are equivalent to the Unicode characters of the same code values. A character can have zero or more properties called @e character @e properties. A character property consists of a @e key and a @e value, where key is a symbol and value is anything that can be cast to (void *). "The character property that belongs to character C and whose key is K" may be shortened to "the K property of C". */ /***ja @addtogroup m17nCharacter @brief 文字オブジェクトとそれに関する API. m17n ライブラリは @e 文字 を文字コード(整数)で表現する。 最小の文字コードは @c 0 であり、最大の文字コードはマクロ #MCHAR_MAX によって定義されている。#MCHAR_MAX は @c 0x3FFFFF(22ビット) 以上であることが保証されている。 @c 0 から @c 0x10FFFF までの文字は、それと同じ値を持つ Unicode の文字に割り当てられている。 各文字は @e 文字プロパティ と呼ぶプロパティを 0 個以上持つことができる。 文字プロパティは @e キー と @e 値 からなる。 キーはシンボルであり、値は (void *) 型にキャストできるものなら何でもよい。 「文字 C の文字プロパティのうちキーが K であるもの」を簡単に「文字 C の K プロパティ」と呼ぶことがある。 */ /*=*/ #if !defined (FOR_DOXYGEN) || defined (DOXYGEN_INTERNAL_MODULE) /*** @addtogroup m17nInternal @{ */ #include #include #include #include #include #include #include "m17n-core.h" #include "m17n-misc.h" #include "internal.h" typedef struct { MSymbol type; void *mdb; MCharTable *table; } MCharPropRecord; static MPlist *char_prop_list; static void free_string (int from, int to, void *str, void *arg) { free (str); } /* Internal API */ int mchar__init () { Mname = msymbol ("name"); Mcategory = msymbol ("category"); Mcombining_class = msymbol ("combining-class"); Mbidi_category = msymbol ("bidirectional-category"); Msimple_case_folding = msymbol ("simple-case-folding"); Mcomplicated_case_folding = msymbol ("complicated-case-folding"); Mscript = msymbol ("script"); return 0; } void mchar__fini (void) { MPlist *p; if (char_prop_list) { for (p = char_prop_list; mplist_key (p) != Mnil; p = mplist_next (p)) { MCharPropRecord *record = mplist_value (p); if (record->table) { if (record->type == Mstring) mchartable_map (record->table, NULL, free_string, NULL); M17N_OBJECT_UNREF (record->table); } free (record); } M17N_OBJECT_UNREF (char_prop_list); } } void mchar__define_prop (MSymbol key, MSymbol type, void *mdb) { MCharPropRecord *record; if (char_prop_list) record = mplist_get (char_prop_list, key); else char_prop_list = mplist (), record = NULL; if (record) { if (record->table) M17N_OBJECT_UNREF (record->table); } else { MSTRUCT_CALLOC (record, MERROR_CHAR); mplist_put (char_prop_list, key, record); } record->type = type; record->mdb = mdb; if (mdb) { record->table = NULL; } else { void *default_value = NULL; if (type == Minteger) default_value = (void *) -1; record->table = mchartable (type, default_value); } } /*** @} */ #endif /* !FOR_DOXYGEN || DOXYGEN_INTERNAL_MODULE */ /* External API */ /*** @addtogroup m17nCharacter @{ */ /*=*/ #ifdef FOR_DOXYGEN /***en @brief Maximum character code. The macro #MCHAR_MAX gives the maximum character code. */ /***ja @brief 文字コードの最大値. マクロ #MCHAR_MAX は文字コードの最大値を表す。 */ #define MCHAR_MAX /*=*/ #endif /* FOR_DOXYGEN */ /***en @name Variables: Keys of character properties These symbols are used as keys of character properties. */ /***ja @ingroup m17nCharacter @name 変数: 文字プロパティのキー これらのシンボルは文字プロパティのキーとして使われる。*/ /*** @{ */ /***en @brief Key for script. The symbol #Mscript has the name "script" and is used as the key of a character property. The value of such a property is a symbol representing the script to which the character belongs. Each symbol that represents a script has one of the names listed in the Unicode Technical Report #24. */ /***ja @brief スクリプトを表わすキー. シンボル #Mscript は "script" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、この文字の属するスクリプトを表わすシンボルである。 スクリプトを表わすシンボルの名前は、Unicode Technical Report #24 にリストされているもののいずれかである。 */ MSymbol Mscript; /*=*/ /***en @brief Key for character name. The symbol #Mname has the name "name" and is used as the key of a character property. The value of such a property is a C-string representing the name of the character. */ /***ja @brief 名前を表わすキー. シンボル #Mname は "name" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値はその文字の名前を表わす C の文字列である。 */ MSymbol Mname; /*=*/ /***en @brief Key for general category. The symbol #Mcategory has the name "category" and is used as the key of a character property. The value of such a property is a symbol representing the general category of the character. Each symbol that represents a general category has one of the names listed as abbreviations for General Category in Unicode. */ /***ja @brief 一般カテゴリを表わすキー. シンボル #Mcategory は "category" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、対応する 一般カテゴリ を表わすシンボルである。 一般カテゴリを表わすシンボルの名前は、General Category の省略形として Unicode に定義されているものである。 */ MSymbol Mcategory; /*=*/ /***en @brief Key for canonical combining class. The symbol #Mcombining_class has the name "combining-class" and is used as the key of a character property. The value of such a property is an integer that represents the canonical combining class of the character. The meaning of each integer that represents a canonical combining class is identical to the one defined in Unicode. */ /***ja @brief 標準結合クラスを表わすキー. シンボル #Mcombining_class は "combining-class" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、対応する @e 標準結合クラス を表わす整数である。 標準結合クラスを表わす整数の意味は、Unicode に定義されているものと同じである。 */ MSymbol Mcombining_class; /*=*/ /***en @brief Key for bidi category. The symbol #Mbidi_category has the name "bidi-category" and is used as the key of a character property. The value of such a property is a symbol that represents the bidirectional category of the character. Each symbol that represents a bidirectional category has one of the names listed as types of Bidirectional Category in Unicode. */ /***ja @brief 双方向カテゴリを表わすキー. シンボル #Mbidi_category は "bidi-category" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、対応する @e 双方向カテゴリ を表わすシンボルである。 双方向カテゴリを表わすシンボルの名前は、Bidirectional Category の型として Unicode に定義されているものである。 */ MSymbol Mbidi_category; /*=*/ /***en @brief Key for corresponding single lowercase character. The symbol #Msimple_case_folding has the name "simple-case-folding" and is used as the key of a character property. The value of such a property is the corresponding single lowercase character that is used when comparing M-texts ignoring cases. If a character requires a complicated comparison (i.e. cannot be compared by simply mapping to another single character), the value of such a property is @c 0xFFFF. In this case, the character has another property whose key is #Mcomplicated_case_folding. */ /***ja @brief 対応する小文字一文字を表わすキー. シンボル #Msimple_case_folding は "simple-case-folding" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、対応する小文字一文字であり、大文字/小文字の区別を無視した文字列比較の際に使われる。 複雑な比較方法を必要とする文字であった場合 (別の一文字と対応付けることによって比較できない場合)、このプロパティの値は @c 0xFFFF になる。この場合その文字は、#Mcomplicated_case_folding というキーの文字プロパティを持つ。 */ MSymbol Msimple_case_folding; /***en @brief Key for corresponding multiple lowercase characters. The symbol #Mcomplicated_case_folding has the name "complicated-case-folding" and is used as the key of a character property. The value of such a property is the corresponding M-text that contains a sequence of lowercase characters to be used for comparing M-texts ignoring case. */ /***ja @brief 対応する小文字の列を表わすキー. シンボル #Mcomplicated_case_folding は "complicated-case-folding" という名前を持ち、文字プロパティのキーとして使われる。 このプロパティの値は、対応する小文字列からなる M-text であり、大文字/小文字の区別を無視した文字列比較の際に使 われる。 */ MSymbol Mcomplicated_case_folding; /*=*/ /*** @} */ /*=*/ /***en @brief Define a character property. The mchar_define_property () function searches the m17n database for a data whose tags are \<#Mchar_table, $TYPE, $SYM \>. Here, $SYM is a symbol whose name is $NAME. $TYPE must be #Mstring, #Mtext, #Msymbol, #Minteger, or #Mplist. @return If the operation was successful, mchar_define_property () returns $SYM. Otherwise it returns #Mnil. */ /***ja @brief 文字プロパティを定義する. 関数 mchar_define_property () は、 \<#Mchar_table, $TYPE, $SYM \> というタグを持ったデータベースを m17n 言語情報ベースから探す。 ここで $SYM は $NAME という名前のシンボルである。$TYPE は#Mstring, #Mtext, #Msymbol, #Minteger, #Mplist のいずれかでなければならない。 @return 処理に成功すれば mchar_define_property () は$SYM を返す。 失敗した場合は #Mnil を返す。 */ /*** @errors @c MERROR_DB @seealso mchar_get_prop (), mchar_put_prop () */ MSymbol mchar_define_property (const char *name, MSymbol type) { MSymbol key = msymbol (name); void *mdb; if (mdatabase__finder) mdb = (*mdatabase__finder) (Mchar_table, type, key, Mnil); else mdb = NULL; mchar__define_prop (key, type, mdb); return key; } /*=*/ /***en @brief Get the value of a character property. The mchar_get_prop () function searches character $C for the character property whose key is $KEY. @return If the operation was successful, mchar_get_prop () returns the value of the character property. Otherwise it returns @c NULL. */ /***ja @brief 文字プロパティの値を得る. 関数 mchar_get_prop () は、文字 $C の文字プロパティのうちキーが $KEY であるものを探す。 @return 処理が成功すれば mchar_get_prop () は見つかったプロパティの値を返す。 失敗した場合は @c NULL を返す。 @latexonly \IPAlabel{mchar_get_prop} @endlatexonly */ /*** @errors @c MERROR_SYMBOL, @c MERROR_DB @seealso mchar_define_property (), mchar_put_prop () */ void * mchar_get_prop (int c, MSymbol key) { MCharPropRecord *record; if (! char_prop_list) return NULL; record = mplist_get (char_prop_list, key); if (! record) return NULL; if (record->mdb) { record->table = (*mdatabase__loader) (record->mdb); if (! record->table) MERROR (MERROR_DB, NULL); record->mdb = NULL; } return mchartable_lookup (record->table, c); } /*=*/ /***en @brief Set the value of a character property. The mchar_put_prop () function searches character $C for the character property whose key is $KEY and assigns $VAL to the value of the found property. @return If the operation was successful, mchar_put_prop () returns 0. Otherwise, it returns -1. */ /***ja @brief 文字プロパティの値を設定する. 関数 mchar_put_prop () は、文字 $C の文字プロパティのうちキーが $KEY であるものを探し、その値として $VAL を設定する。 @return 処理が成功すれば mchar_put_prop () は0を返す。失敗した場合は-1を返す。 */ /*** @errors @c MERROR_SYMBOL, @c MERROR_DB @seealso mchar_define_property (), mchar_get_prop () */ int mchar_put_prop (int c, MSymbol key, void *val) { MCharPropRecord *record; if (! char_prop_list) MERROR (MERROR_CHAR, -1); record = mplist_get (char_prop_list, key); if (! record) return -1; if (record->mdb) { record->table = (*mdatabase__loader) (record->mdb); if (! record->table) MERROR (MERROR_DB, -1); record->mdb = NULL; } return mchartable_set (record->table, c, val); } /*=*/ /***en @brief Get the char-table for a character property. The mchar_get_prop_table () function returns a char-table that contains the character property whose key is $KEY. If $TYPE is not NULL, this function stores the type of the property in the place pointed by $TYPE. See mchar_define_property () for types of character property. @return If $KEY is a valid character property key, this function returns a char-table. Otherwise NULL is retuned. */ /***ja @brief 文字プロパティの文字テーブルを得る. 関数 mchar_get_prop_table () は、キーが $KEY である文字プロパティ を含む文字テーブルを返す。もし $TYPE が NULL でなければ、 $TYPE で 指される場所にその文字のプロパティを格納する。文字プロパティの種類 に関しては mchar_define_property () を見よ。 @return もし $KEY が正当な文字プロパティのキーであれば、文字テーブルが返さ れる。そうでない場合は NULL が返される。 */ MCharTable * mchar_get_prop_table (MSymbol key, MSymbol *type) { MCharPropRecord *record; if (! char_prop_list) return NULL; record = mplist_get (char_prop_list, key); if (! record) return NULL; if (record->mdb) { record->table = (*mdatabase__loader) (record->mdb); if (! record->table) MERROR (MERROR_DB, NULL); record->mdb = NULL; } if (type) *type = record->type; return record->table; } /*** @} */ /* Local Variables: coding: euc-japan End: */