[BACK]Return to ox.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_toolkit

Diff for /OpenXM/src/ox_toolkit/ox.c between version 1.2 and 1.16

version 1.2, 1999/12/13 02:27:15 version 1.16, 2000/11/28 22:11:13
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.1 1999/12/09 22:44:56 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.15 2000/10/12 15:53:25 ohara Exp $ */
   
 /*  /*
 関数の名前付け規約(その2):     This module includes functions for sending/receiveng CMO's.
 (1) receive_cmo 関数はCMOタグとデータ本体を受信する. この関数は CMOタグの     Some commnets is written in Japanese by the EUC-JP coded
 値が事前に分からないときに使用する. 返り値として、cmo へのポインタを返す.     character set.
 (2) receive_cmo_XXX 関数は, CMOタグを親の関数で受信してから呼び出される関  
 数で、データ本体のみを受信し、cmo_XXX へのポインタを返す.  しかも、  
 関数内部で new_cmo_XXX 関数を呼び出す.  
 (3) send_cmo 関数はCMOタグとデータ本体を送信する.  
 (4) send_cmo_XXX 関数はCMOタグを親の関数で送信してから呼び出される関数で、  
 データ本体のみを送信する.  
   
 ----  
 (5) receive_ox_XXX 関数は存在しない(作らない).  receive_cmo を利用する.  
 (6) send_ox_XXX 関数は OX タグを含めて送信する.  
 (7) ox_XXX 関数は一連の送受信を含むより抽象的な操作を表現する.  
 ox_XXX 関数は、第一引数として、ox_file_t型の変数 sv をとる.  
   
 (8) YYY_cmo 関数と YYY_cmo_XXX 関数の関係は次の通り:  
 まず YYY_cmo 関数で cmo のタグを処理し、タグを除いた残りの部分を  
 YYY_cmo_XXX 関数が処理する.  cmo の内部に cmo_ZZZ へのポインタが  
 あるときには、その種類によらずに YYY_cmo 関数を呼び出す.  
 */  */
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
 #include <errno.h>  
 #include <fcntl.h>  #include <fcntl.h>
 #include <gmp.h>  
 #include <unistd.h>  
 #include <sys/file.h>  #include <sys/file.h>
   #include <time.h>
   
 #include "mysocket.h"  #include "mysocket.h"
 #include "ox.h"  #include "ox_toolkit.h"
 #include "parse.h"  #include "parse.h"
   
 static int          cmolen_cmo_int32(cmo_int32* c);  /* CMO_xxx の値の順にならべること(デバッグのため) */
 static int          cmolen_cmo_list(cmo_list* c);  static cmo_null*         receive_cmo_null(OXFILE *oxfp);
 static int          cmolen_cmo_mathcap(cmo_mathcap* c);  static cmo_int32*        receive_cmo_int32(OXFILE *oxfp);
 static int          cmolen_cmo_null(cmo_null* c);  static cmo_string*       receive_cmo_string(OXFILE *oxfp);
 static int          cmolen_cmo_string(cmo_string* c);  static cmo_mathcap*      receive_cmo_mathcap(OXFILE *oxfp);
 static int          cmolen_cmo_zz(cmo_zz* c);  static cmo_list*         receive_cmo_list(OXFILE *oxfp);
 static int          cmolen_cmo_monomial32(cmo_monomial32* c);  static cmo_monomial32*   receive_cmo_monomial32(OXFILE *oxfp);
   static cmo_zz*           receive_cmo_zz(OXFILE *oxfp);
   static cmo_zero*         receive_cmo_zero(OXFILE *oxfp);
   static cmo_dms_generic*  receive_cmo_dms_generic(OXFILE *oxfp);
   static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp);
   static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp);
   
 static int          dump_cmo_int32(cmo_int32* m);  static cmo_error2*       receive_cmo_error2(OXFILE *oxfp);
 static int          dump_cmo_list(cmo_list* m);  static void              receive_mpz(OXFILE *oxfp, mpz_ptr mpz);
 static int          dump_cmo_mathcap(cmo_mathcap* m);  
 static int          dump_cmo_null(cmo_null* m);  
 static int          dump_cmo_string(cmo_string* m);  
 static int          dump_cmo_monomial32(cmo_monomial32* c);  
 static int          dump_cmo_zz(cmo_zz* c);  
 static int          dump_string(char *s, int len);  
 static int          dump_integer(int x);  
 static int          dump_mpz(mpz_ptr mpz);  
   
 static int          login_with_otp(int fd, char* passwd);  static int          send_cmo_null(OXFILE *oxfp, cmo_null* c);
 static char         *create_otp();  static int          send_cmo_int32(OXFILE *oxfp, cmo_int32* m);
   static int          send_cmo_string(OXFILE *oxfp, cmo_string* m);
   static int          send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c);
   static int          send_cmo_list(OXFILE *oxfp, cmo_list* c);
   static int          send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c);
   static int          send_cmo_zz(OXFILE *oxfp, cmo_zz* c);
   static int          send_cmo_error2(OXFILE *oxfp, cmo_error2* c);
   static int          send_mpz(OXFILE *oxfp, mpz_ptr mpz);
   static int          send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c);
   
 /* CMO_xxx の値順にならべること(デバッグのため) */  /* hook functions. (yet not implemented) */
 static cmo_null*         receive_cmo_null(int fd);  
 static cmo_int32*        receive_cmo_int32(int fd);  
 static cmo_string*       receive_cmo_string(int fd);  
 static cmo_mathcap*      receive_cmo_mathcap(int fd);  
 static cmo_list*         receive_cmo_list(int fd);  
 static cmo_monomial32*   receive_cmo_monomial32(int fd);  
 static cmo_zz*           receive_cmo_zz(int fd);  
 static cmo_zero*         receive_cmo_zero(int fd);  
 static cmo_dms_generic*  receive_cmo_dms_generic(int fd);  
 static cmo_ring_by_name* receive_cmo_ring_by_name(int fd);  
 static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(int fd);  
   
 static cmo_error2*       receive_cmo_error2(int fd);  
 static void              receive_mpz(int fd, mpz_ptr mpz);  
   
 static int          send_cmo_null(int fd, cmo_null* c);  
 static int          send_cmo_int32(int fd, cmo_int32* m);  
 static int          send_cmo_string(int fd, cmo_string* m);  
 static int          send_cmo_mathcap(int fd, cmo_mathcap* c);  
 static int          send_cmo_list(int fd, cmo_list* c);  
 static int          send_cmo_monomial32(int fd, cmo_monomial32* c);  
 static int          send_cmo_zz(int fd, cmo_zz* c);  
 static int          send_cmo_error2(int fd, cmo_error2* c);  
 static int          send_mpz(int fd, mpz_ptr mpz);  
 static int          send_cmo_distributed_polynomial(int fd, cmo_distributed_polynomial* c);  
   
 static void         resize_mpz(mpz_ptr mpz, int size);  
   
 int current_fd = 0;  
 int set_current_fd(int fd)  
 {  
         current_fd = fd;  
 }  
   
 /* hook 関数 */  
 static hook_t hook_before_send_cmo = NULL;  static hook_t hook_before_send_cmo = NULL;
 static hook_t hook_after_send_cmo  = NULL;  static hook_t hook_after_send_cmo  = NULL;
   
 int add_hook_before_send_cmo(hook_t func)  int add_hook_before_send_cmo(hook_t func)
 {  {
         hook_before_send_cmo = func;      hook_before_send_cmo = func;
       return 0;
 }  }
   
 int add_hook_after_send_cmo(hook_t func)  int add_hook_after_send_cmo(hook_t func)
 {  {
         hook_after_send_cmo = func;      hook_after_send_cmo = func;
       return 0;
 }  }
   
 static cmo *call_hook_before_send_cmo(int fd, cmo *c)  static cmo *call_hook_before_send_cmo(OXFILE *oxfp, cmo *c)
 {  {
         if (hook_before_send_cmo != NULL) {      if (hook_before_send_cmo != NULL) {
                 return hook_before_send_cmo(fd, c);          return hook_before_send_cmo(oxfp, c);
         }      }
         return c;      return c;
 }  }
   
 static cmo *call_hook_after_send_cmo(int fd, cmo *c)  static cmo *call_hook_after_send_cmo(OXFILE *oxfp, cmo *c)
 {  {
         if (hook_after_send_cmo != NULL) {      if (hook_after_send_cmo != NULL) {
                 return hook_after_send_cmo(fd, c);          return hook_after_send_cmo(oxfp, c);
         }      }
         return c;      return c;
 }  }
   
 /* エラーハンドリングのため */  /* Handling an error. */
 static int current_received_serial = 0;  static int current_received_serial = 0;
   
 /* エラーを起こしたときにサーバは次を呼び出す.  */  /* If an error object be needed, then a server call the following function. */
 cmo_error2* make_error_object(int err_code, cmo *ob)  cmo_error2* make_error_object(int err_code, cmo *ob)
 {  {
     cmo_list* li = new_cmo_list();      cmo_list* li = new_cmo_list();
     append_cmo_list(li, (cmo *)new_cmo_int32(current_received_serial));      list_append(li, (cmo *)new_cmo_int32(current_received_serial));
     append_cmo_list(li, (cmo *)new_cmo_int32(err_code));      list_append(li, (cmo *)new_cmo_int32(err_code));
     append_cmo_list(li, ob);      list_append(li, ob);
     /* 他の情報を加えるならココ */      /* 他の情報を加えるならココ */
     return new_cmo_error2((cmo *)li);      return new_cmo_error2((cmo *)li);
 }  }
   
 /* add at Mon Sep  7 15:51:28 JST 1998 */  /* getting a next serial number. */
 #define DEFAULT_SERIAL_NUMBER 0x0000ffff  int next_serial(OXFILE *oxfp)
 #define receive_serial_number(x)   (receive_int32(x))  
   
 /* 新しいシリアル番号を得る */  
 int next_serial()  
 {  {
     static int serial_number = DEFAULT_SERIAL_NUMBER;      return oxfp->serial_number++;
     return serial_number++;  
 }  }
   
 /* int32 型のオブジェクトを送信する.  */  /* sending an object of int32 type. (not equal to cmo_int32 type)  */
 int send_int32(int fd, int int32)  int send_int32(OXFILE *oxfp, int int32)
 {  {
     int32 = htonl(int32);      return oxfp->send_int32(oxfp, int32);
     return write(fd, &int32, sizeof(int));  
 }  }
   
 /* int32 型のオブジェクトを受信する.  */  /* receiving an object of int32 type. (not equal to cmo_int32 type)  */
 int receive_int32(int fd)  int receive_int32(OXFILE *oxfp)
 {  {
     int tag;      return oxfp->receive_int32(oxfp);
     read(fd, &tag, sizeof(int));  
     return ntohl(tag);  
 }  }
   
 /* (OX_tag, serial number) を受信する.  */  /* receiving an (OX_tag, serial number)  */
 int receive_ox_tag(int fd)  int receive_ox_tag(OXFILE *oxfp)
 {  {
     int serial;      int tag = receive_int32(oxfp);
     int tag = receive_int32(fd);      oxfp->received_serial_number = receive_int32(oxfp);
     current_received_serial = receive_serial_number(fd);  
     return tag;      return tag;
 }  }
   
 /* (OX_tag, serial number) を送信する.   */  /* sending an (OX_tag, serial number)  */
 int send_ox_tag(int fd, int tag)  int send_ox_tag(OXFILE *oxfp, int tag)
 {  {
     send_int32(fd, tag);      send_int32(oxfp, tag);
     return send_int32(fd, next_serial());      return send_int32(oxfp, next_serial(oxfp));
 }  }
   
 /* CMO_LIST 関係の関数群 */  /* functions named receive_cmo_*. */
 cell* new_cell()  static cmo_null* receive_cmo_null(OXFILE *oxfp)
 {  {
     cell* h = malloc(sizeof(cell));  
     h->next = NULL;  
     h->cmo  = NULL;  
     return h;  
 }  
   
 cell* next_cell(cell* this)  
 {  
     return this->next;  
 }  
   
 static cell *tail(cmo_list* this) {  
     cell *cp = this->head;  
     while (cp->next != NULL) {  
         cp = cp->next;  
     }  
     return cp;  
 }  
   
 int append_cmo_list(cmo_list* this, cmo* newcmo)  
 {  
     cell *cp = tail(this);  
     cp->cmo  = newcmo;  
     cp->next = new_cell();  
     this->length++;  
     return 0;  
 }  
   
 int length_cmo_list(cmo_list* this)  
 {  
     return this->length;  
 }  
   
 /** receive_cmo_XXX 関数群 **/  
 static cmo_null* receive_cmo_null(int fd)  
 {  
     return new_cmo_null();      return new_cmo_null();
 }  }
   
 static cmo_int32* receive_cmo_int32(int fd)  static cmo_int32* receive_cmo_int32(OXFILE *oxfp)
 {  {
     int i = receive_int32(fd);      int i = receive_int32(oxfp);
     return new_cmo_int32(i);      return new_cmo_int32(i);
 }  }
   
 static cmo_string* receive_cmo_string(int fd)  static cmo_string* receive_cmo_string(OXFILE *oxfp)
 {  {
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     char* s = malloc(len+1);      char* s = malloc(len+1);
     memset(s, '\0', len+1);      memset(s, '\0', len+1);
     if (len > 0) {      if (len > 0) {
         read(fd, s, len);          oxf_read(s, 1, len, oxfp);
     }      }
     return new_cmo_string(s);      return new_cmo_string(s);
 }  }
   
 static cmo_mathcap* receive_cmo_mathcap(int fd)  static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
     return new_cmo_mathcap(ob);      return new_cmo_mathcap(ob);
 }  }
   
 static cmo_list* receive_cmo_list(int fd)  static cmo_list* receive_cmo_list(OXFILE *oxfp)
 {  {
     cmo* ob;      cmo* ob;
     cmo_list* c = new_cmo_list();      cmo_list* c = new_cmo_list();
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
   
     while (len>0) {      while (len>0) {
         ob = receive_cmo(fd);          ob = receive_cmo(oxfp);
         append_cmo_list(c, ob);          list_append(c, ob);
         len--;          len--;
     }      }
     return c;      return c;
 }  }
   
 static cmo_monomial32* receive_cmo_monomial32(int fd)  static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp)
 {  {
     int i;      int i;
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     cmo_monomial32* c = new_cmo_monomial32(len);      cmo_monomial32* c = new_cmo_monomial32(len);
   
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         c->exps[i] = receive_int32(fd);          c->exps[i] = receive_int32(oxfp);
     }      }
     c->coef = receive_cmo(fd);      c->coef = receive_cmo(oxfp);
     return c;      return c;
 }  }
   
 static cmo_zz* receive_cmo_zz(int fd)  static cmo_zz* receive_cmo_zz(OXFILE *oxfp)
 {  {
     cmo_zz* c = new_cmo_zz();      cmo_zz* c = new_cmo_zz();
     receive_mpz(fd, c->mpz);      receive_mpz(oxfp, c->mpz);
     return c;      return c;
 }  }
   
 static cmo_zero* receive_cmo_zero(int fd)  static cmo_zero* receive_cmo_zero(OXFILE *oxfp)
 {  {
     return new_cmo_zero();      return new_cmo_zero();
 }  }
   
 static cmo_dms_generic* receive_cmo_dms_generic(int fd)  static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp)
 {  {
     return new_cmo_dms_generic();      return new_cmo_dms_generic();
 }  }
   
 static cmo_ring_by_name* receive_cmo_ring_by_name(int fd)  static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
     /* 意味的チェックが必要 */      /* We need to check semantics but yet ... */
     return new_cmo_ring_by_name(ob);      return new_cmo_ring_by_name(ob);
 }  }
   
 static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(int fd)  static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp)
 {  {
     cmo* ob;      cmo* ob;
     cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();      cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();
     int len = receive_int32(fd);      int len = receive_int32(oxfp);
     c->ringdef = receive_cmo(fd);      c->ringdef = receive_cmo(oxfp);
   
     while (len>0) {      while (len>0) {
         ob = receive_cmo(fd);          ob = receive_cmo(oxfp);
         append_cmo_list((cmo_list *)c, ob);          list_append((cmo_list *)c, ob);
         len--;          len--;
     }      }
     return c;      return c;
 }  }
   
 static cmo_error2* receive_cmo_error2(int fd)  static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* ob = receive_cmo(oxfp);
     return new_cmo_error2(ob);      return new_cmo_error2(ob);
 }  }
   
 /* receive_ox_tag() == OX_DATA の後に呼び出される */  /* receive_ox_tag() == OX_DATA の後に呼び出される */
 /* 関数ポインタを使った方がきれいに書けるような気がする.  */  /* 関数ポインタを使った方がきれいに書けるような気がする.  */
 /* if (foo[tag] != NULL) foo[tag](fd); とか */  /* if (foo[tag] != NULL) foo[tag](oxfp); とか */
   
 cmo* receive_cmo(int fd)  cmo* receive_cmo(OXFILE *oxfp)
 {  {
     cmo* m;      cmo* m;
     int tag;      int tag = receive_int32(oxfp);
     tag = receive_int32(fd);  
   
     switch(tag) {      switch(tag) {
     case CMO_NULL:      case CMO_NULL:
         m = receive_cmo_null(fd);          m = receive_cmo_null(oxfp);
         break;          break;
     case CMO_INT32:      case CMO_INT32:
         m = (cmo *)receive_cmo_int32(fd);          m = (cmo *)receive_cmo_int32(oxfp);
         break;          break;
     case CMO_STRING:      case CMO_STRING:
         m = (cmo *)receive_cmo_string(fd);          m = (cmo *)receive_cmo_string(oxfp);
         break;          break;
     case CMO_MATHCAP:      case CMO_MATHCAP:
         m = (cmo *)receive_cmo_mathcap(fd);          m = (cmo *)receive_cmo_mathcap(oxfp);
         break;          break;
     case CMO_LIST:      case CMO_LIST:
         m = (cmo *)receive_cmo_list(fd);          m = (cmo *)receive_cmo_list(oxfp);
         break;          break;
     case CMO_MONOMIAL32:      case CMO_MONOMIAL32:
         m = (cmo *)receive_cmo_monomial32(fd);          m = (cmo *)receive_cmo_monomial32(oxfp);
         break;          break;
     case CMO_ZZ:      case CMO_ZZ:
         m = (cmo *)receive_cmo_zz(fd);          m = (cmo *)receive_cmo_zz(oxfp);
         break;          break;
     case CMO_ZERO:      case CMO_ZERO:
         m = (cmo *)receive_cmo_zero(fd);          m = (cmo *)receive_cmo_zero(oxfp);
         break;          break;
     case CMO_DMS_GENERIC:      case CMO_DMS_GENERIC:
         m = (cmo *)receive_cmo_dms_generic(fd);          m = (cmo *)receive_cmo_dms_generic(oxfp);
         break;          break;
     case CMO_RING_BY_NAME:      case CMO_RING_BY_NAME:
         m = (cmo *)receive_cmo_ring_by_name(fd);          m = (cmo *)receive_cmo_ring_by_name(oxfp);
         break;          break;
     case CMO_DISTRIBUTED_POLYNOMIAL:      case CMO_DISTRIBUTED_POLYNOMIAL:
         m = (cmo *)receive_cmo_distributed_polynomial(fd);          m = (cmo *)receive_cmo_distributed_polynomial(oxfp);
         break;          break;
     case CMO_ERROR2:      case CMO_ERROR2:
         m = (cmo *)receive_cmo_error2(fd);          m = (cmo *)receive_cmo_error2(oxfp);
         break;          break;
     case CMO_DATUM:      case CMO_DATUM:
     case CMO_QQ:      case CMO_QQ:
     default:      default:
         fprintf(stderr, "the CMO (%d) is not implemented.\n", m->tag);          m = NULL;
           fprintf(stderr, "the CMO (%d) is not implemented.\n", tag);
     }      }
     return m;      return m;
 }  }
   
 static void receive_mpz(int fd, mpz_ptr mpz)  static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz)
 {  {
     int i;      int i;
     int size  = receive_int32(fd);      int size  = receive_int32(oxfp);
     int len   = abs(size);      int len   = abs(size);
     resize_mpz(mpz, size);      resize_mpz(mpz, size);
   
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         mpz->_mp_d[i] = receive_int32(fd);          mpz->_mp_d[i] = receive_int32(oxfp);
     }      }
 }  }
   
 static void resize_mpz(mpz_ptr mpz, int size)  void send_ox_command(OXFILE *oxfp, int sm_command)
 {  {
     _mpz_realloc(mpz, abs(size));      send_ox_tag(oxfp, OX_COMMAND);
     mpz->_mp_size = size;      send_int32(oxfp, sm_command);
       oxf_flush(oxfp);
 }  }
   
 /** new_cmo_XXX 関数群 **/  void ox_close(OXFILE *sv)
 cmo_null* new_cmo_null()  
 {  {
     cmo_null* m = malloc(sizeof(cmo_null));      send_ox_command(oxf_control(sv), SM_control_kill);
     m->tag = CMO_NULL;  #ifdef DEBUG
     return m;      sleep(2);
       /* We wait thar an OpenXM server terminates. */
       fprintf(stderr, "I have closed the connection to an Open XM server.\n");
   #endif
 }  }
   
 cmo_int32* new_cmo_int32(int i)  void ox_shutdown(OXFILE *sv)
 {  {
     cmo_int32* c;      /* We need to use SM_shutdown but yet ... */
     c = malloc(sizeof(cmo_int32));      ox_close(sv);
     c->tag     = CMO_INT32;  
     c->i = i;  
     return c;  
 }  }
   
 cmo_string* new_cmo_string(char* s)  void ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[])
 {  {
     cmo_string* c = malloc(sizeof(cmo_string));      int i = argc;
     c->tag = CMO_STRING;      while(i-- > 0) {
     if (s != NULL) {          send_ox_cmo(sv, argv[i]);
         c->s = malloc(strlen(s)+1);  
         strcpy(c->s, s);  
     }else {  
         c->s = NULL;  
     }      }
     return c;      send_ox_cmo(sv, (cmo *)new_cmo_int32(argc));
       send_ox_cmo(sv, (cmo *)new_cmo_string(function));
       send_ox_command(sv, SM_executeFunction);
 }  }
   
 cmo_mathcap* new_cmo_mathcap(cmo* ob)  void ox_execute_string(OXFILE *sv, char* s)
 {  {
     cmo_mathcap* c = malloc(sizeof(cmo_mathcap));      send_ox_cmo(sv, (cmo *)new_cmo_string(s));
     c->tag = CMO_MATHCAP;      send_ox_command(sv, SM_executeStringByLocalParser);
     c->ob  = ob;  
     return c;  
 }  }
   
 cmo_list* new_cmo_list()  void ox_push_cmd(OXFILE *sv, int sm_code)
 {  {
     cmo_list* c = malloc(sizeof(cmo_list));      send_ox_command(sv, sm_code);
     c->tag    = CMO_LIST;  
     c->length = 0;  
     c->head->next = NULL;  
     return c;  
 }  }
   
 cmo_monomial32* new_cmo_monomial32()  cmo_mathcap* ox_mathcap(OXFILE *sv)
 {  {
     cmo_monomial32* c = malloc(sizeof(cmo_monomial32));      send_ox_command(sv, SM_mathcap);
     c->tag  = CMO_MONOMIAL32;      send_ox_command(sv, SM_popCMO);
     return c;      receive_ox_tag(sv);          /* OX_DATA */
       return (cmo_mathcap *)receive_cmo(sv);
 }  }
   
 cmo_monomial32* new_cmo_monomial32_size(int size)  char* ox_popString(OXFILE *sv)
 {  {
     cmo_monomial32* c = new_cmo_monomial32();  
     if (size>0) {  
         c->length = size;  
         c->exps = malloc(sizeof(int)*size);  
     }  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz()  
 {  
     cmo_zz* c = malloc(sizeof(cmo_zz));  
     c->tag  = CMO_ZZ;  
     mpz_init(c->mpz);  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_noinit()  
 {  
     cmo_zz* c = malloc(sizeof(cmo_zz));  
     c->tag  = CMO_ZZ;  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_set_si(int i)  
 {  
     cmo_zz* c = new_cmo_zz();  
     mpz_set_si(c->mpz, i);  
     return c;  
 }  
   
 cmo_zz *new_cmo_zz_set_string(char *s)  
 {  
     cmo_zz* c = new_cmo_zz_noinit();  
     mpz_init_set_str(c->mpz, s, 10);  
     return c;  
 }  
   
 cmo_zz* new_cmo_zz_size(int size)  
 {  
     cmo_zz* c = new_cmo_zz();  
     resize_mpz(c->mpz, size);  
     return c;  
 }  
   
 cmo_zero* new_cmo_zero()  
 {  
     cmo_zero* m = malloc(sizeof(cmo_zero));  
     m->tag = CMO_ZERO;  
     return m;  
 }  
   
 cmo_dms_generic* new_cmo_dms_generic()  
 {  
     cmo_dms_generic* m = malloc(sizeof(cmo_dms_generic));  
     m->tag = CMO_DMS_GENERIC;  
     return m;  
 }  
   
 cmo_ring_by_name* new_cmo_ring_by_name(cmo* ob)  
 {  
     cmo_ring_by_name* c = malloc(sizeof(cmo_ring_by_name));  
     c->tag = CMO_RING_BY_NAME;  
     c->ob  = ob;  
     return c;  
 }  
   
 cmo_indeterminate* new_cmo_indeterminate(cmo* ob)  
 {  
     cmo_indeterminate* c = malloc(sizeof(cmo_indeterminate));  
     c->tag = CMO_INDETERMINATE;  
     c->ob  = ob;  
     return c;  
 }  
   
 cmo_distributed_polynomial* new_cmo_distributed_polynomial()  
 {  
     cmo_distributed_polynomial* c = malloc(sizeof(cmo_distributed_polynomial));  
     c->tag     = CMO_DISTRIBUTED_POLYNOMIAL;  
     c->length  = 0;  
     c->head->next = NULL;  
     c->ringdef = NULL;  
     return c;  
 }  
   
 cmo_error2* new_cmo_error2(cmo* ob)  
 {  
     cmo_error2* c = malloc(sizeof(cmo_error2));  
     c->tag = CMO_ERROR2;  
     c->ob  = ob;  
     return c;  
 }  
   
 void send_ox_command(int fd, int sm_command)  
 {  
     send_ox_tag(fd, OX_COMMAND);  
     send_int32(fd, sm_command);  
 }  
   
 int print_cmo(cmo* c)  
 {  
     int tag = c->tag;  
   
     symbol* symp = lookup_by_tag(tag);  
     if (symp != NULL) {  
         fprintf(stderr, "(%s", symp->key);  
     }else {  
         fprintf(stderr, "(%d", tag);  
     }  
   
     switch(tag) {  
     case CMO_LIST:  
         print_cmo_list((cmo_list *)c);  
         break;  
     case CMO_INT32:  
         print_cmo_int32((cmo_int32 *)c);  
         break;  
     case CMO_MATHCAP:  
     case CMO_INDETERMINATE:  
     case CMO_RING_BY_NAME:  
     case CMO_ERROR2:  
         print_cmo_mathcap((cmo_mathcap *)c);  
         break;  
     case CMO_STRING:  
         print_cmo_string((cmo_string *)c);  
         break;  
     case CMO_NULL:  
     case CMO_ZERO:  
     case CMO_DMS_GENERIC:  
         fprintf(stderr, ")");  
         break;  
     default:  
         fprintf(stderr, "print_cmo() does not know how to print.\n");  
     }  
 }  
   
 int print_cmo_int32(cmo_int32* c)  
 {  
     fprintf(stderr, ", %d)", c->i);  
 }  
   
 int print_cmo_list(cmo_list* li)  
 {  
     cell* cp = li->head;  
     while(cp->next != NULL) {  
         fprintf(stderr, ", ");  
         print_cmo(cp->cmo);  
         cp=cp->next;  
     }  
     fprintf(stderr, ")");  
 }  
   
 int print_cmo_mathcap(cmo_mathcap* c)  
 {  
     fprintf(stderr, ", ");  
     print_cmo(c->ob);  
     fprintf(stderr, ")");  
 }  
   
 int print_cmo_string(cmo_string* c)  
 {  
     fprintf(stderr, ", \"%s\")", c->s);  
 }  
   
 void ox_close(ox_file_t sv)  
 {  
     send_ox_command(sv->control, SM_control_kill);  
 #ifdef DEBUG  
     sleep(2); /* OpenXM server の終了を待つ. あまり意味はない. */  
     fprintf(stderr, "I have closed the connection to an Open XM server.\n");  
 #endif  
 }  
   
 void ox_executeStringByLocalParser(ox_file_t sv, char* s)  
 {  
     if (s != NULL) {  
         /* 文字列ををスタックにプッシュ. */  
         send_ox_cmo(sv->stream, (cmo *)new_cmo_string(s));  
         /* サーバに実行させる. */  
         send_ox_command(sv->stream, SM_executeStringByLocalParser);  
     }  
 }  
   
 /* ox_mathcap() をコールする.  */  
 cmo_mathcap* ox_mathcap(ox_file_t sv)  
 {  
     send_ox_command(sv->stream, SM_mathcap);  
     send_ox_command(sv->stream, SM_popCMO);  
     receive_ox_tag(sv->stream);          /* OX_DATA */  
     return (cmo_mathcap *)receive_cmo(sv->stream);  
 }  
   
 char* ox_popString(ox_file_t sv, int fd)  
 {  
     cmo_string* m = NULL;      cmo_string* m = NULL;
   
     send_ox_command(fd, SM_popString);      send_ox_command(sv, SM_popString);
     receive_ox_tag(fd); /* OX_DATA */      receive_ox_tag(sv); /* OX_DATA */
     m = (cmo_string *)receive_cmo(fd);      m = (cmo_string *)receive_cmo(sv);
     return m->s;      return m->s;
 }  }
   
 cmo* ox_pop_cmo(ox_file_t sv, int fd)  void ox_pops(OXFILE *sv, int num)
 {  {
     send_ox_command(fd, SM_popCMO);      send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
     receive_ox_tag(fd); /* OX_DATA */      send_ox_command(sv, SM_pops);
     return receive_cmo(fd);  
 }  }
   
 /* 手抜き. (後で改善しよう...) */  cmo* ox_pop_cmo(OXFILE *sv)
 static char *create_otp()  
 {  {
     static char otp[] = "otpasswd";      send_ox_command(sv, SM_popCMO);
     return otp;      receive_ox_tag(sv); /* OX_DATA */
       return receive_cmo(sv);
 }  }
   
 /* OneTimePassword の処理 */  void ox_push_cmo(OXFILE *sv, cmo *c)
 static int login_with_otp(int fd, char* passwd)  
 {  {
     int len   = strlen(passwd)+1;      send_ox_cmo(sv, c);
     char *buf = alloca(len);  
     int n     = read(fd, buf, len);  
     int ret   = strcmp(passwd, buf);  
   
 #ifdef DEBUG  
     if (ret != 0) {  
         fprintf(stderr, "Socket#%d: Login incorrect.\n", fd);  
     }else {  
         fprintf(stderr, "Socket#%d: login!.\n", fd);  
     }  
     fprintf(stderr, "password = (%s), %d bytes.\n", passwd, len);  
     fprintf(stderr, "received = (%s), %d bytes.\n", buf, n);  
     fflush(stderr);  
 #endif  
   
     return ret;  
 }  }
   
 static int exists_ox(char *dir, char *prog)  /* a dummy function for flushing a connection. */
   int ox_flush(OXFILE *sv)
 {  {
     char *path = alloca(strlen(dir)+strlen(prog)+6);      return 1;
     sprintf(path, "%s/%s", dir, prog);  
     return access(path, X_OK|R_OK);  
 }  }
   
 static char *search_ox(char *prog)  void ox_reset(OXFILE *sv)
 {  {
     char *env = getenv("OpenXM_HOME");      send_ox_command(oxf_control(sv), SM_control_reset_connection);
     char *dir;  
     if (env != NULL) {  
         dir = malloc(strlen(env)+5);  
         sprintf(dir, "%s/bin", env);  
         if (exists_ox(dir, prog) == 0) {  
             return dir;  
         }  
         free(dir);  
     }  
     dir = "/usr/local/OpenXM/bin";  
     if (exists_ox(dir, prog) == 0) {  
         return dir;  
     }  
     dir = ".";  
     if (exists_ox(dir, prog) == 0) {  
         return dir;  
     }  
     return NULL;  
 }  
   
 static int mysocketAccept2(int fd, char *pass)      receive_ox_tag(oxf_control(sv));      /* OX_DATA */
 {      receive_cmo(oxf_control(sv));         /* (CMO_INT32, 0) */
     fd = mysocketAccept(fd);  
     if(login_with_otp(fd, pass)==0) {  
         decideByteOrderClient(fd, 0);  
         return fd;  
     }  
     close(fd);  
     return -1;  
 }  
   
 /*      while(receive_ox_tag(sv) != OX_SYNC_BALL) {
    (-reverse 版の ox_start)          receive_cmo(sv); /* skipping a message. */
    ox_start は クライアントが呼び出すための関数である.  
    サーバでは使われない.  ctl_prog は コントロールサーバであり,  
    -ox, -reverse, -data, -control, -pass, -host  
    というオプションを理解することを仮定する. dat_prog は計算サーバである.  
    接続時には, sv->control を先にオープンする.  
 */  
   
 ox_file_t ox_start(char* host, char* ctl_prog, char* dat_prog)  
 {  
     char *pass;  
     char ctl[16], dat[16];  
     short portControl = 0; /* short であることに注意 */  
     short portStream  = 0;  
     ox_file_t sv = NULL;  
     char *dir;  
   
     if ((dir = search_ox(ctl_prog)) == NULL) {  
         fprintf(stderr, "client:: %s not found.\n", ctl_prog);  
         return NULL;  
     }      }
     sv = malloc(sizeof(__ox_file_struct));  
     sv->control = mysocketListen(host, &portControl);  
     sv->stream  = mysocketListen(host, &portStream);  
   
     sprintf(ctl, "%d", portControl);      send_ox_tag(sv, OX_SYNC_BALL);
     sprintf(dat, "%d", portStream);  
     pass = create_otp();  
   
     if (fork() == 0) {  
         dup2(2, 1);  
         dup2(open(DEFAULT_LOGFILE, O_RDWR|O_CREAT|O_TRUNC, 0644), 2);  
         chdir(dir);  
         execl(ctl_prog, ctl_prog, "-reverse", "-ox", dat_prog,  
               "-data", dat, "-control", ctl, "-pass", pass,  
               "-host", host, NULL);  
     }  
   
     if ((sv->control = mysocketAccept2(sv->control, pass)) == -1) {  
         close(sv->stream);  
         return NULL;  
     }  
     /* 10マイクロ秒, 時間稼ぎする. */  
     usleep(10);  
     if((sv->stream  = mysocketAccept2(sv->stream, pass)) == -1) {  
         return NULL;  
     }  
     return sv;  
 }  
   
 /*  
    (-insecure 版の ox_start)  まだ、中身はありません。  
    ox_start_insecure_nonreverse は クライアントが呼び出すための関数である.  
    接続時には, sv->control を先にオープンする.  
    既定値:  
    portControl = 1200  
    portStream  = 1300  
 */  
   
 ox_file_t ox_start_insecure_nonreverse(char* host, short portControl, short portStream)  
 {  
     ox_file_t sv = malloc(sizeof(__ox_file_struct));  
   
     sv->control = mysocketOpen(host, portControl);  
 #if 0  
     /* ox は insecure のとき byte order の決定が正しくできないようだ... */  
     decideByteOrderClient(sv->control, 0);  
 #endif  
     /* 10マイクロ秒, 時間稼ぎする. */  
     usleep(10);  
     sv->stream  = mysocketOpen(host, portStream);  
     decideByteOrderClient(sv->stream, 0);  
     return sv;  
 }  
   
 void ox_reset(ox_file_t sv)  
 {  
     send_ox_command(sv->control, SM_control_reset_connection);  
   
     receive_ox_tag(sv->control);      /* OX_DATA */  
     receive_cmo(sv->control);         /* (CMO_INT32, 0) */  
   
     while(receive_ox_tag(sv->stream) != OX_SYNC_BALL) {  
         receive_cmo(sv->stream); /* skipping a message. */  
     }  
   
     send_ox_tag(sv->stream, OX_SYNC_BALL);  
 #ifdef DEBUG  #ifdef DEBUG
     fprintf(stderr, "I have reset an Open XM server.\n");      fprintf(stderr, "I have reset an Open XM server.\n");
 #endif  #endif
 }  }
   
 /* 以下は bconv.c で必要とする関数群である. */  void send_ox(OXFILE *oxfp, ox *m)
   
 /* cmolen 関数は cmo の(送信時の)バイト長を返す. */  
 /* cmolen_XXX 関数は cmo_XXX の tag を除いたバイト長を返す. */  
   
 static int cmolen_cmo_null(cmo_null* c)  
 {  {
     return 0;  
 }  
   
 static int cmolen_cmo_int32(cmo_int32* c)  
 {  
     return sizeof(int);  
 }  
   
 static int cmolen_cmo_string(cmo_string* c)  
 {  
     return sizeof(int)+strlen(c->s);  
 }  
   
 static int cmolen_cmo_mathcap(cmo_mathcap* c)  
 {  
     return cmolen_cmo(c->ob);  
 }  
   
 static int cmolen_cmo_list(cmo_list* c)  
 {  
     int size = sizeof(int);  
     cell* cp = c->head;  
   
     while(cp->next != NULL) {  
         size += cmolen_cmo(cp->cmo);  
         cp = cp->next;  
     }  
     return size;  
 }  
   
 static int cmolen_cmo_monomial32(cmo_monomial32* c)  
 {  
     int len = (c->length + 1)*sizeof(int);  
     return len + cmolen_cmo(c->coef);  
 }  
   
 static int cmolen_cmo_zz(cmo_zz* c)  
 {  
     int len = abs(c->mpz->_mp_size);  
     return sizeof(len) + len*sizeof(int);  
 }  
   
 static int cmolen_cmo_distributed_polynomial(cmo_distributed_polynomial* c)  
 {  
     return cmolen_cmo_list((cmo_list *)c) + cmolen_cmo(c->ringdef);  
 }  
   
 /* CMO がバイトエンコードされた場合のバイト列の長さを求める */  
 int cmolen_cmo(cmo* c)  
 {  
     int size = sizeof(int);  
   
     switch(c->tag) {  
     case CMO_NULL:  
     case CMO_ZERO:  
     case CMO_DMS_GENERIC:  
         size += cmolen_cmo_null(c);  
         break;  
     case CMO_INT32:  
         size += cmolen_cmo_int32((cmo_int32 *)c);  
         break;  
     case CMO_STRING:  
         size += cmolen_cmo_string((cmo_string *)c);  
         break;  
     case CMO_MATHCAP:  
     case CMO_RING_BY_NAME:  
     case CMO_INDETERMINATE:  
     case CMO_ERROR2:  
         size += cmolen_cmo_mathcap((cmo_mathcap *)c);  
         break;  
     case CMO_LIST:  
         size += cmolen_cmo_list((cmo_list *)c);  
         break;  
     case CMO_MONOMIAL32:  
         size += cmolen_cmo_monomial32((cmo_monomial32 *)c);  
         break;  
     case CMO_ZZ:  
         size += cmolen_cmo_zz((cmo_zz *)c);  
         break;  
     case CMO_DISTRIBUTED_POLYNOMIAL:  
         size += cmolen_cmo_distributed_polynomial((cmo_distributed_polynomial *)c);  
         break;  
     default:  
     }  
     return size;  
 }  
   
 static int  d_ptr;  
 static char *d_buf;  
   
 int init_dump_buffer(char *s)  
 {  
     d_buf = s;  
     d_ptr = 0;  
 }  
   
 static int dump_cmo_null(cmo_null* m)  
 {  
     return 0;  
 }  
   
 static int dump_cmo_int32(cmo_int32* m)  
 {  
     dump_integer(m->i);  
 }  
   
 static int dump_cmo_string(cmo_string* m)  
 {  
     int len = strlen(m->s);  
     dump_integer(len);  
     dump_string(m->s, len);  
 }  
   
 static int dump_cmo_mathcap(cmo_mathcap* c)  
 {  
     dump_cmo(c->ob);  
 }  
   
 static int dump_cmo_list(cmo_list* m)  
 {  
     cell* cp = m->head;  
     int len = length_cmo_list(m);  
     dump_integer(len);  
   
     while(cp->next != NULL) {  
         dump_cmo(cp->cmo);  
         cp = cp->next;  
     }  
 }  
   
 static int dump_cmo_monomial32(cmo_monomial32* c)  
 {  
     int i;  
     int length = c->length;  
     dump_integer(c->length);  
     for(i=0; i<length; i++) {  
         dump_integer(c->exps[i]);  
     }  
     dump_cmo(c->coef);  
 }  
   
 static int dump_cmo_zz(cmo_zz* c)  
 {  
     dump_mpz(c->mpz);  
 }  
   
 static int dump_cmo_distributed_polynomial(cmo_distributed_polynomial* m)  
 {  
     cell* cp = m->head;  
     int len = length_cmo_list((cmo_list *)m);  
     dump_integer(len);  
     dump_cmo(m->ringdef);  
     while(cp != NULL) {  
         dump_cmo(cp->cmo);  
         cp = cp->next;  
     }  
 }  
   
 /* タグを書き出してから、各関数を呼び出す */  
 int dump_cmo(cmo* m)  
 {  
     dump_integer(m->tag);  
     switch(m->tag) {      switch(m->tag) {
     case CMO_NULL:      case OX_DATA:
     case CMO_ZERO:          send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
     case CMO_DMS_GENERIC:  
         dump_cmo_null(m);  
         break;          break;
     case CMO_INT32:      case OX_COMMAND:
         dump_cmo_int32((cmo_int32 *)m);          send_ox_command(oxfp, ((ox_command *)m)->command);
         break;          break;
     case CMO_STRING:  
         dump_cmo_string((cmo_string *)m);  
         break;  
     case CMO_MATHCAP:  
     case CMO_RING_BY_NAME:  
     case CMO_INDETERMINATE:  
     case CMO_ERROR2:  
         dump_cmo_mathcap((cmo_mathcap *)m);  
         break;  
     case CMO_LIST:  
         dump_cmo_list((cmo_list *)m);  
         break;  
     case CMO_MONOMIAL32:  
         dump_cmo_monomial32((cmo_monomial32 *)m);  
         break;  
     case CMO_ZZ:  
         dump_cmo_zz((cmo_zz *)m);  
         break;  
     case CMO_DISTRIBUTED_POLYNOMIAL:  
         dump_cmo_distributed_polynomial((cmo_distributed_polynomial *)m);  
         break;  
     default:      default:
     }  
 }  
   
 static int dump_mpz(mpz_ptr mpz)  
 {  
     int i;  
     int len = abs(mpz->_mp_size);  
     dump_integer(mpz->_mp_size);  
     for(i=0; i<len; i++) {  
         dump_integer(mpz->_mp_d[i]);  
     }  
     return;  
 }  
   
 static int dump_string(char *s, int len)  
 {  
     memcpy(&d_buf[d_ptr], s, len);  
     d_ptr += len;  
 }  
   
 static int dump_integer(int x)  
 {  
     int nx = htonl(x);  
     dump_string((char *)&nx, sizeof(int));  
 }  
   
 int dump_ox_data(ox_data* m)  
 {  
     dump_integer(OX_DATA);  
     dump_integer(-1);  
     dump_cmo(m->cmo);  
 }  
   
 int dump_ox_command(ox_command* m)  
 {  
     dump_integer(OX_COMMAND);  
     dump_integer(-1);  
     dump_integer(m->command);  
 }  
   
 int send_ox(ox_file_t s, ox *m)  
 {  
     int tag = m->tag;  
     int code;  
     if (tag == OX_DATA) {  
         send_ox_cmo(s->stream, ((ox_data *)m)->cmo);  
     }else if (tag == OX_COMMAND) {  
         code = ((ox_command *)m)->command;  
         if (code >= 1024) {  
             /* control command */  
             send_ox_command(s->control, code);  
         }else {  
             send_ox_command(s->stream, code);  
         }  
     }else {  
         /* CMO?? */          /* CMO?? */
         send_ox_cmo(s->stream, (cmo *)m);          send_ox_cmo(oxfp, (cmo *)m);
     }      }
 }  }
   
 int send_ox_cmo(int fd, cmo* m)  void send_ox_cmo(OXFILE *oxfp, cmo* m)
 {  {
     send_ox_tag(fd, OX_DATA);      send_ox_tag(oxfp, OX_DATA);
     send_cmo(fd, m);      send_cmo(oxfp, m);
       oxf_flush(oxfp);
 }  }
   
 /* send_cmo_xxx 関数群 */  /* send_cmo_* functions */
 static int send_cmo_null(int fd, cmo_null* c)  static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
 {  {
     return 0;      return 0;
 }  }
   
 static int send_cmo_int32(int fd, cmo_int32* m)  static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
 {  {
     send_int32(fd, m->i);      return send_int32(oxfp, m->i);
 }  }
   
 static int send_cmo_string(int fd, cmo_string* m)  static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
 {  {
     int len = (m->s != NULL)? strlen(m->s): 0;      int len = (m->s != NULL)? strlen(m->s): 0;
     send_int32(fd, len);      send_int32(oxfp, len);
     if (len > 0) {      if (len > 0) {
         write(fd, m->s, len);          oxf_write(m->s, 1, len, oxfp);
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_mathcap(int fd, cmo_mathcap* c)  static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
 {  {
     send_cmo(fd, c->ob);      send_cmo(oxfp, c->ob);
     return 0;      return 0;
 }  }
   
 static int send_cmo_list(int fd, cmo_list* c)  static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
 {  {
     cell* cp = c->head;      cell* el = list_first(c);
     int len = length_cmo_list(c);      int len = list_length(c);
     send_int32(fd, len);      send_int32(oxfp, len);
   
     while(cp->next != NULL) {      while(!list_endof(c, el)) {
         send_cmo(fd, cp->cmo);          send_cmo(oxfp, el->cmo);
         cp = cp->next;          el = list_next(el);
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_distributed_polynomial(int fd, cmo_distributed_polynomial* c)  static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
 {  {
     cell* cp = c->head;      cell* el = list_first((cmo_list *)c);
     int len = length_cmo_list((cmo_list *)c);      int len = list_length((cmo_list *)c);
     send_int32(fd, len);      send_int32(oxfp, len);
     send_cmo(fd, c->ringdef);      send_cmo(oxfp, c->ringdef);
       while(!list_endof((cmo_list *)c, el)) {
     while(cp->next != NULL) {          send_cmo(oxfp, el->cmo);
         send_cmo(fd, cp->cmo);          el = list_next(el);
         cp = cp->next;  
     }      }
     return 0;      return 0;
 }  }
   
 static int send_cmo_monomial32(int fd, cmo_monomial32* c)  static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
 {  {
     int i;      int i;
     int len = c->length;      int len = c->length;
     send_int32(fd, len);      send_int32(oxfp, len);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         send_int32(fd, c->exps[i]);          send_int32(oxfp, c->exps[i]);
     }      }
     send_cmo(fd, c->coef);      send_cmo(oxfp, c->coef);
     return 0;      return 0;
 }  }
   
 static int send_cmo_zz(int fd, cmo_zz* c)  static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
 {  {
     send_mpz(fd, c->mpz);      send_mpz(oxfp, c->mpz);
     return 0;      return 0;
 }  }
   
 static int send_cmo_error2(int fd, cmo_error2* c)  static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c)
 {  {
     send_cmo(fd, c->ob);      send_cmo(oxfp, c->ob);
     return 0;      return 0;
 }  }
   
 /* CMOを送る.  OX_tag は送信済*/  /* sending a CMO.  (Remarks: OX_tag is already sent.) */
 int send_cmo(int fd, cmo* c)  void send_cmo(OXFILE *oxfp, cmo* c)
 {  {
     int tag = c->tag;      int tag = c->tag;
   
         c = call_hook_before_send_cmo(fd, c);      c = call_hook_before_send_cmo(oxfp, c);
   
     send_int32(fd, tag);      send_int32(oxfp, tag);
     switch(tag) {      switch(tag) {
     case CMO_NULL:      case CMO_NULL:
     case CMO_ZERO:      case CMO_ZERO:
     case CMO_DMS_GENERIC:      case CMO_DMS_GENERIC:
         send_cmo_null(fd, c);  /* 空の関数 */          send_cmo_null(oxfp, c);  /* empty function. */
         break;          break;
     case CMO_INT32:      case CMO_INT32:
         send_cmo_int32(fd, (cmo_int32 *)c);          send_cmo_int32(oxfp, (cmo_int32 *)c);
         break;          break;
     case CMO_STRING:      case CMO_STRING:
         send_cmo_string(fd, (cmo_string *)c);          send_cmo_string(oxfp, (cmo_string *)c);
         break;          break;
     case CMO_MATHCAP:      case CMO_MATHCAP:
     case CMO_ERROR2:      case CMO_ERROR2:
     case CMO_RING_BY_NAME:      case CMO_RING_BY_NAME:
     case CMO_INDETERMINATE:      case CMO_INDETERMINATE:
         send_cmo_mathcap(fd, (cmo_mathcap *)c);          send_cmo_mathcap(oxfp, (cmo_mathcap *)c);
         break;          break;
     case CMO_LIST:      case CMO_LIST:
         send_cmo_list(fd, (cmo_list *)c);          send_cmo_list(oxfp, (cmo_list *)c);
         break;          break;
     case CMO_MONOMIAL32:      case CMO_MONOMIAL32:
         send_cmo_monomial32(fd, (cmo_monomial32 *)c);          send_cmo_monomial32(oxfp, (cmo_monomial32 *)c);
         break;          break;
     case CMO_ZZ:      case CMO_ZZ:
         send_cmo_zz(fd, (cmo_zz *)c);          send_cmo_zz(oxfp, (cmo_zz *)c);
         break;          break;
     case CMO_DISTRIBUTED_POLYNOMIAL:      case CMO_DISTRIBUTED_POLYNOMIAL:
         send_cmo_distributed_polynomial(fd, (cmo_distributed_polynomial *)c);          send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c);
         break;          break;
     default:      default:
                 call_hook_after_send_cmo(fd, c);          call_hook_after_send_cmo(oxfp, c);
     }      }
 }  }
   
 static int send_mpz(int fd, mpz_ptr mpz)  static int send_mpz(OXFILE *oxfp, mpz_ptr mpz)
 {  {
     int i;      int i;
     int len = abs(mpz->_mp_size);      int len = abs(mpz->_mp_size);
     send_int32(fd, mpz->_mp_size);      send_int32(oxfp, mpz->_mp_size);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         send_int32(fd, mpz->_mp_d[i]);          send_int32(oxfp, mpz->_mp_d[i]);
     }      }
     return 0;      return 0;
 }  }
Line 1237  ox_sync_ball* new_ox_sync_ball()
Line 570  ox_sync_ball* new_ox_sync_ball()
     ox_sync_ball *m = malloc(sizeof(ox_sync_ball));      ox_sync_ball *m = malloc(sizeof(ox_sync_ball));
     m->tag = OX_SYNC_BALL;      m->tag = OX_SYNC_BALL;
     return m;      return m;
 }  
   
 #define ID_TEMP   "(CMO_LIST, (CMO_INT32, %d), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"))"  
   
 static cmo_list* make_list_of_id(int ver, char* ver_s, char* sysname)  
 {  
     cmo_list *cap;  
     char buff[512];  
   
     setgetc(mygetc);  
     sprintf(buff, ID_TEMP, ver, sysname, ver_s, getenv("HOSTTYPE"));  
     setmode_mygetc(buff, 512);  
     cap = (cmo_list *)parse();  
     resetgetc();  
   
     return cap;  
 }  
   
 static cmo_list *make_list_of_tag(int type)  
 {  
     cmo_list *li = new_cmo_list();  
     symbol *symp;  
     int i = 0;  
     while((symp = lookup(i++))->key != NULL) {  
         if (symp->type == type) {  
             append_cmo_list(li, (cmo *)new_cmo_int32(symp->tag));  
         }  
     }  
     return li;  
 }  
   
 cmo* make_mathcap_object(int version, char *id_string)  
 {  
     char *sysname    = "ox_math";  
     cmo_list *li     = new_cmo_list();  
     cmo_list *li_1st = make_list_of_id(version, id_string, sysname);  
     cmo_list *li_2nd = make_list_of_tag(IS_SM);  
     cmo_list *li_3rd = new_cmo_list();  
     cmo_list *li_cmo = make_list_of_tag(IS_CMO);  
   
     cmo_list *li_ox_data  = new_cmo_list();  
     append_cmo_list(li_ox_data,  (cmo *)new_cmo_int32(OX_DATA));  
     append_cmo_list(li_ox_data,  (cmo *)li_cmo);  
     append_cmo_list(li_3rd, (cmo *)li_ox_data);  
   
     append_cmo_list(li, (cmo *)li_1st);  
     append_cmo_list(li, (cmo *)li_2nd);  
     append_cmo_list(li, (cmo *)li_3rd);  
   
     return (cmo *)new_cmo_mathcap((cmo *)li);  
 }  
   
 /* ファイルディスクリプタ fd の通信路での integer の byte order を決定する */  
 /* 実際には order (0,1,or 0xFF)をみてはいない */  
 int decideByteOrderClient(oxfd fd, int order)  
 {  
     char zero = OX_BYTE_NETWORK_BYTE_ORDER;  
     char dest;  
     read(fd, &dest, sizeof(char));  
     write(fd, &zero, sizeof(char));  
     return 0;  
 }  
   
 /* Server 側ではこちらを用いる */  
 /* いまの実装は dup されていることが前提になっている */  
 int decideByteOrderServer(oxfd fd, int order)  
 {  
     char zero = OX_BYTE_NETWORK_BYTE_ORDER;  
     char dest;  
     write(fd, &zero, sizeof(char));  
     read(fd, &dest, sizeof(char));  
     return 0;  
 }  
   
 /* cmo と string (ここではC言語のstring) の変換関数群 */  
 char *convert_zz_to_string(cmo_zz *c)  
 {  
     return mpz_get_str(NULL, 10, c->mpz);  
 }  
   
 char *convert_null_to_string()  
 {  
     static char* null_string = "";  
     return null_string;  
 }  
   
 char *convert_int_to_string(int integer)  
 {  
     char buff[1024];  
     char *s;  
   
     sprintf(buff, "%d", integer);  
     s = malloc(strlen(buff)+1);  
     strcpy(s, buff);  
   
     return s;  
 }  
   
 char *convert_cmo_list_to_string(cmo_list *m)  
 {  
     char *s;  
     int i;  
     int size = 0;  
     int len = length_cmo_list(m);  
     char **sp = malloc(len*sizeof(cmo *));  
   
     cell *cp = m->head;  
     for(i = 0; i < len; i++) {  
         sp[i] = convert_cmo_to_string(cp->cmo);  
         size += strlen(sp[i]) + 3;  
         cp = cp->next;  
     }  
     s = malloc(size+2);  
     strcpy(s, "[ ");  
     for(i = 0; i < len - 1; i++) {  
         strcat(s, sp[i]);  
         strcat(s, " , ");  
     }  
     strcat(s, sp[len-1]);  
     strcat(s, " ]");  
     free(sp);  
     return s;  
 }  
   
 char *convert_cmo_to_string(cmo *m)  
 {  
     symbol *symp;  
     switch(m->tag) {  
     case CMO_ZZ:  
         return convert_zz_to_string((cmo_zz *)m);  
     case CMO_INT32:  
         return convert_int_to_string(((cmo_int32 *)m)->i);  
     case CMO_STRING:  
         return ((cmo_string *)m)->s;  
     case CMO_NULL:  
         return convert_null_to_string();  
     case CMO_LIST:  
         return convert_cmo_list_to_string((cmo_list *)m);  
     default:  
 #ifdef DEBUG  
         symp = lookup_by_tag(m->tag);  
         fprintf(stderr, "I do not know how to convert %s to a string.\n", symp->key);  
 #endif  
         /* まだ実装していません. */  
         return NULL;  
     }  
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.16

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>