File: [local] / OpenXM / src / ox_toolkit / mathcap.c (download)
Revision 1.1, Tue Oct 10 05:23:20 2000 UTC (23 years, 7 months ago) by ohara
Branch: MAIN
ox_toolkit is up to date.
0. OXFILE is introduced.
1. we support new method of ox connection.
2. we support exchaging byte order.
(in possible, we choose a byte order of machine integer).
3. cmo_list is rewritten.
4. we support a mathcap database.
etc.
Sorry, I forgot many changes.
|
/* -*- mode: C; coding: euc-japan -*- */
/* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.1 2000/10/10 05:23:20 ohara Exp $ */
/* This module includes functions for handling mathcap databases. */
#include <stdlib.h>
#include "ox_toolkit.h"
typedef struct {
int tag;
int flag;
} mc_cell;
static int mathcap_cmo_isallow_tag(int tag);
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_popString,
SM_mathcap,
SM_pops,
SM_executeStringByLocalParser,
SM_executeFunction,
SM_setMathCap,
SM_shutdown,
SM_control_kill,
SM_control_reset_connection,
0
};
static struct {
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)
{
mc_cell *e = mathcap_cmo;
while (e->tag != 0 && e->tag != tag) {
e++;
}
return e->flag;
}
/* 次の tag についてのキーを探す */
static mc_cell *mathcap_cmo_lookup(int tag)
{
mc_cell *e = mathcap_cmo;
while (e->tag != 0) {
if (e->tag == tag) {
return e;
}
e++;
}
return NULL;
}
static int mathcap_cmo_isallow_cmo_list(cmo_list *ob)
{
cell *el;
if (mathcap_cmo_isallow_tag(ob->tag)) {
el = list_first(ob);
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)
{
return mathcap_cmo_isallow_tag(ob->tag)
&& mathcap_cmo_isallow_cmo(ob->coef);
}
static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob)
{
return mathcap_cmo_isallow_tag(ob->tag)
&& mathcap_cmo_isallow_cmo(ob->ob);
}
/* 次の cmo の送信が許可されているかを調べる */
int mathcap_cmo_isallow_cmo(cmo *ob)
{
int tag = ob->tag;
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 の送信を許可する */
void mathcap_cmo_allow(int tag)
{
mc_cell *e = mathcap_cmo_lookup(tag);
if (e != NULL) {
e->flag = MATHCAP_FLAG_ALLOW;
}
}
/* 次の 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;
}
/* 既知の sm コマンドのリストを得る */
cmo_list *mathcap_sm_get_all()
{
cmo_list *list = new_cmo_list();
int i;
for(i=0; mathcap_sm[i] != 0; i++) {
list_append(list, new_cmo_int32(mathcap_sm[i]));
}
return list;
}
/* システム情報を得る */
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);
}
}
/* cmo_mathcap が妥当な構造を持つかを調べる. (未実装) */
int cmo_mathcap_isvalid(cmo_mathcap *mc)
{
return 1;
}
/* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */
/* ^^^^^ Here! */
static cmo_list *get_messagetypes(cmo_list *ob, int type)
{
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! */
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);
}
/* 受信した mathcap データを反映させる */
void mathcap_update(cmo_mathcap *mc)
{
cmo_list *types;
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();
}