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>