[BACK]Return to ox.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_toolkit

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>