Annotation of OpenXM/src/ox_toolkit/mathcap.c, Revision 1.5
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.5 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.4 2000/11/21 07:59:08 ohara Exp $ */
1.1 ohara 3:
4: /* This module includes functions for handling mathcap databases. */
5:
6: #include <stdlib.h>
1.5 ! ohara 7: #include <string.h>
1.1 ohara 8: #include "ox_toolkit.h"
9:
1.5 ! ohara 10: #define MATHCAP_FLAG_DENY 0
! 11: #define MATHCAP_FLAG_ALLOW 1
1.3 ohara 12:
1.1 ohara 13: typedef struct {
14: int tag;
15: int flag;
1.5 ! ohara 16: } table;
1.1 ohara 17:
1.5 ! ohara 18: typedef struct mathcap {
! 19: table *cmotbl;
! 20: table *smtbl;
1.3 ohara 21: } mathcap;
22:
1.5 ! ohara 23: static void table_init(table *m, int key);
! 24: static table *new_table(int *src);
! 25: static table *table_lookup(table *tbl, int tag);
! 26: static void table_ctl(table *tbl, int tag, int flag);
! 27: static void table_ctl_all(table *tbl, int flag);
! 28: static cmo_list *table_get_all(table *tbl);
! 29: static void table_allow(table *tbl, int tag);
! 30: static void table_deny(table *tbl, int tag);
! 31: static void table_update(table *cmotbl, cmo_list* types);
! 32: static int table_allowQ_tag(table *tbl, int tag);
! 33: static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob);
! 34: static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob);
! 35: static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob);
! 36: static int table_allowQ_cmo(table *cmotbl, cmo *ob);
! 37: static cmo_list *sysinfo_get();
1.3 ohara 38: static char *new_string(char *s);
1.5 ! ohara 39: static int *new_int_array(int *array);
! 40: static cmo_list *get_messagetypes(cmo_list *ob, int type);
1.3 ohara 41: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
1.2 ohara 42:
1.5 ! ohara 43: static int cmotbl_a[] = {
1.3 ohara 44: CMO_NULL,
45: CMO_INT32,
46: CMO_DATUM,
47: CMO_STRING,
48: CMO_MATHCAP,
49: CMO_LIST,
50: CMO_MONOMIAL32,
51: CMO_ZZ,
52: CMO_ZERO,
53: CMO_DMS_GENERIC,
54: CMO_RING_BY_NAME,
55: CMO_INDETERMINATE,
56: CMO_DISTRIBUTED_POLYNOMIAL,
57: CMO_ERROR2,
58: 0,
1.1 ohara 59: };
60:
1.5 ! ohara 61: static int smtbl_a[] = {
1.3 ohara 62: SM_popCMO,
63: SM_popString,
64: SM_mathcap,
65: SM_pops,
66: SM_executeStringByLocalParser,
67: SM_executeFunction,
68: SM_setMathCap,
69: SM_shutdown,
70: SM_control_kill,
71: SM_control_reset_connection,
1.5 ! ohara 72: SM_control_spawn_server,
! 73: SM_control_terminate_server,
1.3 ohara 74: 0,
1.1 ohara 75: };
76:
1.5 ! ohara 77: static struct {
! 78: int version;
! 79: char *version_string;
! 80: char *sysname;
! 81: char *hosttype;
! 82: int *cmo_tags;
! 83: int *sm_cmds;
! 84: } sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN", cmotbl_a, smtbl_a};
! 85:
1.3 ohara 86: __inline__
1.5 ! ohara 87: static void table_init(table *m, int key)
1.3 ohara 88: {
89: m->tag = key;
90: m->flag = MATHCAP_FLAG_ALLOW;
91: }
1.2 ohara 92:
1.5 ! ohara 93: static table *new_table(int *src)
1.2 ohara 94: {
1.5 ! ohara 95: table *new;
1.3 ohara 96: int len=0;
97: int i;
98: while (src[len++] != 0) {
99: }
1.5 ! ohara 100: new = malloc(sizeof(table)*len);
1.3 ohara 101: for(i=0; i<len; i++) {
1.5 ! ohara 102: table_init(new+i, src[i]);
1.3 ohara 103: }
104: return new;
1.2 ohara 105: }
106:
107: /* 次の tag についてのキーを探す */
1.5 ! ohara 108: static table *table_lookup(table *tbl, int tag)
1.2 ohara 109: {
1.5 ! ohara 110: while (tbl->tag != 0) {
! 111: if (tbl->tag == tag) {
! 112: return tbl;
1.2 ohara 113: }
1.5 ! ohara 114: tbl++;
1.2 ohara 115: }
116: return NULL;
117: }
118:
119: /* tag に対する送信制御 */
1.5 ! ohara 120: static void table_ctl(table *tbl, int tag, int flag)
1.2 ohara 121: {
1.5 ! ohara 122: table *e = table_lookup(tbl, tag);
1.2 ohara 123: if (e != NULL) {
124: e->flag = flag;
125: }
126: }
127:
128: /* 全データに対する送信制御 */
1.5 ! ohara 129: static void table_ctl_all(table *tbl, int flag)
1.2 ohara 130: {
1.5 ! ohara 131: while (tbl->tag != 0) {
! 132: tbl->flag = flag;
! 133: tbl++;
1.2 ohara 134: }
135: }
136:
137: /* 送信許可されている tag のリストを得る */
1.5 ! ohara 138: static cmo_list *table_get_all(table *tbl)
1.2 ohara 139: {
140: cmo_list *list = new_cmo_list();
1.5 ! ohara 141: while (tbl->tag != 0) {
! 142: if (tbl->flag == MATHCAP_FLAG_ALLOW) {
! 143: list_append(list, (cmo *)new_cmo_int32(tbl->tag));
1.2 ohara 144: }
1.5 ! ohara 145: tbl++;
1.2 ohara 146: }
147: return list;
148: }
149:
1.5 ! ohara 150: /* 次の tag をもつ cmo or sm_cmd の送信を許可する */
! 151: __inline__
! 152: static void table_allow(table *tbl, int tag)
! 153: {
! 154: table_ctl(tbl, tag, MATHCAP_FLAG_ALLOW);
! 155: }
! 156:
! 157: /* 次の tag をもつ cmo or sm_cmd の送信を不許可にする */
! 158: __inline__
! 159: static void table_deny(table *tbl, int tag)
! 160: {
! 161: table_ctl(tbl, tag, MATHCAP_FLAG_DENY);
! 162: }
! 163:
! 164: static void table_update(table *cmotbl, cmo_list* types)
! 165: {
! 166: cell *el = list_first(types);
! 167: cmo_int32 *ob;
! 168: while(!list_endof(types, el)) {
! 169: ob = (cmo_int32 *)el->cmo;
! 170: if (ob->tag == CMO_INT32) {
! 171: table_allow(cmotbl, ob->i);
! 172: }
! 173: el = list_next(el);
! 174: }
! 175: }
1.1 ohara 176:
1.5 ! ohara 177: /* 次の tag をもつ cmo or sm_cmd の送信が許可されているかを調べる */
! 178: static int table_allowQ_tag(table *tbl, int tag)
1.1 ohara 179: {
1.5 ! ohara 180: while (tbl->tag != 0 && tbl->tag != tag) {
! 181: tbl++;
1.1 ohara 182: }
1.5 ! ohara 183: return tbl->flag;
1.1 ohara 184: }
185:
1.5 ! ohara 186: static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob)
1.1 ohara 187: {
188: cell *el;
1.5 ! ohara 189: if (table_allowQ_tag(cmotbl, ob->tag)) {
1.1 ohara 190: el = list_first(ob);
191: while (!list_endof(ob, el)) {
1.5 ! ohara 192: if (!table_allowQ_cmo(cmotbl, el->cmo)) {
1.1 ohara 193: return MATHCAP_FLAG_DENY;
194: }
195: el = list_next(el);
196: }
197: return MATHCAP_FLAG_ALLOW;
198: }
199: return MATHCAP_FLAG_DENY;
200: }
201:
1.2 ohara 202: __inline__
1.5 ! ohara 203: static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob)
1.1 ohara 204: {
1.5 ! ohara 205: return table_allowQ_tag(cmotbl, ob->tag)
! 206: && table_allowQ_cmo(cmotbl, ob->coef);
1.1 ohara 207: }
208:
1.2 ohara 209: __inline__
1.5 ! ohara 210: static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob)
1.1 ohara 211: {
1.5 ! ohara 212: return table_allowQ_tag(cmotbl, ob->tag)
! 213: && table_allowQ_cmo(cmotbl, ob->ob);
1.1 ohara 214: }
215:
216: /* 次の cmo の送信が許可されているかを調べる */
1.5 ! ohara 217: static int table_allowQ_cmo(table *cmotbl, cmo *ob)
1.1 ohara 218: {
219: int tag = ob->tag;
220: switch(tag) {
221: case CMO_LIST:
222: case CMO_DISTRIBUTED_POLYNOMIAL:
1.5 ! ohara 223: return table_allowQ_cmo_list(cmotbl, (cmo_list *)ob);
1.1 ohara 224: case CMO_MATHCAP:
225: case CMO_ERROR2:
226: case CMO_RING_BY_NAME:
227: case CMO_INDETERMINATE:
1.5 ! ohara 228: return table_allowQ_cmo_mathcap(cmotbl, (cmo_mathcap *)ob);
1.1 ohara 229: case CMO_MONOMIAL32:
1.5 ! ohara 230: return table_allowQ_cmo_monomial32(cmotbl, (cmo_monomial32 *)ob);
1.1 ohara 231: default:
1.5 ! ohara 232: return table_allowQ_tag(cmotbl, tag);
1.1 ohara 233: }
234: }
235:
236: /* システム情報を得る */
1.5 ! ohara 237: static cmo_list *sysinfo_get()
1.1 ohara 238: {
239: cmo_list *syslist = new_cmo_list();
1.3 ohara 240: cmo_int32 *ver = new_cmo_int32(sysinfo.version);
241: cmo_string *vers = new_cmo_string(sysinfo.version_string);
242: cmo_string *host = new_cmo_string(sysinfo.hosttype);
243: cmo_string *sname = new_cmo_string(sysinfo.sysname);
244: return list_appendl(syslist, ver, sname, vers, host, NULL);
1.1 ohara 245: }
246:
247: static char *new_string(char *s)
248: {
249: char *t = malloc(sizeof(s)+1);
250: strcpy(t, s);
251: return t;
252: }
253:
1.5 ! ohara 254: static int *new_int_array(int *array)
! 255: {
! 256: int *new_array;
! 257: int length = 0;
! 258: while(array[length++] != 0)
! 259: ;
! 260: new_array = malloc(sizeof(int)*length);
! 261: return memcpy(new_array, array, sizeof(int)*length);
! 262: }
! 263:
! 264: void mathcap_init(int ver, char *vstr, char *sysname, int cmos[], int sms[])
1.1 ohara 265: {
266: char *host = getenv("HOSTTYPE");
1.3 ohara 267: sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN";
268: sysinfo.sysname = new_string(sysname);
269: sysinfo.version_string = new_string(vstr);
1.5 ! ohara 270: sysinfo.version = ver;
! 271: if (cmos != NULL) {
! 272: sysinfo.cmo_tags = new_int_array(cmos);
! 273: }
! 274: if (sms != NULL) {
! 275: sysinfo.sm_cmds = new_int_array(sms);
! 276: }
1.3 ohara 277: }
1.1 ohara 278:
1.5 ! ohara 279: mathcap *new_mathcap()
1.3 ohara 280: {
1.5 ! ohara 281: mathcap *new = malloc(sizeof(mathcap));
! 282: new->cmotbl = new_table(sysinfo.cmo_tags);
! 283: new->smtbl = new_table(sysinfo.sm_cmds);
! 284: return new;
1.1 ohara 285: }
286:
287: /* データベースから cmo_mathcap を生成する */
1.3 ohara 288: cmo_mathcap* mathcap_get(mathcap *this)
1.1 ohara 289: {
290: cmo_list *mc = new_cmo_list();
291: cmo_list *l3 = new_cmo_list();
1.3 ohara 292: list_append(l3, list_appendl(new_cmo_list(),
293: new_cmo_int32(OX_DATA),
1.5 ! ohara 294: table_get_all(this->cmotbl), NULL));
! 295: list_appendl(mc, (cmo *)sysinfo_get(),
! 296: (cmo *)table_get_all(this->smtbl), (cmo *)l3, NULL);
1.1 ohara 297: return new_cmo_mathcap((cmo *)mc);
298: }
299:
300: /* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */
301: /* ^^^^^ Here! */
302: static cmo_list *get_messagetypes(cmo_list *ob, int type)
303: {
304: cmo_list *c;
305: cell *el;
306:
307: for (el = list_first(ob); !list_endof(ob, el); el = list_next(el)) {
308: c = (cmo_list *)el->cmo;
309: if (((cmo_int32 *)list_nth(c, 0))->i == type) {
310: return (cmo_list *)list_nth(c, 1);
311: }
312: }
313: return NULL;
314: }
315:
316: /* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */
317: /* ^^^^^ Here! */
1.2 ohara 318: __inline__
1.1 ohara 319: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc)
320: {
321: cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2);
322: return get_messagetypes(ob, OX_DATA);
323: }
324:
325: /* 受信した mathcap データを反映させる */
1.3 ohara 326: /* this == NULL のとき、はじめて mathcap* オブジェクトをせいせいする */
327: mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc)
1.1 ohara 328: {
329: cmo_list *types;
1.5 ! ohara 330: types = cmo_mathcap_get_cmotypes(mc);
! 331: if (types != NULL) {
! 332: /* すべての cmo の送信を禁止 */
! 333: table_ctl_all(this->cmotbl, MATHCAP_FLAG_DENY);
! 334: table_update(this->cmotbl, types);
1.1 ohara 335: }
1.5 ! ohara 336:
! 337: return this;
! 338: }
! 339:
! 340: int mathcap_allowQ_cmo(mathcap *this, cmo *ob)
! 341: {
! 342: return table_allowQ_cmo(this->cmotbl, ob);
1.1 ohara 343: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>