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

Diff for /OpenXM/src/ox_toolkit/mathcap.c between version 1.2 and 1.12.2.1

version 1.2, 2000/10/12 15:40:41 version 1.12.2.1, 2005/10/12 03:49:17
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.1 2000/10/10 05:23:20 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.12 2005/07/26 12:52:05 ohara Exp $ */
   
 /* This module includes functions for handling mathcap databases. */  /* This module includes functions for handling mathcap databases. */
   /* This version will be in the new-mathcap-branch. */
   
   #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
   #include <string.h>
 #include "ox_toolkit.h"  #include "ox_toolkit.h"
   
 typedef struct {  #define MATHCAP_1ST_FORMAT "(CMO_LIST (CMO_INT32 %d) (CMO_STRING \"%s\") (CMO_STRING \"%s\") (CMO_STRING \"%s\"))"
     int tag;  
     int flag;  
 } mcdb;  
   
 static mcdb *mcdb_lookup(mcdb *db, int tag);  static int default_cmd[] = {
 static void mcdb_ctl(mcdb *db, int tag, int flag);      SM_popCMO,
 static void mcdb_ctl_all(mcdb *db, int flag);      SM_popString,
 static cmo_list *mcdb_get_allow_all(mcdb *db);      SM_mathcap,
       SM_pops,
       SM_executeStringByLocalParser,
       SM_executeFunction,
       SM_control_kill,
       SM_control_reset_connection,
       0 };
   static int default_cmo[] = {
       CMO_NULL,
       CMO_INT32,
       CMO_STRING,
       CMO_MATHCAP,
       CMO_LIST,
       CMO_MONOMIAL32,
       CMO_ZZ,
       CMO_QQ,
       CMO_ZERO,
       CMO_DMS_GENERIC,
       CMO_RING_BY_NAME,
       CMO_RECURSIVE_POLYNOMIAL,
       CMO_DISTRIBUTED_POLYNOMIAL,
       CMO_POLYNOMIAL_IN_ONE_VARIABLE,
       CMO_64BIT_MACHINE_DOUBLE,
       CMO_IEEE_DOUBLE_FLOAT,
       CMO_INDETERMINATE,
       CMO_TREE,
       CMO_LAMBDA,
       CMO_ERROR2,
       0 };
   static int default_oxtag[] = { OX_DATA, 0 };
   
 static char *new_string(char *s);  static struct {
 static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);      int  ox_version;
 static cmo_list *get_messagetypes(cmo_list *ob, int type);      char *sysname;
 static cmo_list *mathcap_sm_get_all();      char *version;
 static cmo_list *mathcap_sysinfo_get_all();      char *hosttype;
 static int mathcap_cmo_isallow_cmo_list(cmo_list *ob);  } sysinfo = {OX_PROTOCOL_VERSION, "ox_toolkit", OX_TOOLKIT_VERSION, "generic"};
 static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob);  
 static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob);  
 static int mathcap_cmo_isallow_tag(int tag);  
 static void mathcap_cmo_allow(int tag);  
 static void mathcap_cmo_allow_all();  
 static void mathcap_cmo_deny(int tag);  
 static void mathcap_cmo_deny_all();  
 static void mathcap_cmo_update(cmo_list* types);  
   
 static mcdb mathcap_cmo[] = {  mathcap default_mathcap = {default_cmd, default_cmo};
     {CMO_NULL,       MATHCAP_FLAG_ALLOW},  
     {CMO_INT32,      MATHCAP_FLAG_ALLOW},  
     {CMO_DATUM,      MATHCAP_FLAG_ALLOW},  
     {CMO_STRING,     MATHCAP_FLAG_ALLOW},  
     {CMO_MATHCAP,    MATHCAP_FLAG_ALLOW},  
     {CMO_LIST,       MATHCAP_FLAG_ALLOW},  
     {CMO_MONOMIAL32, MATHCAP_FLAG_ALLOW},  
     {CMO_ZZ,         MATHCAP_FLAG_ALLOW},  
     {CMO_ZERO,       MATHCAP_FLAG_ALLOW},  
     {CMO_DMS_GENERIC, MATHCAP_FLAG_ALLOW},  
     {CMO_RING_BY_NAME, MATHCAP_FLAG_ALLOW},  
     {CMO_INDETERMINATE, MATHCAP_FLAG_ALLOW},  
     {CMO_DISTRIBUTED_POLYNOMIAL, MATHCAP_FLAG_ALLOW},  
     {CMO_ERROR2,     MATHCAP_FLAG_ALLOW},  
     {0,              MATHCAP_FLAG_DENY}  
 };  
   
 static mcdb mathcap_sm[] = {  static int ilen(int a[]);
     {SM_popCMO,     MATHCAP_FLAG_ALLOW},  static int *icopy(int s[]);
     {SM_popString,      MATHCAP_FLAG_ALLOW},  static int *icopyn(int s[], int n);
     {SM_mathcap,        MATHCAP_FLAG_ALLOW},  static int cmo_int32_to_int(cmo_int32* m);
     {SM_pops,           MATHCAP_FLAG_ALLOW},  static int *imerge(int *base, int *diff);
     {SM_executeStringByLocalParser,             MATHCAP_FLAG_ALLOW},  static mathcap *mathcap_merge_io(mathcap *this, mathcap *diff);
     {SM_executeFunction,        MATHCAP_FLAG_ALLOW},  
     {SM_setMathCap,                 MATHCAP_FLAG_ALLOW},  
     {SM_shutdown,                   MATHCAP_FLAG_ALLOW},  
     {SM_control_kill,           MATHCAP_FLAG_ALLOW},  
     {SM_control_reset_connection,               MATHCAP_FLAG_ALLOW},  
     {0,              MATHCAP_FLAG_DENY}  
 };  
   
 typedef struct {  mathcap *new_mathcap()
         mcdb *cmo_db;  
         mcdb *sm_db;  
 } mathcap;  
   
 mathcap default_mathcap = {mathcap_cmo, mathcap_sm};  
   
 mcdb *new_mcdb(mcdb *src)  
 {  {
         mcdb *new;      mathcap *mcap = MALLOC(sizeof(mathcap));
         int len=0;      mcap->cmo = icopy(default_cmo);
         while ((src+(len++))->tag != 0) {      mcap->cmd = icopy(default_cmd);
         }      return mcap;
         new = malloc(sizeof(mcdb)*len);  
         memcpy(new, src, sizeof(mcdb)*len);  
         return new;  
 }  }
   
 mathcap *new_mathcap()  mathcap *new_mathcap_set(int *cmd, int *cmo)
 {  {
         mathcap *new = malloc(sizeof(mathcap));      mathcap *mcap  = MALLOC(sizeof(mathcap));
         new->cmo_db = new_mcdb(mathcap_cmo);          mcap->cmd = (cmd)? cmd: icopy(default_cmd);
         new->sm_db  = new_mcdb(mathcap_sm);          mcap->cmo = (cmo)? cmo: icopy(default_cmo);
         return new;      return mcap;
 }  }
   
 /* 次の tag についてのキーを探す */  cmo_list *cmo_mathcap_1st()
 static mcdb *mcdb_lookup(mcdb *db, int tag)  
 {  {
     while (db->tag != 0) {      char buffer[BUFSIZ];
         if (db->tag == tag) {      static char format[] = MATHCAP_1ST_FORMAT;
             return db;      int len = sizeof(format) + 32
         }                  + strlen(sysinfo.sysname)
         db++;                  + strlen(sysinfo.version)
                   + strlen(sysinfo.hosttype);
       if (len < BUFSIZ) {
           sprintf(buffer, format, sysinfo.ox_version, sysinfo.sysname,
                                   sysinfo.version, sysinfo.hosttype);
           return (cmo_list *)ox_parse_lisp(buffer);
     }      }
     return NULL;      return NULL;
 }  }
   
 /* tag に対する送信制御 */  /* 0: terminator of array of integer. */
 static void mcdb_ctl(mcdb *db, int tag, int flag)  static int ilen(int a[])
 {  {
     mcdb *e = mcdb_lookup(db, tag);      int i=0;
     if (e != NULL) {      if (a != NULL) {
         e->flag = flag;          for( ; a[i] !=0; i++) {
     }  
 }  
   
 /* 全データに対する送信制御 */  
 static void mcdb_ctl_all(mcdb *db, int flag)  
 {  
     while (db->tag != 0) {  
         db->flag = flag;  
         db++;  
     }  
 }  
   
 /* 送信許可されている tag のリストを得る */  
 static cmo_list *mcdb_get_allow_all(mcdb *db)  
 {  
     cmo_list *list = new_cmo_list();  
     while (db->tag != 0) {  
         if (db->flag == MATHCAP_FLAG_ALLOW) {  
             list_append(list, (cmo *)new_cmo_int32(db->tag));  
         }          }
         db++;  
     }      }
     return list;      return i;
 }  }
   
 static struct {  static int *icopy(int s[])
     int  version;  
     char *version_string;  
     char *sysname;  
     char *hosttype;  
 } mathcap_sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN"};  
   
 /* 次の tag をもつ cmo の送信が許可されているかを調べる */  
 static int mathcap_cmo_isallow_tag(int tag)  
 {  {
     mcdb *e = mathcap_cmo;      int n = sizeof(int)*(ilen(s)+1);
     while (e->tag != 0 && e->tag != tag) {      int *d = MALLOC(n);
         e++;      memcpy(d,s,n);
     }      return d;
     return e->flag;  
 }  }
   
 static int mathcap_cmo_isallow_cmo_list(cmo_list *ob)  static int *icopyn(int s[], int n)
 {  {
     cell *el;      int *d = MALLOC((n = sizeof(int)*(n+1)));
     if (mathcap_cmo_isallow_tag(ob->tag)) {      memcpy(d,s,n);
         el = list_first(ob);      return d;
         while (!list_endof(ob, el)) {  
             if (!mathcap_cmo_isallow_cmo(el->cmo)) {  
                 return MATHCAP_FLAG_DENY;  
             }  
             el = list_next(el);  
         }  
         return MATHCAP_FLAG_ALLOW;  
     }  
     return MATHCAP_FLAG_DENY;  
 }  }
   
 __inline__  cmo_mathcap *new_cmo_mathcap_by_mathcap(mathcap *mcap)
 static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob)  
 {  {
     return mathcap_cmo_isallow_tag(ob->tag)      cmo_list *cap1, *cap2, *cap3, *cap4;
         && mathcap_cmo_isallow_cmo(ob->coef);      cap1 = cmo_mathcap_1st();
       cap2 = new_cmo_list_map(mcap->cmd, ilen(mcap->cmd), new_cmo_int32);
       cap3 = new_cmo_list_map(default_oxtag,
                               ilen(default_oxtag),
                               new_cmo_int32);
       cap4 = new_cmo_list_map(mcap->cmo, ilen(mcap->cmo), new_cmo_int32);
       /* new_cmo_mathcap([cap1, cap2, [cap3, cap4]]) */
       return new_cmo_mathcap(
           (cmo *)list_appendl(NULL, cap1, cap2, list_appendl(NULL, cap3, cap4, NULL)));
 }  }
   
 __inline__  static int cmo_int32_to_int(cmo_int32* m)
 static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob)  
 {  {
     return mathcap_cmo_isallow_tag(ob->tag)      return m->i;
         && mathcap_cmo_isallow_cmo(ob->ob);  
 }  }
   
 /* 次の cmo の送信が許可されているかを調べる */  mathcap *new_mathcap_by_cmo_mathcap(cmo_mathcap *cap)
 int mathcap_cmo_isallow_cmo(cmo *ob)  
 {  {
     int tag = ob->tag;      int *cmd = list_to_array_map(list_nth(cap->ob, 1), cmo_int32_to_int);
     switch(tag) {      int *cmo = list_to_array_map(list_nth(list_nth(cap->ob, 2), 1),
     case CMO_LIST:                                   cmo_int32_to_int);
     case CMO_DISTRIBUTED_POLYNOMIAL:      return new_mathcap_set(cmd, cmo);
         return mathcap_cmo_isallow_cmo_list((cmo_list *)ob);  
     case CMO_MATHCAP:  
     case CMO_ERROR2:  
     case CMO_RING_BY_NAME:  
     case CMO_INDETERMINATE:  
         return mathcap_cmo_isallow_cmo_mathcap((cmo_mathcap *)ob);  
     case CMO_MONOMIAL32:  
         return mathcap_cmo_isallow_cmo_monomial32((cmo_monomial32 *)ob);  
     default:  
         return mathcap_cmo_isallow_tag(tag);  
     }  
 }  }
   
 /* 次の tag をもつ cmo の送信を許可する */  /* if base is unsorted. */
 __inline__  static int *imerge(int *base, int *diff)
 static void mathcap_cmo_allow(int tag)  
 {  {
         mcdb_ctl(mathcap_cmo, tag, MATHCAP_FLAG_ALLOW);      int i,j,k;
 }      int n = ilen(base);
       int m = ilen(diff);
 /* 次の tag をもつ cmo の送信を不許可にする */      int *t = ALLOCA(sizeof(int)*(n+1));
 __inline__      int *ret;
 static void mathcap_cmo_deny(int tag)      for(i=0,j=0; i<n; i++) {
 {          for(k=0; k<m; k++) {
         mcdb_ctl(mathcap_cmo, tag, MATHCAP_FLAG_DENY);              if (base[i] == diff[k]) {
 }                  t[j++] = base[i];
                   break;
 /* 全ての種類の cmo の送信を不許可にする */              }
 __inline__  
 static void mathcap_cmo_deny_all()  
 {  
         mcdb_ctl_all(mathcap_cmo, MATHCAP_FLAG_DENY);  
 }  
   
 /* 全ての種類の cmo の送信を許可する */  
 __inline__  
 static void mathcap_cmo_allow_all()  
 {  
         mcdb_ctl_all(mathcap_cmo, MATHCAP_FLAG_ALLOW);  
 }  
   
 /* 送信許可されている cmo のリストを得る */  
 cmo_list *mathcap_cmo_get_allow_all()  
 {  
         return mcdb_get_allow_all(mathcap_cmo);  
 }  
   
 /* 既知の sm コマンドのリストを得る */  
 __inline__  
 static cmo_list *mathcap_sm_get_all()  
 {  
         return mcdb_get_allow_all(mathcap_sm);  
 }  
   
 /* システム情報を得る */  
 static cmo_list *mathcap_sysinfo_get_all()  
 {  
     cmo_list *syslist = new_cmo_list();  
     cmo_int32 *ver    = new_cmo_int32(mathcap_sysinfo.version);  
     cmo_string *vers  = new_cmo_string(mathcap_sysinfo.version_string);  
     cmo_string *host  = new_cmo_string(mathcap_sysinfo.hosttype);  
     cmo_string *sname = new_cmo_string(mathcap_sysinfo.sysname);  
     return list_appendl(syslist, ver, sname, vers, host);  
 }  
   
 static char *new_string(char *s)  
 {  
     char *t = malloc(sizeof(s)+1);  
     strcpy(t, s);  
     return t;  
 }  
   
 void mathcap_sysinfo_set(int version, char *version_string, char *sysname)  
 {  
     char *host = getenv("HOSTTYPE");  
   
     mathcap_sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN";  
     mathcap_sysinfo.sysname  = new_string(sysname);  
     mathcap_sysinfo.version_string = new_string(version_string);  
     mathcap_sysinfo.version  = version;  
 }  
   
 /* データベースから cmo_mathcap を生成する */  
 cmo_mathcap* mathcap_get()  
 {  
     cmo_list *mc = new_cmo_list();  
     cmo_list *l3 = new_cmo_list();  
     list_append(l3, list_appendl(new_cmo_list(), new_cmo_int32(OX_DATA), mathcap_cmo_get_allow_all(), NULL));  
     list_appendl(mc, (cmo *)mathcap_sysinfo_get_all(), (cmo *)mathcap_sm_get_all(), (cmo *)l3, NULL);  
     return new_cmo_mathcap((cmo *)mc);  
 }  
   
 static void mathcap_cmo_update(cmo_list* types)  
 {  
     cell *el = list_first(types);  
     cmo_int32 *ob;  
     while(!list_endof(types, el)) {  
         ob = (cmo_int32 *)el->cmo;  
         if (ob->tag == CMO_INT32) {  
             mathcap_cmo_allow(ob->i);  
         }          }
         el = list_next(el);  
     }      }
       t[j] = 0;
       ret = icopyn(t,j);
       return ret;
 }  }
   
 /* cmo_mathcap が妥当な構造を持つかを調べる.  (未実装) */  static mathcap *mathcap_merge_io(mathcap *this, mathcap *diff)
 int cmo_mathcap_isvalid(cmo_mathcap *mc)  
 {  {
     return 1;      int *tmp;
       tmp = imerge(this->cmo, diff->cmo);
       FREE(this->cmo);
       this->cmo = tmp;
       return this;
 }  }
   
 /* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... )  */  /* for compatibility */
 /*                ^^^^^ Here!                          */  void mathcap_init(char *version, char *sysname)
 static cmo_list *get_messagetypes(cmo_list *ob, int type)  
 {  {
     cmo_list  *c;      sysinfo.hosttype = getenv("HOSTTYPE");
     cell *el;      sysinfo.version  = version;
       sysinfo.sysname  = sysname;
     for (el = list_first(ob); !list_endof(ob, el); el = list_next(el)) {  
         c = (cmo_list *)el->cmo;  
         if (((cmo_int32 *)list_nth(c, 0))->i == type) {  
             return (cmo_list *)list_nth(c, 1);  
         }  
     }  
     return NULL;  
 }  }
   cmo_mathcap* mathcap_get(mathcap *this)
 /* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */  
 /*                                              ^^^^^ Here!         */  
 __inline__  
 static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc)  
 {  {
     cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2);      return new_cmo_mathcap_by_mathcap(this);
     return get_messagetypes(ob, OX_DATA);  
 }  }
   mathcap *mathcap_update(mathcap *this, cmo_mathcap *m)
 /* 受信した mathcap データを反映させる */  
 void mathcap_update(cmo_mathcap *mc)  
 {  {
     cmo_list *types;      return mathcap_merge_io(this, new_mathcap_by_cmo_mathcap(m));
     if (cmo_mathcap_isvalid(mc)) {  
         types = cmo_mathcap_get_cmotypes(mc);  
         if (types != NULL) {  
             mathcap_cmo_deny_all(); /* すべての cmo の送信を禁止 */  
             mathcap_cmo_update(types);  
         }  
     }  
 }  }

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

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