NOTE    2013/11/20

新機能等に関する補足


1. 拡張ライブラリの動的リンク

  組込み述語
  dlib_require/1
  dlib_require/2
  dlib_get_error_str/1
  dlib_get_load_map/1
  dlib_get_search_path/1
  dlib_set_search_path/1
  dlib_search_path_push/1
  dlib_search_path_pop/0

  初期状態での探索パスは要素一個だけで、
    ['/usr/lib/azprolog/ext']
  となっている。(AZProlog環境変数が設定されていないとき)

  AZProlog=/usr/localの場合には
    ['/usr/local/lib/azprolog/ext']
  となる。

  探索パスの中に拡張ライブラリ(*.so)が存在すれば探索対象になる。
  現在は、mecab.so, redis.so, websock.soの三個が入っている。

  探索パスは自由に変更できるが、絶対パスで指定していない場合の振る舞いは、
  dlopen(3)の仕様に依存する。
  探索パスの項目の優先順位は先頭からで、後からdlib_search_path_push/1した方が
  優先する。

  dlib_require/1で指定するライブラリにパスが含まれている場合には、
　それが絶対パスならそのまま解釈される。相対パスならプロセスの
  カレントディレクトリに対する相対パスと解釈される。
  パスが含まれていない場合にはファイル名(但し共有ライブラリとしての拡張子を除く)
  と解釈され、探索パスの中でチェックされる。

  例：  /home/abc/ext/xyz.soをリンクする場合

  ?- dlib_search_path_push('/home/abc/ext').
  ?- dlib_require(xyz).

  (* 単にdlib_require('/home/abc/ext/xyz')でもよいが。)


  一度dlib_require/1が成功すると、dlib_require/1を同じ名前で何度呼び出しても
  何もしない(成功する)。
  これはパスで指定した場合も名前部分だけで同じかどうか判断する。
  従って、一度dlib_requireが成功すると、パス部分だけが違う指定をしても必ず成功する。

  ?- dlib_require('mecab').           % => 成功
  ?- dlib_require('/foo/bar/mecab').  % => 存在しなくても成功

  成功したdlib_require/1によって登録されるファイル名と実際のパスの関係についての情報は、
  dlib_get_load_map/1を使用して参照できる。

  ?- dlib_get_load_map(X).

    X  = [mecab.so ==> /usr/local/lib/azprolog/ext/mecab.so, redis.so ==> 
          /usr/local/lib/azprolog/ext/redis.so]

  リストの各要素は、"ファイル名 ==> 絶対パス" という形式のアトムである。


  dlib_require/2は、dlib_require/1と同じ機能であるが、呼び出される初期化関数の
  名前を指定したものに変更する、もしくは初期化関数を呼び出さないようにするための
  ものである。
  第二引数に初期化関数名をアトムで与えれば、それを呼び出す。
  文字列長0のアトムを与えれば、何も呼び出さない。
  dlib_require/1で呼び出される初期化関数の名前は、"initiate_" + ライブラリ名
  である。

   例: ?- dlib_require('mecab', '').

  dlib_get_error_str/1は、dlib_requireが失敗したときに、失敗原因を文字列で返す。
  dlib_require以外の述語の失敗については値を取得できない。



2. 追加API

  アトムの最大文字列バイトサイズ

    #define AZ_MAX_ATOM_LENGTH    ....

  アトム(BASEINT)の文字列バイトサイズを返す

    int az_get_atom_length(BASEINT number);

  アトム項の文字列バイトサイズを返す

    int az_get_atom_term_length(Frame* Env, TERM* t);

  リストの長さを返す(リストでないときには-1を返す)

    int az_list_len(TERM* t);

  C文字列をリストにする(戻り値 0:成功, -1:エラー)

    int az_cstring_to_list(Frame* Env, const char *s, int len, TERM* t);

  項(アトム/リスト)の内容をC文字列にしたときのバイト数を返す

    int az_term_to_cstring_length(Frame* Env, TERM* t);

  項(アトム/リスト)の内容をC文字列にする
    終端の'\0'も含めてbufに入る
    (正常終了のときにはバイト数が返る, bufsizeに入らないときには-1が返る)

    int az_term_to_cstring(Frame* Env, TERM* t, char *buf, int bufsize);

  現在の文字エンコーディングを返す

    int az_charsetmode(void);

  AZ-Prologをインストールしたベースのディレクトリを取得する

    int az_get_install_base_dir(char* buf, int buf_size);

  パス文字列を正規化(Windowsの'\'を'/'に変換)する

    int az_normalize_path(char* path, int len);

  OSに依存したディレクトリ区切り文字を末尾に追加する

    char* az_add_os_depend_dir_sep(char* path, int len);



3. Prologライブラリを共有ライブラリではなく静的ライブラリでリンクする方法

  -lazpを -Bstatic -Bdynamicで囲む

  例)
	gcc -o azredis userfile.o /usr/local/lib/azprolog/obj/curses.o /usr/local/lib/azprolog/obj/azpi.o azredis.o putil.o -lhiredis -Wl,-Bstatic -lazp -Wl,-Bdynamic -lcurses -lm



4. 拡張ライブラリ 初期化関数の戻り値 (仕様の明確化)

  戻り値の型はint型で、値は以下の意味とする。
  (但し、現在は戻り値を参照してはいない)

  戻り値
  1: 正常終了
  0: エラー

  例:

    extern int initiate_mecab(void)
    {
      .......

      return 1;
    }


//END
