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>