2009/11/25

Recent entries from same category

  1. Go 言語プログラミングエッセンスという本を書きました。
  2. errors.Join が入った。
  3. unsafe.StringData、unsafe.String、unsafe.SliceData が入った。
  4. Re: Go言語で画像ファイルか確認してみる
  5. net/url に JoinPath が入った。

そろそろgoでライブラリを作る頃かなーと思って、migemo(cmigemo)を使う物を書いてみた。
mattn's go-migemo at master - GitHub

migemo extension for go

コードの中ではKoRoNさんのcmigemoを使った。コードは少ないけど実は少しハマって、今日はそれを書き記したい。

migemoでは、正規表現文字列やパターン文字列をunsigned char*で引数として扱っているんですが、cgoを使ったC言語ライブラリの取り込みを行う場合、char*と型が合わなくてコンパイルエラーが発生する。しかしC言語の様に *C.uchar(p)
等と書けない(これだとucharの参照になってしまう)Go君は、致し方なくchar*を引数に持つwrapper関数を用意するしかないんだけど、実はcgoに食わせるgoファイルでは
package migemo

/*
#include <migemo.h>
static char* _migemo_query(migemo* object, const char* query) {
  return (char*)migemo_query(object, (const unsigned char*)query);
}
static void _migemo_release(migemo* object, const char* str) {
  migemo_release(object, (unsigned char*)str);
}
*/
import "C";
と言った様に、Cのコードが書ける。ここにGoで扱い易い型のwrapperを書けば良い。今回の例だとunsigned char*の引数を持つ関数をchar*で渡せる(C.CString)関数を用意している事になる。

これにより、いちいち別ファイルにwrapper関数用意したりMakefileにwrapperをビルドする為のターゲットを書かなくても良い。

これは便利だ。

話戻してmigemo拡張ですが、現状Open/Close/Load/Queryの4メソッドを持っています。
Queryで渡したパターンによるマッチし得る複数の正規表現が得られます。
package main

import (
  "fmt";
  "regexp";
  "strings";
  "migemo";
)

func main() {
    var pattern = "goGengo";
    var match = "go言語";
    m := migemo.Open("../dict/utf-8.d/migemo-dict");
    s := migemo.Query(m, pattern);
    if (regexp.MustCompile(s).Match(strings.Bytes(match))) {
        fmt.Printf("%s は %s にマッチします!\n", pattern, match);
    } else {
        fmt.Printf("%s は %s にマッチしません!\n", pattern, match);
    }
}
実行すると goGengo は go言語 にマッチします!
と出力されます。
地味に使えるかも。

Posted at by | Edit