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