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

Annotation of OpenXM/src/ox_math/sm_ext.c, Revision 1.1

1.1     ! ohara       1: /* -*- mode: C; coding: euc-japan -*- */
        !             2: /* $OpenXM$ */
        !             3:
        !             4: /*
        !             5:    Copyright (C) Katsuyoshi OHARA, 2000.
        !             6:    Portions copyright 1999 Wolfram Research, Inc.
        !             7:
        !             8:    You must see OpenXM/Copyright/Copyright.generic.
        !             9:    The MathLink Library is licensed from Wolfram Research Inc..
        !            10:    See OpenXM/Copyright/Copyright.mathlink for detail.
        !            11: */
        !            12:
        !            13: /*
        !            14:    Remarks:
        !            15:    file descripter 3 and 4 are already opened by the parent process.
        !            16: */
        !            17:
        !            18: #include <stdio.h>
        !            19: #include <stdlib.h>
        !            20: #include <unistd.h>
        !            21: #include <gmp.h>
        !            22: #include <mathlink.h>
        !            23: #include <ox_toolkit.h>
        !            24: #include "sm.h"
        !            25:
        !            26: extern int flag_mlo_symbol;
        !            27:
        !            28: /* MathLink independent */
        !            29: static cmo **stack = NULL;
        !            30: static int stack_ptr = 0;
        !            31: static int stack_size = 0;
        !            32: OXFILE *stack_oxfp = NULL;
        !            33:
        !            34: #define DIFFERENCE_OF_STACK  1024
        !            35:
        !            36: void stack_extend()
        !            37: {
        !            38:     int newsize = stack_size + DIFFERENCE_OF_STACK;
        !            39:     cmo **newstack = (cmo **)malloc(sizeof(cmo *)*newsize);
        !            40:     if (stack != NULL) {
        !            41:         memcpy(newstack, stack, sizeof(cmo *)*stack_size);
        !            42:         free(stack);
        !            43:     }
        !            44:     stack_size = newsize;
        !            45:     stack = newstack;
        !            46: }
        !            47:
        !            48: void push(cmo* m)
        !            49: {
        !            50: #if DEBUG
        !            51:     symbol_t symp;
        !            52:
        !            53:     if (m->tag == CMO_STRING) {
        !            54:         fprintf(stderr, "ox_math:: a CMO_STRING(%s) was pushed.\n", ((cmo_string *)m)->s);
        !            55:     }else {
        !            56:         symp = lookup_by_tag(m->tag);
        !            57:         fprintf(stderr, "ox_math:: a %s was pushed.\n", symbol_get_key(symp));
        !            58:     }
        !            59: #endif
        !            60:     if (stack_ptr >= stack_size) {
        !            61:         stack_extend();
        !            62:     }
        !            63:     stack[stack_ptr] = m;
        !            64:     stack_ptr++;
        !            65: }
        !            66:
        !            67: /* if the stack is empty, then pop() returns (CMO_NULL). */
        !            68: cmo *pop()
        !            69: {
        !            70:     if (stack_ptr > 0) {
        !            71:         return stack[--stack_ptr];
        !            72:     }
        !            73:     return new_cmo_null();
        !            74: }
        !            75:
        !            76: void pops(int n)
        !            77: {
        !            78:     stack_ptr -= n;
        !            79:     if (stack_ptr < 0) {
        !            80:         stack_ptr = 0;
        !            81:     }
        !            82: }
        !            83:
        !            84: void push_error(int errcode, cmo* pushback)
        !            85: {
        !            86:     return push((cmo *)make_error_object(errcode, pushback));
        !            87: }
        !            88:
        !            89: /*
        !            90: If error occurs, then
        !            91: an sm_*() function returns non-zero and
        !            92: an error obect is set by a function which calls sm_*().
        !            93: */
        !            94: int sm_popCMO(OXFILE* oxfp)
        !            95: {
        !            96:     cmo* m = pop();
        !            97: #ifdef DEBUG
        !            98:     symbol_t symp = lookup_by_tag(m->tag);
        !            99:     fprintf(stderr, "ox_math:: opecode = SM_popCMO. (%s)\n", symbol_get_key(symp));
        !           100: #endif
        !           101:
        !           102:     if (m != NULL) {
        !           103:         send_ox_cmo(oxfp, m);
        !           104:         return 0;
        !           105:     }
        !           106:     return SM_popCMO;
        !           107: }
        !           108:
        !           109: int sm_pops(OXFILE* oxfp)
        !           110: {
        !           111:     cmo* m = pop();
        !           112:     if (m != NULL && m->tag == CMO_INT32) {
        !           113:         pops(((cmo_int32 *)m)->i);
        !           114:         return 0;
        !           115:     }
        !           116:     return ERROR_ID_UNKNOWN_SM;
        !           117: }
        !           118:
        !           119: /* MathLink dependent */
        !           120: int sm_popString(OXFILE* oxfp)
        !           121: {
        !           122:     char *s;
        !           123:     cmo *err;
        !           124:     cmo *m;
        !           125:
        !           126: #ifdef DEBUG
        !           127:     fprintf(stderr, "ox_math:: opecode = SM_popString.\n");
        !           128: #endif
        !           129:
        !           130:     m = pop();
        !           131:     if (m->tag == CMO_STRING) {
        !           132:         send_ox_cmo(oxfp, m);
        !           133:     }else if ((s = new_string_set_cmo(m)) != NULL) {
        !           134:         send_ox_cmo(oxfp, (cmo *)new_cmo_string(s));
        !           135:     }else {
        !           136:         err = make_error_object(SM_popString, m);
        !           137:         send_ox_cmo(oxfp, err);
        !           138:     }
        !           139:     return 0;
        !           140: }
        !           141:
        !           142: int local_execute(char *s)
        !           143: {
        !           144:     if(*s == 'i') {
        !           145:         switch(s[1]) {
        !           146:         case '+':
        !           147:             flag_mlo_symbol = FLAG_MLTKSYM_IS_STRING;
        !           148:             break;
        !           149:         case '-':
        !           150:         case '=':
        !           151:         default:
        !           152:             flag_mlo_symbol = FLAG_MLTKSYM_IS_INDETERMINATE;
        !           153:         }
        !           154:     }
        !           155:     return 0;
        !           156: }
        !           157:
        !           158: /* The following function is depend on an implementation of a server. */
        !           159: int sm_executeStringByLocalParser(OXFILE* oxfp)
        !           160: {
        !           161:     symbol_t symp;
        !           162:     cmo* m = pop();
        !           163:     char *s = NULL;
        !           164: #ifdef DEBUG
        !           165:     fprintf(stderr, "ox_math:: opecode = SM_executeStringByLocalParser.\n");
        !           166: #endif
        !           167:
        !           168:     if (m->tag == CMO_STRING
        !           169:         && strlen(s = ((cmo_string *)m)->s) != 0) {
        !           170:         if (s[0] == ':') {
        !           171:             local_execute(++s);
        !           172:         }else {
        !           173:             /* for mathematica */
        !           174:             /* Sending the string `s' to mathematica for its evaluation. */
        !           175:             ml_evaluateStringByLocalParser(s);
        !           176:             ml_select();
        !           177:             push(receive_mlo());
        !           178:         }
        !           179:         return 0;
        !           180:     }
        !           181: #ifdef DEBUG
        !           182:     symp = lookup_by_tag(m->tag);
        !           183:     fprintf(stderr, "ox_math:: error. the top of stack is %s.\n", symbol_get_key(symp));
        !           184: #endif
        !           185:     return SM_executeStringByLocalParser;
        !           186: }
        !           187:
        !           188: int sm_executeFunction(OXFILE* oxfp)
        !           189: {
        !           190:     int i, argc;
        !           191:     cmo **argv;
        !           192:     char* func;
        !           193:     cmo* m;
        !           194:
        !           195:     if ((m = pop()) == NULL || m->tag != CMO_STRING) {
        !           196:         return SM_executeFunction;
        !           197:     }
        !           198:     func = ((cmo_string *)m)->s;
        !           199:
        !           200:     if ((m = pop()) == NULL || m->tag != CMO_INT32) {
        !           201:         return SM_executeFunction;
        !           202:     }
        !           203:
        !           204:     argc = ((cmo_int32 *)m)->i;
        !           205:     argv = malloc(argc*sizeof(cmo *));
        !           206:     for (i=0; i<argc; i++) {
        !           207:         argv[i] = pop();
        !           208:     }
        !           209:     ml_executeFunction(func, argc, argv);
        !           210:     ml_select();
        !           211:     push(receive_mlo());
        !           212:     return 0;
        !           213: }
        !           214:
        !           215: int sm_mathcap(OXFILE* oxfp)
        !           216: {
        !           217:     push((cmo *)oxf_cmo_mathcap(oxfp));
        !           218:     return 0;
        !           219: }
        !           220:
        !           221: void sm_set_mathcap(OXFILE *oxfp)
        !           222: {
        !           223:     cmo_mathcap *m = (cmo_mathcap *)pop();
        !           224:     if (m->tag == CMO_MATHCAP) {
        !           225:         oxf_mathcap_update(oxfp, m);
        !           226:     }else {
        !           227:         push_error(-1, m);
        !           228:         /* an error object must be pushed */
        !           229:     }
        !           230: }
        !           231:
        !           232: int receive_sm_command(OXFILE* oxfp)
        !           233: {
        !           234:     return receive_int32(oxfp);
        !           235: }
        !           236:
        !           237: int execute_sm_command(OXFILE* oxfp, int code)
        !           238: {
        !           239:     int err = 0;
        !           240: #ifdef DEBUG
        !           241:     symbol_t sp = lookup_by_tag(code);
        !           242:     fprintf(stderr, "ox_math:: %s received.\n", symbol_get_key(sp));
        !           243: #endif
        !           244:
        !           245:     switch(code) {
        !           246:     case SM_popCMO:
        !           247:         err = sm_popCMO(oxfp);
        !           248:         break;
        !           249:     case SM_popString:
        !           250:         err = sm_popString(oxfp);
        !           251:         break;
        !           252:     case SM_mathcap:
        !           253:         err = sm_mathcap(oxfp);
        !           254:         break;
        !           255:     case SM_pops:
        !           256:         err = sm_pops(oxfp);
        !           257:         break;
        !           258:     case SM_executeStringByLocalParser:
        !           259:     case SM_executeStringByLocalParserInBatchMode:
        !           260:         err = sm_executeStringByLocalParser(oxfp);
        !           261:         break;
        !           262:     case SM_executeFunction:
        !           263:         err = sm_executeFunction(oxfp);
        !           264:         break;
        !           265:     case SM_shutdown:
        !           266:         shutdown();
        !           267:         break;
        !           268:     case SM_setMathCap:
        !           269:         pop();  /* ignore */
        !           270:         break;
        !           271:     default:
        !           272:         fprintf(stderr, "unknown command: %d.\n", code);
        !           273:         err = ERROR_ID_UNKNOWN_SM;
        !           274:     }
        !           275:
        !           276:     if (err != 0) {
        !           277:         push((cmo *)make_error_object(err, new_cmo_null()));
        !           278:     }
        !           279: }
        !           280:
        !           281: int sm_run(int code)
        !           282: {
        !           283:     return execute_sm_command(stack_oxfp, code);
        !           284: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>