Go to the first, previous, next, last section, table of contents.

## ライブラリインタフェース

Asir の提供する機能を他のプログラムから使用する方法として, OpenXM による 他に, ライブラリの直接リンクによる方法が可能である. ライブラリは, GC ライブラリである ``libasir-gc.a'` とともに OpenXM distribution (`http://www.math.kobe-u.ac.jp/OpenXM`) に含まれる. 現状ではOpenXM インタフェースのみが公開されているため, 以下では OpenXM がインストールされていると仮定する. OpenXM root ディレクトリを `$OpenXM_HOME`と書く. ライブラリファイルは全て ``$OpenXM_HOME/lib'` におかれている. ライブラリには以下の 3 種類がある.

- ``libasir.a'`
  PARI, X11 関連の機能を含まない. リンクには ``libasir-gc.a'` のみが必要.
- ``libasir_pari.a'`
  X11 関連の機能を含まない. リンクには ``libasir-gc.a'`, ``libpari.a'` が必要.
- ``libasir_pari_X.a'`
  全ての機能を含む. リンクには ``libasir-gc.a'`, ``libpari.a'` および X11 関連のライブラリ指定が必要.

提供されている関数は以下の通りである.

- `int asir_ox_init(int byteorder)`
  ライブラリの初期化. byteorder はメモリ上へのバイナリ CMO データ への展開方法を指定する. byteorder が 0 のときマシン固有の byteorder を用いる. 1 のとき network byteorder を用いる. 初期化に成功した場合 0, 失敗の時 -1 を返す.
- `void asir_ox_push_cmo(void *cmo)`
  メモリ上に置かれた CMO データを Asir の内部形式に変換してスタックに push する. It converts CMO data pointed by cmo into an Asir object and it pushes the object onto the stack.
- `int asir_ox_peek_cmo_size()`
  スタックの最上位にある Asir データを CMO に変換したときのサイズを返す. 変換不能な場合には -1 を返す.
- `int asir_ox_pop_cmo(void *cmo, int limit)`
  スタックの最上位にある Asir データを pop し, CMO に変換して cmoで 指される配列に書き, CMO のサイズを返す. このとき, CMO のサイズが limit より大きい場合には -1 を返す. cmo は長さが少なくとも limitバイトの配列を指す必要がある. 変換された CMO を収容できる 配列の長さを知るために, `asir_ox_peek_cmo_size` を用いる.
- `void asir_ox_push_cmd(int cmd)`
  スタックマシンコマンド cmd を実行する.
- `void asir_ox_execute_string(char *str)`
  Asir が実行可能な文字列 str を実行し, その結果をスタックに push する.

include すべき header file は ``$OpenXM_HOME/include/asir/ox.h'` である. この header file には, OpenXM に関する全ての tag, command の定義が含まれて いる. 次の例 (``$OpenXM_HOME/doc/oxlib/test3.c'`) は上記関数の使用 法を示す.

    #include <asir/ox.h>
    #include <signal.h>

    main(int argc, char **argv)
    {
      char buf[BUFSIZ+1];
      int c;
      unsigned char sendbuf[BUFSIZ+10];
      unsigned char *result;
      unsigned char h[3];
      int len,i,j;
      static int result_len = 0;
      char *kwd,*bdy;
      unsigned int cmd;

      signal(SIGINT,SIG_IGN);
      asir_ox_init(1); /* 1: network byte order; 0: native byte order */
      result_len = BUFSIZ;
      result = (void *)malloc(BUFSIZ);
      while ( 1 ) {
        printf("Input>"); fflush(stdout);
        fgets(buf,BUFSIZ,stdin);
        for ( i = 0; buf[i] && isspace(buf[i]); i++ );
        if ( !buf[i] )
          continue;
        kwd = buf+i;
        for ( ; buf[i] && !isspace(buf[i]); i++ );
        buf[i] = 0;
        bdy = buf+i+1;
        if ( !strcmp(kwd,"asir") ) {
          sprintf(sendbuf,"%s;",bdy);
          asir_ox_execute_string(sendbuf);
        } else if ( !strcmp(kwd,"push") ) {
          h[0] = 0;
          h[2] = 0;
          j = 0;
          while ( 1 ) {
            for ( ; (c= *bdy) && isspace(c); bdy++ );
            if ( !c )
              break;
            else if ( h[0] ) {
              h[1] = c;
              sendbuf[j++] = strtoul(h,0,16);
              h[0] = 0;
            } else
              h[0] = c;
            bdy++;
          }
          if ( h[0] )
            fprintf(stderr,"Number of characters is odd.\n");
          else {
            sendbuf[j] = 0;
            asir_ox_push_cmo(sendbuf);
          }
        } else if ( !strcmp(kwd,"cmd") ) {
          cmd = atoi(bdy);
          asir_ox_push_cmd(cmd);
        } else if ( !strcmp(kwd,"pop") ) {
          len = asir_ox_peek_cmo_size();
          if ( !len )
            continue;
          if ( len > result_len ) {
            result = (char *)realloc(result,len);
            result_len = len;
          }
          asir_ox_pop_cmo(result,len);
          printf("Output>"); fflush(stdout);
          printf("\n");
          for ( i = 0; i < len; ) {
            printf("%02x ",result[i]);
            i++;
            if ( !(i%16) )
              printf("\n");
          }
          printf("\n");
        }
      }
    }

このプログラムは, keyword body なる 1 行を入力として受け取り keyword に応じて次のような動作を行う.

- `asir` body
  body を Asir 言語で書かれた式とみなし, 実行結果をスタックに push する. `asir_ox_execute_string()` が用いられる.
- `push` body
  body を 16 進数で表示された CMO データとみなし, Asir オブジェクトに変換 してスタックに push する. `asir_ox_push_cmo()` が用いられる.
- `pop`
  スタック最上位のオブジェクトを CMO に変換し, 16 進数で表示する. `asir_ox_peek_cmo_size()` および `asir_ox_pop_cmo()` が用いられる.
- `cmd` body
  body を SM コマンドとみなし, 実行する. `asir_ox_push_cmd()` が用いられる.

Go to the first, previous, next, last section, table of contents.