[BACK]Return to mathcap.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_toolkit

File: [local] / OpenXM / src / ox_toolkit / mathcap.c (download)

Revision 1.3, Sat Nov 18 05:49:18 2000 UTC (23 years, 6 months ago) by ohara
Branch: MAIN
Changes since 1.2: +140 -134 lines

a tentative code.

/* -*- mode: C; coding: euc-japan -*- */
/* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.3 2000/11/18 05:49:18 ohara Exp $ */

/* This module includes functions for handling mathcap databases. */

#include <stdlib.h>
#include "ox_toolkit.h"

/* 送信許可されている cmo, sm のリストを得る */
#define smdb_get_allow_all(x)   mcdb_get_allow_all((x)->sm_db)
#define cmodb_get_allow_all(x)  mcdb_get_allow_all((x)->cmo_db)

/* 全ての種類の cmo の送信を許可/不許可にする */
#define cmodb_deny_all(x)   mcdb_ctl_all((x), MATHCAP_FLAG_DENY)
#define cmodb_allow_all(x)  mcdb_ctl_all((x), MATHCAP_FLAG_ALLOW)

typedef struct {
    int tag;
    int flag;
} mcdb;

typedef struct {
    mcdb *cmo_db;
    mcdb *sm_db;
} mathcap;

static char *new_string(char *s);
static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
static cmo_list *get_messagetypes(cmo_list *ob, int type);
static cmo_list *mcdb_get_allow_all(mcdb *db);
static cmo_list *sysinfo_get_all();
static int cmodb_isallow_cmo(mcdb *cmo_db, cmo *ob);
static int cmodb_isallow_cmo_list(mcdb *cmo_db, cmo_list *ob);
static int cmodb_isallow_cmo_mathcap(mcdb *cmo_db, cmo_mathcap *ob);
static int cmodb_isallow_cmo_monomial32(mcdb *cmo_db, cmo_monomial32 *ob);
static int cmodb_isallow_tag(mcdb *cmo_db, int tag);
static mcdb *mcdb_lookup(mcdb *db, int tag);
static mcdb *new_mcdb(int *src);
static void cmodb_allow(mcdb *cmo_db, int tag);
static void cmodb_deny(mcdb *cmo_db, int tag);
static void cmodb_update(mcdb *cmo_db, cmo_list* types);
static void mcdb_ctl(mcdb *db, int tag, int flag);
static void mcdb_ctl_all(mcdb *db, int flag);
static void mcdb_init(mcdb *m, int key);
void sysinfo_set(int version, char *version_string, char *sysname);

static int cmodb_d[] = {
    CMO_NULL,
    CMO_INT32,
    CMO_DATUM,
    CMO_STRING,
    CMO_MATHCAP,
    CMO_LIST,
    CMO_MONOMIAL32,
    CMO_ZZ,
    CMO_ZERO,
    CMO_DMS_GENERIC,
    CMO_RING_BY_NAME,
    CMO_INDETERMINATE,
    CMO_DISTRIBUTED_POLYNOMIAL,
    CMO_ERROR2,
    0,
};

static int smdb_d[] = {
    SM_popCMO,
    SM_popString,
    SM_mathcap,
    SM_pops,
    SM_executeStringByLocalParser,
    SM_executeFunction,
    SM_setMathCap,
    SM_shutdown,
    SM_control_kill,
    SM_control_reset_connection,
    0,
};

__inline__
static void mcdb_init(mcdb *m, int key)
{
    m->tag  = key;
    m->flag = MATHCAP_FLAG_ALLOW;
}

static mcdb *new_mcdb(int *src)
{
    mcdb *new;
    int len=0;
    int i;
    while (src[len++] != 0) {
    }
    new = malloc(sizeof(mcdb)*len);
    for(i=0; i<len; i++) {
        mcdb_init(new+i, src[i]);
    }
    return new;
}

mathcap *new_mathcap_d()
{
    mathcap *new = malloc(sizeof(mathcap));
    new->cmo_db = new_mcdb(cmodb_d);
    new->sm_db  = new_mcdb(smdb_d);
    return new;
}

/* 次の tag についてのキーを探す */
static mcdb *mcdb_lookup(mcdb *db, int tag)
{
    while (db->tag != 0) {
        if (db->tag == tag) {
            return db;
        }
        db++;
    }
    return NULL;
}

/* tag に対する送信制御 */
static void mcdb_ctl(mcdb *db, int tag, int flag)
{
    mcdb *e = mcdb_lookup(db, tag);
    if (e != NULL) {
        e->flag = flag;
    }
}

/* 全データに対する送信制御 */
static void mcdb_ctl_all(mcdb *db, int flag)
{
    while (db->tag != 0) {
        db->flag = flag;
        db++;
    }
}

/* 送信許可されている tag のリストを得る */
static cmo_list *mcdb_get_allow_all(mcdb *db)
{
    cmo_list *list = new_cmo_list();
    while (db->tag != 0) {
        if (db->flag == MATHCAP_FLAG_ALLOW) {
            list_append(list, (cmo *)new_cmo_int32(db->tag));
        }
        db++;
    }
    return list;
}

