Open Source WEB

テーブルを表示する関数 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);

しかし、実際にはどんな関数へのポインタになっているのかを探さねばならないのだ。 だいぶ追いかけてきたので、ここで一休みしよう。


戻る:mysql.ccのテーブル表示部分を読んでみよう

次へ:文字幅を求める関数my_numcells_eucjp()


フィードバック:

Name:
Comment:

There is no comment.

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us