Annotation of OpenXM/src/ox_math/serv2.c, Revision 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>