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

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>