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

Annotation of OpenXM/src/ox_math/serv2.c, Revision 1.4

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.4     ! ohara       2: /* $OpenXM: OpenXM/src/ox_math/serv2.c,v 1.3 1999/11/03 10:56:40 ohara Exp $ */
1.1       ohara       3:
                      4: /* Open Mathematica サーバ */
                      5: /* ファイルディスクリプタ 3, 4 は open されていると仮定して動作する. */
                      6:
                      7: /* MathLink との通信部分 */
                      8:
                      9: #include <stdio.h>
                     10: #include <stdlib.h>
                     11: #include <unistd.h>
                     12: #include <gmp.h>
                     13: #include <mathlink.h>
                     14: #include "ox.h"
                     15: #include "serv2.h"
                     16:
                     17: #define UNKNOWN_SM_COMMAND 50000
                     18: #define MATH_ERROR         50001
                     19:
                     20: /* MLINK はポインタ型. */
                     21: MLINK lp = NULL;
                     22:
1.4     ! ohara      23:
        !            24: typedef cmo mlo;
        !            25: typedef cmo_string mlo_string;
        !            26: typedef cmo_zz mlo_zz;
        !            27:
        !            28: /* cmo_list の派生クラス*/
        !            29: typedef struct {
        !            30:        int tag;
        !            31:        int length;
        !            32:        cell *head;
        !            33:        char *function;
        !            34: } mlo_function;
        !            35:
        !            36:
        !            37: mlo *receive_mlo_zz()
        !            38: {
        !            39:        char *s;
        !            40:        mlo  *m;
        !            41:
        !            42:        MLGetString(lp, &s);
        !            43:        fprintf(stderr, "--debug: zz = %s.\n", s);
        !            44:        m = (mlo *)new_cmo_zz_set_string(s);
        !            45:        MLDisownString(lp, s);
        !            46:        return m;
        !            47: }
        !            48:
        !            49: mlo *receive_mlo_string()
        !            50: {
        !            51:        char *s;
        !            52:        mlo  *m;
        !            53:        MLGetString(lp, &s);
        !            54:        m = (cmo *)new_cmo_string(s);
        !            55:        MLDisownString(lp, s);
        !            56:        return m;
        !            57: }
        !            58:
1.1       ohara      59: /* Mathematica を起動する. */
                     60: int MATH_init()
                     61: {
                     62:     int argc = 2;
                     63:     char *argv[] = {"-linkname", "math -mathlink"};
                     64:
                     65:     if(MLInitialize(NULL) != NULL) {
                     66:         lp = MLOpen(argc, argv);
                     67:         if(lp != NULL) {
                     68:             return 0;
                     69:         }
                     70:     }
                     71:     exit(1);
                     72: }
                     73:
                     74: int MATH_exit()
                     75: {
                     76:     /* quit Mathematica then close the link */
                     77:     MLPutFunction(lp, "Exit", 0);
                     78:     MLClose(lp);
                     79: }
                     80:
                     81: char *MATH_getObject()
                     82: {
                     83:     char *s;
                     84:
                     85:     /* skip any packets before the first ReturnPacket */
                     86:     while (MLNextPacket(lp) != RETURNPKT) {
                     87:         usleep(10);
                     88:         MLNewPacket(lp);
                     89:     }
                     90:     /* いまはタイプにかかわらず文字列を取得する. */
                     91:     switch(MLGetNext(lp)) {
                     92:     case MLTKINT:
                     93:         fprintf(stderr, "type is INTEGER.\n");
                     94:         MLGetString(lp, &s);
                     95:         break;
                     96:     case MLTKSTR:
                     97:         fprintf(stderr, "type is STRING.\n");
                     98:         MLGetString(lp, &s);
                     99:         break;
                    100:     default:
                    101:         MLGetString(lp, &s);
                    102:     }
                    103:     return s;
                    104: }
                    105:
