Annotation of OpenXM/src/ox_toolkit/ox.c, Revision 1.42
1.1 ohara 1: /* -*- mode: C; coding: euc-japan -*- */
1.42 ! noro 2: /* $OpenXM: OpenXM/src/ox_toolkit/ox.c,v 1.41 2015/08/05 00:59:05 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.13 ohara 247: static cmo_zero* receive_cmo_zero(OXFILE *oxfp)
1.1 ohara 248: {
249: return new_cmo_zero();
250: }
251:
1.13 ohara 252: static cmo_dms_generic* receive_cmo_dms_generic(OXFILE *oxfp)
1.1 ohara 253: {
254: return new_cmo_dms_generic();
255: }
256:
1.13 ohara 257: static cmo_ring_by_name* receive_cmo_ring_by_name(OXFILE *oxfp)
1.1 ohara 258: {
1.13 ohara 259: cmo* ob = receive_cmo(oxfp);
260: /* We need to check semantics but yet ... */
1.1 ohara 261: return new_cmo_ring_by_name(ob);
262: }
263:
1.26 ohara 264: static cmo_recursive_polynomial* receive_cmo_recursive_polynomial(OXFILE *oxfp)
265: {
1.27 ohara 266: cmo_list* ringdef = (cmo_list *)receive_cmo(oxfp);
267: cmo* coef = receive_cmo(oxfp);
1.26 ohara 268: return new_cmo_recursive_polynomial(ringdef, coef);
269: }
270:
1.13 ohara 271: static cmo_distributed_polynomial* receive_cmo_distributed_polynomial(OXFILE *oxfp)
1.1 ohara 272: {
273: cmo* ob;
274: cmo_distributed_polynomial* c = new_cmo_distributed_polynomial();
1.13 ohara 275: int len = receive_int32(oxfp);
276: c->ringdef = receive_cmo(oxfp);
1.1 ohara 277:
278: while (len>0) {
1.13 ohara 279: ob = receive_cmo(oxfp);
280: list_append((cmo_list *)c, ob);
1.1 ohara 281: len--;
282: }
283: return c;
284: }
285:
1.26 ohara 286: static cmo_polynomial_in_one_variable* receive_cmo_polynomial_in_one_variable(OXFILE *oxfp)
287: {
288: cmo* coef;
289: cmo_polynomial_in_one_variable* c;
290: int len = receive_int32(oxfp);
291: int var = receive_int32(oxfp);
292: int exp;
293: c = new_cmo_polynomial_in_one_variable(var);
294: while (len>0) {
295: exp = receive_int32(oxfp);
296: coef = receive_cmo(oxfp);
1.27 ohara 297: list_append_monomial((cmo_list *)c, coef, exp);
1.26 ohara 298: len--;
299: }
300: return c;
301: }
302:
1.32 ohara 303: static cmo_double* receive_cmo_double(OXFILE *oxfp)
304: {
305: double d = receive_double(oxfp);
306: return new_cmo_double(d);
307: }
308:
1.29 ohara 309: static cmo_indeterminate* receive_cmo_indeterminate(OXFILE *oxfp)
310: {
311: cmo* ob = receive_cmo(oxfp);
312: return new_cmo_indeterminate(ob);
313: }
314:
1.28 ohara 315: static cmo_tree* receive_cmo_tree(OXFILE *oxfp)
316: {
317: cmo_string* name = (cmo_string *)receive_cmo(oxfp);
318: cmo_list* attrib = (cmo_list *)receive_cmo(oxfp);
319: cmo_list* leaves = (cmo_list *)receive_cmo(oxfp);
320: return new_cmo_tree(name, attrib, leaves);
321: }
322:
323: static cmo_lambda* receive_cmo_lambda(OXFILE *oxfp)
324: {
325: cmo_list* args = (cmo_list *)receive_cmo(oxfp);
326: cmo_tree* body = (cmo_tree *)receive_cmo(oxfp);
327: return new_cmo_lambda(args, body);
328: }
329:
1.13 ohara 330: static cmo_error2* receive_cmo_error2(OXFILE *oxfp)
1.1 ohara 331: {
1.13 ohara 332: cmo* ob = receive_cmo(oxfp);
1.1 ohara 333: return new_cmo_error2(ob);
334: }
335:
1.17 ohara 336: /* receive_cmo() is called after receive_ox_tag(). */
1.13 ohara 337: cmo* receive_cmo(OXFILE *oxfp)
1.1 ohara 338: {
1.24 ohara 339: int tag = receive_int32(oxfp);
340: return receive_cmo_tag(oxfp, tag);
341: }
342:
343: cmo *receive_cmo_tag(OXFILE *oxfp, int tag)
344: {
1.1 ohara 345: cmo* m;
346: switch(tag) {
347: case CMO_NULL:
1.13 ohara 348: m = receive_cmo_null(oxfp);
1.1 ohara 349: break;
350: case CMO_INT32:
1.13 ohara 351: m = (cmo *)receive_cmo_int32(oxfp);
1.1 ohara 352: break;
353: case CMO_STRING:
1.13 ohara 354: m = (cmo *)receive_cmo_string(oxfp);
1.1 ohara 355: break;
356: case CMO_MATHCAP:
1.13 ohara 357: m = (cmo *)receive_cmo_mathcap(oxfp);
1.1 ohara 358: break;
359: case CMO_LIST:
1.13 ohara 360: m = (cmo *)receive_cmo_list(oxfp);
1.1 ohara 361: break;
362: case CMO_MONOMIAL32:
1.13 ohara 363: m = (cmo *)receive_cmo_monomial32(oxfp);
1.1 ohara 364: break;
365: case CMO_ZZ:
1.13 ohara 366: m = (cmo *)receive_cmo_zz(oxfp);
1.1 ohara 367: break;
1.33 ohara 368: case CMO_QQ:
369: m = (cmo *)receive_cmo_qq(oxfp);
370: break;
1.38 noro 371: case CMO_BIGFLOAT:
372: m = (cmo *)receive_cmo_bf(oxfp);
373: break;
1.1 ohara 374: case CMO_ZERO:
1.13 ohara 375: m = (cmo *)receive_cmo_zero(oxfp);
1.1 ohara 376: break;
377: case CMO_DMS_GENERIC:
1.13 ohara 378: m = (cmo *)receive_cmo_dms_generic(oxfp);
1.1 ohara 379: break;
380: case CMO_RING_BY_NAME:
1.13 ohara 381: m = (cmo *)receive_cmo_ring_by_name(oxfp);
1.1 ohara 382: break;
383: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 384: m = (cmo *)receive_cmo_distributed_polynomial(oxfp);
1.1 ohara 385: break;
1.26 ohara 386: case CMO_RECURSIVE_POLYNOMIAL:
387: m = (cmo *)receive_cmo_recursive_polynomial(oxfp);
388: break;
389: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
390: m = (cmo *)receive_cmo_polynomial_in_one_variable(oxfp);
1.29 ohara 391: break;
1.32 ohara 392: case CMO_64BIT_MACHINE_DOUBLE:
393: case CMO_IEEE_DOUBLE_FLOAT:
394: m = (cmo *)receive_cmo_double(oxfp);
395: break;
1.29 ohara 396: case CMO_INDETERMINATE:
397: m = (cmo *)receive_cmo_indeterminate(oxfp);
1.28 ohara 398: break;
399: case CMO_TREE:
400: m = (cmo *)receive_cmo_tree(oxfp);
401: break;
402: case CMO_LAMBDA:
403: m = (cmo *)receive_cmo_lambda(oxfp);
404: break;
1.1 ohara 405: case CMO_ERROR2:
1.13 ohara 406: m = (cmo *)receive_cmo_error2(oxfp);
1.1 ohara 407: break;
408: case CMO_DATUM:
409: default:
1.13 ohara 410: m = NULL;
1.20 ohara 411: ox_printf("the CMO (%d) is not implemented.\n", tag);
1.1 ohara 412: }
413: return m;
414: }
415:
1.13 ohara 416: static void receive_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 417: {
418: int i;
1.36 iwane 419: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
1.13 ohara 420: int size = receive_int32(oxfp);
1.1 ohara 421: int len = abs(size);
1.36 iwane 422: int *ptr;
423: if (n == 1) {
424: resize_mpz(mpz, size);
1.37 iwane 425: } else if (size >= 0) {
426: resize_mpz(mpz, (size+1) / n);
1.36 iwane 427: } else {
1.37 iwane 428: resize_mpz(mpz, (size-1) / n);
1.36 iwane 429: }
430:
431: ptr = (int *)mpz->_mp_d;
432: for(i=0; i<len; i++) {
433: ptr[i] = receive_int32(oxfp);
434: }
1.1 ohara 435: }
436:
1.13 ohara 437: void send_ox_command(OXFILE *oxfp, int sm_command)
1.1 ohara 438: {
1.13 ohara 439: send_ox_tag(oxfp, OX_COMMAND);
440: send_int32(oxfp, sm_command);
441: oxf_flush(oxfp);
1.1 ohara 442: }
443:
1.13 ohara 444: void ox_close(OXFILE *sv)
1.1 ohara 445: {
1.13 ohara 446: send_ox_command(oxf_control(sv), SM_control_kill);
1.7 ohara 447: sleep(2);
1.13 ohara 448: /* We wait thar an OpenXM server terminates. */
1.20 ohara 449: ox_printf("I have closed the connection to an Open XM server.\n");
1.1 ohara 450: }
451:
1.13 ohara 452: void ox_shutdown(OXFILE *sv)
1.3 ohara 453: {
1.13 ohara 454: /* We need to use SM_shutdown but yet ... */
455: ox_close(sv);
1.3 ohara 456: }
457:
1.13 ohara 458: void ox_cmo_rpc(OXFILE *sv, char *function, int argc, cmo *argv[])
1.3 ohara 459: {
1.13 ohara 460: int i = argc;
461: while(i-- > 0) {
462: send_ox_cmo(sv, argv[i]);
463: }
464: send_ox_cmo(sv, (cmo *)new_cmo_int32(argc));
465: send_ox_cmo(sv, (cmo *)new_cmo_string(function));
466: send_ox_command(sv, SM_executeFunction);
1.3 ohara 467: }
468:
1.13 ohara 469: void ox_execute_string(OXFILE *sv, char* s)
1.3 ohara 470: {
1.13 ohara 471: send_ox_cmo(sv, (cmo *)new_cmo_string(s));
472: send_ox_command(sv, SM_executeStringByLocalParser);
1.3 ohara 473: }
474:
1.13 ohara 475: void ox_push_cmd(OXFILE *sv, int sm_code)
1.1 ohara 476: {
1.13 ohara 477: send_ox_command(sv, sm_code);
1.1 ohara 478: }
479:
1.13 ohara 480: cmo_mathcap* ox_mathcap(OXFILE *sv)
1.1 ohara 481: {
1.13 ohara 482: send_ox_command(sv, SM_mathcap);
483: send_ox_command(sv, SM_popCMO);
484: receive_ox_tag(sv); /* OX_DATA */
485: return (cmo_mathcap *)receive_cmo(sv);
1.1 ohara 486: }
487:
1.13 ohara 488: char* ox_popString(OXFILE *sv)
1.1 ohara 489: {
490: cmo_string* m = NULL;
491:
1.13 ohara 492: send_ox_command(sv, SM_popString);
493: receive_ox_tag(sv); /* OX_DATA */
494: m = (cmo_string *)receive_cmo(sv);
1.1 ohara 495: return m->s;
496: }
497:
1.13 ohara 498: void ox_pops(OXFILE *sv, int num)
1.3 ohara 499: {
1.13 ohara 500: send_ox_cmo(sv, (cmo *)new_cmo_int32(num));
501: send_ox_command(sv, SM_pops);
1.3 ohara 502: }
503:
1.13 ohara 504: cmo* ox_pop_cmo(OXFILE *sv)
1.3 ohara 505: {
1.13 ohara 506: send_ox_command(sv, SM_popCMO);
507: receive_ox_tag(sv); /* OX_DATA */
508: return receive_cmo(sv);
1.3 ohara 509: }
510:
1.13 ohara 511: void ox_push_cmo(OXFILE *sv, cmo *c)
1.3 ohara 512: {
1.13 ohara 513: send_ox_cmo(sv, c);
1.3 ohara 514: }
515:
1.7 ohara 516: /* a dummy function for flushing a connection. */
1.13 ohara 517: int ox_flush(OXFILE *sv)
1.5 ohara 518: {
1.13 ohara 519: return 1;
1.5 ohara 520: }
521:
1.13 ohara 522: void ox_reset(OXFILE *sv)
1.1 ohara 523: {
1.13 ohara 524: send_ox_command(oxf_control(sv), SM_control_reset_connection);
1.31 iwane 525: while(receive_ox_tag(sv) != OX_SYNC_BALL) {
526: receive_cmo(sv); /* skipping a message. */
1.1 ohara 527: }
528:
1.13 ohara 529: send_ox_tag(sv, OX_SYNC_BALL);
1.20 ohara 530: ox_printf("I have reset an Open XM server.\n");
1.1 ohara 531: }
532:
1.13 ohara 533: void send_ox(OXFILE *oxfp, ox *m)
1.1 ohara 534: {
535: switch(m->tag) {
1.13 ohara 536: case OX_DATA:
537: send_ox_cmo(oxfp, ((ox_data *)m)->cmo);
1.1 ohara 538: break;
1.13 ohara 539: case OX_COMMAND:
540: send_ox_command(oxfp, ((ox_command *)m)->command);
1.1 ohara 541: break;
542: default:
543: /* CMO?? */
1.13 ohara 544: send_ox_cmo(oxfp, (cmo *)m);
1.1 ohara 545: }
546: }
547:
1.13 ohara 548: void send_ox_cmo(OXFILE *oxfp, cmo* m)
1.1 ohara 549: {
1.13 ohara 550: send_ox_tag(oxfp, OX_DATA);
551: send_cmo(oxfp, m);
552: oxf_flush(oxfp);
1.1 ohara 553: }
554:
1.8 ohara 555: /* send_cmo_* functions */
1.13 ohara 556: static int send_cmo_null(OXFILE *oxfp, cmo_null* c)
1.1 ohara 557: {
558: return 0;
559: }
560:
1.13 ohara 561: static int send_cmo_int32(OXFILE *oxfp, cmo_int32* m)
1.1 ohara 562: {
1.13 ohara 563: return send_int32(oxfp, m->i);
1.1 ohara 564: }
565:
1.13 ohara 566: static int send_cmo_string(OXFILE *oxfp, cmo_string* m)
1.1 ohara 567: {
568: int len = (m->s != NULL)? strlen(m->s): 0;
1.13 ohara 569: send_int32(oxfp, len);
1.1 ohara 570: if (len > 0) {
1.13 ohara 571: oxf_write(m->s, 1, len, oxfp);
1.1 ohara 572: }
573: return 0;
574: }
575:
1.13 ohara 576: static int send_cmo_mathcap(OXFILE *oxfp, cmo_mathcap* c)
1.1 ohara 577: {
1.13 ohara 578: send_cmo(oxfp, c->ob);
1.1 ohara 579: return 0;
580: }
581:
1.13 ohara 582: static int send_cmo_list(OXFILE *oxfp, cmo_list* c)
1.1 ohara 583: {
1.13 ohara 584: cell* el = list_first(c);
585: int len = list_length(c);
586: send_int32(oxfp, len);
587:
588: while(!list_endof(c, el)) {
589: send_cmo(oxfp, el->cmo);
590: el = list_next(el);
1.1 ohara 591: }
592: return 0;
593: }
594:
1.13 ohara 595: static int send_cmo_distributed_polynomial(OXFILE *oxfp, cmo_distributed_polynomial* c)
1.1 ohara 596: {
1.13 ohara 597: cell* el = list_first((cmo_list *)c);
598: int len = list_length((cmo_list *)c);
599: send_int32(oxfp, len);
600: send_cmo(oxfp, c->ringdef);
601: while(!list_endof((cmo_list *)c, el)) {
602: send_cmo(oxfp, el->cmo);
603: el = list_next(el);
1.1 ohara 604: }
605: return 0;
606: }
607:
1.26 ohara 608: static int send_cmo_polynomial_in_one_variable(OXFILE *oxfp, cmo_polynomial_in_one_variable* c)
609: {
1.27 ohara 610: cell* el = list_first((cmo_list *)c);
611: int len = list_length((cmo_list *)c);
1.26 ohara 612: send_int32(oxfp, len);
613: send_int32(oxfp, c->var);
614:
1.27 ohara 615: while(!list_endof((cmo_list *)c, el)) {
616: send_int32(oxfp, el->exp);
1.26 ohara 617: send_cmo(oxfp, el->cmo);
618: el = list_next(el);
619: }
620: return 0;
621: }
622:
1.32 ohara 623: static int send_cmo_double(OXFILE *oxfp, cmo_double* c)
624: {
625: return send_double(oxfp, c->d);
626: }
627:
1.13 ohara 628: static int send_cmo_monomial32(OXFILE *oxfp, cmo_monomial32* c)
1.1 ohara 629: {
630: int i;
631: int len = c->length;
1.13 ohara 632: send_int32(oxfp, len);
1.1 ohara 633: for(i=0; i<len; i++) {
1.13 ohara 634: send_int32(oxfp, c->exps[i]);
1.1 ohara 635: }
1.13 ohara 636: send_cmo(oxfp, c->coef);
1.1 ohara 637: return 0;
638: }
639:
1.13 ohara 640: static int send_cmo_zz(OXFILE *oxfp, cmo_zz* c)
1.1 ohara 641: {
1.13 ohara 642: send_mpz(oxfp, c->mpz);
1.1 ohara 643: return 0;
644: }
645:
1.33 ohara 646: static int send_cmo_qq(OXFILE *oxfp, cmo_qq* c)
647: {
1.34 ohara 648: send_mpz(oxfp, mpq_numref(c->mpq));
649: send_mpz(oxfp, mpq_denref(c->mpq));
1.33 ohara 650: return 0;
651: }
652:
1.38 noro 653: static int send_cmo_bf(OXFILE *oxfp, cmo_bf* c)
654: {
655: send_mpfr(oxfp, c->mpfr);
656: return 0;
657: }
658:
1.26 ohara 659: static int send_cmo_recursive_polynomial(OXFILE *oxfp, cmo_recursive_polynomial* c)
660: {
1.27 ohara 661: send_cmo(oxfp, (cmo *)c->ringdef);
1.26 ohara 662: send_cmo(oxfp, c->coef);
663: return 0;
664: }
665:
1.28 ohara 666: static int send_cmo_tree(OXFILE *oxfp, cmo_tree *c)
667: {
668: send_cmo(oxfp, (cmo *)c->name);
669: send_cmo(oxfp, (cmo *)c->attributes);
670: send_cmo(oxfp, (cmo *)c->leaves);
671: return 0;
672: }
673:
674: static int send_cmo_lambda(OXFILE *oxfp, cmo_lambda *c)
675: {
676: send_cmo(oxfp, (cmo *)c->args);
677: send_cmo(oxfp, (cmo *)c->body);
678: return 0;
679: }
680:
1.13 ohara 681: static int send_cmo_error2(OXFILE *oxfp, cmo_error2* c)
1.1 ohara 682: {
1.13 ohara 683: send_cmo(oxfp, c->ob);
1.1 ohara 684: return 0;
685: }
686:
1.8 ohara 687: /* sending a CMO. (Remarks: OX_tag is already sent.) */
1.13 ohara 688: void send_cmo(OXFILE *oxfp, cmo* c)
1.1 ohara 689: {
690: int tag = c->tag;
691:
1.13 ohara 692: c = call_hook_before_send_cmo(oxfp, c);
1.2 ohara 693:
1.13 ohara 694: send_int32(oxfp, tag);
1.1 ohara 695: switch(tag) {
696: case CMO_NULL:
697: case CMO_ZERO:
698: case CMO_DMS_GENERIC:
1.13 ohara 699: send_cmo_null(oxfp, c); /* empty function. */
1.1 ohara 700: break;
701: case CMO_INT32:
1.13 ohara 702: send_cmo_int32(oxfp, (cmo_int32 *)c);
1.1 ohara 703: break;
704: case CMO_STRING:
1.13 ohara 705: send_cmo_string(oxfp, (cmo_string *)c);
1.1 ohara 706: break;
707: case CMO_MATHCAP:
708: case CMO_ERROR2:
709: case CMO_RING_BY_NAME:
710: case CMO_INDETERMINATE:
1.13 ohara 711: send_cmo_mathcap(oxfp, (cmo_mathcap *)c);
1.1 ohara 712: break;
713: case CMO_LIST:
1.13 ohara 714: send_cmo_list(oxfp, (cmo_list *)c);
1.1 ohara 715: break;
716: case CMO_MONOMIAL32:
1.13 ohara 717: send_cmo_monomial32(oxfp, (cmo_monomial32 *)c);
1.1 ohara 718: break;
719: case CMO_ZZ:
1.13 ohara 720: send_cmo_zz(oxfp, (cmo_zz *)c);
1.33 ohara 721: break;
722: case CMO_QQ:
723: send_cmo_qq(oxfp, (cmo_qq *)c);
1.1 ohara 724: break;
1.38 noro 725: case CMO_BIGFLOAT:
726: send_cmo_bf(oxfp, (cmo_bf *)c);
727: break;
1.1 ohara 728: case CMO_DISTRIBUTED_POLYNOMIAL:
1.13 ohara 729: send_cmo_distributed_polynomial(oxfp, (cmo_distributed_polynomial *)c);
1.26 ohara 730: break;
731: case CMO_RECURSIVE_POLYNOMIAL:
732: send_cmo_recursive_polynomial(oxfp, (cmo_recursive_polynomial *)c);
733: break;
734: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
735: send_cmo_polynomial_in_one_variable(oxfp, (cmo_polynomial_in_one_variable *)c);
1.28 ohara 736: break;
1.32 ohara 737: case CMO_64BIT_MACHINE_DOUBLE:
738: case CMO_IEEE_DOUBLE_FLOAT:
739: send_cmo_double(oxfp, (cmo_double *)c);
740: break;
1.28 ohara 741: case CMO_TREE:
742: send_cmo_tree(oxfp, (cmo_tree *)c);
743: break;
744: case CMO_LAMBDA:
745: send_cmo_lambda(oxfp, (cmo_lambda *)c);
1.1 ohara 746: break;
747: default:
1.13 ohara 748: call_hook_after_send_cmo(oxfp, c);
1.1 ohara 749: }
750: }
751:
1.13 ohara 752: static int send_mpz(OXFILE *oxfp, mpz_ptr mpz)
1.1 ohara 753: {
754: int i;
1.35 iwane 755: int n = sizeof(mpz->_mp_d[0]) / sizeof(int);
756: int len = abs(mpz->_mp_size) * n;
757: int *ptr = (int *)mpz->_mp_d;
1.37 iwane 758: int size;
759: if (len > 0 && ptr[len-1] == 0) {
760: len--;
761: }
762: size = mpz->_mp_size < 0 ? -len : len;
763: send_int32(oxfp, size);
1.1 ohara 764: for(i=0; i<len; i++) {
1.35 iwane 765: send_int32(oxfp, ptr[i]);
1.1 ohara 766: }
767: return 0;
768: }
769:
1.41 noro 770: int send_int64(OXFILE *oxfp,UL64 a)
1.38 noro 771: {
1.41 noro 772: return oxfp->send_double(oxfp,((double *)&a)[0]);
1.38 noro 773: }
774:
775: UL64 receive_int64(OXFILE *oxfp)
776: {
1.41 noro 777: double d = receive_double(oxfp);
778: return ((UL64 *)&d)[0];
1.38 noro 779: }
780:
781: static void receive_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
782: {
783: int sgn,prec,len,i;
1.42 ! noro 784: unsigned int hi,lo;
! 785: unsigned long *ptr;
1.38 noro 786: L64 exp;
787:
788: sgn = receive_int32(oxfp);
789: prec = receive_int32(oxfp);
790: exp = receive_int64(oxfp);
791: /* len = length as an int array (int = 4bytes) */
792: len = receive_int32(oxfp);
793:
794: mpfr_init2(mpfr,prec);
795: MPFR_SIGN(mpfr) = sgn;
796: ptr = mpfr->_mpfr_d;
797: mpfr->_mpfr_exp = exp;
798: #if SIZEOF_LONG==4
799: for ( i = 0; i < len; i++ )
800: ptr[i] = receive_int32(oxfp);
801: #else
1.42 ! noro 802: if ( len%2 ) {
! 803: hi = receive_int32(oxfp);
! 804: ptr[0] = (((UL64)hi)<<32);
! 805: i = 1;
! 806: } else
! 807: i = 0;
! 808: len = (len+1)/2;
! 809: for ( ; i < len; i ++ ) {
! 810: lo = (unsigned int)receive_int32(oxfp);
! 811: hi = (unsigned int)receive_int32(oxfp);
! 812: ptr[i] = (((UL64)hi)<<32)|((UL64)lo);
! 813: }
1.38 noro 814: #endif
815: }
816:
817: static int send_mpfr(OXFILE *oxfp, mpfr_ptr mpfr)
818: {
819:
1.42 ! noro 820: int i,len,t;
! 821: unsigned long *ptr;
1.38 noro 822:
823: send_int32(oxfp, MPFR_SIGN(mpfr));
824: send_int32(oxfp, MPFR_PREC(mpfr));
825: send_int64(oxfp, MPFR_EXP(mpfr));
826: len = MPFR_LIMB_SIZE(mpfr);
827: ptr = MPFR_MANT(mpfr);
828: #if SIZEOF_LONG==4
829: send_int32(oxfp, len);
830: for ( i = 0; i < len; i++ )
831: send_int32(oxfp,ptr[i]);
832: #else /* SIZEOF_LONG==8 */
1.42 ! noro 833: t = (MPFR_PREC(mpfr)+31)/32;
! 834: send_int32(oxfp, t);
! 835: if ( t%2 ) {
! 836: send_int32(oxfp,(unsigned int)(ptr[0]>>32));
! 837: i = 1;
! 838: } else
! 839: i = 0;
! 840: t = (t+1)/2;
! 841: for ( ; i < len; i++ ) {
! 842: send_int32(oxfp,(unsigned int)(ptr[i]&0xffffffff));
! 843: send_int32(oxfp,(unsigned int)(ptr[i]>>32));
! 844: }
1.38 noro 845: #endif
846: return 0;
847: }
848:
1.1 ohara 849: ox_data* new_ox_data(cmo* c)
850: {
1.25 ohara 851: ox_data* m = MALLOC(sizeof(ox_data));
1.1 ohara 852: m->tag = OX_DATA;
853: m->cmo = c;
854: return m;
855: }
856:
857: ox_command* new_ox_command(int sm_code)
858: {
1.25 ohara 859: ox_command* m = MALLOC(sizeof(ox_command));
1.1 ohara 860: m->tag = OX_COMMAND;
861: m->command = sm_code;
862: return m;
863: }
864:
865: ox_sync_ball* new_ox_sync_ball()
866: {
1.25 ohara 867: ox_sync_ball *m = MALLOC(sizeof(ox_sync_ball));
1.1 ohara 868: m->tag = OX_SYNC_BALL;
869: return m;
1.19 ohara 870: }
871:
872: int ox_stderr_init(FILE *fp)
873: {
1.21 ohara 874: ox_stderr = fp;
875: if (ox_stderr != NULL) {
876: setbuf(ox_stderr, NULL);
877: }
1.27 ohara 878: return 0;
1.20 ohara 879: }
880:
881: int ox_printf(char *format, ...)
882: {
1.21 ohara 883: if (ox_stderr != NULL) {
884: va_list ap;
885: va_start(ap, format);
886: vfprintf(ox_stderr, format, ap);
887: }
1.27 ohara 888: return 0;
1.1 ohara 889: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>