version 1.1, 2000/10/10 05:23:20 |
version 1.12, 2005/07/26 12:52:05 |
|
|
/* -*- mode: C; coding: euc-japan -*- */ |
/* -*- mode: C; coding: euc-japan -*- */ |
/* $OpenXM$ */ |
/* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.11 2005/03/04 06:29:46 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 "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; |
|
} mc_cell; |
|
|
|
static int mathcap_cmo_isallow_tag(int tag); |
static int default_cmd[] = { |
static mc_cell *mathcap_cmo_lookup(int tag); |
|
static int mathcap_cmo_isallow_cmo_list(cmo_list *ob); |
|
static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob); |
|
static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob); |
|
static char *new_string(char *s); |
|
static void mathcap_cmo_update(cmo_list* types); |
|
static cmo_list *get_messagetypes(cmo_list *ob, int type); |
|
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc); |
|
static cmo_list *get_messagetypes(cmo_list *ob, int type); |
|
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc); |
|
|
|
static mc_cell mathcap_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 int mathcap_sm[] = { |
|
SM_popCMO, |
SM_popCMO, |
SM_popString, |
SM_popString, |
SM_mathcap, |
SM_mathcap, |
SM_pops, |
SM_pops, |
SM_executeStringByLocalParser, |
SM_executeStringByLocalParser, |
SM_executeFunction, |
SM_executeFunction, |
SM_setMathCap, |
|
SM_shutdown, |
|
SM_control_kill, |
SM_control_kill, |
SM_control_reset_connection, |
SM_control_reset_connection, |
0 |
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 struct { |
static struct { |
int version; |
int ox_version; |
char *version_string; |
|
char *sysname; |
char *sysname; |
|
char *version; |
char *hosttype; |
char *hosttype; |
} mathcap_sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN"}; |
} sysinfo = {OX_PROTOCOL_VERSION, "ox_toolkit", OX_TOOLKIT_VERSION, "generic"}; |
|
|
/* 次の tag をもつ cmo の送信が許可されているかを調べる */ |
mathcap default_mathcap = {default_cmd, default_cmo}; |
static int mathcap_cmo_isallow_tag(int tag) |
|
{ |
|
mc_cell *e = mathcap_cmo; |
|
while (e->tag != 0 && e->tag != tag) { |
|
e++; |
|
} |
|
return e->flag; |
|
} |
|
|
|
/* 次の tag についてのキーを探す */ |
static int ilen(int a[]); |
static mc_cell *mathcap_cmo_lookup(int tag) |
static int *icopy(int s[]); |
{ |
static int *icopyn(int s[], int n); |
mc_cell *e = mathcap_cmo; |
static int cmo_int32_to_int(cmo_int32* m); |
while (e->tag != 0) { |
static int *imerge(int *base, int *diff); |
if (e->tag == tag) { |
static mathcap *mathcap_merge_io(mathcap *this, mathcap *diff); |
return e; |
|
} |
|
e++; |
|
} |
|
return NULL; |
|
} |
|
|
|
static int mathcap_cmo_isallow_cmo_list(cmo_list *ob) |
mathcap *new_mathcap() |
{ |
{ |
cell *el; |
mathcap *mcap = MALLOC(sizeof(mathcap)); |
if (mathcap_cmo_isallow_tag(ob->tag)) { |
mcap->cmo = icopy(default_cmo); |
el = list_first(ob); |
mcap->cmd = icopy(default_cmd); |
while (!list_endof(ob, el)) { |
return mcap; |
if (!mathcap_cmo_isallow_cmo(el->cmo)) { |
|
return MATHCAP_FLAG_DENY; |
|
} |
|
el = list_next(el); |
|
} |
|
return MATHCAP_FLAG_ALLOW; |
|
} |
|
return MATHCAP_FLAG_DENY; |
|
} |
} |
|
|
static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob) |
mathcap *new_mathcap_set(int *cmd, int *cmo) |
{ |
{ |
return mathcap_cmo_isallow_tag(ob->tag) |
mathcap *mcap = MALLOC(sizeof(mathcap)); |
&& mathcap_cmo_isallow_cmo(ob->coef); |
mcap->cmd = (cmd)? cmd: icopy(default_cmd); |
|
mcap->cmo = (cmo)? cmo: icopy(default_cmo); |
|
return mcap; |
} |
} |
|
|
static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob) |
cmo_list *cmo_mathcap_1st() |
{ |
{ |
return mathcap_cmo_isallow_tag(ob->tag) |
char buffer[BUFSIZ]; |
&& mathcap_cmo_isallow_cmo(ob->ob); |
static char format[] = MATHCAP_1ST_FORMAT; |
} |
int len = sizeof(format) + 32 |
|
+ strlen(sysinfo.sysname) |
/* 次の cmo の送信が許可されているかを調べる */ |
+ strlen(sysinfo.version) |
int mathcap_cmo_isallow_cmo(cmo *ob) |
+ strlen(sysinfo.hosttype); |
{ |
if (len < BUFSIZ) { |
int tag = ob->tag; |
sprintf(buffer, format, sysinfo.ox_version, sysinfo.sysname, |
switch(tag) { |
sysinfo.version, sysinfo.hosttype); |
case CMO_LIST: |
return (cmo_list *)ox_parse_lisp(buffer); |
case CMO_DISTRIBUTED_POLYNOMIAL: |
|
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); |
|
} |
} |
|
return NULL; |
} |
} |
|
|
/* 次の tag をもつ cmo の送信を許可する */ |
/* 0: terminator of array of integer. */ |
void mathcap_cmo_allow(int tag) |
static int ilen(int a[]) |
{ |
{ |
mc_cell *e = mathcap_cmo_lookup(tag); |
int i=0; |
if (e != NULL) { |
if (a != NULL) { |
e->flag = MATHCAP_FLAG_ALLOW; |
for( ; a[i] !=0; i++) { |
} |
|
} |
|
|
|
/* 次の tag をもつ cmo の送信を不許可にする */ |
|
void mathcap_cmo_deny(int tag) |
|
{ |
|
mc_cell *e = mathcap_cmo_lookup(tag); |
|
if (e != NULL) { |
|
e->flag = MATHCAP_FLAG_DENY; |
|
} |
|
} |
|
|
|
/* 全ての種類の cmo の送信を不許可にする */ |
|
void mathcap_cmo_deny_all() |
|
{ |
|
mc_cell *e = mathcap_cmo; |
|
while (e->tag != 0) { |
|
e->flag = MATHCAP_FLAG_DENY; |
|
e++; |
|
} |
|
} |
|
|
|
/* 全ての種類の cmo の送信を許可する */ |
|
void mathcap_cmo_allow_all() |
|
{ |
|
mc_cell *e = mathcap_cmo; |
|
while (e->tag != 0) { |
|
e->flag = MATHCAP_FLAG_ALLOW; |
|
e++; |
|
} |
|
} |
|
|
|
/* 送信許可されている cmo のリストを得る */ |
|
cmo_list *mathcap_cmo_get_allow_all() |
|
{ |
|
cmo_list *list = new_cmo_list(); |
|
mc_cell *e = mathcap_cmo; |
|
while (e->tag != 0) { |
|
if (e->flag != MATHCAP_FLAG_DENY) { |
|
list_append(list, new_cmo_int32(e->tag)); |
|
} |
} |
e++; |
|
} |
} |
return list; |
return i; |
} |
} |
|
|
/* 既知の sm コマンドのリストを得る */ |
static int *icopy(int s[]) |
cmo_list *mathcap_sm_get_all() |
|
{ |
{ |
cmo_list *list = new_cmo_list(); |
int n = sizeof(int)*(ilen(s)+1); |
int i; |
int *d = MALLOC(n); |
for(i=0; mathcap_sm[i] != 0; i++) { |
memcpy(d,s,n); |
list_append(list, new_cmo_int32(mathcap_sm[i])); |
return d; |
} |
|
return list; |
|
} |
} |
|
|
/* システム情報を得る */ |
static int *icopyn(int s[], int n) |
cmo_list *mathcap_sysinfo_get_all() |
|
{ |
{ |
cmo_list *syslist = new_cmo_list(); |
int *d = MALLOC((n = sizeof(int)*(n+1))); |
cmo_int32 *ver = new_cmo_int32(mathcap_sysinfo.version); |
memcpy(d,s,n); |
cmo_string *vers = new_cmo_string(mathcap_sysinfo.version_string); |
return d; |
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) |
cmo_mathcap *new_cmo_mathcap_by_mathcap(mathcap *mcap) |
{ |
{ |
char *t = malloc(sizeof(s)+1); |
cmo_list *cap1, *cap2, *cap3, *cap4; |
strcpy(t, s); |
cap1 = cmo_mathcap_1st(); |
return t; |
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))); |
} |
} |
|
|
void mathcap_sysinfo_set(int version, char *version_string, char *sysname) |
static int cmo_int32_to_int(cmo_int32* m) |
{ |
{ |
char *host = getenv("HOSTTYPE"); |
return m->i; |
|
|
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 を生成する */ |
mathcap *new_mathcap_by_cmo_mathcap(cmo_mathcap *cap) |
cmo_mathcap* mathcap_get() |
|
{ |
{ |
cmo_list *mc = new_cmo_list(); |
int *cmd = list_to_array_map(list_nth(cap->ob, 1), cmo_int32_to_int); |
cmo_list *l3 = new_cmo_list(); |
int *cmo = list_to_array_map(list_nth(list_nth(cap->ob, 2), 1), |
list_append(l3, list_appendl(new_cmo_list(), new_cmo_int32(OX_DATA), mathcap_cmo_get_allow_all(), NULL)); |
cmo_int32_to_int); |
list_appendl(mc, (cmo *)mathcap_sysinfo_get_all(), (cmo *)mathcap_sm_get_all(), (cmo *)l3, NULL); |
return new_mathcap_set(cmd, cmo); |
return new_cmo_mathcap((cmo *)mc); |
|
} |
} |
|
|
static void mathcap_cmo_update(cmo_list* types) |
/* if base is unsorted. */ |
|
static int *imerge(int *base, int *diff) |
{ |
{ |
cell *el = list_first(types); |
int i,j,k; |
cmo_int32 *ob; |
int n = ilen(base); |
while(!list_endof(types, el)) { |
int m = ilen(diff); |
ob = (cmo_int32 *)el->cmo; |
int *t = ALLOCA(sizeof(int)*(n+1)); |
if (ob->tag == CMO_INT32) { |
int *ret; |
mathcap_cmo_allow(ob->i); |
for(i=0,j=0; i<n; i++) { |
|
for(k=0; k<m; k++) { |
|
if (base[i] == diff[k]) { |
|
t[j++] = base[i]; |
|
break; |
|
} |
} |
} |
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! */ |
|
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); |
|
} |
|
} |
|
} |
} |
|
|
/* 互換性のため */ |
|
cmo* make_mathcap_object(int version, char *id_string) |
|
{ |
|
mathcap_sysinfo_set(version, id_string, "ox_math"); |
|
return (cmo *)mathcap_get(); |
|
} |
|
|
|