Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
テーブルを表示する関数 print_table_data() の中で、 以下の部分がどうも、レコードの1カラム分を処理しているところらしい。
2209 uint currlength= (uint) lengths[off]; 2210 uint numcells= charset_info->cset->numcells(charset_info, 2211 str, str + currlength); 2212 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", 2213 maxlength + currlength - numcells, str);
この中の 2210行にある変数が numcells という名前が付いているし、 次の tee_fprintf の中の "%*s" の中の * に対応する式、 つまり表示幅を指定する式
maxlength + currlength - numcells
の中で 引かれているのが何とも怪しい。
どうも、文字幅をちゃんと調整しようと努力しているような気がする。
charset_info->cset->numcell を追いかけてみよう
2210行で関数を呼び出しているのだが、ちょっとややこしい書き方になっている。
charset_infoが指す構造体の要素csetが構造体へのポインタで、 その指す構造体中のnumcellsというのが関数へのポインタになっている訳だ。 文章で書くと面倒になってしまうので、 -> の使い方に慣れてしまうのが一番だ。
まず、最初の charset_info は何かと言うと、
178 static CHARSET_INFO *charset_info= &my_charset_latin1;
となっていて、キャラクタセット情報を保持する変数らしい。 CHARSET_INFOという型があるらしいが、 mysql.ccでは定義していないので、 どこかにあるらしい。
こういうのは、どこかにincludeファイル(.h)としてまとめられているはずである。
ということで探したら、
mysql-5.0.7-beta/include mysqlの共通includeファイル(.h)
というディレクトリにちゃんとまとめられていた。
MySQLのキャラクタセットは、以下の構造体で管理されているようだ。
include/m_ctype.h
206 typedef struct charset_info_st
207 {
208 uint number;
209 uint primary_number;
210 uint binary_number;
211 uint state;
212 const char *csname;
213 const char *name;
214 const char *comment;
215 const char *tailoring;
216 uchar *ctype;
217 uchar *to_lower;
218 uchar *to_upper;
219 uchar *sort_order;
220 uint16 *contractions;
221 uint16 **sort_order_big;
222 uint16 *tab_to_uni;
223 MY_UNI_IDX *tab_from_uni;
224 MY_UNICASE_INFO **caseinfo;
225 uchar *state_map;
226 uchar *ident_map;
227 uint strxfrm_multiply;
228 uchar caseup_multiply;
229 uchar casedn_multiply;
230 uint mbminlen;
231 uint mbmaxlen;
232 uint16 min_sort_char;
233 uint16 max_sort_char; /* For LIKE optimization */
234
235 MY_CHARSET_HANDLER *cset;
236 MY_COLLATION_HANDLER *coll;
237
238 } CHARSET_INFO;
charset_info->cset の cset は
235 MY_CHARSET_HANDLER *cset;
となっていて、次は MY_CHARSET_HANDLER を探さねばならない。
147 typedef struct my_charset_handler_st
148 {
149 my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
150 /* Multibyte routines */
151 int (*ismbchar)(struct charset_info_st *, const char *, const char *);
152 int (*mbcharlen)(struct charset_info_st *, uint);
153 uint (*numchars)(struct charset_info_st *, const char *b, const char *e);
154 uint (*charpos)(struct charset_info_st *, const char *b, const char *e, uint pos);
155 uint (*well_formed_len)(struct charset_info_st *,
156 const char *b,const char *e,
157 uint nchars, int *error);
158 uint (*lengthsp)(struct charset_info_st *, const char *ptr, uint length);
159 uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
160
‥‥‥‥中略‥‥‥‥
200 } MY_CHARSET_HANDLER;
さすがハンドラーというだけあって、関数へのポインタがずらっと並んでいる。 キャラクタセットにより、様々な処理を行なう実際のハンドラーは、 各キャラクタセットに依存した処理を行なうだろうが、 このハンドラを使っている限り、 キャラクタセットに依存しないプログラムを作れるようだ。
いま調べているハンドラは、以下である。
159 uint (*numcells)(struct charset_info_st *, const char *b, const char *e);
しかし、実際にはどんな関数へのポインタになっているのかを探さねばならないのだ。 だいぶ追いかけてきたので、ここで一休みしよう。
次へ:文字幅を求める関数my_numcells_eucjp()
フィードバック:
There is no comment.