[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

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>