Annotation of OpenXM/src/ox_math/serv2.c, Revision 1.11
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.11 ! ohara 2: /* $OpenXM: OpenXM/src/ox_math/serv2.c,v 1.10 1999/11/29 12:09:58 ohara Exp $ */
1.1 ohara 3:
4: /* Open Mathematica サーバ */
5: /* ファイルディスクリプタ 3, 4 は open されていると仮定して動作する. */
6:
7: #include <stdio.h>
8: #include <stdlib.h>
9: #include <unistd.h>
10: #include <gmp.h>
11: #include <mathlink.h>
12: #include "ox.h"
1.6 ohara 13: #include "parse.h"
1.1 ohara 14: #include "serv2.h"
15:
1.10 ohara 16: extern int flag_mlo_symbol;
1.1 ohara 17:
18: /* MathLink 非依存部分 */
1.11 ! ohara 19: #define INIT_S_SIZE 2048
! 20: #define EXT_S_SIZE 2048
1.1 ohara 21:
1.11 ! ohara 22: static int stack_size = 0;
! 23: static int stack_pointer = 0;
! 24: static cmo **stack = NULL;
1.1 ohara 25:
26: int initialize_stack()
27: {
1.11 ! ohara 28: stack_pointer = 0;
! 29: stack_size = INIT_S_SIZE;
! 30: stack = malloc(stack_size*sizeof(cmo*));
! 31: }
! 32:
! 33: static int extend_stack()
! 34: {
! 35: int size2 = stack_size + EXT_S_SIZE;
! 36: cmo **stack2 = malloc(size2*sizeof(cmo*));
! 37: memcpy(stack2, stack, stack_size*sizeof(cmo *));
! 38: free(stack);
! 39: stack = stack2;
! 40: stack_size = size2;
1.10 ohara 41: }
1.1 ohara 42:
43: int push(cmo* m)
44: {
45: #if DEBUG
1.7 ohara 46: symbol *symp;
1.6 ohara 47:
1.1 ohara 48: if (m->tag == CMO_STRING) {
1.7 ohara 49: fprintf(stderr, "ox_math:: a CMO_STRING(%s) was pushed.\n", ((cmo_string *)m)->s);
1.5 ohara 50: }else {
1.7 ohara 51: symp = lookup_by_tag(m->tag);
52: fprintf(stderr, "ox_math:: a %s was pushed.\n", symp->key);
53: }
1.1 ohara 54: #endif
1.11 ! ohara 55: stack[stack_pointer] = m;
! 56: stack_pointer++;
! 57: if (stack_pointer >= stack_size) {
! 58: extend_stack();
1.1 ohara 59: }
60: }
61:
1.3 ohara 62: /* スタックが空のときは, (CMO_NULL) をかえす. */
1.1 ohara 63: cmo* pop()
64: {
1.11 ! ohara 65: if (stack_pointer > 0) {
! 66: stack_pointer--;
! 67: return stack[stack_pointer];
1.1 ohara 68: }
1.3 ohara 69: return new_cmo_null();
1.1 ohara 70: }
71:
72: void pops(int n)
73: {
1.11 ! ohara 74: stack_pointer -= n;
! 75: if (stack_pointer < 0) {
! 76: stack_pointer = 0;
1.1 ohara 77: }
78: }
79:
80: /* sm_XXX 関数群は、エラーのときは 0 以外の値を返し、呼び出し元で
81: エラーオブジェクトをセットする */
82: int sm_popCMO(int fd_write)
83: {
84: cmo* m = pop();
1.6 ohara 85: #ifdef DEBUG
1.7 ohara 86: symbol *symp = lookup_by_tag(m->tag);
1.6 ohara 87: fprintf(stderr, "ox_math:: opecode = SM_popCMO. (%s)\n", symp->key);
88: #endif
1.10 ohara 89:
1.1 ohara 90: if (m != NULL) {
91: send_ox_cmo(fd_write, m);
92: return 0;
93: }
94: return SM_popCMO;
95: }
96:
97: int sm_pops(int fd_write)
98: {
99: cmo* m = pop();
100: if (m != NULL && m->tag == CMO_INT32) {
101: pops(((cmo_int32 *)m)->i);
102: return 0;
103: }
1.7 ohara 104: return ERROR_ID_UNKNOWN_SM;
1.1 ohara 105: }
106:
107: /* MathLink 依存部分 */
108: int sm_popString(int fd_write)
109: {
1.6 ohara 110: char *s;
111: cmo *err;
112: cmo *m;
1.1 ohara 113:
114: #ifdef DEBUG
1.5 ohara 115: fprintf(stderr, "ox_math:: opecode = SM_popString.\n");
1.1 ohara 116: #endif
117:
1.7 ohara 118: m = pop();
119: if (m->tag == CMO_STRING) {
1.6 ohara 120: send_ox_cmo(fd_write, m);
1.11 ! ohara 121: }else if ((s = new_string_set_cmo(m)) != NULL) {
1.2 ohara 122: send_ox_cmo(fd_write, (cmo *)new_cmo_string(s));
1.6 ohara 123: }else {
1.7 ohara 124: err = make_error_object(SM_popString, m);
125: send_ox_cmo(fd_write, err);
126: }
127: return 0;
1.6 ohara 128: }
129:
130: int local_execute(char *s)
131: {
1.10 ohara 132: if(*s == 'i') {
133: switch(s[1]) {
134: case '+':
135: flag_mlo_symbol = FLAG_MLTKSYM_IS_STRING;
136: break;
137: case '-':
138: case '=':
139: default:
140: flag_mlo_symbol = FLAG_MLTKSYM_IS_INDETERMINATE;
141: }
142: }
1.7 ohara 143: return 0;
1.1 ohara 144: }
145:
146: /* この関数はサーバに依存する. */
147: int sm_executeStringByLocalParser(int fd_write)
148: {
1.7 ohara 149: symbol *symp;
1.6 ohara 150: cmo* m = pop();
1.7 ohara 151: char *s = NULL;
1.1 ohara 152: #ifdef DEBUG
1.5 ohara 153: fprintf(stderr, "ox_math:: opecode = SM_executeStringByLocalParser.\n");
1.1 ohara 154: #endif
1.6 ohara 155:
156: if (m->tag == CMO_STRING
1.7 ohara 157: && strlen(s = ((cmo_string *)m)->s) != 0) {
158: if (s[0] == ':') {
1.8 ohara 159: local_execute(++s);
1.7 ohara 160: }else {
161: /* for mathematica */
162: /* mathematica に文字列を送って評価させる */
1.10 ohara 163: ml_evaluateStringByLocalParser(s);
1.11 ! ohara 164: ml_select();
! 165: push(receive_mlo());
1.7 ohara 166: }
167: return 0;
1.1 ohara 168: }
1.6 ohara 169: #ifdef DEBUG
1.10 ohara 170: symp = lookup_by_tag(m->tag);
171: fprintf(stderr, "ox_math:: error. the top of stack is %s.\n", symp->key);
1.6 ohara 172: #endif
1.1 ohara 173: return SM_executeStringByLocalParser;
174: }
175:
176: int sm_executeFunction(int fd_write)
177: {
178: int i, argc;
179: cmo **argv;
180: char* func;
181: cmo* m;
182:
183: if ((m = pop()) == NULL || m->tag != CMO_STRING) {
184: return SM_executeFunction;
185: }
186: func = ((cmo_string *)m)->s;
187:
188: if ((m = pop()) == NULL || m->tag != CMO_INT32) {
189: return SM_executeFunction;
190: }
1.6 ohara 191:
1.1 ohara 192: argc = ((cmo_int32 *)m)->i;
1.7 ohara 193: argv = malloc(argc*sizeof(cmo *));
1.1 ohara 194: for (i=0; i<argc; i++) {
1.6 ohara 195: argv[i] = pop();
1.1 ohara 196: }
1.10 ohara 197: ml_executeFunction(func, argc, argv);
1.11 ! ohara 198: ml_select();
! 199: push(receive_mlo());
1.1 ohara 200: return 0;
201: }
202:
1.11 ! ohara 203: /* 平成12年12月14日 */
! 204: #define VERSION 0x11121400
! 205: #define ID_STRING "ox_math server 1999/12/14 15:25:00"
1.1 ohara 206:
207: int sm_mathcap(int fd_write)
208: {
1.7 ohara 209: push(make_mathcap_object(VERSION, ID_STRING));
1.1 ohara 210: return 0;
211: }
212:
213: int receive_sm_command(int fd_read)
214: {
215: return receive_int32(fd_read);
216: }
217:
218: int execute_sm_command(int fd_write, int code)
219: {
220: int err = 0;
1.10 ohara 221: #ifdef DEBUG
222: symbol *sp = lookup_by_tag(code);
223: fprintf(stderr, "ox_math:: %s received.\n", sp->key);
1.8 ohara 224: #endif
1.1 ohara 225:
226: switch(code) {
227: case SM_popCMO:
228: err = sm_popCMO(fd_write);
229: break;
230: case SM_popString:
231: err = sm_popString(fd_write);
232: break;
233: case SM_mathcap:
234: err = sm_mathcap(fd_write);
235: break;
236: case SM_pops:
237: err = sm_pops(fd_write);
238: break;
239: case SM_executeStringByLocalParser:
1.10 ohara 240: case SM_executeStringByLocalParserInBatchMode:
1.1 ohara 241: err = sm_executeStringByLocalParser(fd_write);
242: break;
243: case SM_executeFunction:
244: err = sm_executeFunction(fd_write);
245: break;
1.10 ohara 246: case SM_shutdown:
247: shutdown();
248: break;
1.2 ohara 249: case SM_setMathCap:
1.1 ohara 250: pop(); /* 無視する */
251: break;
252: default:
253: fprintf(stderr, "unknown command: %d.\n", code);
1.7 ohara 254: err = ERROR_ID_UNKNOWN_SM;
1.1 ohara 255: }
256:
257: if (err != 0) {
1.7 ohara 258: push((cmo *)make_error_object(err, new_cmo_null()));
1.1 ohara 259: }
260: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>