version 1.1, 2000/10/10 05:23:20 |
version 1.6, 2000/11/27 09:57:10 |
|
|
/* -*- mode: C; coding: euc-japan -*- */ |
/* -*- mode: C; coding: euc-japan -*- */ |
/* $OpenXM$ */ |
/* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.5 2000/11/24 05:49:26 ohara Exp $ */ |
|
|
/* This module includes functions for handling mathcap databases. */ |
/* This module includes functions for handling mathcap databases. */ |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
|
#include <string.h> |
#include "ox_toolkit.h" |
#include "ox_toolkit.h" |
|
|
typedef struct { |
#define MATHCAP_FLAG_DENY 0 |
int tag; |
#define MATHCAP_FLAG_ALLOW 1 |
int flag; |
|
} mc_cell; |
|
|
|
static int mathcap_cmo_isallow_tag(int tag); |
static void table_init(table *m, int key); |
static mc_cell *mathcap_cmo_lookup(int tag); |
static table *new_table(int *src); |
static int mathcap_cmo_isallow_cmo_list(cmo_list *ob); |
static table *table_lookup(table *tbl, int tag); |
static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob); |
static void table_ctl(table *tbl, int tag, int flag); |
static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob); |
static void table_ctl_all(table *tbl, int flag); |
|
static cmo_list *table_get_all(table *tbl); |
|
static void table_allow(table *tbl, int tag); |
|
static void table_deny(table *tbl, int tag); |
|
static void table_update(table *cmotbl, cmo_list* types); |
|
static int table_allowQ_tag(table *tbl, int tag); |
|
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 char *new_string(char *s); |
static void mathcap_cmo_update(cmo_list* types); |
static int *new_int_array(int *array); |
static cmo_list *get_messagetypes(cmo_list *ob, int type); |
static cmo_list *get_messagetypes(cmo_list *ob, int type); |
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc); |
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[] = { |
static int cmotbl_a[] = { |
{CMO_NULL, MATHCAP_FLAG_ALLOW}, |
CMO_NULL, |
{CMO_INT32, MATHCAP_FLAG_ALLOW}, |
CMO_INT32, |
{CMO_DATUM, MATHCAP_FLAG_ALLOW}, |
CMO_DATUM, |
{CMO_STRING, MATHCAP_FLAG_ALLOW}, |
CMO_STRING, |
{CMO_MATHCAP, MATHCAP_FLAG_ALLOW}, |
CMO_MATHCAP, |
{CMO_LIST, MATHCAP_FLAG_ALLOW}, |
CMO_LIST, |
{CMO_MONOMIAL32, MATHCAP_FLAG_ALLOW}, |
CMO_MONOMIAL32, |
{CMO_ZZ, MATHCAP_FLAG_ALLOW}, |
CMO_ZZ, |
{CMO_ZERO, MATHCAP_FLAG_ALLOW}, |
CMO_ZERO, |
{CMO_DMS_GENERIC, MATHCAP_FLAG_ALLOW}, |
CMO_DMS_GENERIC, |
{CMO_RING_BY_NAME, MATHCAP_FLAG_ALLOW}, |
CMO_RING_BY_NAME, |
{CMO_INDETERMINATE, MATHCAP_FLAG_ALLOW}, |
CMO_INDETERMINATE, |
{CMO_DISTRIBUTED_POLYNOMIAL, MATHCAP_FLAG_ALLOW}, |
CMO_DISTRIBUTED_POLYNOMIAL, |
{CMO_ERROR2, MATHCAP_FLAG_ALLOW}, |
CMO_ERROR2, |
{0, MATHCAP_FLAG_DENY} |
0, |
}; |
}; |
|
|
static int mathcap_sm[] = { |
static int smtbl_a[] = { |
SM_popCMO, |
SM_popCMO, |
SM_popString, |
SM_popString, |
SM_mathcap, |
SM_mathcap, |
Line 52 static int mathcap_sm[] = { |
|
Line 59 static int mathcap_sm[] = { |
|
SM_shutdown, |
SM_shutdown, |
SM_control_kill, |
SM_control_kill, |
SM_control_reset_connection, |
SM_control_reset_connection, |
0 |
SM_control_spawn_server, |
|
SM_control_terminate_server, |
|
0, |
}; |
}; |
|
|
static struct { |
static struct { |
|
|
char *version_string; |
char *version_string; |
char *sysname; |
char *sysname; |
char *hosttype; |
char *hosttype; |
} mathcap_sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN"}; |
int *cmo_tags; |
|
int *sm_cmds; |
|
} sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN", cmotbl_a, smtbl_a}; |
|
|
/* 次の tag をもつ cmo の送信が許可されているかを調べる */ |
__inline__ |
static int mathcap_cmo_isallow_tag(int tag) |
static void table_init(table *m, int key) |
{ |
{ |
mc_cell *e = mathcap_cmo; |
m->tag = key; |
while (e->tag != 0 && e->tag != tag) { |
m->flag = MATHCAP_FLAG_ALLOW; |
e++; |
} |
|
|
|
static table *new_table(int *src) |
|
{ |
|
table *new; |
|
int len=0; |
|
int i; |
|
while (src[len++] != 0) { |
} |
} |
return e->flag; |
new = malloc(sizeof(table)*len); |
|
for(i=0; i<len; i++) { |
|
table_init(new+i, src[i]); |
|
} |
|
return new; |
} |
} |
|
|
/* 次の tag についてのキーを探す */ |
/* 次の tag についてのキーを探す */ |
static mc_cell *mathcap_cmo_lookup(int tag) |
static table *table_lookup(table *tbl, int tag) |
{ |
{ |
mc_cell *e = mathcap_cmo; |
while (tbl->tag != 0) { |
while (e->tag != 0) { |
if (tbl->tag == tag) { |
if (e->tag == tag) { |
return tbl; |
return e; |
|
} |
} |
e++; |
tbl++; |
} |
} |
return NULL; |
return NULL; |
} |
} |
|
|
static int mathcap_cmo_isallow_cmo_list(cmo_list *ob) |
/* tag に対する送信制御 */ |
|
static void table_ctl(table *tbl, int tag, int flag) |
{ |
{ |
cell *el; |
table *e = table_lookup(tbl, tag); |
if (mathcap_cmo_isallow_tag(ob->tag)) { |
if (e != NULL) { |
el = list_first(ob); |
e->flag = flag; |
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; |
|
} |
} |
|
|
static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob) |
/* 全データに対する送信制御 */ |
|
static void table_ctl_all(table *tbl, int flag) |
{ |
{ |
return mathcap_cmo_isallow_tag(ob->tag) |
while (tbl->tag != 0) { |
&& mathcap_cmo_isallow_cmo(ob->coef); |
tbl->flag = flag; |
|
tbl++; |
|
} |
} |
} |
|
|
static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob) |
/* 送信許可されている tag のリストを得る */ |
|
static cmo_list *table_get_all(table *tbl) |
{ |
{ |
return mathcap_cmo_isallow_tag(ob->tag) |
cmo_list *list = new_cmo_list(); |
&& mathcap_cmo_isallow_cmo(ob->ob); |
while (tbl->tag != 0) { |
|
if (tbl->flag == MATHCAP_FLAG_ALLOW) { |
|
list_append(list, (cmo *)new_cmo_int32(tbl->tag)); |
|
} |
|
tbl++; |
|
} |
|
return list; |
} |
} |
|
|
/* 次の cmo の送信が許可されているかを調べる */ |
/* 次の tag をもつ cmo or sm_cmd の送信を許可する */ |
int mathcap_cmo_isallow_cmo(cmo *ob) |
__inline__ |
|
static void table_allow(table *tbl, int tag) |
{ |
{ |
int tag = ob->tag; |
table_ctl(tbl, tag, MATHCAP_FLAG_ALLOW); |
switch(tag) { |
|
case CMO_LIST: |
|
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); |
|
} |
|
} |
} |
|
|
/* 次の tag をもつ cmo の送信を許可する */ |
/* 次の tag をもつ cmo or sm_cmd の送信を不許可にする */ |
void mathcap_cmo_allow(int tag) |
__inline__ |
|
static void table_deny(table *tbl, int tag) |
{ |
{ |
mc_cell *e = mathcap_cmo_lookup(tag); |
table_ctl(tbl, tag, MATHCAP_FLAG_DENY); |
if (e != NULL) { |
|
e->flag = MATHCAP_FLAG_ALLOW; |
|
} |
|
} |
} |
|
|
/* 次の tag をもつ cmo の送信を不許可にする */ |
static void table_update(table *cmotbl, cmo_list* types) |
void mathcap_cmo_deny(int tag) |
|
{ |
{ |
mc_cell *e = mathcap_cmo_lookup(tag); |
cell *el = list_first(types); |
if (e != NULL) { |
cmo_int32 *ob; |
e->flag = MATHCAP_FLAG_DENY; |
while(!list_endof(types, el)) { |
|
ob = (cmo_int32 *)el->cmo; |
|
if (ob->tag == CMO_INT32) { |
|
table_allow(cmotbl, ob->i); |
|
} |
|
el = list_next(el); |
} |
} |
} |
} |
|
|
/* 全ての種類の cmo の送信を不許可にする */ |
/* 次の tag をもつ cmo or sm_cmd の送信が許可されているかを調べる */ |
void mathcap_cmo_deny_all() |
static int table_allowQ_tag(table *tbl, int tag) |
{ |
{ |
mc_cell *e = mathcap_cmo; |
while (tbl->tag != 0 && tbl->tag != tag) { |
while (e->tag != 0) { |
tbl++; |
e->flag = MATHCAP_FLAG_DENY; |
|
e++; |
|
} |
} |
|
return tbl->flag; |
} |
} |
|
|
/* 全ての種類の cmo の送信を許可する */ |
static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob) |
void mathcap_cmo_allow_all() |
|
{ |
{ |
mc_cell *e = mathcap_cmo; |
cell *el; |
while (e->tag != 0) { |
if (table_allowQ_tag(cmotbl, ob->tag)) { |
e->flag = MATHCAP_FLAG_ALLOW; |
el = list_first(ob); |
e++; |
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; |
} |
} |
|
|
/* 送信許可されている cmo のリストを得る */ |
__inline__ |
cmo_list *mathcap_cmo_get_allow_all() |
static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob) |
{ |
{ |
cmo_list *list = new_cmo_list(); |
return table_allowQ_tag(cmotbl, ob->tag) |
mc_cell *e = mathcap_cmo; |
&& table_allowQ_cmo(cmotbl, ob->coef); |
while (e->tag != 0) { |
|
if (e->flag != MATHCAP_FLAG_DENY) { |
|
list_append(list, new_cmo_int32(e->tag)); |
|
} |
|
e++; |
|
} |
|
return list; |
|
} |
} |
|
|
/* 既知の sm コマンドのリストを得る */ |
__inline__ |
cmo_list *mathcap_sm_get_all() |
static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob) |
{ |
{ |
cmo_list *list = new_cmo_list(); |
return table_allowQ_tag(cmotbl, ob->tag) |
int i; |
&& table_allowQ_cmo(cmotbl, ob->ob); |
for(i=0; mathcap_sm[i] != 0; i++) { |
} |
list_append(list, new_cmo_int32(mathcap_sm[i])); |
|
|
/* 次の cmo の送信が許可されているかを調べる */ |
|
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); |
} |
} |
return list; |
|
} |
} |
|
|
/* システム情報を得る */ |
/* システム情報を得る */ |
cmo_list *mathcap_sysinfo_get_all() |
static cmo_list *sysinfo_get() |
{ |
{ |
cmo_list *syslist = new_cmo_list(); |
cmo_list *syslist = new_cmo_list(); |
cmo_int32 *ver = new_cmo_int32(mathcap_sysinfo.version); |
cmo_int32 *ver = new_cmo_int32(sysinfo.version); |
cmo_string *vers = new_cmo_string(mathcap_sysinfo.version_string); |
cmo_string *vers = new_cmo_string(sysinfo.version_string); |
cmo_string *host = new_cmo_string(mathcap_sysinfo.hosttype); |
cmo_string *host = new_cmo_string(sysinfo.hosttype); |
cmo_string *sname = new_cmo_string(mathcap_sysinfo.sysname); |
cmo_string *sname = new_cmo_string(sysinfo.sysname); |
return list_appendl(syslist, ver, sname, vers, host); |
return list_appendl(syslist, ver, sname, vers, host, NULL); |
} |
} |
|
|
static char *new_string(char *s) |
static char *new_string(char *s) |
Line 214 static char *new_string(char *s) |
|
Line 241 static char *new_string(char *s) |
|
return t; |
return t; |
} |
} |
|
|
void mathcap_sysinfo_set(int version, char *version_string, char *sysname) |
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[]) |
|
{ |
char *host = getenv("HOSTTYPE"); |
char *host = getenv("HOSTTYPE"); |
|
sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN"; |
|
sysinfo.sysname = new_string(sysname); |
|
sysinfo.version_string = new_string(vstr); |
|
sysinfo.version = ver; |
|
if (cmos != NULL) { |
|
sysinfo.cmo_tags = new_int_array(cmos); |
|
} |
|
if (sms != NULL) { |
|
sysinfo.sm_cmds = new_int_array(sms); |
|
} |
|
} |
|
|
mathcap_sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN"; |
mathcap *new_mathcap() |
mathcap_sysinfo.sysname = new_string(sysname); |
{ |
mathcap_sysinfo.version_string = new_string(version_string); |
mathcap *new = malloc(sizeof(mathcap)); |
mathcap_sysinfo.version = version; |
new->cmotbl = new_table(sysinfo.cmo_tags); |
|
new->smtbl = new_table(sysinfo.sm_cmds); |
|
return new; |
} |
} |
|
|
/* データベースから cmo_mathcap を生成する */ |
/* データベースから cmo_mathcap を生成する */ |
cmo_mathcap* mathcap_get() |
cmo_mathcap* mathcap_get(mathcap *this) |
{ |
{ |
cmo_list *mc = new_cmo_list(); |
cmo_list *mc = new_cmo_list(); |
cmo_list *l3 = 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_append(l3, list_appendl(new_cmo_list(), |
list_appendl(mc, (cmo *)mathcap_sysinfo_get_all(), (cmo *)mathcap_sm_get_all(), (cmo *)l3, NULL); |
new_cmo_int32(OX_DATA), |
|
table_get_all(this->cmotbl), NULL)); |
|
list_appendl(mc, (cmo *)sysinfo_get(), |
|
(cmo *)table_get_all(this->smtbl), (cmo *)l3, NULL); |
return new_cmo_mathcap((cmo *)mc); |
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); |
|
} |
|
} |
|
|
|
/* cmo_mathcap が妥当な構造を持つかを調べる. (未実装) */ |
|
int cmo_mathcap_isvalid(cmo_mathcap *mc) |
|
{ |
|
return 1; |
|
} |
|
|
|
/* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */ |
/* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */ |
/* ^^^^^ Here! */ |
/* ^^^^^ Here! */ |
static cmo_list *get_messagetypes(cmo_list *ob, int type) |
static cmo_list *get_messagetypes(cmo_list *ob, int type) |
Line 271 static cmo_list *get_messagetypes(cmo_list *ob, int ty |
|
Line 305 static cmo_list *get_messagetypes(cmo_list *ob, int ty |
|
|
|
/* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */ |
/* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */ |
/* ^^^^^ Here! */ |
/* ^^^^^ Here! */ |
|
__inline__ |
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc) |
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc) |
{ |
{ |
cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2); |
cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2); |
Line 278 static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap |
|
Line 313 static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap |
|
} |
} |
|
|
/* 受信した mathcap データを反映させる */ |
/* 受信した mathcap データを反映させる */ |
void mathcap_update(cmo_mathcap *mc) |
/* this == NULL のとき、はじめて mathcap* オブジェクトをせいせいする */ |
|
mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc) |
{ |
{ |
cmo_list *types; |
cmo_list *types; |
if (cmo_mathcap_isvalid(mc)) { |
types = cmo_mathcap_get_cmotypes(mc); |
types = cmo_mathcap_get_cmotypes(mc); |
if (types != NULL) { |
if (types != NULL) { |
/* すべての cmo の送信を禁止 */ |
mathcap_cmo_deny_all(); /* すべての cmo の送信を禁止 */ |
table_ctl_all(this->cmotbl, MATHCAP_FLAG_DENY); |
mathcap_cmo_update(types); |
table_update(this->cmotbl, types); |
} |
|
} |
} |
|
|
|
return this; |
} |
} |
|
|
/* 互換性のため */ |
int mathcap_allowQ_cmo(mathcap *this, cmo *ob) |
cmo* make_mathcap_object(int version, char *id_string) |
|
{ |
{ |
mathcap_sysinfo_set(version, id_string, "ox_math"); |
return table_allowQ_cmo(this->cmotbl, ob); |
return (cmo *)mathcap_get(); |
|
} |
} |
|
|