[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.1

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

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