Annotation of OpenXM/src/ox_toolkit/ox.c, Revision 1.44
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.44 ! noro 2: /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.43 2015/08/17 05:18:35 noro Exp $ */
1.1 ohara 3:
1.8 ohara 4: /*
5: This module includes functions for sending/receiveng CMO's.
6: Some commnets is written in Japanese by the EUC-JP coded
7: character set.
1.1 ohara 8: */
9:
10: #include <stdio.h>
11: #include <stdlib.h>
1.20 ohara 12: #include <stdarg.h>
1.1 ohara 13: #include <string.h>
14: #include <unistd.h>
15: #include <fcntl.h>
1.5 ohara 16: #include <sys/file.h>
1.13 ohara 17: #include <time.h>
1.1 ohara 18:
1.38 noro 19: #include <mpfr.h>
20: /* XXX : defined in mpfr-impl.h */
21: #define MPFR_PREC(x) ((x)->_mpfr_prec)
22: #define MPFR_EXP(x) ((x)->_mpfr_exp)
23: #define MPFR_MANT(x) ((x)->_mpfr_d)
24: #define MPFR_LAST_LIMB(x) ((MPFR_PREC (x) - 1) / GMP_NUMB_BITS)
25: #define MPFR_LIMB_SIZE(x) (MPFR_LAST_LIMB (x) + 1)
26:
27: #if SIZEOF_LONG==4
28: typedef long long L64;
29: typedef unsigned long long UL64;
30: #else
31: typedef long L64;
32: typedef unsigned long UL64;
33: #endif
34:
1.1 ohara 35: #include "mysocket.h"
1.12 ohara 36: #include "ox_toolkit.h"
1.1 ohara 37: #include "parse.h"
38:
1.20 ohara 39: static FILE *ox_stderr = NULL;
40:
1.17 ohara 41: /* sorting by the value of CMO_xxx. (for debugging) */
1.13 ohara 42: static cmo_null* receive_cmo_null(OXFILE *oxfp);
43: static cmo_int32* receive_cmo_int32(OXFILE *oxfp);
44: static cmo_string* receive_cmo_string(OXFILE *oxfp);
45: static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp);
46: static cmo_list* receive_cmo_list(OXFILE *oxfp);
47: static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp);
48: static cmo_zero* receive_cmo_zero(OXFILE *oxfp);
49: static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp);
50: static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp);
51: static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp);
1.26 ohara 52: static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp);
53: static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp);
1.32 ohara 54: static cmo_double* receive_cmo_double(OXFILE *oxfp);
1.13 ohara 55: static cmo_error2* receive_cmo_error2(OXFILE *oxfp);
56:
57: static int send_cmo_null(OXFILE *oxfp, cmo_null* c);
58: static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m);
59: static int send_cmo_string(OXFILE *oxfp, cmo_string* m);
60: static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c);
61: static int send_cmo_list(OXFILE *oxfp, cmo_list* c);
62: static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c);
1.32 ohara 63: static int send_cmo_double(OXFILE *oxfp, cmo_double* c);
1.22 ohara 64: static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c);
65: static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c);
1.26 ohara 66: static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c);
67: static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c);
1.22 ohara 68:
69: static cmo_zz* receive_cmo_zz(OXFILE *oxfp);
70: static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz);
1.13 ohara 71: static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c);
72: static int send_mpz(OXFILE *oxfp, mpz_ptr mpz);
1.38 noro 73: static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
74: static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr);
1.3 ohara 75:
1.8 ohara 76: /* hook functions. (yet not implemented) */
1.2 ohara 77: static hook_t hook_before_send_cmo = NULL;
78: static hook_t hook_after_send_cmo = NULL;
79:
80: int add_hook_before_send_cmo(hook_t func)
81: {
1.13 ohara 82: hook_before_send_cmo = func;
83: return 0;
1.2 ohara 84: }
85:
86: int add_hook_after_send_cmo(hook_t func)
87: {
1.13 ohara 88: hook_after_send_cmo = func;
89: return 0;
1.2 ohara 90: }
91:
1.13 ohara 92: static cmo *call_hook_before_send_cmo(OXFILE *oxfp, cmo *c)
1.2 ohara 93: {
1.13 ohara 94: if (hook_before_send_cmo != NULL) {
95: return hook_before_send_cmo(oxfp, c);
96: }
97: return c;
1.2 ohara 98: }
99:
1.13 ohara 100: static cmo *call_hook_after_send_cmo(OXFILE *oxfp, cmo *c)
1.2 ohara 101: {
1.13 ohara 102: if (hook_after_send_cmo != NULL) {
103: return hook_after_send_cmo(oxfp, c);
104: }
105: return c;
1.2 ohara 106: }
1.1 ohara 107:
1.7 ohara 108: /* Handling an error. */
1.1 ohara 109: static int current_received_serial = 0;
110:
1.7 ohara 111: /* If an error object be needed, then a server call the following function. */
1.1 ohara 112: cmo_error2* make_error_object(int err_code, cmo *ob)
113: {
114: cmo_list* li = new_cmo_list();
1.13 ohara 115: list_append(li, (cmo *)new_cmo_int32(current_received_serial));
116: list_append(li, (cmo *)new_cmo_int32(err_code));
117: list_append(li, ob);
1.1 ohara 118: return new_cmo_error2((cmo *)li);
119: }
120:
1.7 ohara 121: /* getting a next serial number. */
1.13 ohara 122: int next_serial(OXFILE *oxfp)
1.1 ohara 123: {
1.13 ohara 124: return oxfp->serial_number++;
1.1 ohara 125: }
126:
1.7 ohara 127: /* sending an object of int32 type. (not equal to cmo_int32 type) */
1.13 ohara 128: int send_int32(OXFILE *oxfp, int int32)
1.1 ohara 129: {
1.13 ohara 130: return oxfp->send_int32(oxfp, int32);
1.1 ohara 131: }
132:
1.13 ohara 133: /* receiving an object of int32 type. (not equal to cmo_int32 type) */
134: int receive_int32(OXFILE *oxfp)
1.1 ohara 135: {
1.13 ohara 136: return oxfp->receive_int32(oxfp);
1.1 ohara 137: }
138:
1.32 ohara 139: /* sending an object of int32 type. (not equal to cmo_int32 type) */
140: int send_double(OXFILE *oxfp, double d)
141: {
142: return oxfp->send_double(oxfp, d);
143: }
144:
145: /* receiving an object of int32 type. (not equal to cmo_int32 type) */
146: double receive_double(OXFILE *oxfp)
147: {
148: return oxfp->receive_double(oxfp);
149: }
150:
1.13 ohara 151: /* receiving an (OX_tag, serial number) */
152: int receive_ox_tag(OXFILE *oxfp)
1.1 ohara 153: {
1.13 ohara 154: int tag = receive_int32(oxfp);
1.16 ohara 155: oxfp->received_serial_number = receive_int32(oxfp);
1.13 ohara 156: return tag;
1.1 ohara 157: }
158:
1.13 ohara 159: /* sending an (OX_tag, serial number) */
160: int send_ox_tag(OXFILE *oxfp, int tag)
1.3 ohara 161: {
1.13 ohara 162: send_int32(oxfp, tag);
163: return send_int32(oxfp, next_serial(oxfp));
1.1 ohara 164: }
165:
1.7 ohara 166: /* functions named receive_cmo_*. */
1.13 ohara 167: static cmo_null* receive_cmo_null(OXFILE *oxfp)
1.1 ohara 168: {
169: return new_cmo_null();
170: }
171:
1.13 ohara 172: static cmo_int32* receive_cmo_int32(OXFILE *oxfp)
1.1 ohara 173: {
1.13 ohara 174: int i = receive_int32(oxfp);
1.1 ohara 175: return new_cmo_int32(i);
176: }
177:
1.13 ohara 178: static cmo_string* receive_cmo_string(OXFILE *oxfp)
1.1 ohara 179: {
1.13 ohara 180: int len = receive_int32(oxfp);
1.25 ohara 181: char* s = MALLOC(len+1);
1.1 ohara 182: memset(s, '\0', len+1);
183: if (len > 0) {
1.13 ohara 184: oxf_read(s, 1, len, oxfp);
1.1 ohara 185: }
186: return new_cmo_string(s);
187: }
188:
1.13 ohara 189: static cmo_mathcap* receive_cmo_mathcap(OXFILE *oxfp)
1.1 ohara 190: {
1.13 ohara 191: cmo* ob = receive_cmo(oxfp);
1.1 ohara 192: return new_cmo_mathcap(ob);
193: }
194:
1.13 ohara 195: static cmo_list* receive_cmo_list(OXFILE *oxfp)
1.1 ohara 196: {
197: cmo* ob;
198: cmo_list* c = new_cmo_list();
1.13 ohara 199: int len = receive_int32(oxfp);
1.1 ohara 200:
201: while (len>0) {
1.13 ohara 202: ob = receive_cmo(oxfp);
203: list_append(c, ob);
1.1 ohara 204: len--;
205: }
206: return c;
207: }
208:
1.13 ohara 209: static cmo_monomial32* receive_cmo_monomial32(OXFILE *oxfp)
1.1 ohara 210: {
211: int i;
1.13 ohara 212: int len = receive_int32(oxfp);
1.1 ohara 213: cmo_monomial32* c = new_cmo_monomial32(len);
214:
215: for(i=0; i<len; i++) {
1.13 ohara 216: c->exps[i] = receive_int32(oxfp);
1.1 ohara 217: }
1.13 ohara 218: c->coef = receive_cmo(oxfp);
1.1 ohara 219: return c;
220: }
221:
1.13 ohara 222: static cmo_zz* receive_cmo_zz(OXFILE *oxfp)
1.1 ohara 223: {
224: cmo_zz* c = new_cmo_zz();
1.13 ohara 225: receive_mpz(oxfp, c->mpz);
1.1 ohara 226: return c;
227: }
228:
1.33 ohara 229: static cmo_qq* receive_cmo_qq(OXFILE *oxfp)
230: {
1.34 ohara 231: mpz_t num, den;
232: mpz_init(num);
233: mpz_init(den);
234: receive_mpz(oxfp, num);
235: receive_mpz(oxfp, den);
236: return new_cmo_qq_set_mpz(num, den);
1.33 ohara 237: }
238:
1.38 noro 239: static cmo_bf* receive_cmo_bf(OXFILE *oxfp)
240: {
241: mpfr_t num;
242: mpfr_init(num);
243: receive_mpfr(oxfp, num);
244: return new_cmo_bf_set_mpfr(num);
245: }
246:
1.44 ! noro 247: static cmo_complex* receive_cmo_complex(OXFILE *oxfp)
! 248: {
! 249: cmo *re, *im;
! 250:
! 251: re = receive_cmo(oxfp);
! 252: im = receive_cmo(oxfp);
! 253: return new_cmo_complex_set_re_im(re,im);
! 254: }
! 255:
! 256:
1.13 ohara 257: static cmo_zero* receive_cmo_zero(OXFILE *oxfp)
1.1 ohara 258: {
259: return new_cmo_zero();
260: }
261:
1.13 ohara 262: static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp)
1.1 ohara 263: {
264: return new_cmo_dms_generic();
265: }
266:
1.13 ohara 267: static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp)
1.1 ohara 268: {
1.13 ohara 269: cmo* ob = receive_cmo(oxfp);
270: /* We need to check semantics but yet ... */
1.1 ohara 271: return new_cmo_ring_by_name(ob);
272: }
273:
1.26 ohara 274: static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp)
275: {
1.27 ohara 276: cmo_list* ringdef = (cmo_list *)receive_cmo(oxfp);
277: cmo* coef = receive_cmo(oxfp);
1.26 ohara 278: return new_cmo_recursive_polynomial(ringdef, coef);
279: }
280:
1.13 ohara 281: static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp)
1.1 ohara 282: {
283: cmo* ob;
284: cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();
1.13 ohara 285: int len = receive_int32(oxfp);
286: c->ringdef = receive_cmo(oxfp);
1.1 ohara 287:
288: while (len>0) {
1.13 ohara 289: ob = receive_cmo(oxfp);
290: list_append((cmo_list *)c, ob);
1.1 ohara 291: len--;
292: }
293: return c;
294: }
295:
1.26 ohara 296: static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp)
297: {
298: cmo* coef;
299: cmo_polynomial_in_one_variable* c;
300: int len = receive_int32(oxfp);
301: int var = receive_int32(oxfp);
302: int exp;
303: c = new_cmo_polynomial_in_one_variable(var);
304: while (len>0) {
305: exp = receive_int32(oxfp);
306: coef = receive_cmo(oxfp);
1.27 ohara 307: list_append_monomial((cmo_list *)c, coef, exp);
1.26 ohara 308: len--;
309: }
310: return c;
311: }
312:
1.32 ohara 313: static cmo_double* receive_cmo_double(OXFILE *oxfp)
314: {
315: double d = receive_double(oxfp);
316: return new_cmo_double(d);
317: }
318:
1.29 ohara 319: static cmo_indeterminate* receive_cmo_indeterminate(OXFILE *oxfp)
320: {
321: cmo* ob = receive_cmo(oxfp);
322: return new_cmo_indeterminate(ob);
323: }
324:
1.28 ohara 325: static cmo_tree* receive_cmo_tree(OXFILE *oxfp)
326: {
327: cmo_string* name = (cmo_string *)receive_cmo(oxfp);
328: cmo_list* attrib = (cmo_list *)receive_cmo(oxfp);
329: cmo_list* leaves = (cmo_list *)receive_cmo(oxfp);
330: return new_cmo_tree(name, attrib, leaves);
331: }
332:
333: static cmo_lambda* receive_cmo_lambda(OXFILE *oxfp)
334: {
335: cmo_list* args = (cmo_list *)receive_cmo(oxfp);
336: cmo_tree* body = (cmo_tree *)receive_cmo(oxfp);
337: return new_cmo_lambda(args, body);
338: }
339:
1.13 ohara 340: static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
1.1 ohara 341: {
1.13 ohara 342: cmo* ob = receive_cmo(oxfp);
1.1 ohara 343: return new_cmo_error2(ob);
344: }
345:
1.17 ohara 346: /* receive_cmo() is called after receive_ox_tag(). */
1.13 ohara 347: cmo* receive_cmo(OXFILE *oxfp)
1.1 ohara 348: {
1.24 ohara 349: int tag = receive_int32(oxfp);
350: return receive_cmo_tag(oxfp, tag);
351: }
352:
353: cmo *receive_cmo_tag(OXFILE *oxfp, int tag)
354: {
1.1 ohara 355: cmo* m;
356: switch(tag) {
357: case CMO_NULL:
1.13 ohara 358: m = receive_cmo_null(oxfp);
1.1 ohara 359: break;
360: case CMO_INT32:
1.13 ohara 361: m = (cmo *)receive_cmo_int32(oxfp);
1.1 ohara 362: break;
363: case CMO_STRING:
1.13 ohara 364: m = (cmo *)receive_cmo_string(oxfp);
1.1 ohara 365: break;
366: case CMO_MATHCAP:
1.13 ohara 367: m = (cmo *)receive_cmo_mathcap(oxfp);
1.1 ohara 368: break;
369: case CMO_LIST:
1.13 ohara 370: m = (cmo *)receive_cmo_list(oxfp);
1.1 ohara 371: break;
372: case CMO_MONOMIAL32:
1.13 ohara 373: m = (cmo *)receive_cmo_monomial32(oxfp);
1.1 ohara 374: break;
375: case CMO_ZZ:
1.13 ohara 376: m = (cmo *)receive_cmo_zz(oxfp);
1.1 ohara 377: break;
1.33 ohara 378: case CMO_QQ:
379: m = (cmo *)receive_cmo_qq(oxfp);
380: break;
1.38 noro 381: case CMO_BIGFLOAT:
382: m = (cmo *)receive_cmo_bf(oxfp);
383: break;
1.44 ! noro 384: case CMO_COMPLEX:
! 385: m = (cmo *)receive_cmo_complex(oxfp);
! 386: break;
1.1 ohara 387: case CMO_ZERO:
1.13 ohara 388: m = (cmo *)receive_cmo_zero(oxfp);
1.1 ohara 389: break;
390: case CMO_DMS_GENERIC:
1.13 ohara 391: m = (cmo *)receive_cmo_dms_generic(oxfp);
1.1 ohara 392: break;
393: case CMO_RING_BY_NAME:
1.13 ohara 394: m = (cmo *)receive_cmo_ring_by_name(oxfp);
1.1 ohara 395: break;
396: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 397: m = (cmo *)receive_cmo_distributed_polynomial(oxfp);
1.1 ohara 398: break;
1.26 ohara 399: case CMO_RECURSIVE_POLYNOMIAL:
400: m = (cmo *)receive_cmo_recursive_polynomial(oxfp);
401: break;
402: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
403: m = (cmo *)receive_cmo_polynomial_in_one_variable(oxfp);
1.29 ohara 404: break;
1.32 ohara 405: case CMO_64BIT_MACHINE_DOUBLE:
406: case CMO_IEEE_DOUBLE_FLOAT:
407: m = (cmo *)receive_cmo_double(oxfp);
408: break;
1.29 ohara 409: case CMO_INDETERMINATE:
410: m = (cmo *)receive_cmo_indeterminate(oxfp);
1.28 ohara 411: break;
412: case CMO_TREE:
413: m = (cmo *)receive_cmo_tree(oxfp);
414: break;
415: case CMO_LAMBDA:
416: m = (cmo *)receive_cmo_lambda(oxfp);
417: break;
1.1 ohara 418: case CMO_ERROR2:
1.13 ohara 419: m = (cmo *)receive_cmo_error2(oxfp);
1.1 ohara 420: break;
421: case CMO_DATUM:
422: default:
1.13 ohara 423: m = NULL;
1.20 ohara 424: ox_printf("the CMO (%d) is not implemented.\n", tag);
1.1 ohara 425: }
426: return m;
427: }
428:
1.13 ohara 429: static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 430: {
431: int i;
1.36 iwane 432: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
1.13 ohara 433: int size = receive_int32(oxfp);
1.1 ohara 434: int len = abs(size);
1.36 iwane 435: int *ptr;
436: if (n == 1) {
437: resize_mpz(mpz, size);
1.37 iwane 438: } else if (size >= 0) {
439: resize_mpz(mpz, (size+1) / n);
1.36 iwane 440: } else {
1.37 iwane 441: resize_mpz(mpz, (size-1) / n);
1.36 iwane 442: }
443:
444: ptr = (int *)mpz->_mp_d;
445: for(i=0; i<len; i++) {
446: ptr[i] = receive_int32(oxfp);
447: }
1.1 ohara 448: }
449:
1.13 ohara 450: void send_ox_command(OXFILE *oxfp, int sm_command)
1.1 ohara 451: {
1.13 ohara 452: send_ox_tag(oxfp, OX_COMMAND);
453: send_int32(oxfp, sm_command);
454: oxf_flush(oxfp);
1.1 ohara 455: }
456:
1.13 ohara 457: void ox_close(OXFILE *sv)
1.1 ohara 458: {
1.13 ohara 459: send_ox_command(oxf_control(sv), SM_control_kill);
1.7 ohara 460: sleep(2);
1.13 ohara 461: /* We wait thar an OpenXM server terminates. */
1.20 ohara 462: ox_printf("I have closed the connection to an Open XM server.\n");
1.1 ohara 463: }
464:
1.13 ohara 465: void ox_shutdown(OXFILE *sv)
1.3 ohara 466: {
1.13 ohara 467: /* We need to use SM_shutdown but yet ... */
468: ox_close(sv);
1.3 ohara 469: }
470:
1.13 ohara 471: void ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[])
1.3 ohara 472: {
1.13 ohara 473: int i = argc;
474: while(i-- > 0) {
475: send_ox_cmo(sv, argv[i]);
476: }
477: send_ox_cmo(sv, (cmo *)new_cmo_int32(argc));
478: send_ox_cmo(sv, (cmo *)new_cmo_string(function));
479: send_ox_command(sv, SM_executeFunction);
1.3 ohara 480: }
481:
1.13 ohara 482: void ox_execute_string(OXFILE *sv, char* s)
1.3 ohara 483: {
1.13 ohara 484: send_ox_cmo(sv, (cmo *)new_cmo_string(s));
485: send_ox_command(sv, SM_executeStringByLocalParser);
1.3 ohara 486: }
487:
1.13 ohara 488: void ox_push_cmd(OXFILE *sv, int sm_code)
1.1 ohara 489: {
1.13 ohara 490: send_ox_command(sv, sm_code);
1.1 ohara 491: }
492:
1.13 ohara 493: cmo_mathcap* ox_mathcap(OXFILE *sv)
1.1 ohara 494: {
1.13 ohara 495: send_ox_command(sv, SM_mathcap);
496: send_ox_command(sv, SM_popCMO);
497: receive_ox_tag(sv); /* OX_DATA */
498: return (cmo_mathcap *)receive_cmo(sv);
1.1 ohara 499: }
500:
1.13 ohara 501: char* ox_popString(OXFILE *sv)
1.1 ohara 502: {
503: cmo_string* m = NULL;
504:
1.13 ohara 505: send_ox_command(sv, SM_popString);
506: receive_ox_tag(sv); /* OX_DATA */
507: m = (cmo_string *)receive_cmo(sv);
1.1 ohara 508: return m->s;
509: }
510:
1.13 ohara 511: void ox_pops(OXFILE *sv, int num)
1.3 ohara 512: {
1.13 ohara 513: send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
514: send_ox_command(sv, SM_pops);
1.3 ohara 515: }
516:
1.13 ohara 517: cmo* ox_pop_cmo(OXFILE *sv)
1.3 ohara 518: {
1.13 ohara 519: send_ox_command(sv, SM_popCMO);
520: receive_ox_tag(sv); /* OX_DATA */
521: return receive_cmo(sv);
1.3 ohara 522: }
523:
1.13 ohara 524: void ox_push_cmo(OXFILE *sv, cmo *c)
1.3 ohara 525: {
1.13 ohara 526: send_ox_cmo(sv, c);
1.3 ohara 527: }
528:
1.7 ohara 529: /* a dummy function for flushing a connection. */
1.13 ohara 530: int ox_flush(OXFILE *sv)
1.5 ohara 531: {
1.13 ohara 532: return 1;
1.5 ohara 533: }
534:
1.13 ohara 535: void ox_reset(OXFILE *sv)
1.1 ohara 536: {
1.13 ohara 537: send_ox_command(oxf_control(sv), SM_control_reset_connection);
1.31 iwane 538: while(receive_ox_tag(sv) != OX_SYNC_BALL) {
539: receive_cmo(sv); /* skipping a message. */
1.1 ohara 540: }
541:
1.13 ohara 542: send_ox_tag(sv, OX_SYNC_BALL);
1.20 ohara 543: ox_printf("I have reset an Open XM server.\n");
1.1 ohara 544: }
545:
1.13 ohara 546: void send_ox(OXFILE *oxfp, ox *m)
1.1 ohara 547: {
548: switch(m->tag) {
1.13 ohara 549: case OX_DATA:
550: send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
1.1 ohara 551: break;
1.13 ohara 552: case OX_COMMAND:
553: send_ox_command(oxfp, ((ox_command *)m)->command);
1.1 ohara 554: break;
555: default:
556: /* CMO?? */
1.13 ohara 557: send_ox_cmo(oxfp, (cmo *)m);
1.1 ohara 558: }
559: }
560:
1.13 ohara 561: void send_ox_cmo(OXFILE *oxfp, cmo* m)
1.1 ohara 562: {
1.13 ohara 563: send_ox_tag(oxfp, OX_DATA);
564: send_cmo(oxfp, m);
565: oxf_flush(oxfp);
1.1 ohara 566: }
567:
1.8 ohara 568: /* send_cmo_* functions */
1.13 ohara 569: static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
1.1 ohara 570: {
571: return 0;
572: }
573:
1.13 ohara 574: static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
1.1 ohara 575: {
1.13 ohara 576: return send_int32(oxfp, m->i);
1.1 ohara 577: }
578:
1.13 ohara 579: static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
1.1 ohara 580: {
581: int len = (m->s != NULL)? strlen(m->s): 0;
1.13 ohara 582: send_int32(oxfp, len);
1.1 ohara 583: if (len > 0) {
1.13 ohara 584: oxf_write(m->s, 1, len, oxfp);
1.1 ohara 585: }
586: return 0;
587: }
588:
1.13 ohara 589: static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
1.1 ohara 590: {
1.13 ohara 591: send_cmo(oxfp, c->ob);
1.1 ohara 592: return 0;
593: }
594:
1.13 ohara 595: static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
1.1 ohara 596: {
1.13 ohara 597: cell* el = list_first(c);
598: int len = list_length(c);
599: send_int32(oxfp, len);
600:
601: while(!list_endof(c, el)) {
602: send_cmo(oxfp, el->cmo);
603: el = list_next(el);
1.1 ohara 604: }
605: return 0;
606: }
607:
1.13 ohara 608: static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
1.1 ohara 609: {
1.13 ohara 610: cell* el = list_first((cmo_list *)c);
611: int len = list_length((cmo_list *)c);
612: send_int32(oxfp, len);
613: send_cmo(oxfp, c->ringdef);
614: while(!list_endof((cmo_list *)c, el)) {
615: send_cmo(oxfp, el->cmo);
616: el = list_next(el);
1.1 ohara 617: }
618: return 0;
619: }
620:
1.26 ohara 621: static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c)
622: {
1.27 ohara 623: cell* el = list_first((cmo_list *)c);
624: int len = list_length((cmo_list *)c);
1.26 ohara 625: send_int32(oxfp, len);
626: send_int32(oxfp, c->var);
627:
1.27 ohara 628: while(!list_endof((cmo_list *)c, el)) {
629: send_int32(oxfp, el->exp);
1.26 ohara 630: send_cmo(oxfp, el->cmo);
631: el = list_next(el);
632: }
633: return 0;
634: }
635:
1.32 ohara 636: static int send_cmo_double(OXFILE *oxfp, cmo_double* c)
637: {
638: return send_double(oxfp, c->d);
639: }
640:
1.13 ohara 641: static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
1.1 ohara 642: {
643: int i;
644: int len = c->length;
1.13 ohara 645: send_int32(oxfp, len);
1.1 ohara 646: for(i=0; i<len; i++) {
1.13 ohara 647: send_int32(oxfp, c->exps[i]);
1.1 ohara 648: }
1.13 ohara 649: send_cmo(oxfp, c->coef);
1.1 ohara 650: return 0;
651: }
652:
1.13 ohara 653: static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
1.1 ohara 654: {
1.13 ohara 655: send_mpz(oxfp, c->mpz);
1.1 ohara 656: return 0;
657: }
658:
1.33 ohara 659: static int send_cmo_qq(OXFILE *oxfp, cmo_qq* c)
660: {
1.34 ohara 661: send_mpz(oxfp, mpq_numref(c->mpq));
662: send_mpz(oxfp, mpq_denref(c->mpq));
1.33 ohara 663: return 0;
664: }
665:
1.38 noro 666: static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c)
667: {
668: send_mpfr(oxfp, c->mpfr);
669: return 0;
670: }
671:
1.44 ! noro 672: static int send_cmo_complex(OXFILE *oxfp, cmo_complex* c)
! 673: {
! 674: send_cmo(oxfp, c->re);
! 675: send_cmo(oxfp, c->im);
! 676: return 0;
! 677: }
! 678:
1.26 ohara 679: static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c)
680: {
1.27 ohara 681: send_cmo(oxfp, (cmo *)c->ringdef);
1.26 ohara 682: send_cmo(oxfp, c->coef);
683: return 0;
684: }
685:
1.28 ohara 686: static int send_cmo_tree(OXFILE *oxfp, cmo_tree *c)
687: {
688: send_cmo(oxfp, (cmo *)c->name);
689: send_cmo(oxfp, (cmo *)c->attributes);
690: send_cmo(oxfp, (cmo *)c->leaves);
691: return 0;
692: }
693:
694: static int send_cmo_lambda(OXFILE *oxfp, cmo_lambda *c)
695: {
696: send_cmo(oxfp, (cmo *)c->args);
697: send_cmo(oxfp, (cmo *)c->body);
698: return 0;
699: }
700:
1.13 ohara 701: static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c)
1.1 ohara 702: {
1.13 ohara 703: send_cmo(oxfp, c->ob);
1.1 ohara 704: return 0;
705: }
706:
1.8 ohara 707: /* sending a CMO. (Remarks: OX_tag is already sent.) */
1.13 ohara 708: void send_cmo(OXFILE *oxfp, cmo* c)
1.1 ohara 709: {
710: int tag = c->tag;
711:
1.13 ohara 712: c = call_hook_before_send_cmo(oxfp, c);
1.2 ohara 713:
1.13 ohara 714: send_int32(oxfp, tag);
1.1 ohara 715: switch(tag) {
716: case CMO_NULL:
717: case CMO_ZERO:
718: case CMO_DMS_GENERIC:
1.13 ohara 719: send_cmo_null(oxfp, c); /* empty function. */
1.1 ohara 720: break;
721: case CMO_INT32:
1.13 ohara 722: send_cmo_int32(oxfp, (cmo_int32 *)c);
1.1 ohara 723: break;
724: case CMO_STRING:
1.13 ohara 725: send_cmo_string(oxfp, (cmo_string *)c);
1.1 ohara 726: break;
727: case CMO_MATHCAP:
728: case CMO_ERROR2:
729: case CMO_RING_BY_NAME:
730: case CMO_INDETERMINATE:
1.13 ohara 731: send_cmo_mathcap(oxfp, (cmo_mathcap *)c);
1.1 ohara 732: break;
733: case CMO_LIST:
1.13 ohara 734: send_cmo_list(oxfp, (cmo_list *)c);
1.1 ohara 735: break;
736: case CMO_MONOMIAL32:
1.13 ohara 737: send_cmo_monomial32(oxfp, (cmo_monomial32 *)c);
1.1 ohara 738: break;
739: case CMO_ZZ:
1.13 ohara 740: send_cmo_zz(oxfp, (cmo_zz *)c);
1.33 ohara 741: break;
742: case CMO_QQ:
743: send_cmo_qq(oxfp, (cmo_qq *)c);
1.1 ohara 744: break;
1.38 noro 745: case CMO_BIGFLOAT:
746: send_cmo_bf(oxfp, (cmo_bf *)c);
747: break;
1.44 ! noro 748: case CMO_COMPLEX:
! 749: send_cmo_complex(oxfp, (cmo_complex *)c);
! 750: break;
1.1 ohara 751: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 752: send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c);
1.26 ohara 753: break;
754: case CMO_RECURSIVE_POLYNOMIAL:
755: send_cmo_recursive_polynomial(oxfp, (cmo_recursive_polynomial *)c);
756: break;
757: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
758: send_cmo_polynomial_in_one_variable(oxfp, (cmo_polynomial_in_one_variable *)c);
1.28 ohara 759: break;
1.32 ohara 760: case CMO_64BIT_MACHINE_DOUBLE:
761: case CMO_IEEE_DOUBLE_FLOAT:
762: send_cmo_double(oxfp, (cmo_double *)c);
763: break;
1.28 ohara 764: case CMO_TREE:
765: send_cmo_tree(oxfp, (cmo_tree *)c);
766: break;
767: case CMO_LAMBDA:
768: send_cmo_lambda(oxfp, (cmo_lambda *)c);
1.1 ohara 769: break;
770: default:
1.13 ohara 771: call_hook_after_send_cmo(oxfp, c);
1.1 ohara 772: }
773: }
774:
1.13 ohara 775: static int send_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 776: {
777: int i;
1.35 iwane 778: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
779: int len = abs(mpz->_mp_size) * n;
780: int *ptr = (int *)mpz->_mp_d;
1.37 iwane 781: int size;
782: if (len > 0 && ptr[len-1] == 0) {
783: len--;
784: }
785: size = mpz->_mp_size < 0 ? -len : len;
786: send_int32(oxfp, size);
1.1 ohara 787: for(i=0; i<len; i++) {
1.35 iwane 788: send_int32(oxfp, ptr[i]);
1.1 ohara 789: }
790: return 0;
791: }
792:
1.41 noro 793: int send_int64(OXFILE *oxfp,UL64 a)
1.38 noro 794: {
1.41 noro 795: return oxfp->send_double(oxfp,((double *)&a)[0]);
1.38 noro 796: }
797:
798: UL64 receive_int64(OXFILE *oxfp)
799: {
1.41 noro 800: double d = receive_double(oxfp);
801: return ((UL64 *)&d)[0];
1.38 noro 802: }
803:
804: static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
805: {
806: int sgn,prec,len,i;
1.42 noro 807: unsigned int hi,lo;
808: unsigned long *ptr;
1.38 noro 809: L64 exp;
810:
811: sgn = receive_int32(oxfp);
812: prec = receive_int32(oxfp);
1.43 noro 813: exp = receive_int64(oxfp);
1.38 noro 814: /* len = length as an int array (int = 4bytes) */
815: len = receive_int32(oxfp);
816:
817: mpfr_init2(mpfr,prec);
818: MPFR_SIGN(mpfr) = sgn;
819: ptr = mpfr->_mpfr_d;
820: mpfr->_mpfr_exp = exp;
821: #if SIZEOF_LONG==4
822: for ( i = 0; i < len; i++ )
823: ptr[i] = receive_int32(oxfp);
824: #else
1.42 noro 825: if ( len%2 ) {
826: hi = receive_int32(oxfp);
827: ptr[0] = (((UL64)hi)<<32);
828: i = 1;
829: } else
830: i = 0;
831: len = (len+1)/2;
832: for ( ; i < len; i ++ ) {
833: lo = (unsigned int)receive_int32(oxfp);
834: hi = (unsigned int)receive_int32(oxfp);
835: ptr[i] = (((UL64)hi)<<32)|((UL64)lo);
836: }
1.38 noro 837: #endif
838: }
839:
840: static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
841: {
842:
1.42 noro 843: int i,len,t;
844: unsigned long *ptr;
1.43 noro 845: UL64 uexp;
1.38 noro 846:
847: send_int32(oxfp, MPFR_SIGN(mpfr));
848: send_int32(oxfp, MPFR_PREC(mpfr));
849: send_int64(oxfp, MPFR_EXP(mpfr));
850: len = MPFR_LIMB_SIZE(mpfr);
851: ptr = MPFR_MANT(mpfr);
852: #if SIZEOF_LONG==4
853: send_int32(oxfp, len);
854: for ( i = 0; i < len; i++ )
855: send_int32(oxfp,ptr[i]);
856: #else /* SIZEOF_LONG==8 */
1.42 noro 857: t = (MPFR_PREC(mpfr)+31)/32;
858: send_int32(oxfp, t);
859: if ( t%2 ) {
860: send_int32(oxfp,(unsigned int)(ptr[0]>>32));
861: i = 1;
862: } else
863: i = 0;
864: t = (t+1)/2;
865: for ( ; i < len; i++ ) {
866: send_int32(oxfp,(unsigned int)(ptr[i]&0xffffffff));
867: send_int32(oxfp,(unsigned int)(ptr[i]>>32));
868: }
1.38 noro 869: #endif
870: return 0;
871: }
872:
1.1 ohara 873: ox_data* new_ox_data(cmo* c)
874: {
1.25 ohara 875: ox_data* m = MALLOC(sizeof(ox_data));
1.1 ohara 876: m->tag = OX_DATA;
877: m->cmo = c;
878: return m;
879: }
880:
881: ox_command* new_ox_command(int sm_code)
882: {
1.25 ohara 883: ox_command* m = MALLOC(sizeof(ox_command));
1.1 ohara 884: m->tag = OX_COMMAND;
885: m->command = sm_code;
886: return m;
887: }
888:
889: ox_sync_ball* new_ox_sync_ball()
890: {
1.25 ohara 891: ox_sync_ball *m = MALLOC(sizeof(ox_sync_ball));
1.1 ohara 892: m->tag = OX_SYNC_BALL;
893: return m;
1.19 ohara 894: }
895:
896: int ox_stderr_init(FILE *fp)
897: {
1.21 ohara 898: ox_stderr = fp;
899: if (ox_stderr != NULL) {
900: setbuf(ox_stderr, NULL);
901: }
1.27 ohara 902: return 0;
1.20 ohara 903: }
904:
905: int ox_printf(char *format, ...)
906: {
1.21 ohara 907: if (ox_stderr != NULL) {
908: va_list ap;
909: va_start(ap, format);
910: vfprintf(ox_stderr, format, ap);
911: }
1.27 ohara 912: return 0;
1.1 ohara 913: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>