[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.12 and 1.18

version 1.12, 2005/07/26 12:52:05 version 1.18, 2016/08/23 05:36:39
Line 1 
Line 1 
 /* -*- mode: C; coding: euc-japan -*- */  /* -*- mode: C; coding: euc-japan -*- */
 /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.11 2005/03/04 06:29:46 ohara Exp $ */  /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.17 2016/08/23 02:24:19 ohara Exp $ */
   
 /* This module includes functions for handling mathcap databases. */  /* This module includes functions for handling mathcap databases. */
   
 #include <stdio.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include "ox_toolkit.h"  #include "ox_toolkit.h"
   
 #define MATHCAP_1ST_FORMAT "(CMO_LIST (CMO_INT32 %d) (CMO_STRING \"%s\") (CMO_STRING \"%s\") (CMO_STRING \"%s\"))"  #define MATHCAP_FLAG_DENY   0
   #define MATHCAP_FLAG_ALLOW  1
   
 static int default_cmd[] = {  static void table_init(table *m, int key);
     SM_popCMO,  static table *new_table(int *src);
     SM_popString,  static table *table_lookup(table *tbl, int tag);
     SM_mathcap,  static void table_ctl(table *tbl, int tag, int flag);
     SM_pops,  static void table_ctl_all(table *tbl, int flag);
     SM_executeStringByLocalParser,  static cmo_list *table_get_all(table *tbl);
     SM_executeFunction,  static void table_allow(table *tbl, int tag);
     SM_control_kill,  static void table_deny(table *tbl, int tag);
     SM_control_reset_connection,  static void table_update(table *cmotbl, cmo_list* types);
     0 };  static int table_allowQ_tag(table *tbl, int tag);
 static int default_cmo[] = {  static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob);
   static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob);
   static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob);
   static int table_allowQ_cmo(table *cmotbl, cmo *ob);
   static cmo_list *sysinfo_get();
   static char *new_string(char *s);
   static int *new_int_array(int *array);
   static cmo_list *get_messagetypes(cmo_list *ob, int type);
   static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
   
   static int cmotbl_a[] = {
     CMO_NULL,      CMO_NULL,
     CMO_INT32,      CMO_INT32,
       CMO_DATUM,
     CMO_STRING,      CMO_STRING,
     CMO_MATHCAP,      CMO_MATHCAP,
     CMO_LIST,      CMO_LIST,
     CMO_MONOMIAL32,      CMO_MONOMIAL32,
     CMO_ZZ,      CMO_ZZ,
     CMO_QQ,      CMO_QQ,
       CMO_BIGFLOAT32,
       CMO_COMPLEX,
       CMO_IEEE_DOUBLE_FLOAT,
     CMO_ZERO,      CMO_ZERO,
     CMO_DMS_GENERIC,      CMO_DMS_GENERIC,
     CMO_RING_BY_NAME,      CMO_RING_BY_NAME,
     CMO_RECURSIVE_POLYNOMIAL,      CMO_INDETERMINATE,
     CMO_DISTRIBUTED_POLYNOMIAL,      CMO_DISTRIBUTED_POLYNOMIAL,
       CMO_RECURSIVE_POLYNOMIAL,
     CMO_POLYNOMIAL_IN_ONE_VARIABLE,      CMO_POLYNOMIAL_IN_ONE_VARIABLE,
     CMO_64BIT_MACHINE_DOUBLE,  
     CMO_IEEE_DOUBLE_FLOAT,  
     CMO_INDETERMINATE,  
     CMO_TREE,  
     CMO_LAMBDA,  
     CMO_ERROR2,      CMO_ERROR2,
     0 };      0,
 static int default_oxtag[] = { OX_DATA, 0 };  };
   
   static int smtbl_a[] = {
       SM_popCMO,
       SM_popString,
       SM_mathcap,
       SM_pops,
       SM_executeStringByLocalParser,
       SM_executeFunction,
       SM_setMathCap,
       SM_shutdown,
       SM_control_kill,
       SM_control_reset_connection,
       SM_control_spawn_server,
       SM_control_terminate_server,
       0,
   };
   
 static struct {  static struct {
     int  ox_version;      int  version;
       char *version_string;
     char *sysname;      char *sysname;
     char *version;  
     char *hosttype;      char *hosttype;
 } sysinfo = {OX_PROTOCOL_VERSION, "ox_toolkit", OX_TOOLKIT_VERSION, "generic"};      int  *cmo_tags;
       int  *sm_cmds;
           char **opts;
   } sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN", cmotbl_a, smtbl_a, NULL};
   
 mathcap default_mathcap = {default_cmd, default_cmo};  __inline__
   static void table_init(table *m, int key)
   {
       m->tag  = key;
       m->flag = MATHCAP_FLAG_ALLOW;
   }
   
 static int ilen(int a[]);  static table *new_table(int *src)
 static int *icopy(int s[]);  {
 static int *icopyn(int s[], int n);      table *new;
 static int cmo_int32_to_int(cmo_int32* m);      int len=0;
 static int *imerge(int *base, int *diff);      int i;
 static mathcap *mathcap_merge_io(mathcap *this, mathcap *diff);      while (src[len++] != 0) {
       }
       new = MALLOC(sizeof(table)*len);
       for(i=0; i<len; i++) {
           table_init(new+i, src[i]);
       }
       return new;
   }
   
 mathcap *new_mathcap()  /* looking for an item of the tag */
   static table *table_lookup(table *tbl, int tag)
 {  {
     mathcap *mcap = MALLOC(sizeof(mathcap));      while (tbl->tag != 0) {
     mcap->cmo = icopy(default_cmo);          if (tbl->tag == tag) {
     mcap->cmd = icopy(default_cmd);              return tbl;
     return mcap;          }
           tbl++;
       }
       return NULL;
 }  }
   
 mathcap *new_mathcap_set(int *cmd, int *cmo)  /* controller about a cmo identified by the tag */
   static void table_ctl(table *tbl, int tag, int flag)
 {  {
     mathcap *mcap  = MALLOC(sizeof(mathcap));      table *e = table_lookup(tbl, tag);
         mcap->cmd = (cmd)? cmd: icopy(default_cmd);      if (e != NULL) {
         mcap->cmo = (cmo)? cmo: icopy(default_cmo);          e->flag = flag;
     return mcap;      }
 }  }
   
 cmo_list *cmo_mathcap_1st()  /* controller about all CMObjects */
   static void table_ctl_all(table *tbl, int flag)
 {  {
     char buffer[BUFSIZ];      while (tbl->tag != 0) {
     static char format[] = MATHCAP_1ST_FORMAT;          tbl->flag = flag;
     int len = sizeof(format) + 32          tbl++;
                 + strlen(sysinfo.sysname)  
                 + 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;  
 }  }
   
 /* 0: terminator of array of integer. */  /* getting the list of tags of all allowed objects */
 static int ilen(int a[])  static cmo_list *table_get_all(table *tbl)
 {  {
     int i=0;      cmo_list *list = new_cmo_list();
     if (a != NULL) {      while (tbl->tag != 0) {
         for( ; a[i] !=0; i++) {          if (tbl->flag == MATHCAP_FLAG_ALLOW) {
               list_append(list, (cmo *)new_cmo_int32(tbl->tag));
         }          }
           tbl++;
     }      }
     return i;      return list;
 }  }
   
 static int *icopy(int s[])  /* giving a permssion to send objects identified by the tag. */
   __inline__
   static void table_allow(table *tbl, int tag)
 {  {
     int n = sizeof(int)*(ilen(s)+1);      table_ctl(tbl, tag, MATHCAP_FLAG_ALLOW);
     int *d = MALLOC(n);  
     memcpy(d,s,n);  
     return d;  
 }  }
   
 static int *icopyn(int s[], int n)  /* taking a permssion to send objects identified by the tag. */
   __inline__
   static void table_deny(table *tbl, int tag)
 {  {
     int *d = MALLOC((n = sizeof(int)*(n+1)));      table_ctl(tbl, tag, MATHCAP_FLAG_DENY);
     memcpy(d,s,n);  
     return d;  
 }  }
   
 cmo_mathcap *new_cmo_mathcap_by_mathcap(mathcap *mcap)  static void table_update(table *cmotbl, cmo_list* types)
 {  {
     cmo_list *cap1, *cap2, *cap3, *cap4;      cell *el = list_first(types);
     cap1 = cmo_mathcap_1st();      cmo_int32 *ob;
     cap2 = new_cmo_list_map(mcap->cmd, ilen(mcap->cmd), new_cmo_int32);      while(!list_endof(types, el)) {
     cap3 = new_cmo_list_map(default_oxtag,          ob = (cmo_int32 *)el->cmo;
                             ilen(default_oxtag),          if (ob->tag == CMO_INT32) {
                             new_cmo_int32);              table_allow(cmotbl, ob->i);
     cap4 = new_cmo_list_map(mcap->cmo, ilen(mcap->cmo), new_cmo_int32);          }
     /* new_cmo_mathcap([cap1, cap2, [cap3, cap4]]) */          el = list_next(el);
     return new_cmo_mathcap(      }
         (cmo *)list_appendl(NULL, cap1, cap2, list_appendl(NULL, cap3, cap4, NULL)));  
 }  }
   
 static int cmo_int32_to_int(cmo_int32* m)  /* getting a permission to send objects identified by the tag. */
   static int table_allowQ_tag(table *tbl, int tag)
 {  {
     return m->i;      while (tbl->tag != 0 && tbl->tag != tag) {
           tbl++;
       }
       return tbl->flag;
 }  }
   
 mathcap *new_mathcap_by_cmo_mathcap(cmo_mathcap *cap)  static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob)
 {  {
     int *cmd = list_to_array_map(list_nth(cap->ob, 1), cmo_int32_to_int);      cell *el;
     int *cmo = list_to_array_map(list_nth(list_nth(cap->ob, 2), 1),      if (table_allowQ_tag(cmotbl, ob->tag)) {
                                  cmo_int32_to_int);          el = list_first(ob);
     return new_mathcap_set(cmd, cmo);          while (!list_endof(ob, el)) {
               if (!table_allowQ_cmo(cmotbl, el->cmo)) {
                   return MATHCAP_FLAG_DENY;
               }
               el = list_next(el);
           }
           return MATHCAP_FLAG_ALLOW;
       }
       return MATHCAP_FLAG_DENY;
 }  }
   
 /* if base is unsorted. */  __inline__
 static int *imerge(int *base, int *diff)  static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob)
 {  {
     int i,j,k;      return table_allowQ_tag(cmotbl, ob->tag)
     int n = ilen(base);          && table_allowQ_cmo(cmotbl, ob->coef);
     int m = ilen(diff);  }
     int *t = ALLOCA(sizeof(int)*(n+1));  
     int *ret;  __inline__
     for(i=0,j=0; i<n; i++) {  static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob)
         for(k=0; k<m; k++) {  {
             if (base[i] == diff[k]) {      return table_allowQ_tag(cmotbl, ob->tag)
                 t[j++] = base[i];          && table_allowQ_cmo(cmotbl, ob->ob);
                 break;  }
             }  
   /* getting a permission to send the following object. */
   static int table_allowQ_cmo(table *cmotbl, cmo *ob)
   {
       int tag = ob->tag;
       switch(tag) {
       case CMO_LIST:
       case CMO_DISTRIBUTED_POLYNOMIAL:
           return table_allowQ_cmo_list(cmotbl, (cmo_list *)ob);
       case CMO_MATHCAP:
       case CMO_ERROR2:
       case CMO_RING_BY_NAME:
       case CMO_INDETERMINATE:
           return table_allowQ_cmo_mathcap(cmotbl, (cmo_mathcap *)ob);
       case CMO_MONOMIAL32:
           return table_allowQ_cmo_monomial32(cmotbl, (cmo_monomial32 *)ob);
       default:
           return table_allowQ_tag(cmotbl, tag);
       }
   }
   
   /* getting the System Information */
   static cmo_list *sysinfo_get()
   {
       cmo_list *syslist = new_cmo_list();
       cmo_int32 *ver    = new_cmo_int32(sysinfo.version);
       cmo_string *vers  = new_cmo_string(sysinfo.version_string);
       cmo_string *host  = new_cmo_string(sysinfo.hosttype);
       cmo_string *sname = new_cmo_string(sysinfo.sysname);
       return list_appendl(syslist, ver, sname, vers, host, NULL);
   }
   
   static char *new_string(char *s)
   {
       char *t = MALLOC(strlen(s)+1);
       strcpy(t, s);
       return t;
   }
   
   static int *new_int_array(int *array)
   {
       int *new_array;
       int length = 0;
       while(array[length++] != 0)
           ;
       new_array = MALLOC(sizeof(int)*length);
       return memcpy(new_array, array, sizeof(int)*length);
   }
   
   void mathcap_init(int ver, char *vstr, char *sysname, int cmos[], int sms[])
   {
       mathcap_init2(ver, vstr, sysname, cmos, sms, NULL);
   }
   
   /* src must be terminated by NULL */
   static char **clone_str_list(char **src)
   {
       int i,len;
       char **new = NULL;
       if(src) {
           for(len=0; src[len]!=NULL; len++) {
         }          }
           new = (char **)MALLOC(sizeof(char *)*(len+1));
           new[len] = NULL;
           for(i=0; i<len; i++) {
               new[i] = (char *)MALLOC(strlen(src[i])+1);
               strcpy(new[i], src[i]);
           }
     }      }
     t[j] = 0;      return new;
     ret = icopyn(t,j);  
     return ret;  
 }  }
   
 static mathcap *mathcap_merge_io(mathcap *this, mathcap *diff)  /* options must be terminated by NULL */
   void mathcap_init2(int ver, char *vstr, char *sysname, int cmos[], int sms[], char *options[])
 {  {
     int *tmp;      char *host = getenv("HOSTTYPE");
     tmp = imerge(this->cmo, diff->cmo);      sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN";
     FREE(this->cmo);      sysinfo.sysname  = new_string(sysname);
     this->cmo = tmp;      sysinfo.version_string = new_string(vstr);
     return this;      sysinfo.version  = ver;
       if (cmos != NULL) {
           sysinfo.cmo_tags = new_int_array(cmos);
       }
       if (sms != NULL) {
           sysinfo.sm_cmds = new_int_array(sms);
       }
       sysinfo.opts = clone_str_list(options);
 }  }
   
 /* for compatibility */  mathcap *new_mathcap()
 void mathcap_init(char *version, char *sysname)  
 {  {
     sysinfo.hosttype = getenv("HOSTTYPE");      mathcap *new = MALLOC(sizeof(mathcap));
     sysinfo.version  = version;      new->cmotbl = new_table(sysinfo.cmo_tags);
     sysinfo.sysname  = sysname;      new->smtbl  = new_table(sysinfo.sm_cmds);
       new->opts   = clone_str_list(sysinfo.opts);
       return new;
 }  }
   
   /* generating a cmo_mathcap by a local database. */
 cmo_mathcap* mathcap_get(mathcap *this)  cmo_mathcap* mathcap_get(mathcap *this)
 {  {
     return new_cmo_mathcap_by_mathcap(this);      cmo_list *mc = new_cmo_list();
       cmo_list *l3 = new_cmo_list();
       cmo_list *si = sysinfo_get();
       cmo_list *sm=  table_get_all(this->smtbl);
       cmo_list *opts;
       int i;
   
       list_append(l3, (cmo *)list_appendl(new_cmo_list(),
                                    new_cmo_int32(OX_DATA),
                                    table_get_all(this->cmotbl), NULL));
       if(this->opts) {
           opts = new_cmo_list();
           for(i=0; this->opts[i]!=NULL; i++) {
               list_append(opts, (cmo *)new_cmo_string(this->opts[i]));
           }
           list_appendl(mc, (cmo *)si, (cmo *)sm, (cmo *)l3, (cmo *)opts, NULL);
       }else {
           list_appendl(mc, (cmo *)si, (cmo *)sm, (cmo *)l3, NULL);
       }
       return new_cmo_mathcap((cmo *)mc);
 }  }
 mathcap *mathcap_update(mathcap *this, cmo_mathcap *m)  
   /* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... )  */
   /*                ^^^^^ Here!                          */
   static cmo_list *get_messagetypes(cmo_list *ob, int type)
 {  {
     return mathcap_merge_io(this, new_mathcap_by_cmo_mathcap(m));      cmo_list  *c;
       cell *el;
   
       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->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 get_messagetypes(ob, OX_DATA);
   }
   
   /* The mathcap_update integrates received cmo_mathcap into the mathcap
      database. If this == NULL, then an instance of mathcap is generated. */
   mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc)
   {
       cmo_list *types;
       types = cmo_mathcap_get_cmotypes(mc);
       if (types != NULL) {
           table_ctl_all(this->cmotbl, MATHCAP_FLAG_DENY);
           table_update(this->cmotbl, types);
       }
   
       return this;
   }
   
   int mathcap_allowQ_cmo(mathcap *this, cmo *ob)
   {
       return table_allowQ_cmo(this->cmotbl, ob);
 }  }

Legend:
Removed from v.1.12  
changed lines
  Added in v.1.18

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