| version 1.12.2.1, 2005/10/12 03:49:17 |
version 1.17, 2016/08/23 02:24:19 |
|
|
| /* -*- mode: C; coding: euc-japan -*- */ |
/* -*- mode: C; coding: euc-japan -*- */ |
| /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.12 2005/07/26 12:52:05 ohara Exp $ */ |
/* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.16 2016/06/29 05:07:23 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 <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); |
| } |
} |