[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.10 and 1.41

version 1.10, 2000/01/20 15:38:12 version 1.41, 2015/08/05 00:59:05
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.9 2000/01/20 08:46:44 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.40 2015/08/04 10:19:31 noro Exp $ */
   
 /*  /*
    This module includes functions for sending/receiveng CMO's.     This module includes functions for sending/receiveng CMO's.
Line 7 
Line 7 
    character set.     character set.
 */  */
   
   
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
   #include <stdarg.h>
 #include <string.h>  #include <string.h>
 #include <unistd.h>  #include <unistd.h>
 #include <errno.h>  
 #include <fcntl.h>  #include <fcntl.h>
 #include <sys/file.h>  #include <sys/file.h>
 #include <gmp.h>  #include <time.h>
   
   #include <mpfr.h>
   /* XXX : defined in mpfr-impl.h */
   #define MPFR_PREC(x)      ((x)->_mpfr_prec)
   #define MPFR_EXP(x)       ((x)->_mpfr_exp)
   #define MPFR_MANT(x)      ((x)->_mpfr_d)
   #define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
   #define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
   
   #if SIZEOF_LONG==4
   typedef long long L64;
   typedef unsigned long long UL64;
   #else
   typedef long L64;
   typedef unsigned long UL64;
   #endif
   
 #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);  static FILE *ox_stderr = NULL;
 static int          cmolen_cmo_list(cmo_list* c);  
 static int          cmolen_cmo_mathcap(cmo_mathcap* c);  
 static int          cmolen_cmo_null(cmo_null* c);  
 static int          cmolen_cmo_string(cmo_string* c);  
 static int          cmolen_cmo_zz(cmo_zz* c);  
 static int          cmolen_cmo_monomial32(cmo_monomial32* c);  
   
 static int          dump_cmo_int32(cmo_int32* m);  /* sorting by the value of CMO_xxx.  (for debugging) */
 static int          dump_cmo_list(cmo_list* m);  static cmo_null*         receive_cmo_null(OXFILE *oxfp);
 static int          dump_cmo_mathcap(cmo_mathcap* m);  static cmo_int32*        receive_cmo_int32(OXFILE *oxfp);
 static int          dump_cmo_null(cmo_null* m);  static cmo_string*       receive_cmo_string(OXFILE *oxfp);
 static int          dump_cmo_string(cmo_string* m);  static cmo_mathcap*      receive_cmo_mathcap(OXFILE *oxfp);
 static int          dump_cmo_monomial32(cmo_monomial32* c);  static cmo_list*         receive_cmo_list(OXFILE *oxfp);
 static int          dump_cmo_zz(cmo_zz* c);  static cmo_monomial32*   receive_cmo_monomial32(OXFILE *oxfp);
 static int          dump_string(char *s, int len);  static cmo_zero*         receive_cmo_zero(OXFILE *oxfp);
 static int          dump_integer(int x);  static cmo_dms_generic*  receive_cmo_dms_generic(OXFILE *oxfp);
 static int          dump_mpz(mpz_ptr mpz);  static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp);
   static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp);
   static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp);
   static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp);
   static cmo_double*       receive_cmo_double(OXFILE *oxfp);
   static cmo_error2*       receive_cmo_error2(OXFILE *oxfp);
   
 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_double(OXFILE *oxfp, cmo_double* c);
   static int          send_cmo_error2(OXFILE *oxfp, cmo_error2* c);
   static int          send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c);
   static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c);
   static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c);
   
 /* CMO_xxx の値の順にならべること(デバッグのため) */  static cmo_zz*      receive_cmo_zz(OXFILE *oxfp);
 static cmo_null*         receive_cmo_null(int fd);  static void         receive_mpz(OXFILE *oxfp, mpz_ptr mpz);
 static cmo_int32*        receive_cmo_int32(int fd);  static int          send_cmo_zz(OXFILE *oxfp, cmo_zz* c);
 static cmo_string*       receive_cmo_string(int fd);  static int          send_mpz(OXFILE *oxfp, mpz_ptr mpz);
 static cmo_mathcap*      receive_cmo_mathcap(int fd);  static void         receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
 static cmo_list*         receive_cmo_list(int fd);  static int          send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
 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);  
   
 static int          print_cmo_int32(cmo_int32* c);  
 static int          print_cmo_list(cmo_list* li);  
 static int          print_cmo_mathcap(cmo_mathcap* c);  
 static int          print_cmo_string(cmo_string* c);  
   
 static char*        new_string_set_cmo_null();  
 static char*        new_string_set_cmo_int32(int integer);  
 static char*        new_string_set_cmo_list(cmo_list *c);  
 static char*        new_string_set_cmo_zz(cmo_zz *c);  
   
 int current_fd = 0;  
 int set_current_fd(int fd)  
 {  
         current_fd = fd;  
 }  
   
 /* hook functions. (yet not implemented) */  /* hook functions. (yet not implemented) */
 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. */  /* Handling an error. */
