Annotation of OpenXM/src/ox_toolkit/mathcap.c, Revision 1.1
1.1 ! ohara 1: /* -*- mode: C; coding: euc-japan -*- */
! 2: /* $OpenXM$ */
! 3:
! 4: /* This module includes functions for handling mathcap databases. */
! 5:
! 6: #include <stdlib.h>
! 7: #include "ox_toolkit.h"
! 8:
! 9: typedef struct {
! 10: int tag;
! 11: int flag;
! 12: } mc_cell;
! 13:
! 14: static int mathcap_cmo_isallow_tag(int tag);
! 15: static mc_cell *mathcap_cmo_lookup(int tag);
! 16: static int mathcap_cmo_isallow_cmo_list(cmo_list *ob);
! 17: static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob);
! 18: static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob);
! 19: static char *new_string(char *s);
! 20: static void mathcap_cmo_update(cmo_list* types);
! 21: static cmo_list *get_messagetypes(cmo_list *ob, int type);
! 22: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
! 23: static cmo_list *get_messagetypes(cmo_list *ob, int type);
! 24: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
! 25:
! 26: static mc_cell mathcap_cmo[] = {
! 27: {CMO_NULL, MATHCAP_FLAG_ALLOW},
! 28: {CMO_INT32, MATHCAP_FLAG_ALLOW},
! 29: {CMO_DATUM, MATHCAP_FLAG_ALLOW},
! 30: {CMO_STRING, MATHCAP_FLAG_ALLOW},
! 31: {CMO_MATHCAP, MATHCAP_FLAG_ALLOW},
! 32: {CMO_LIST, MATHCAP_FLAG_ALLOW},
! 33: {CMO_MONOMIAL32, MATHCAP_FLAG_ALLOW},
! 34: {CMO_ZZ, MATHCAP_FLAG_ALLOW},
! 35: {CMO_ZERO, MATHCAP_FLAG_ALLOW},
! 36: {CMO_DMS_GENERIC, MATHCAP_FLAG_ALLOW},
! 37: {CMO_RING_BY_NAME, MATHCAP_FLAG_ALLOW},
! 38: {CMO_INDETERMINATE, MATHCAP_FLAG_ALLOW},
! 39: {CMO_DISTRIBUTED_POLYNOMIAL, MATHCAP_FLAG_ALLOW},
! 40: {CMO_ERROR2, MATHCAP_FLAG_ALLOW},
! 41: {0, MATHCAP_FLAG_DENY}
! 42: };
! 43:
! 44: static int mathcap_sm[] = {
! 45: SM_popCMO,
! 46: SM_popString,
! 47: SM_mathcap,
! 48: SM_pops,
! 49: SM_executeStringByLocalParser,
! 50: SM_executeFunction,
! 51: SM_setMathCap,
! 52: SM_shutdown,
! 53: SM_control_kill,
! 54: SM_control_reset_connection,
! 55: 0
! 56: };
! 57:
! 58: static struct {
! 59: int version;
! 60: char *version_string;
! 61: char *sysname;
! 62: char *hosttype;
! 63: } mathcap_sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN"};
! 64:
! 65: /* 次の tag をもつ cmo の送信が許可されているかを調べる */
! 66: static int mathcap_cmo_isallow_tag(int tag)
! 67: {
! 68: mc_cell *e = mathcap_cmo;
! 69: while (e->tag != 0 && e->tag != tag) {
! 70: e++;
! 71: }
! 72: return e->flag;
! 73: }
! 74:
! 75: /* 次の tag についてのキーを探す */
! 76: static mc_cell *mathcap_cmo_lookup(int tag)
! 77: {
! 78: mc_cell *e = mathcap_cmo;
! 79: while (e->tag != 0) {
! 80: if (e->tag == tag) {
! 81: return e;
! 82: }
! 83: e++;
! 84: }
! 85: return NULL;
! 86: }
! 87:
! 88: static int mathcap_cmo_isallow_cmo_list(cmo_list *ob)
! 89: {
! 90: cell *el;
! 91: if (mathcap_cmo_isallow_tag(ob->tag)) {
! 92: el = list_first(ob);
! 93: while (!list_endof(ob, el)) {
! 94: if (!mathcap_cmo_isallow_cmo(el->cmo)) {
! 95: return MATHCAP_FLAG_DENY;
! 96: }
! 97: el = list_next(el);
! 98: }
! 99: return MATHCAP_FLAG_ALLOW;
! 100: }
! 101: return MATHCAP_FLAG_DENY;
! 102: }
! 103:
! 104: static int mathcap_cmo_isallow_cmo_monomial32(cmo_monomial32 *ob)
! 105: {
! 106: return mathcap_cmo_isallow_tag(ob->tag)
! 107: && mathcap_cmo_isallow_cmo(ob->coef);
! 108: }
! 109:
! 110: static int mathcap_cmo_isallow_cmo_mathcap(cmo_mathcap *ob)
! 111: {
! 112: return mathcap_cmo_isallow_tag(ob->tag)
! 113: && mathcap_cmo_isallow_cmo(ob->ob);
! 114: }
! 115:
! 116: /* 次の cmo の送信が許可されているかを調べる */
! 117: int mathcap_cmo_isallow_cmo(cmo *ob)
! 118: {
! 119: int tag = ob->tag;
! 120: switch(tag) {
! 121: case CMO_LIST:
! 122: case CMO_DISTRIBUTED_POLYNOMIAL:
! 123: return mathcap_cmo_isallow_cmo_list((cmo_list *)ob);
! 124: case CMO_MATHCAP:
! 125: case CMO_ERROR2:
! 126: case CMO_RING_BY_NAME:
! 127: case CMO_INDETERMINATE:
! 128: return mathcap_cmo_isallow_cmo_mathcap((cmo_mathcap *)ob);
! 129: case CMO_MONOMIAL32:
! 130: return mathcap_cmo_isallow_cmo_monomial32((cmo_monomial32 *)ob);
! 131: default:
! 132: return mathcap_cmo_isallow_tag(tag);
! 133: }
! 134: }
! 135:
! 136: /* 次の tag をもつ cmo の送信を許可する */
! 137: void mathcap_cmo_allow(int tag)
! 138: {
! 139: mc_cell *e = mathcap_cmo_lookup(tag);
! 140: if (e != NULL) {
! 141: e->flag = MATHCAP_FLAG_ALLOW;
! 142: }
! 143: }
! 144:
! 145: /* 次の tag をもつ cmo の送信を不許可にする */
! 146: void mathcap_cmo_deny(int tag)
! 147: {
! 148: mc_cell *e = mathcap_cmo_lookup(tag);
! 149: if (e != NULL) {
! 150: e->flag = MATHCAP_FLAG_DENY;
! 151: }
! 152: }
! 153:
! 154: /* 全ての種類の cmo の送信を不許可にする */
! 155: void mathcap_cmo_deny_all()
! 156: {
! 157: mc_cell *e = mathcap_cmo;
! 158: while (e->tag != 0) {
! 159: e->flag = MATHCAP_FLAG_DENY;
! 160: e++;
! 161: }
! 162: }
! 163:
! 164: /* 全ての種類の cmo の送信を許可する */
! 165: void mathcap_cmo_allow_all()
! 166: {
! 167: mc_cell *e = mathcap_cmo;
! 168: while (e->tag != 0) {
! 169: e->flag = MATHCAP_FLAG_ALLOW;
! 170: e++;
! 171: }
! 172: }
! 173:
! 174: /* 送信許可されている cmo のリストを得る */
! 175: cmo_list *mathcap_cmo_get_allow_all()
! 176: {
! 177: cmo_list *list = new_cmo_list();
! 178: mc_cell *e = mathcap_cmo;
! 179: while (e->tag != 0) {
! 180: if (e->flag != MATHCAP_FLAG_DENY) {
! 181: list_append(list, new_cmo_int32(e->tag));
! 182: }
! 183: e++;
! 184: }
! 185: return list;
! 186: }
! 187:
! 188: /* 既知の sm コマンドのリストを得る */
! 189: cmo_list *mathcap_sm_get_all()
! 190: {
! 191: cmo_list *list = new_cmo_list();
! 192: int i;
! 193: for(i=0; mathcap_sm[i] != 0; i++) {
! 194: list_append(list, new_cmo_int32(mathcap_sm[i]));
! 195: }
! 196: return list;
! 197: }
! 198:
! 199: /* システム情報を得る */
! 200: cmo_list *mathcap_sysinfo_get_all()
! 201: {
! 202: cmo_list *syslist = new_cmo_list();
! 203: cmo_int32 *ver = new_cmo_int32(mathcap_sysinfo.version);
! 204: cmo_string *vers = new_cmo_string(mathcap_sysinfo.version_string);
! 205: cmo_string *host = new_cmo_string(mathcap_sysinfo.hosttype);
! 206: cmo_string *sname = new_cmo_string(mathcap_sysinfo.sysname);
! 207: return list_appendl(syslist, ver, sname, vers, host);
! 208: }
! 209:
! 210: static char *new_string(char *s)
! 211: {
! 212: char *t = malloc(sizeof(s)+1);
! 213: strcpy(t, s);
! 214: return t;
! 215: }
! 216:
! 217: void mathcap_sysinfo_set(int version, char *version_string, char *sysname)
! 218: {
! 219: char *host = getenv("HOSTTYPE");
! 220:
! 221: mathcap_sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN";
! 222: mathcap_sysinfo.sysname = new_string(sysname);
! 223: mathcap_sysinfo.version_string = new_string(version_string);
! 224: mathcap_sysinfo.version = version;
! 225: }
! 226:
! 227: /* データベースから cmo_mathcap を生成する */
! 228: cmo_mathcap* mathcap_get()
! 229: {
! 230: cmo_list *mc = new_cmo_list();
! 231: cmo_list *l3 = new_cmo_list();
! 232: list_append(l3, list_appendl(new_cmo_list(), new_cmo_int32(OX_DATA), mathcap_cmo_get_allow_all(), NULL));
! 233: list_appendl(mc, (cmo *)mathcap_sysinfo_get_all(), (cmo *)mathcap_sm_get_all(), (cmo *)l3, NULL);
! 234: return new_cmo_mathcap((cmo *)mc);
! 235: }
! 236:
! 237: static void mathcap_cmo_update(cmo_list* types)
! 238: {
! 239: cell *el = list_first(types);
! 240: cmo_int32 *ob;
! 241: while(!list_endof(types, el)) {
! 242: ob = (cmo_int32 *)el->cmo;
! 243: if (ob->tag == CMO_INT32) {
! 244: mathcap_cmo_allow(ob->i);
! 245: }
! 246: el = list_next(el);
! 247: }
! 248: }
! 249:
! 250: /* cmo_mathcap が妥当な構造を持つかを調べる. (未実装) */
! 251: int cmo_mathcap_isvalid(cmo_mathcap *mc)
! 252: {
! 253: return 1;
! 254: }
! 255:
! 256: /* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */
! 257: /* ^^^^^ Here! */
! 258: static cmo_list *get_messagetypes(cmo_list *ob, int type)
! 259: {
! 260: cmo_list *c;
! 261: cell *el;
! 262:
! 263: for (el = list_first(ob); !list_endof(ob, el); el = list_next(el)) {
! 264: c = (cmo_list *)el->cmo;
! 265: if (((cmo_int32 *)list_nth(c, 0))->i == type) {
! 266: return (cmo_list *)list_nth(c, 1);
! 267: }
! 268: }
! 269: return NULL;
! 270: }
! 271:
! 272: /* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */
! 273: /* ^^^^^ Here! */
! 274: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc)
! 275: {
! 276: cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2);
! 277: return get_messagetypes(ob, OX_DATA);
! 278: }
! 279:
! 280: /* 受信した mathcap データを反映させる */
! 281: void mathcap_update(cmo_mathcap *mc)
! 282: {
! 283: cmo_list *types;
! 284: if (cmo_mathcap_isvalid(mc)) {
! 285: types = cmo_mathcap_get_cmotypes(mc);
! 286: if (types != NULL) {
! 287: mathcap_cmo_deny_all(); /* すべての cmo の送信を禁止 */
! 288: mathcap_cmo_update(types);
! 289: }
! 290: }
! 291: }
! 292:
! 293: /* 互換性のため */
! 294: cmo* make_mathcap_object(int version, char *id_string)
! 295: {
! 296: mathcap_sysinfo_set(version, id_string, "ox_math");
! 297: return (cmo *)mathcap_get();
! 298: }
! 299:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>