1.4     ! ohara     106:
1.1       ohara     107: cmo *MATH_getObject2()
                    108: {
                    109:     /* skip any packets before the first ReturnPacket */
                    110:     while (MLNextPacket(lp) != RETURNPKT) {
                    111:         usleep(10);
                    112:         MLNewPacket(lp);
                    113:     }
                    114:     /* いまはタイプにかかわらず文字列を取得する. */
1.4     ! ohara     115:        return MATH_getObject3();
        !           116: }
        !           117:
        !           118: cmo *MATH_getObject3()
        !           119: {
        !           120:     char *s;
        !           121:     cmo  *m;
        !           122:     cmo  *ob;
        !           123:     int  i,n;
        !           124:        int type;
        !           125:
        !           126:     /* いまはタイプにかかわらず文字列を取得する. */
        !           127:        type = MLGetNext(lp);
        !           128:     switch(type) {
1.1       ohara     129:     case MLTKINT:
1.4     ! ohara     130:         fprintf(stderr, "--debug: MLO == MLTKINT.\n");
        !           131:                m = receive_mlo_zz();
1.1       ohara     132:         break;
                    133:     case MLTKSTR:
1.4     ! ohara     134:         fprintf(stderr, "--debug: MLO == MLTKSTR.\n");
        !           135:                m = receive_mlo_string();
        !           136:         break;
        !           137: #if 0
        !           138:     case MLTKREAL:
        !           139:         fprintf(stderr, "MLTKREAL is not supported: we use MLTKSTR.\n");
1.1       ohara     140:         MLGetString(lp, &s);
                    141:         m = (cmo *)new_cmo_string(s);
                    142:         break;
                    143:     case MLTKERR:
1.4     ! ohara     144:         fprintf(stderr, "--debug: MLO == MLTKERR.\n");
1.2       ohara     145:         m = (cmo *)gen_error_object(MATH_ERROR);
1.1       ohara     146:         break;
1.4     ! ohara     147: #endif
1.1       ohara     148:     case MLTKSYM:
1.4     ! ohara     149:                fprintf(stderr, "--debug: MLO == MLTKSYM.\n");
        !           150:                /* この部分に問題がある. */
        !           151:         MLGetSymbol(lp, &s);
        !           152:                fprintf(stderr, "--debug: Symbol \"%s\".\n", s);
1.1       ohara     153:         m = (cmo *)new_cmo_string(s);
                    154:         break;
                    155:     case MLTKFUNC:
1.4     ! ohara     156:         fprintf(stderr, "--debug: MLO == MLTKFUNC.\n");
        !           157:         MLGetFunction(lp, &s, &n);
        !           158:         fprintf(stderr, "--debug: Function = \"%s\", # of args = %d\n", s, n);
        !           159:                m = new_cmo_list();
        !           160:                append_cmo_list(m, new_cmo_string(s));
        !           161:                fflush(stderr);
        !           162:         for (i=0; i<n; i++) {
        !           163:             fprintf(stderr, "--debug: arg[%d]\n", i);
        !           164:                        fflush(stderr);
        !           165:                        ob = MATH_getObject3();
        !           166:                        append_cmo_list(m, ob);
1.1       ohara     167:         }
                    168:         break;
                    169:     default:
1.4     ! ohara     170:         fprintf(stderr, "--debug: MLO(%d) != MLTKINT, MLTKSTR.\n", type);
        !           171:         fprintf(stderr, "--debug: MLTKFUNC(%d), MLTKSYM(%d).\n", MLTKFUNC, MLTKSYM);
        !           172:
1.1       ohara     173:         MLGetString(lp, &s);
1.4     ! ohara     174:                fprintf(stderr, "--debug: \"%s\"\n", s);
1.1       ohara     175:         m = (cmo *)new_cmo_string(s);
                    176:     }
                    177:     return m;
                    178: }
                    179:
                    180: int MATH_sendObject(cmo *m)
                    181: {
                    182:     char *s;
                    183:     switch(m->tag) {
                    184:     case CMO_INT32:
                    185:         MLPutInteger(lp, ((cmo_int32 *)m)->i);
                    186:         break;
                    187:     case CMO_STRING:
                    188:         s = ((cmo_string *)m)->s;
                    189:         MLPutString(lp, s);
                    190:         fprintf(stderr, "put %s.", s);
                    191:         break;
                    192:     default:
                    193:         MLPutFunction(lp, "ToExpression", 1);
1.3       ohara     194:         s = convert_cmo_to_string(m);
1.1       ohara     195:         MLPutString(lp, s);
                    196:         fprintf(stderr, "put %s.", s);
                    197:         break;
                    198:     }
                    199: }
                    200:
                    201: int MATH_evaluateStringByLocalParser(char *str)
                    202: {
                    203:     MLPutFunction(lp, "ToExpression", 1);
                    204:     MLPutString(lp, str);
                    205:     MLEndPacket(lp);
                    206: }
                    207:
                    208: int MATH_executeFunction(char *function, int argc, cmo *argv[])
                    209: {
                    210:     int i;
                    211:     MLPutFunction(lp, function, argc);
                    212:     for (i=0; i<argc; i++) {
                    213:         MATH_sendObject(argv[i]);
                    214:     }
                    215:     MLEndPacket(lp);
                    216: }
                    217:
                    218: /* MathLink 非依存部分 */
                    219:
                    220: #define SIZE_OPERAND_STACK   2048
                    221:
                    222: static cmo* Operand_Stack[SIZE_OPERAND_STACK];
                    223: static int Stack_Pointer = 0;
                    224:
                    225: int initialize_stack()
                    226: {
                    227:     Stack_Pointer = 0;
                    228: }
                    229:
                    230: int push(cmo* m)
                    231: {
                    232: #if DEBUG
                    233:     fprintf(stderr, "server:: a cmo is pushed: tag == %d.\n", m->tag);
                    234:     if (m->tag == CMO_STRING) {
                    235:         fprintf(stderr, "server:: %s\n", ((cmo_string *)m)->s);
                    236:     }
                    237: #endif
                    238:     Operand_Stack[Stack_Pointer] = m;
                    239:     Stack_Pointer++;
                    240:     if (Stack_Pointer >= SIZE_OPERAND_STACK) {
                    241:         fprintf(stderr, "stack over flow.\n");
                    242:         exit(1);
                    243:     }
                    244: }
                    245:
