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