Line 125  static int current_received_serial = 0;
Line 112  static int current_received_serial = 0;
 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);
 }  }
   
 #define DEFAULT_SERIAL_NUMBER 0x0000ffff  
 #define receive_serial_number(x)   (receive_int32(x))  
   
 /* getting a next serial number. */  /* getting a next serial number. */
 int next_serial()  int next_serial(OXFILE *oxfp)
 {  {
     static int serial_number = DEFAULT_SERIAL_NUMBER;      return oxfp->serial_number++;
     return serial_number++;  
 }  }
   
 /* sending an object of int32 type. (not equal to cmo_int32 type)  */  /* 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));  
 }  }
   
 /* receiving an object of int32 type. (not equal to cmo_int32 type)  */  /* 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);  
 }  }
   
 /* receiving an (OX_tag, serial number)  */  /* sending an object of int32 type. (not equal to cmo_int32 type)  */
 int receive_ox_tag(int fd)  int send_double(OXFILE *oxfp, double d)
 {  {
     int serial;      return oxfp->send_double(oxfp, d);
     int tag = receive_int32(fd);  
     current_received_serial = receive_serial_number(fd);  
     return tag;  
 }  }
   
 /* sending an (OX_tag, serial number)  */  /* receiving an object of int32 type. (not equal to cmo_int32 type)  */
 int send_ox_tag(int fd, int tag)  double receive_double(OXFILE *oxfp)
 {  {
     send_int32(fd, tag);      return oxfp->receive_double(oxfp);
     return send_int32(fd, next_serial());  
 }  }
   
 /* functions for a cmo_list */  /* receiving an (OX_tag, serial number)  */
 cell* new_cell()  int receive_ox_tag(OXFILE *oxfp)
 {  {
     cell* h = malloc(sizeof(cell));      int tag = receive_int32(oxfp);
     h->next = NULL;      oxfp->received_serial_number = receive_int32(oxfp);
     h->cmo  = NULL;      return tag;
     return h;  
 }  }
   
 cell* next_cell(cell* this)  /* sending an (OX_tag, serial number)  */
   int send_ox_tag(OXFILE *oxfp, int tag)
 {  {
     return this->next;      send_int32(oxfp, tag);
       return send_int32(oxfp, next_serial(oxfp));
 }  }
   
 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;  
 }  
   
 cmo *nth_cmo_list(cmo_list* this, int n)  
 {  
         cell *cp = this->head;  
         if(this->length <= n) {  
                 return NULL;  
         }  
         while(n-- > 0) {  
                 cp = cp->next;  
         }  
         return cp->cmo;  
 }  
   
 int length_cmo_list(cmo_list* this)  
 {  
     return this->length;  
 }  
   
 /* functions named receive_cmo_*. */  /* functions named receive_cmo_*. */
 static cmo_null* receive_cmo_null(int fd)  static cmo_null* receive_cmo_null(OXFILE *oxfp)
 {  {
     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_qq* receive_cmo_qq(OXFILE *oxfp)
 {  {
       mpz_t num, den;
       mpz_init(num);
       mpz_init(den);
       receive_mpz(oxfp, num);
       receive_mpz(oxfp, den);
       return new_cmo_qq_set_mpz(num, den);
   }
   
   static cmo_bf* receive_cmo_bf(OXFILE *oxfp)
   {
       mpfr_t num;
       mpfr_init(num);
       receive_mpfr(oxfp, num);
       return new_cmo_bf_set_mpfr(num);
   }
   
   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 ... */      /* 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_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp)
 {  {
           cmo_list* ringdef = (cmo_list *)receive_cmo(oxfp);
           cmo* coef         = receive_cmo(oxfp);
       return new_cmo_recursive_polynomial(ringdef, coef);
   }
   
   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_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp)
 {  {
     cmo* ob = receive_cmo(fd);      cmo* coef;
       cmo_polynomial_in_one_variable* c;
       int len = receive_int32(oxfp);
       int var = receive_int32(oxfp);
       int exp;
       c = new_cmo_polynomial_in_one_variable(var);
       while (len>0) {
           exp  = receive_int32(oxfp);
           coef = receive_cmo(oxfp);
           list_append_monomial((cmo_list *)c, coef, exp);
           len--;
       }
       return c;
   }
   
   static cmo_double* receive_cmo_double(OXFILE *oxfp)
   {
           double d = receive_double(oxfp);
           return new_cmo_double(d);
   }
   
   static cmo_indeterminate* receive_cmo_indeterminate(OXFILE *oxfp)
   {
       cmo* ob = receive_cmo(oxfp);
       return new_cmo_indeterminate(ob);
   }
   
   static cmo_tree* receive_cmo_tree(OXFILE *oxfp)
   {
       cmo_string* name = (cmo_string *)receive_cmo(oxfp);
       cmo_list* attrib = (cmo_list *)receive_cmo(oxfp);
       cmo_list* leaves = (cmo_list *)receive_cmo(oxfp);
       return new_cmo_tree(name, attrib, leaves);
   }
   
   static cmo_lambda* receive_cmo_lambda(OXFILE *oxfp)
   {
       cmo_list* args = (cmo_list *)receive_cmo(oxfp);
       cmo_tree* body = (cmo_tree *)receive_cmo(oxfp);
       return new_cmo_lambda(args, body);
   }
   
   static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
   {
       cmo* ob = receive_cmo(oxfp);
     return new_cmo_error2(ob);      return new_cmo_error2(ob);
 }  }
   
 /* receive_ox_tag() == OX_DATA の後に呼び出される */  /* receive_cmo() is called after receive_ox_tag(). */
 /* 関数ポインタを使った方がきれいに書けるような気がする.  */  cmo* receive_cmo(OXFILE *oxfp)
 /* if (foo[tag] != NULL) foo[tag](fd); とか */  {
       int tag = receive_int32(oxfp);
       return receive_cmo_tag(oxfp, tag);
   }
   
 cmo* receive_cmo(int fd)  cmo *receive_cmo_tag(OXFILE *oxfp, int tag)
 {  {
     cmo* m;      cmo* m;
     int tag;  
     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_QQ:
           m = (cmo *)receive_cmo_qq(oxfp);
           break;
       case CMO_BIGFLOAT:
           m = (cmo *)receive_cmo_bf(oxfp);
           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_RECURSIVE_POLYNOMIAL:
           m = (cmo *)receive_cmo_recursive_polynomial(oxfp);
           break;
       case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
           m = (cmo *)receive_cmo_polynomial_in_one_variable(oxfp);
           break;
           case CMO_64BIT_MACHINE_DOUBLE:
           case CMO_IEEE_DOUBLE_FLOAT:
           m = (cmo *)receive_cmo_double(oxfp);
           break;
       case CMO_INDETERMINATE:
           m = (cmo *)receive_cmo_indeterminate(oxfp);
           break;
       case CMO_TREE:
           m = (cmo *)receive_cmo_tree(oxfp);
           break;
       case CMO_LAMBDA:
           m = (cmo *)receive_cmo_lambda(oxfp);
           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:  
     default:      default:
         fprintf(stderr, "the CMO (%d) is not implemented.\n", m->tag);          m = NULL;
           ox_printf("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 n = sizeof(mpz->_mp_d[0]) / sizeof(int);
       int size  = receive_int32(oxfp);
     int len   = abs(size);      int len   = abs(size);
     resize_mpz(mpz, size);      int *ptr;
       if (n == 1) {
           resize_mpz(mpz, size);
       } else if (size >= 0) {
           resize_mpz(mpz, (size+1) / n);
       } else {
           resize_mpz(mpz, (size-1) / n);
       }
   
       ptr = (int *)mpz->_mp_d;
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         mpz->_mp_d[i] = receive_int32(fd);          ptr[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);
 }  }
   
 /* functions named new_cmo_*. */  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;      sleep(2);
     return m;      /* We wait thar an OpenXM server terminates. */
       ox_printf("I have closed the connection to an Open XM server.\n");
 }  }
   
 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_mpz(mpz_ptr z)  
 {  
     cmo_zz* c = new_cmo_zz();  
     mpz_set(c->mpz, z);  
     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");  
     }  
 }  
   
 static int print_cmo_int32(cmo_int32* c)  
 {  
     fprintf(stderr, ", %d)", c->i);  
 }  
   
 static 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, ")");  
 }  
   
 static int print_cmo_mathcap(cmo_mathcap* c)  
 {  
     fprintf(stderr, ", ");  
     print_cmo(c->ob);  
     fprintf(stderr, ")");  
 }  
   
 static 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);  
         /* We wait thar an OpenXM server terminates. */  
     fprintf(stderr, "I have closed the connection to an Open XM server.\n");  
 #endif  
 }  
   
 void ox_shutdown(ox_file_t sv)  
 {  
         /* We need to use SM_shutdown but yet ... */  
         ox_close(sv);  
 }  
   
 int ox_cmo_rpc(ox_file_t sv, char *function, int argc, cmo *argv[])  
 {  
         int i = argc;  
         while(i-- > 0) {  
                 send_ox_cmo(sv->stream, argv[i]);  
         }  
         send_ox_cmo(sv->stream, (cmo *)new_cmo_int32(argc));  
         send_ox_cmo(sv->stream, (cmo *)new_cmo_string(function));  
         send_ox_command(sv->stream, SM_executeFunction);  
 }  
   
 void ox_execute_string(ox_file_t sv, char* s)  
 {  
         send_ox_cmo(sv->stream, (cmo *)new_cmo_string(s));  
         send_ox_command(sv->stream, SM_executeStringByLocalParser);  
 }  
   
 void ox_push_cmd(ox_file_t sv, int sm_code)  
 {  
     send_ox_command(sv->stream, sm_code);  
 }  
   
 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)  
 {  
     cmo_string* m = NULL;      cmo_string* m = NULL;
   
     send_ox_command(sv->stream, SM_popString);      send_ox_command(sv, SM_popString);
     receive_ox_tag(sv->stream); /* OX_DATA */      receive_ox_tag(sv); /* OX_DATA */
     m = (cmo_string *)receive_cmo(sv->stream);      m = (cmo_string *)receive_cmo(sv);
     return m->s;      return m->s;
 }  }
   
 int ox_pops(ox_file_t sv, int num)  void ox_pops(OXFILE *sv, int num)
 {  {
         send_ox_cmo(sv->stream, (cmo *)new_cmo_int32(num));      send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
     send_ox_command(sv->stream, SM_pops);      send_ox_command(sv, SM_pops);
 }  }
   
 cmo* ox_pop_cmo(ox_file_t sv)  cmo* ox_pop_cmo(OXFILE *sv)
 {  {
     send_ox_command(sv->stream, SM_popCMO);      send_ox_command(sv, SM_popCMO);
     receive_ox_tag(sv->stream); /* OX_DATA */      receive_ox_tag(sv); /* OX_DATA */
     return receive_cmo(sv->stream);      return receive_cmo(sv);
 }  }
   
 void ox_push_cmo(ox_file_t sv, cmo *c)  void ox_push_cmo(OXFILE *sv, cmo *c)
 {  {
         send_ox_cmo(sv->stream, c);      send_ox_cmo(sv, c);
 }  }
   
 /* a dummy function for flushing a connection. */  /* a dummy function for flushing a connection. */
 int ox_flush(ox_file_t sv)  int ox_flush(OXFILE *sv)
 {  {
         return 1;      return 1;
 }  }
   
 /* a dummy password function. */  void ox_reset(OXFILE *sv)
 static char *create_otp()  
 {  {
     static char otp[] = "otpasswd";      send_ox_command(oxf_control(sv), SM_control_reset_connection);
     return otp;      while(receive_ox_tag(sv) != OX_SYNC_BALL) {
 }          receive_cmo(sv); /* skipping a message. */
   
 /* proceeding an one time password. */  
 static int login_with_otp(int fd, char* passwd)  
 {  
     int len   = strlen(passwd)+1;  
     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;      send_ox_tag(sv, OX_SYNC_BALL);
       ox_printf("I have reset an Open XM server.\n");
 }  }
   
 /* The environment variable OpenXM_HOME must be defined. */  void send_ox(OXFILE *oxfp, ox *m)
 static char *concat_openxm_home_bin(char *s)  
 {  {
     char *path;      switch(m->tag) {
     char *base;      case OX_DATA:
           send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
     /* if s includes '/' then it is not concaticated. */  
         if (strchr(s, '/') != NULL) {  
                 return s;  
         }  
   
         base = getenv("OpenXM_HOME");  
         path = malloc(strlen(base)+6+strlen(s));  
         sprintf(path, "%s/bin/%s", base, s);  
         return path;  
 }  
   
 /* example: which("xterm", getenv("PATH")); */  
 static char *which(char *prog, char *path_env)  
 {  
         char *tok;  
         char *path;  
         char delim[] = ":";  
         char *e = alloca(strlen(path_env)+1);  
         strcpy(e, path_env);  
         tok = strtok(e, delim);  
         while (tok != NULL) {  
                 char *path = malloc(strlen(tok)+strlen(prog)+2);  
                 sprintf(path, "%s/%s", tok, prog);  
                 if (access(path, X_OK&R_OK) == 0) {  
                         return path;  
                 }  
                 free(path);  
                 tok = strtok(NULL, delim);  
         }  
         return NULL;  
 }  
   
 static int mysocketAccept2(int fd, char *pass)  
 {  
     fd = mysocketAccept(fd);  
     if(login_with_otp(fd, pass)==0) {  
         decideByteOrderClient(fd, 0);  
         return fd;  
     }  
     close(fd);  
     return -1;  
 }  
   
 /* if it is not 0, then we use oxlog to execute ox. */  
 static int flag_ox_start_with_oxlog = 1;  
   
 /*  
    (-reverse 版の ox_start)  
    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)  
 {  
     ox_file_t sv = NULL;  
     char *pass;  
     char ctl[128], dat[128];  
     short portControl = 0;  /* short! */  
     short portStream  = 0;  
         char *oxlog;  
   
         /* not overwrite */  
         setenv("OpenXM_HOME", "/usr/local/OpenXM", 0);  
   
         oxlog    = concat_openxm_home_bin("oxlog");  
         ctl_prog = concat_openxm_home_bin(ctl_prog);  
         dat_prog = concat_openxm_home_bin(dat_prog);  
   
     sv = malloc(sizeof(__ox_file_struct));  
     sv->control = mysocketListen(host, &portControl);  
     sv->stream  = mysocketListen(host, &portStream);  
   
     sprintf(ctl, "%d", portControl);  
     sprintf(dat, "%d", portStream);  
     pass = create_otp();  
   
     if (fork() == 0) {  
                 if (flag_ox_start_with_oxlog) {  
                         execl(oxlog, oxlog, "xterm", "-icon", "-e", ctl_prog,  
                                   "-reverse", "-ox", dat_prog,  
                                   "-data", dat, "-control", ctl, "-pass", pass,  
                                   "-host", host, NULL);  
                 }else {  
                         dup2(2, 1);  
                         dup2(open(tempnam("/tmp", "ox."), O_RDWR|O_CREAT|O_TRUNC, 0644),  2);  
                         execl(ctl_prog, ctl_prog, "-reverse", "-ox", dat_prog,  
                                   "-data", dat, "-control", ctl, "-pass", pass,  
                                   "-host", host, NULL);  
                 }  
                 exit(1);  
     }  
   
     if ((sv->control = mysocketAccept2(sv->control, pass)) == -1) {  
         close(sv->stream);  
         return NULL;  
     }  
     /* waiting 10 micro second. */  
     usleep(10);  
     if((sv->stream  = mysocketAccept2(sv->stream, pass)) == -1) {  
         return NULL;  
     }  
     return sv;  
 }  
   
 ox_file_t ox_start_remote_with_ssh(char *dat_prog, char* host)  
 {  
         ssh_ox_server(host, "ox", dat_prog, 1200, 1300);  
         return ox_start_insecure_nonreverse(host, 1200, 1300);  
 }  
   
 /* ssh -f host oxlog xterm -e ox -ox ox_asir ... */  
 int ssh_ox_server(char *host, char *ctl_prog, char *dat_prog, short portControl, short portStream)  
 {  
         char *oxlog;  
         char *ssh;  
   
         oxlog    = concat_openxm_home_bin("oxlog");  
         ctl_prog = concat_openxm_home_bin(ctl_prog);  
         dat_prog = concat_openxm_home_bin(dat_prog);  
   
         ssh = which("ssh", getenv("PATH"));  
   
         if (fork() == 0) {  
                 execl(ssh, ssh, "-f", host, oxlog, "xterm", "-icon",  
                           "-e", ctl_prog, "-insecure", "-ox", dat_prog,  
                           "-data", portStream, "-control", portControl,  
                           "-host", host, NULL);  
                 exit(1);  
         }  
 }  
   
 /*  
    (-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  
     /* wainting 10 micro second. */  
     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  
     fprintf(stderr, "I have reset an Open XM server.\n");  
 #endif  
 }  
   
 /* the following functions are needed by bconv.c */  
   
 /* 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);  
 }  
   
 /* calculating the length of the byte stream of given 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;          break;
     case CMO_INT32:      case OX_COMMAND:
         size += cmolen_cmo_int32((cmo_int32 *)c);          send_ox_command(oxfp, ((ox_command *)m)->command);
         break;          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:      default:
           /* CMO?? */
           send_ox_cmo(oxfp, (cmo *)m);
     }      }
     return size;  
 }  }
   
 static int  d_ptr;  void send_ox_cmo(OXFILE *oxfp, cmo* m)
 static char *d_buf;  
   
 int init_dump_buffer(char *s)  
 {  {
     d_buf = s;      send_ox_tag(oxfp, OX_DATA);
     d_ptr = 0;      send_cmo(oxfp, m);
       oxf_flush(oxfp);
 }  }
   
 static int dump_cmo_null(cmo_null* m)  /* send_cmo_* functions */
   static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
 {  {
     return 0;      return 0;
 }  }
   
 static int dump_cmo_int32(cmo_int32* m)  static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
 {  {
     dump_integer(m->i);      return send_int32(oxfp, m->i);
 }  }
   
 static int dump_cmo_string(cmo_string* m)  static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
 {  {
     int len = strlen(m->s);      int len = (m->s != NULL)? strlen(m->s): 0;
     dump_integer(len);      send_int32(oxfp, len);
     dump_string(m->s, len);      if (len > 0) {
           oxf_write(m->s, 1, len, oxfp);
       }
       return 0;
 }  }
   
 static int dump_cmo_mathcap(cmo_mathcap* c)  static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
 {  {
     dump_cmo(c->ob);      send_cmo(oxfp, c->ob);
       return 0;
 }  }
   
 static int dump_cmo_list(cmo_list* m)  static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
 {  {
     cell* cp = m->head;      cell* el = list_first(c);
     int len = length_cmo_list(m);      int len = list_length(c);
     dump_integer(len);      send_int32(oxfp, len);
   
     while(cp->next != NULL) {      while(!list_endof(c, el)) {
         dump_cmo(cp->cmo);          send_cmo(oxfp, el->cmo);
         cp = cp->next;          el = list_next(el);
     }      }
       return 0;
 }  }
   
 static int dump_cmo_monomial32(cmo_monomial32* c)  static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
 {  {
     int i;      cell* el = list_first((cmo_list *)c);
     int length = c->length;      int len = list_length((cmo_list *)c);
     dump_integer(c->length);      send_int32(oxfp, len);
     for(i=0; i<length; i++) {      send_cmo(oxfp, c->ringdef);
         dump_integer(c->exps[i]);      while(!list_endof((cmo_list *)c, el)) {
           send_cmo(oxfp, el->cmo);
           el = list_next(el);
     }      }
     dump_cmo(c->coef);      return 0;
 }  }
   
 static int dump_cmo_zz(cmo_zz* c)  static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c)
 {  {
     dump_mpz(c->mpz);      cell* el = list_first((cmo_list *)c);
 }      int len = list_length((cmo_list *)c);
       send_int32(oxfp, len);
           send_int32(oxfp, c->var);
   
 static int dump_cmo_distributed_polynomial(cmo_distributed_polynomial* m)      while(!list_endof((cmo_list *)c, el)) {
 {          send_int32(oxfp, el->exp);
     cell* cp = m->head;          send_cmo(oxfp, el->cmo);
     int len = length_cmo_list((cmo_list *)m);          el = list_next(el);
     dump_integer(len);  
     dump_cmo(m->ringdef);  
     while(cp != NULL) {  
         dump_cmo(cp->cmo);  
         cp = cp->next;  
     }      }
       return 0;
 }  }
   
 /* after its tag is sent, we invoke each functions. */  static int send_cmo_double(OXFILE *oxfp, cmo_double* c)
 int dump_cmo(cmo* m)  
 {  {
     dump_integer(m->tag);      return send_double(oxfp, c->d);
     switch(m->tag) {  
     case CMO_NULL:  
     case CMO_ZERO:  
     case CMO_DMS_GENERIC:  
         dump_cmo_null(m);  
         break;  
     case CMO_INT32:  
         dump_cmo_int32((cmo_int32 *)m);  
         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:  
     }  
 }  }
   
 static int dump_mpz(mpz_ptr mpz)  static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
 {  {
     int i;      int i;
     int len = abs(mpz->_mp_size);      int len = c->length;
     dump_integer(mpz->_mp_size);      send_int32(oxfp, len);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         dump_integer(mpz->_mp_d[i]);          send_int32(oxfp, c->exps[i]);
     }      }
     return;      send_cmo(oxfp, c->coef);
 }  
   
 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(int fd, ox *m)  
 {  
     int code;  
         switch(m->tag) {  
         case OX_DATA:  
         send_ox_cmo(fd, ((ox_data *)m)->cmo);  
                 break;  
         case OX_COMMAND:  
                 send_ox_command(fd, ((ox_command *)m)->command);  
                 break;  
         default:  
 #if 0  
         /* CMO?? */  
         send_ox_cmo(s->stream, (cmo *)m);  
 #endif  
     }  
 }  
   
 int send_ox_cmo(int fd, cmo* m)  
 {  
     send_ox_tag(fd, OX_DATA);  
     send_cmo(fd, m);  
 }  
   
 /* send_cmo_* functions */  
 static int send_cmo_null(int fd, cmo_null* c)  
 {  
     return 0;      return 0;
 }  }
   
 static int send_cmo_int32(int fd, cmo_int32* m)  static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
 {  {
     send_int32(fd, m->i);      send_mpz(oxfp, c->mpz);
 }  
   
 static int send_cmo_string(int fd, cmo_string* m)  
 {  
     int len = (m->s != NULL)? strlen(m->s): 0;  
     send_int32(fd, len);  
     if (len > 0) {  
         write(fd, m->s, len);  
     }  
     return 0;      return 0;
 }  }
   
 static int send_cmo_mathcap(int fd, cmo_mathcap* c)  static int send_cmo_qq(OXFILE *oxfp, cmo_qq* c)
 {  {
     send_cmo(fd, c->ob);      send_mpz(oxfp, mpq_numref(c->mpq));
       send_mpz(oxfp, mpq_denref(c->mpq));
     return 0;      return 0;
 }  }
   
 static int send_cmo_list(int fd, cmo_list* c)  static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c)
 {  {
     cell* cp = c->head;      send_mpfr(oxfp, c->mpfr);
     int len = length_cmo_list(c);  
     send_int32(fd, len);  
   
     while(cp->next != NULL) {  
         send_cmo(fd, cp->cmo);  
         cp = cp->next;  
     }  
     return 0;      return 0;
 }  }
   
 static int send_cmo_distributed_polynomial(int fd, cmo_distributed_polynomial* c)  static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c)
 {  {
     cell* cp = c->head;          send_cmo(oxfp, (cmo *)c->ringdef);
     int len = length_cmo_list((cmo_list *)c);      send_cmo(oxfp, c->coef);
     send_int32(fd, len);  
     send_cmo(fd, c->ringdef);  
   
     while(cp->next != NULL) {  
         send_cmo(fd, cp->cmo);  
         cp = cp->next;  
     }  
     return 0;      return 0;
 }  }
   
 static int send_cmo_monomial32(int fd, cmo_monomial32* c)  static int send_cmo_tree(OXFILE *oxfp, cmo_tree *c)
 {  {
     int i;      send_cmo(oxfp, (cmo *)c->name);
     int len = c->length;      send_cmo(oxfp, (cmo *)c->attributes);
     send_int32(fd, len);      send_cmo(oxfp, (cmo *)c->leaves);
     for(i=0; i<len; i++) {  
         send_int32(fd, c->exps[i]);  
     }  
     send_cmo(fd, c->coef);  
     return 0;      return 0;
 }  }
   
 static int send_cmo_zz(int fd, cmo_zz* c)  static int send_cmo_lambda(OXFILE *oxfp, cmo_lambda *c)
 {  {
     send_mpz(fd, c->mpz);      send_cmo(oxfp, (cmo *)c->args);
       send_cmo(oxfp, (cmo *)c->body);
     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;
 }  }
   
 /* sending a CMO.  (Remarks: OX_tag is already sent.) */  /* 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);  /* empty function. */          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_QQ:
           send_cmo_qq(oxfp, (cmo_qq *)c);
           break;
       case CMO_BIGFLOAT:
           send_cmo_bf(oxfp, (cmo_bf *)c);
           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;
       case CMO_RECURSIVE_POLYNOMIAL:
           send_cmo_recursive_polynomial(oxfp, (cmo_recursive_polynomial *)c);
           break;
       case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
           send_cmo_polynomial_in_one_variable(oxfp, (cmo_polynomial_in_one_variable *)c);
           break;
           case CMO_64BIT_MACHINE_DOUBLE:
           case CMO_IEEE_DOUBLE_FLOAT:
                   send_cmo_double(oxfp, (cmo_double *)c);
                   break;
       case CMO_TREE:
           send_cmo_tree(oxfp, (cmo_tree *)c);
           break;
       case CMO_LAMBDA:
           send_cmo_lambda(oxfp, (cmo_lambda *)c);
           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 n = sizeof(mpz->_mp_d[0]) / sizeof(int);
     send_int32(fd, mpz->_mp_size);      int len = abs(mpz->_mp_size) * n;
           int *ptr = (int *)mpz->_mp_d;
       int size;
       if (len > 0 && ptr[len-1] == 0) {
           len--;
       }
       size = mpz->_mp_size < 0 ? -len : len;
       send_int32(oxfp, size);
     for(i=0; i<len; i++) {      for(i=0; i<len; i++) {
         send_int32(fd, mpz->_mp_d[i]);          send_int32(oxfp, ptr[i]);
     }      }
     return 0;      return 0;
 }  }
   
 ox_data* new_ox_data(cmo* c)  int send_int64(OXFILE *oxfp,UL64 a)
 {  {
     ox_data* m = malloc(sizeof(ox_data));    return oxfp->send_double(oxfp,((double *)&a)[0]);
     m->tag = OX_DATA;  
     m->cmo = c;  
     return m;  
 }  }
   
 ox_command* new_ox_command(int sm_code)  UL64 receive_int64(OXFILE *oxfp)
 {  {
     ox_command* m = malloc(sizeof(ox_command));          double d = receive_double(oxfp);
     m->tag = OX_COMMAND;    return ((UL64 *)&d)[0];
     m->command = sm_code;  
     return m;  
 }  }
   
 ox_sync_ball* new_ox_sync_ball()  static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
 {  {
     ox_sync_ball *m = malloc(sizeof(ox_sync_ball));    int sgn,prec,len,i;
     m->tag = OX_SYNC_BALL;    long *ptr;
     return m;    L64 exp;
 }  
   
 #define ID_TEMP   "(CMO_LIST, (CMO_INT32, %d), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"), (CMO_STRING, \"%s\"))"    sgn  = receive_int32(oxfp);
     prec  = receive_int32(oxfp);
     exp  = receive_int64(oxfp);
     /* len = length as an int array (int = 4bytes) */
     len  = receive_int32(oxfp);
   
 static cmo_list* make_list_of_id(int ver, char* ver_s, char* sysname)    mpfr_init2(mpfr,prec);
 {    MPFR_SIGN(mpfr) = sgn;
     cmo_list *cap;    ptr = mpfr->_mpfr_d;
     char buff[512];    mpfr->_mpfr_exp = exp;
   #if SIZEOF_LONG==4
     sprintf(buff, ID_TEMP, ver, sysname, ver_s, getenv("HOSTTYPE"));    for ( i = 0; i < len; i++ )
     init_parser(buff);      ptr[i] = receive_int32(oxfp);
     cap = (cmo_list *)parse();  #else
     len >>= 1;
     return cap;    for ( i = 0; i < len; i++ )
       ptr[i] = receive_int64(oxfp);
   #endif
 }  }
   
 static cmo_list *make_list_of_tag(int type)  static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
 {  {
     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)    int i,len;
 {    long *ptr;
     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();    send_int32(oxfp, MPFR_SIGN(mpfr));
     append_cmo_list(li_ox_data,  (cmo *)new_cmo_int32(OX_DATA));    send_int32(oxfp, MPFR_PREC(mpfr));
     append_cmo_list(li_ox_data,  (cmo *)li_cmo);    send_int64(oxfp, MPFR_EXP(mpfr));
     append_cmo_list(li_3rd, (cmo *)li_ox_data);    len = MPFR_LIMB_SIZE(mpfr);
     ptr = MPFR_MANT(mpfr);
     append_cmo_list(li, (cmo *)li_1st);  #if SIZEOF_LONG==4
     append_cmo_list(li, (cmo *)li_2nd);    send_int32(oxfp, len);
     append_cmo_list(li, (cmo *)li_3rd);    for ( i = 0; i < len; i++ )
       send_int32(oxfp,ptr[i]);
     return (cmo *)new_cmo_mathcap((cmo *)li);  #else /* SIZEOF_LONG==8 */
 }    send_int32(oxfp, 2*len);
     for ( i = 0; i < len; i++ )
 /* ファイルディスクリプタ fd の通信路での integer の byte order を決定する */      send_int64(oxfp,ptr[i]);
 /* 実際には order (0,1,or 0xFF)をみてはいない */  #endif
 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;      return 0;
 }  }
   
 /* Server 側ではこちらを用いる */  ox_data* new_ox_data(cmo* c)
 /* いまの実装は dup されていることが前提になっている */  
 int decideByteOrderServer(oxfd fd, int order)  
 {  {
     char zero = OX_BYTE_NETWORK_BYTE_ORDER;      ox_data* m = MALLOC(sizeof(ox_data));
     char dest;      m->tag = OX_DATA;
     write(fd, &zero, sizeof(char));      m->cmo = c;
     read(fd, &dest, sizeof(char));      return m;
     return 0;  
 }  }
   
 /* cmo と string (ここではC言語のstring) の変換関数群 */  ox_command* new_ox_command(int sm_code)
 static char *new_string_set_cmo_zz(cmo_zz *c)  
 {  {
     return mpz_get_str(NULL, 10, c->mpz);      ox_command* m = MALLOC(sizeof(ox_command));
       m->tag = OX_COMMAND;
       m->command = sm_code;
       return m;
 }  }
   
 static char *new_string_set_cmo_null()  ox_sync_ball* new_ox_sync_ball()
 {  {
     static char* null_string = "";      ox_sync_ball *m = MALLOC(sizeof(ox_sync_ball));
     return null_string;      m->tag = OX_SYNC_BALL;
       return m;
 }  }
   
 static char *new_string_set_cmo_int32(int integer)  int ox_stderr_init(FILE *fp)
 {  {
     char buff[1024];      ox_stderr = fp;
     char *s;      if (ox_stderr != NULL) {
           setbuf(ox_stderr, NULL);
     sprintf(buff, "%d", integer);  
     s = malloc(strlen(buff)+1);  
     strcpy(s, buff);  
   
     return s;  
 }  
   
 static char *new_string_set_cmo_list(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] = new_string_set_cmo(cp->cmo);  
         size += strlen(sp[i]) + 3;  
         cp = cp->next;  
     }      }
     s = malloc(size+2);      return 0;
     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 *new_string_set_cmo(cmo *m)  int ox_printf(char *format, ...)
 {  {
     symbol *symp;      if (ox_stderr != NULL) {
     switch(m->tag) {          va_list ap;
     case CMO_ZZ:          va_start(ap, format);
         return new_string_set_cmo_zz((cmo_zz *)m);          vfprintf(ox_stderr, format, ap);
     case CMO_INT32:  
         return new_string_set_cmo_int32(((cmo_int32 *)m)->i);  
     case CMO_STRING:  
         return ((cmo_string *)m)->s;  
     case CMO_NULL:  
         return new_string_set_cmo_null();  
     case CMO_LIST:  
         return new_string_set_cmo_list((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  
         /* yet not implemented. */  
         return NULL;  
     }      }
       return 0;
 }  }

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.41

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