Annotation of OpenXM/src/ox_toolkit/mathcap.c, Revision 1.17
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.17 ! ohara 2: /* $OpenXM: OpenXM/src/ox_toolkit/mathcap.c,v 1.16 2016/06/29 05:07:23 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.13 takayama 10: #define MATHCAP_FLAG_DENY 0
11: #define MATHCAP_FLAG_ALLOW 1
1.3 ohara 12:
1.13 takayama 13: static void table_init(table *m, int key);
14: static table *new_table(int *src);
15: static table *table_lookup(table *tbl, int tag);
16: static void table_ctl(table *tbl, int tag, int flag);
17: static void table_ctl_all(table *tbl, int flag);
18: static cmo_list *table_get_all(table *tbl);
19: static void table_allow(table *tbl, int tag);
20: static void table_deny(table *tbl, int tag);
21: static void table_update(table *cmotbl, cmo_list* types);
22: static int table_allowQ_tag(table *tbl, int tag);
23: static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob);
24: static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob);
25: static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob);
26: static int table_allowQ_cmo(table *cmotbl, cmo *ob);
27: static cmo_list *sysinfo_get();
28: static char *new_string(char *s);
29: static int *new_int_array(int *array);
30: static cmo_list *get_messagetypes(cmo_list *ob, int type);
31: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc);
32:
33: static int cmotbl_a[] = {
1.3 ohara 34: CMO_NULL,
35: CMO_INT32,
1.13 takayama 36: CMO_DATUM,
1.3 ohara 37: CMO_STRING,
38: CMO_MATHCAP,
39: CMO_LIST,
40: CMO_MONOMIAL32,
41: CMO_ZZ,
1.11 ohara 42: CMO_QQ,
1.16 ohara 43: CMO_BIGFLOAT32,
1.15 noro 44: CMO_COMPLEX,
1.13 takayama 45: CMO_IEEE_DOUBLE_FLOAT,
1.3 ohara 46: CMO_ZERO,
47: CMO_DMS_GENERIC,
48: CMO_RING_BY_NAME,
1.13 takayama 49: CMO_INDETERMINATE,
1.12 ohara 50: CMO_DISTRIBUTED_POLYNOMIAL,
1.15 noro 51: CMO_RECURSIVE_POLYNOMIAL,
52: CMO_POLYNOMIAL_IN_ONE_VARIABLE,
1.3 ohara 53: CMO_ERROR2,
1.13 takayama 54: 0,
55: };
56:
57: static int smtbl_a[] = {
58: SM_popCMO,
59: SM_popString,
60: SM_mathcap,
61: SM_pops,
62: SM_executeStringByLocalParser,
63: SM_executeFunction,
64: SM_setMathCap,
65: SM_shutdown,
66: SM_control_kill,
67: SM_control_reset_connection,
68: SM_control_spawn_server,
69: SM_control_terminate_server,
70: 0,
71: };
1.1 ohara 72:
1.5 ohara 73: static struct {
1.13 takayama 74: int version;
75: char *version_string;
1.5 ohara 76: char *sysname;
77: char *hosttype;
1.13 takayama 78: int *cmo_tags;
79: int *sm_cmds;
1.17 ! ohara 80: char **opts;
! 81: } sysinfo = {0, "NO VERSION", "NONAME", "UNKNOWN", cmotbl_a, smtbl_a, NULL};
1.5 ohara 82:
1.13 takayama 83: __inline__
84: static void table_init(table *m, int key)
85: {
86: m->tag = key;
87: m->flag = MATHCAP_FLAG_ALLOW;
88: }
1.2 ohara 89:
1.13 takayama 90: static table *new_table(int *src)
91: {
92: table *new;
93: int len=0;
94: int i;
95: while (src[len++] != 0) {
96: }
97: new = MALLOC(sizeof(table)*len);
98: for(i=0; i<len; i++) {
99: table_init(new+i, src[i]);
100: }
101: return new;
102: }
1.2 ohara 103:
1.13 takayama 104: /* looking for an item of the tag */
105: static table *table_lookup(table *tbl, int tag)
1.2 ohara 106: {
1.13 takayama 107: while (tbl->tag != 0) {
108: if (tbl->tag == tag) {
109: return tbl;
110: }
111: tbl++;
1.2 ohara 112: }
113: return NULL;
114: }
115:
1.13 takayama 116: /* controller about a cmo identified by the tag */
117: static void table_ctl(table *tbl, int tag, int flag)
1.2 ohara 118: {
1.13 takayama 119: table *e = table_lookup(tbl, tag);
120: if (e != NULL) {
121: e->flag = flag;
1.2 ohara 122: }
123: }
124:
1.13 takayama 125: /* controller about all CMObjects */
126: static void table_ctl_all(table *tbl, int flag)
1.2 ohara 127: {
1.13 takayama 128: while (tbl->tag != 0) {
129: tbl->flag = flag;
130: tbl++;
131: }
1.2 ohara 132: }
133:
1.13 takayama 134: /* getting the list of tags of all allowed objects */
135: static cmo_list *table_get_all(table *tbl)
1.2 ohara 136: {
1.13 takayama 137: cmo_list *list = new_cmo_list();
138: while (tbl->tag != 0) {
139: if (tbl->flag == MATHCAP_FLAG_ALLOW) {
140: list_append(list, (cmo *)new_cmo_int32(tbl->tag));
141: }
142: tbl++;
143: }
144: return list;
1.2 ohara 145: }
146:
1.13 takayama 147: /* giving a permssion to send objects identified by the tag. */
148: __inline__
149: static void table_allow(table *tbl, int tag)
1.5 ohara 150: {
1.13 takayama 151: table_ctl(tbl, tag, MATHCAP_FLAG_ALLOW);
1.5 ohara 152: }
153:
1.13 takayama 154: /* taking a permssion to send objects identified by the tag. */
155: __inline__
156: static void table_deny(table *tbl, int tag)
1.5 ohara 157: {
1.13 takayama 158: table_ctl(tbl, tag, MATHCAP_FLAG_DENY);
1.5 ohara 159: }
160:
1.13 takayama 161: static void table_update(table *cmotbl, cmo_list* types)
1.5 ohara 162: {
1.13 takayama 163: cell *el = list_first(types);
164: cmo_int32 *ob;
165: while(!list_endof(types, el)) {
166: ob = (cmo_int32 *)el->cmo;
167: if (ob->tag == CMO_INT32) {
168: table_allow(cmotbl, ob->i);
169: }
170: el = list_next(el);
171: }
1.5 ohara 172: }
1.1 ohara 173:
1.13 takayama 174: /* getting a permission to send objects identified by the tag. */
175: static int table_allowQ_tag(table *tbl, int tag)
1.1 ohara 176: {
1.13 takayama 177: while (tbl->tag != 0 && tbl->tag != tag) {
178: tbl++;
179: }
180: return tbl->flag;
181: }
182:
183: static int table_allowQ_cmo_list(table *cmotbl, cmo_list *ob)
184: {
185: cell *el;
186: if (table_allowQ_tag(cmotbl, ob->tag)) {
187: el = list_first(ob);
188: while (!list_endof(ob, el)) {
189: if (!table_allowQ_cmo(cmotbl, el->cmo)) {
190: return MATHCAP_FLAG_DENY;
1.1 ohara 191: }
1.13 takayama 192: el = list_next(el);
1.1 ohara 193: }
1.13 takayama 194: return MATHCAP_FLAG_ALLOW;
195: }
196: return MATHCAP_FLAG_DENY;
197: }
198:
199: __inline__
200: static int table_allowQ_cmo_monomial32(table *cmotbl, cmo_monomial32 *ob)
201: {
202: return table_allowQ_tag(cmotbl, ob->tag)
203: && table_allowQ_cmo(cmotbl, ob->coef);
204: }
205:
206: __inline__
207: static int table_allowQ_cmo_mathcap(table *cmotbl, cmo_mathcap *ob)
208: {
209: return table_allowQ_tag(cmotbl, ob->tag)
210: && table_allowQ_cmo(cmotbl, ob->ob);
211: }
212:
213: /* getting a permission to send the following object. */
214: static int table_allowQ_cmo(table *cmotbl, cmo *ob)
215: {
216: int tag = ob->tag;
217: switch(tag) {
218: case CMO_LIST:
219: case CMO_DISTRIBUTED_POLYNOMIAL:
220: return table_allowQ_cmo_list(cmotbl, (cmo_list *)ob);
221: case CMO_MATHCAP:
222: case CMO_ERROR2:
223: case CMO_RING_BY_NAME:
224: case CMO_INDETERMINATE:
225: return table_allowQ_cmo_mathcap(cmotbl, (cmo_mathcap *)ob);
226: case CMO_MONOMIAL32:
227: return table_allowQ_cmo_monomial32(cmotbl, (cmo_monomial32 *)ob);
228: default:
229: return table_allowQ_tag(cmotbl, tag);
1.1 ohara 230: }
231: }
232:
1.13 takayama 233: /* getting the System Information */
234: static cmo_list *sysinfo_get()
235: {
236: cmo_list *syslist = new_cmo_list();
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);
242: }
243:
244: static char *new_string(char *s)
245: {
246: char *t = MALLOC(strlen(s)+1);
247: strcpy(t, s);
248: return t;
249: }
250:
251: static int *new_int_array(int *array)
1.1 ohara 252: {
1.13 takayama 253: int *new_array;
254: int length = 0;
255: while(array[length++] != 0)
256: ;
257: new_array = MALLOC(sizeof(int)*length);
258: return memcpy(new_array, array, sizeof(int)*length);
259: }
260:
261: void mathcap_init(int ver, char *vstr, char *sysname, int cmos[], int sms[])
262: {
1.17 ! ohara 263: mathcap_init2(ver, vstr, sysname, cmos, sms, NULL);
! 264: }
! 265:
! 266: /* src must be terminated by NULL */
! 267: static char **clone_str_list(char **src)
! 268: {
! 269: int i,len;
! 270: char **new = NULL;
! 271: if(!src) {
! 272: for(len=0; src[len]!=NULL; len++) {
! 273: }
! 274: new = (char **)MALLOC(sizeof(char *)*(len+1));
! 275: new[len] = NULL;
! 276: for(i=0; i<len; i++) {
! 277: new[i] = (char *)MALLOC(strlen(src[i])+1);
! 278: strcpy(new[i], src[i]);
! 279: }
! 280: }
! 281: return new;
! 282: }
! 283:
! 284: /* options must be terminated by NULL */
! 285: void mathcap_init2(int ver, char *vstr, char *sysname, int cmos[], int sms[], char *options[])
! 286: {
1.13 takayama 287: char *host = getenv("HOSTTYPE");
288: sysinfo.hosttype = (host != NULL)? new_string(host): "UNKNOWN";
289: sysinfo.sysname = new_string(sysname);
290: sysinfo.version_string = new_string(vstr);
291: sysinfo.version = ver;
292: if (cmos != NULL) {
293: sysinfo.cmo_tags = new_int_array(cmos);
294: }
295: if (sms != NULL) {
296: sysinfo.sm_cmds = new_int_array(sms);
297: }
1.17 ! ohara 298: sysinfo.opts = clone_str_list(options);
1.5 ohara 299: }
300:
1.13 takayama 301: mathcap *new_mathcap()
1.1 ohara 302: {
1.13 takayama 303: mathcap *new = MALLOC(sizeof(mathcap));
304: new->cmotbl = new_table(sysinfo.cmo_tags);
305: new->smtbl = new_table(sysinfo.sm_cmds);
1.17 ! ohara 306: new->opts = clone_str_list(sysinfo.opts);
1.13 takayama 307: return new;
1.3 ohara 308: }
1.13 takayama 309:
310: /* generating a cmo_mathcap by a local database. */
1.3 ohara 311: cmo_mathcap* mathcap_get(mathcap *this)
1.1 ohara 312: {
1.13 takayama 313: cmo_list *mc = new_cmo_list();
314: cmo_list *l3 = new_cmo_list();
1.17 ! ohara 315: cmo_list *si = sysinfo_get();
! 316: cmo_list *sm= table_get_all(this->smtbl);
! 317: cmo_list *opts;
! 318: int i;
! 319:
1.13 takayama 320: list_append(l3, (cmo *)list_appendl(new_cmo_list(),
321: new_cmo_int32(OX_DATA),
322: table_get_all(this->cmotbl), NULL));
1.17 ! ohara 323: if(this->opts) {
! 324: opts = new_cmo_list();
! 325: for(i=0; this->opts[i]!=NULL; i++) {
! 326: list_append(opts, (cmo *)new_cmo_string(this->opts[i]));
! 327: }
! 328: list_appendl(mc, (cmo *)si, (cmo *)sm, (cmo *)l3, (cmo *)opts, NULL);
! 329: }else {
! 330: list_appendl(mc, (cmo *)si, (cmo *)sm, (cmo *)l3, NULL);
! 331: }
1.13 takayama 332: return new_cmo_mathcap((cmo *)mc);
333: }
334:
335: /* ( ..., ( type, (...) ), (cmo_int32, (...) ), ... ) */
336: /* ^^^^^ Here! */
337: static cmo_list *get_messagetypes(cmo_list *ob, int type)
338: {
339: cmo_list *c;
340: cell *el;
341:
342: for (el = list_first(ob); !list_endof(ob, el); el = list_next(el)) {
343: c = (cmo_list *)el->cmo;
344: if (((cmo_int32 *)list_nth(c, 0))->i == type) {
345: return (cmo_list *)list_nth(c, 1);
346: }
347: }
348: return NULL;
1.1 ohara 349: }
1.13 takayama 350:
351: /* cmo_mathcap->ob = ( (...), (...), ( ( cmo_int32, (...) ), ...), ...) */
352: /* ^^^^^ Here! */
353: __inline__
354: static cmo_list *cmo_mathcap_get_cmotypes(cmo_mathcap *mc)
355: {
356: cmo_list *ob = (cmo_list *)list_nth((cmo_list *)mc->ob, 2);
357: return get_messagetypes(ob, OX_DATA);
358: }
359:
360: /* The mathcap_update integrates received cmo_mathcap into the mathcap
361: database. If this == NULL, then an instance of mathcap is generated. */
362: mathcap *mathcap_update(mathcap *this, cmo_mathcap *mc)
363: {
364: cmo_list *types;
365: types = cmo_mathcap_get_cmotypes(mc);
366: if (types != NULL) {
367: table_ctl_all(this->cmotbl, MATHCAP_FLAG_DENY);
368: table_update(this->cmotbl, types);
369: }
370:
371: return this;
372: }
373:
374: int mathcap_allowQ_cmo(mathcap *this, cmo *ob)
1.5 ohara 375: {
1.13 takayama 376: return table_allowQ_cmo(this->cmotbl, ob);
1.1 ohara 377: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>