1.3       ohara     246: /* スタックが空のときは, (CMO_NULL) をかえす. */
1.1       ohara     247: cmo* pop()
                    248: {
                    249:     if (Stack_Pointer > 0) {
                    250:         Stack_Pointer--;
                    251:         return Operand_Stack[Stack_Pointer];
                    252:     }
1.3       ohara     253:     return new_cmo_null();
1.1       ohara     254: }
                    255:
                    256: void pops(int n)
                    257: {
                    258:     Stack_Pointer -= n;
                    259:     if (Stack_Pointer < 0) {
                    260:         Stack_Pointer = 0;
                    261:     }
                    262: }
                    263:
                    264: /* sm_XXX 関数群は、エラーのときは 0 以外の値を返し、呼び出し元で
                    265:    エラーオブジェクトをセットする */
                    266: int sm_popCMO(int fd_write)
                    267: {
                    268:     cmo* m = pop();
                    269:
                    270:     fprintf(stderr, "code: SM_popCMO.\n");
                    271:     if (m != NULL) {
                    272:         send_ox_cmo(fd_write, m);
                    273:         return 0;
                    274:     }
                    275:     return SM_popCMO;
                    276: }
                    277:
                    278: int sm_pops(int fd_write)
                    279: {
                    280:     cmo* m = pop();
                    281:     if (m != NULL && m->tag == CMO_INT32) {
                    282:         pops(((cmo_int32 *)m)->i);
                    283:         return 0;
                    284:     }
                    285:     return UNKNOWN_SM_COMMAND;
                    286: }
                    287:
                    288: /* MathLink 依存部分 */
                    289: int sm_popString(int fd_write)
                    290: {
                    291:     char* s;
                    292:     cmo*  m;
                    293:
                    294: #ifdef DEBUG
                    295:     fprintf(stderr, "code: SM_popString.\n");
                    296: #endif
                    297:
1.3       ohara     298:     if ((m = pop()) != NULL && (s = convert_cmo_to_string(m)) != NULL) {
1.2       ohara     299:         send_ox_cmo(fd_write, (cmo *)new_cmo_string(s));
1.1       ohara     300:         return 0;
                    301:     }
                    302:     return SM_popString;
                    303: }
                    304:
                    305: /* この関数はサーバに依存する. */
                    306: int sm_executeStringByLocalParser(int fd_write)
                    307: {
                    308:     cmo* m = NULL;
                    309: #ifdef DEBUG
                    310:     fprintf(stderr, "code: SM_executeStringByLocalParser.\n");
                    311: #endif
                    312:     if ((m = pop()) != NULL && m->tag == CMO_STRING) {
                    313:         /* for mathematica */
                    314:         /* mathematica に文字列を送って評価させる */
                    315:         MATH_evaluateStringByLocalParser(((cmo_string *)m)->s);
                    316:         push(MATH_getObject2());
                    317:         return 0;
                    318:     }
                    319:     fprintf(stderr, "cannot execute: top of stack is not string!(%p, %d)\n", m, m->tag);
                    320:     return SM_executeStringByLocalParser;
                    321: }
                    322:
                    323: int sm_executeFunction(int fd_write)
                    324: {
                    325:     int i, argc;
                    326:     cmo **argv;
                    327:     char* func;
                    328:     cmo* m;
                    329:
                    330:     if ((m = pop()) == NULL || m->tag != CMO_STRING) {
                    331:         return SM_executeFunction;
                    332:     }
                    333:     func = ((cmo_string *)m)->s;
                    334:
                    335:     if ((m = pop()) == NULL || m->tag != CMO_INT32) {
                    336:         return SM_executeFunction;
                    337:     }
                    338:     argc = ((cmo_int32 *)m)->i;
                    339:     argv = malloc(sizeof(cmo *)*argc);
                    340:     for (i=0; i<argc; i++) {
                    341:         if ((argv[i] = pop()) == NULL) {
                    342:             return SM_executeFunction;
                    343:         }
                    344:     }
                    345:     MATH_executeFunction(func, argc, argv);
                    346:     push(MATH_getObject2());
                    347:     return 0;
                    348: }
                    349:
                    350: /* 平成11年10月13日 */
                    351: #define VERSION 0x11102700
                    352: #define ID_STRING  "ox_math server 1999/10/28 17:29:25"
                    353:
                    354: int sm_mathcap(int fd_write)
                    355: {
                    356:     cmo* c = make_mathcap_object(VERSION, ID_STRING);
                    357:     push(c);
                    358:     return 0;
                    359: }
                    360:
                    361: int receive_sm_command(int fd_read)
                    362: {
                    363:     return receive_int32(fd_read);
                    364: }
                    365:
                    366: int execute_sm_command(int fd_write, int code)
                    367: {
                    368:     int err = 0;
                    369:
                    370:     switch(code) {
                    371:     case SM_popCMO:
                    372:         err = sm_popCMO(fd_write);
                    373:         break;
                    374:     case SM_popString:
                    375:         err = sm_popString(fd_write);
                    376:         break;
                    377:     case SM_mathcap:
                    378:         err = sm_mathcap(fd_write);
                    379:         break;
                    380:     case SM_pops:
                    381:         err = sm_pops(fd_write);
                    382:         break;
                    383:     case SM_executeStringByLocalParser:
                    384:         err = sm_executeStringByLocalParser(fd_write);
                    385:         break;
                    386:     case SM_executeFunction:
                    387:         err = sm_executeFunction(fd_write);
                    388:         break;
1.2       ohara     389:     case SM_setMathCap:
1.1       ohara     390:         pop();  /* 無視する */
                    391:         break;
                    392:     default:
                    393:         fprintf(stderr, "unknown command: %d.\n", code);
                    394:         err = UNKNOWN_SM_COMMAND;
                    395:     }
                    396:
                    397:     if (err != 0) {
1.2       ohara     398:         push((cmo *)gen_error_object(err));
1.1       ohara     399:     }
                    400: }

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