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