static struct {
    int  version;
    char *version_string;
    char *sysname;
    char *hosttype;
} sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN"};

/* 次の tag をもつ cmo の送信が許可されているかを調べる */
static int cmodb_isallow_tag(mcdb *cmo_db, int tag)
{
    while (cmo_db->tag != 0 && cmo_db->tag != tag) {
        cmo_db++;
    }
    return cmo_db->flag;
}

static int cmodb_isallow_cmo_list(mcdb *cmo_db, cmo_list *ob)
{
    cell *el;
    if (cmodb_isallow_tag(cmo_db, ob->tag)) {
        el = list_first(ob);
        while (!list_endof(ob, el)) {
            if (!cmodb_isallow_cmo(cmo_db, el->cmo)) {
                return MATHCAP_FLAG_DENY;
            }
            el = list_next(el);
        }
        return MATHCAP_FLAG_ALLOW;
    }
    return MATHCAP_FLAG_DENY;
}

__inline__
static int cmodb_isallow_cmo_monomial32(mcdb *cmo_db, cmo_monomial32 *ob)
{
    return cmodb_isallow_tag(cmo_db, ob->tag)
        && cmodb_isallow_cmo(cmo_db, ob->coef);
}

__inline__
static int cmodb_isallow_cmo_mathcap(mcdb *cmo_db, cmo_mathcap *ob)
{
    return cmodb_isallow_tag(cmo_db, ob->tag)
        && cmodb_isallow_cmo(cmo_db, ob->ob);
}

/* 次の cmo の送信が許可されているかを調べる */
static int cmodb_isallow_cmo(mcdb *cmo_db, cmo *ob)
{
    int tag = ob->tag;
    switch(tag) {
    case CMO_LIST:
    case CMO_DISTRIBUTED_POLYNOMIAL:
        return cmodb_isallow_cmo_list(cmo_db, (cmo_list *)ob);
    case CMO_MATHCAP:
    case CMO_ERROR2:
    case CMO_RING_BY_NAME:
    case CMO_INDETERMINATE:
        return cmodb_isallow_cmo_mathcap(cmo_db, (cmo_mathcap *)ob);
    case CMO_MONOMIAL32:
        return cmodb_isallow_cmo_monomial32(cmo_db, (cmo_monomial32 *)ob);
    default:
        return cmodb_isallow_tag(cmo_db, tag);
    }
}

/* 次の tag をもつ cmo の送信を許可する */
__inline__
static void cmodb_allow(mcdb *cmo_db, int tag)
{
    mcdb_ctl(cmo_db, tag, MATHCAP_FLAG_ALLOW);
}

/* 次の tag をもつ cmo の送信を不許可にする */
__inline__
static void cmodb_deny(mcdb *cmo_db, int tag)
{
    mcdb_ctl(cmo_db, tag, MATHCAP_FLAG_DENY);
}

/* システム情報を得る */
static cmo_list *sysinfo_get_all()
{
    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);
}

__inline__
static char *new_string(char *s)
{
    char *t = malloc(sizeof(s)+1);
    strcpy(t, s);
    return t;
}

void sysinfo_set(int version, char *vstr, char *sysname)
{
    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  = version;
}

void mathcap_global_init(int ver, char *vstr, char *sysname, int cmos[], int sms[])
{
	sysinfo_set(ver, vstr, sysname); /* global! */
	if (cmos == NULL) {
		cmos = cmodb_d;
	}
	if (sms == NULL) {
		sms = smdb_d;
	}
	/* ... */
}

/* データベースから cmo_mathcap を生成する */
cmo_mathcap* mathcap_get(mathcap *this)
{
    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),
                                 cmodb_get_allow_all(this), NULL));
    list_appendl(mc, (cmo *)sysinfo_get_all(),
                 (cmo *)smdb_get_allow_all(this), (cmo *)l3, NULL);
    return new_cmo_mathcap((cmo *)mc);
}

static void cmodb_update(mcdb *cmo_db, 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) {
            cmodb_allow(cmo_db, ob->i);
        }
        el = list_next(el);
    }
}

/* cmo_mathcap が妥当な構造を持つかを調べる.  (未実装) */
int cmo_mathcap_isvalid(cmo_mathcap *mc)
{
	/* print_cmo(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!         */
__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);
}

/* 受信した mathcap データを反映させる */
/* this == NULL のとき、はじめて mathcap* オブジェクトをせいせいする */
mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc)
{
    cmo_list *types;
    if (cmo_mathcap_isvalid(mc)) {
        types = cmo_mathcap_get_cmotypes(mc);
        if (types != NULL) {
            cmodb_deny_all(this->cmo_db); /* すべての cmo の送信を禁止 */
            cmodb_update(this->cmo_db, types);
        }
    }
	return this;
}