# Author: 小原功任 @ 金沢大学理学部計算科学教室 # URI: http://omega.s.kanazawa-u.ac.jp/ohara/ # $OpenXM: OpenXM/src/ox_toolkit/README,v 1.15 2000/11/21 07:59:08 ohara Exp $ /*&ja ox_toolkit ユーザガイド */ /*&en A user's guide for OpenXM C library. */ /* &ja いきさつ このライブラリは ox_math および math2ox を開発するために設計された。 ライブラリ自身には、 Mathematica に依存した部分はない。 */ /* &en Introduction */ /*&ja libox.a を利用するには次のヘッダファイルをインクルードする必要があります。 */ /*&en How to use OpenXM C library? In order to use libox.a, you need to include the following header files: */ /*&common #include */ /*&ja 1. データ型 このツールキットで定義されている各構造体の生成については次節を参照せよ。 1.1 CMO (Common Math Object) 次のデータ型(構造体)が用意されている。 */ /*&en 1. Types 1.1 CMO (Common Math Object) The following structures are defined in ox_toolkit.h: */ /*&common cmo cmo_null cmo_int32 cmo_datum cmo_string cmo_mathcap cmo_list cmo_monomial32 cmo_zz cmo_qq cmo_zero cmo_dms_generic cmo_ring_by_name cmo_distributed_polynomial cmo_indeterminate cmo_error2 */ /*&ja このうち cmo 型はいわば抽象基底クラスに相当するものであり、この型のオ ブジェクトを明示的には生成されない。このクラスはポインタ型のキャストの ために用意されている。また cmo_distributed_polynomial は cmo_list の派 生クラスであると思ってもよい。 */ /*&en The cmo above is abstract base class; you never make an object of cmo class. */ /*&ja 1.2 OX オブジェクト 次のデータ型(構造体)が用意されている。 */ /*&en 1.2 OX objects The following structures are defined in ox_toolkit.h: */ /*&common ox ox_command ox_data */ /*&ja このうち、ox 型は抽象基底クラスなので、オブジェクトをつくってはいけない。 */ /*&en The ox above is abstract base class. */ /*&ja 2. オブジェクトの生成 オブジェクトを生成するために、new 関数群が用意されている。それぞれの関 数はオブジェクトを生成して、そのオブジェクトへのポインタを返す。 */ /*&en 2. How to make CMObjects? Use the following functions to generate an object. It returns a pointer to the object. */ /*&common new_cmo_null(); new_cmo_int32(int i); new_cmo_string(char* s); new_cmo_mathcap(cmo* ob); new_cmo_list(); new_cmo_monomial32(); new_cmo_monomial32_size(int size); new_cmo_zz(); new_cmo_zz_size(int size); new_cmo_zz_set_si(int integer); new_cmo_zz_noinit(); new_cmo_zero(); new_cmo_distributed_polynomial(); new_cmo_dms_generic(); new_cmo_ring_by_name(cmo* ob); new_cmo_indeterminate(cmo* ob); new_cmo_error2(cmo* ob); */ /*&ja 3. コネクション OXFILE は OpenXM での通信路を表現するクラスである。このクラスのオブジェ クトを明示的には生成しないこと。必ずコンストラクタを利用しなければなら ない。これはクライアントとサーバで接続時の手順が異なることに由来する。 バイトオーダに関連した処理はこのクラスのメソッドで実現される。このクラ スのメソッドとして次のものが用意されている。 3.1 コンストラクタ OXFILE *oxf_connect_active(char *hostname, short port); 能動的に接続する場合のコンストラクタ。通常、サーバで利用する。 OXFILE *oxf_connect_passive(int listened); 受動的に接続するためのコンストラクタ。 内部で accept() を呼ぶので、listened には mysocketListen() の返した値が必要。 OXFILE *oxf_open(int fd); インスタンスを生成するだけで、接続は行わない。すでにオープンされたファ イルディスクリプタを fd に指定する。計算サーバでの利用を想定。 3.2 認証に関連したメソッド int oxf_confirm_client(OXFILE *oxfp, char *passwd); クライアント側での認証を行う。返り値が1のときに成功、0のときに失敗。 int oxf_confirm_server(OXFILE *oxfp, char *passwd); サーバ側での認証を行う。常に成功する。 void oxf_determine_byteorder_client(OXFILE *oxfp); void oxf_determine_byteorder_server(OXFILE *oxfp); oxfp の指す通信路でのバイトオーダを決定し、oxfp のインスタンスを書き換える。 void oxf_setopt(OXFILE *oxfp, int mode); oxfp の設定を行う。oxf_determine_byteorder_XXX() で用いられている。 3.3 その他のメソッド int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp); int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp); void oxf_flush(OXFILE *oxfp); void oxf_close(OXFILE *oxfp); fread, fwrite, fflush, fclose に準拠。 */ /*&ja 4. 高水準 API(この記述は古いので使わないこと) 高水準 API は「OpenXM クライアント」から利用することを前提に設計されている。 4.1 通信の開始 通信を開始する場合には、次の関数のいずれかを利用する。 */ /*&en 4. High-level API High-level API is prepared to help an implementation of OpenXM clients. 4.1 How to make connections to OpenXM servers? In order to open a connection to an OpenXM server, you need to call ox_start() or to call ox_start_insecure_nonreverse(). */ /*&common OXFILE *ox_start(char* host, char* prog1, char* prog2); OXFILE *ox_start_insecure_nonreverse(char* host, short portControl, short portStream); */ /*&ja 第一の関数は、ローカルマシン上に OpenXM サーバを起動し、そのサーバとの 間に"reverse モード"で通信路を開設する。通信に使われるポート番号は自動 的に生成される。host はローカルマシンのホスト名(あるいは "localhost")、 prog1 はコントロールサーバの実行ファイル名、 prog2 は計算サーバの実行ファイル名でなければならない。 第二の関数は、リモートマシン上に既に起動されている OpenXM サーバとの間に 通信路を開設する。通信に使われるポート番号は明示的に与えなければならない。 host はリモートマシンのホスト名、 portControl はコントロールサーバとの通信のためのポート番号、 portStream は計算サーバとの通信のためのポート番号である。 それぞれの関数はサーバ(正確には二つのサーバの組)の識別子を返す。 この識別子は高水準 API の各関数で利用される。 */ /*&en The ox_start() function invoke an OpenXM server on its local machine and open a connection to the server with "reverse" mode. The client choose a port number of TCP/IP automatically. The ox_start_insecure_nonreverse() function open a connection to an OpenXM server run on a remote host and you need to provide port numbers. */ /*&ja 4.2 通信の終了 通信の終了のためには次の二つの関数が用意されている。 */ /*&en 4.2 How to close connections to OpenXM servers? In order to close a connection to an OpenXM server, you need to call ox_close() or to call ox_shutdown(). */ /*&common void ox_close(OXFILE *sv); void ox_shutdown(OXFILE *sv); */ /*&ja 第一の関数はコントロールサーバに SM_control_kill を送ることによって、 サーバを終了させる。第二の関数は計算サーバに SM_shutdown を送ることに よって、サーバを終了させる(予定)。 */ /*&ja 4.3 SM コマンドの送信 */ /*&en 4.3 How to command to OpenXM stack machines? */ /*&common void ox_push_cmd(OXFILE *sv, int sm_code); */ /*&ja サーバにスタックマシンコマンドを送る。コマンドはコマンド番号で与える。 */ /*&en ox_push_cmd() sends an operation code to an OpenXM stack machine. See OpenXM/include/ox_toolkit_tags.h for a list of operation codes. */ /*&ja 4.4 CMO の送受信 */ /*&en 4.4 How to receive a CMO? */ /*&common void ox_push_cmo(OXFILE *sv, cmo *c); cmo* ox_pop_cmo(OXFILE *sv); char* ox_popString(OXFILE *sv); */ /*&ja ox_push_cmo は cmo を送信、ox_pop_cmo は cmo を受信する。ox_popString は cmo を文字列形式に変換して受信するが、変換の結果はサーバによって異 なる。 */ /*&en */ /*&ja 4.5 スタック処理 */ /*&common int ox_pops(OXFILE *sv, int num); */ /*&ja スタック上の num 個のオブジェクトを廃棄する。 */ /*&ja 4.6 通信路のフラッシュ */ /*&common int ox_flush(OXFILE *sv); */ /*&ja 通信路を flush する(実際には何もしない)。 */ /*&ja 4.7 通信の中断 */ /*&common void ox_reset(OXFILE *sv); */ /*&ja 計算を中断する。 */ /*&ja 4.8 ローカル言語で書かれたコマンドの評価 */ /*&common void ox_execute_string(OXFILE *sv, char* str); */ /*&ja サーバのローカル言語で書かれた命令を評価し、結果をスタックに積む。 */ /*&ja 4.9 関数呼び出し */ /*&common int ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[]); */ /*&ja function(argv[1], ...) を計算し、結果をスタックに積む。 */ /*&ja 4.10 Mathcap の受信 */ /*&common cmo_mathcap* ox_mathcap(OXFILE *sv); */ /*&ja Mathcap を受け取る。現在は Mathcap の処理はユーザプログラムに任されている。 いずれこの関数は廃止される予定。 */ /*&ja 5. 低水準 API 低水準 API はファイルディスクリプタを直接利用する。 5.1 通信に使われるバイトオーダの決定 */ /*&en 5. Low-level API. In this section, ``fd'' is an identifier of an OpenXM connection. 5.1 How to decide a byte order of integers? */ /*&common int decideByteOrderServer(int fd, int order); */ /*&ja このツールキットは、サーバが開始されるときにはすでに通信路が設定されて いるが、その通信路に用いるバイトオーダの決定は行われていないと仮定して いる。詳しくは、高山-野呂, "OpenXM の設計と実装" を参照せよ。 (注意) クライアント側でのバイトオーダの設定は、高水準 API で自動的に行われる。 */ /*&en You need to call it when your OpenXM server is initialized. This function always choose the network byte order as an expression for integers. */ /*&common 5.2 */ /*&common int send_int32(int fd, int integer); int receive_int32(int fd); */ /*&ja fd に 32bit 整数を書き込む。 fd から 32bit 整数を読み込む。 */ /*&en send_int32() writes 32bits integer to an OpenXM connection. receive_int32() reads 32bits integer from an OpenXM connection. */ /*&common 5.3 */ /*&common int send_cmo(int fd, cmo* m); cmo* receive_cmo(int fd); */ /*&ja fd に cmo を書き込む。 fd から cmo を読み込む。 */ /*&en send_cmo() writes an CMObject to an OpenXM connection. receive_cmo() reads an CMObject from an OpenXM connection. */ /*&common 5.4 */ /*&common int next_serial(); */ /*&ja シリアルナンバを生成する。 */ /*&en next_serial() generates a serial number for ox message. */ /*&common 5.5 */ /*&common int send_ox_tag(int fd, int tag); int receive_ox_tag(int fd); */ /*&ja fd に OX メッセージのヘッダ(tag+serial#)を書き込む。シリアル番号は 自動的に生成される。 fd から OX メッセージのヘッダ(tag+serial#)を読み込む。 */ /*&en send_ox_tag() writes a tag and an automatically generated serial number of an ox message to an OpenXM conection. receive_ox_tag() reads a tag and a serial number of an ox message. */ /*&common 5.6 Sending OX messages. */ /*&common int send_ox(int fd, ox* m); int send_ox_cmo(int fd, cmo* m); void send_ox_command(int fd, int sm_command); */ /*&ja OX メッセージを送信する。 */ /*&ja 6. OX expression パーサ */ /*&en 6. Parser for OX expressions */ /*&ja OpenXM C library には 文字列表現された OX expression および CMO expression から、ox 構造体または cmo 構造体を生成するためのパーサが付 属している。ここではこのパーサについて説明する。 */ /*&en We have a parser which generate an OX object or a CMO from a string encoded OX/CMO expression. In this section, we explain the parser. */ /*&en 6.1 Setting an option */ /*&ja 6.1 オプション */ /*&common int setflag_parse(int flag); */ /*&ja setflag_parse(PFLAG_ADDREV) によって、CMO の短縮表現を許す。 */ /*&en We set an option for the parser. If we call setflag_parse(PFLAG_ADDREV), then the parser admits external expressios. */ /*&en 6.2 Initializing */ /*&ja 6.2 初期化 */ /*&common int init_parser(char *str); */ /*&ja パーサが処理すべき文字列をセットする。 */ /*&en We give the parser an OX/CMO expression, that is, a Lisp style string. */ /*&en 6.3 Getting an object */ /*&ja 6.3 結果を得る */ /*&common cmo *parse(); */ /*&ja Lisp 表現による OX expression, CMO expression の構文解析器。あらかじめ 設定された文字列を解析して ox 構造体、あるいは cmo 構造体を生成する。 */ /*&en The parser returns an OX/CMO object. If the given string is illegal, then the parser returns NULL. */ /*&ja 7. Mathcap クラス データベース 7.1. 概要 Mathcap クラスは OpenXM アプリケーションの Mathcap を表現するクラスで ある。これは cmo_mathcap とは別物である。Mathcap クラスのインスタンス は各通信路ごとに生成され、OXFILE クラスのメンバになる。このことは、複 数の計算プロセスと同時に通信するクライアントを作成するためである。さて、 Mathcap クラスは、静的メンバももつ。これら静的メンバは、通信路から独立 した、 OpenXM アプリケーション自体の情報を保持するために用いられる。また。 インスタンスの生成時にもその情報は利用される。 7.2. メソッド Mathcap クラスは mathcap.c で実装されている。ユーザは次の関数を介して、 Mathcap クラスにアクセスすることができる。 void mathcap_init(int version, char *id, char *sysname, int cmo[], sm_cmd[]); 静的メンバを初期化する。Mathcap クラスのインスタンスを生成するまえに、 したがって、クライアントおよびサーバはプログラムを開始するときに、この 関数を呼ばなければならない。cmo は、そのアプリケーションの利用する CMO のタグのリストであって、0 で終端しなければならない。NULL のときには既 定値が用いられる。sm_cmd も同様。 cmo_mathcap *mathcap_get(mathcap *this); Mathcap クラスのインスタンスを cmo_mathcap クラスのインスタンスに変換する。 mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc); 通信相手から入手した cmo_mathcap オブジェクトを用いて、Mathcap クラスの インスタンスを更新する。 */ /*&ja 8. 付属プログラムについて */ /*&en 8. Sample programs. */ /*&common testclient */ /*&ja テスト用の小さな OpenXM クライアント。OX expression を入力して送信する ことのみ可能。SM_popCMO, SM_popString を含むメッセージを送信した場合に は、サーバから送られてくるメッセージを表示する。 */ /*&en This is a small OpenXM client. We send an OX message by inputting an OX expression and display data messages gotten from a server. */ /*&common bconv */ /*&ja バイトコードエンコーダ。OX expression あるいは CMO expression を入力す ると、対応するバイト列を表示する。 */ /*&en A byte code encoder. It shows a byte stream which corresponds to an OX expression. */ /*&common ox_Xsample */ /*&ja GUI 表示する OpenXM サーバのサンプル。 */ /*&ja 9. 付録 9.1 ox.c における関数の命名規則 (1) receive_cmo 関数はCMOタグとデータ本体を受信する. この関数は CMOタ グの値が事前に分からないときに使用する. 返り値として、cmo へのポインタ を返す. (2) receive_cmo_X 関数は, CMOタグを親の関数で受信してから呼び出される 関数で、データ本体のみを受信し、cmo_X へのポインタを返す. しかも、関 数内部で new_cmo_X 関数を呼び出す. (3) send_cmo 関数はCMOタグとデータ本体を送信する. (4) send_cmo_X 関数はCMOタグを親の関数で送信してから呼び出される関数で、 データ本体のみを送信する. (5) ただし receive_ox_tag を除いて, receive_ox_X 関数は作らない. receive_cmo を利用する. (6) send_ox_X 関数は OX タグを含めて送信する. (7) ox_X 関数は一連の送受信を含むより抽象的な操作を表現する. ox_X 関 数は、第一引数として、ox_file_t型の変数 sv をとる. (8) Y_cmo 関数と Y_cmo_X 関数の関係は次の通り: まず Y_cmo 関数で cmo のタグを処理し、タグを除いた残りの部分をY_cmo_X 関数が処理する. cmo の内部に cmo_Z へのポインタがあるときには、その種 類によらずに Y_cmo 関数を呼び出す. */