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>