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

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

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