Annotation of OpenXM/src/kan96xx/plugin/cmo.c, Revision 1.18
1.18 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/plugin/cmo.c,v 1.17 2020/10/04 06:10:36 noro Exp $*/
1.1 maekawa 2: #include <stdio.h>
3: #include <string.h>
1.2 takayama 4: /* #include <netinet/in.h> */
1.1 maekawa 5: #include <stdlib.h>
1.18 ! takayama 6: #include <arpa/inet.h>
1.1 maekawa 7: #include "datatype.h"
8: #include "stackm.h"
9: #include "extern.h"
10: #include "extern2.h"
11: #include "mathcap.h"
12: #include "kclass.h"
13: #include "oxMessageTag.h"
14: #include "oxFunctionId.h"
15:
16: #include "file2.h"
17: #include "cmo.h"
18:
19: #include "cmotag.htmp" /* static char *cmotagToName(int tag) is defined
1.8 takayama 20: here. */
1.1 maekawa 21:
1.18 ! takayama 22: void warningCmo(char *s);
! 23: void errorCmo(char *s);
! 24: size_t cmoOutGMPCoeff(mpz_srcptr x); // defined in cmo-gmp.c
! 25: size_t cmoGetGMPCoeff(MP_INT *x, struct cmoBuffer *cb);
! 26: int cmoCheckMathCap(struct object ob, struct object *mathcapObjp); // in oxmisc2.h
! 27:
! 28:
1.1 maekawa 29: extern int OxVersion;
30:
31: int CmoClientMode = 1; /* This flag is used to translate names for
1.8 takayama 32: indeterminates.
33: It does not work well if ox_sm1 have a server, i.e.,
34: sm1 --> ox_sm1 --> ox_sm1
35: */
1.1 maekawa 36:
37: /* void *malloc(int s);
38: #define GC_malloc(x) malloc(x) */
39: /********************** What you have to do when you add new CMO_ **********
40: * Add your new object to cmoObjectToCmo00 ( for sending )
41: * Add your new object to cmoCmoToObject00 ( for receiving )
42: * Edit KSmathCapByStruct();
43: * Edit typeTrans in cmoCheck00 in oxmisc2.c , e.g.,
44: * typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
45: **************************************************************************/
46: /* If you change the format of mathcap, do the follows.
47: Mofify cmoCheckMathCap in oxmisc2.c,
1.4 takayama 48: oxSendMathCap in oxmisc.c,
1.8 takayama 49: newMathCap in cmo.c,
1.4 takayama 50: oxReq, SM_setMathCap: in oxmisc2.c, and
1.1 maekawa 51: grep mathCap and make all modifications.
52: */
53:
54: extern struct ring *CurrentRingp;
55: extern struct ring *SmallRingp;
56: extern int CmoDMSOutputOption;
57:
1.13 takayama 58: struct object NullObjectInCmo = OINIT;
1.1 maekawa 59:
60: extern int SerialCurrent;
61: extern int DebugCMO;
62:
63: #define BUFFERSIZE 1024
64: struct cmoBuffer *cmoOutputToBuf(cmoAction a,void *data, int size)
65: {
66: static struct cmoBuffer b;
67: static int bufferIsInitialized = 0;
68: void *tmp;
69: struct cmoBuffer *cb;
70: int i;
71: if (!bufferIsInitialized) {
72: NullObjectInCmo.tag = Snull;
73: bufferIsInitialized = 1;
74: b.size = BUFFERSIZE;
75: b.pos = 0;
76: b.rpos = 0;
77: b.isStream = 0;
78: b.fp = (FILE2 *)NULL;
79: b.buf = sGC_malloc(BUFFERSIZE);
80: if (b.buf == NULL) errorCmo("cmoOutputToBuf: no memory.");
81: }
82: if (b.isStream) {
83: switch(a) {
84: case CMOINIT:
85: b.pos = 0;
86: b.rpos = 0; /* added, 1997, 12/5 */
87: b.isStream = 0;
88: b.fp = (FILE2 *)data ;
89: b.errorno = 0;
90: break;
91: case CMOINITSTREAM:
92: b.pos = 0;
93: b.isStream = 1;
94: b.rpos = 0; /* added, 1997, 12/5 */
95: b.fp = (FILE2 *)data;
96: b.errorno = 0;
97: break;
98: case CMOPUT:
99: for (i=0; i<size; i++) {
1.8 takayama 100: fp2fputc((int) ((char *)data)[i], b.fp);
1.1 maekawa 101: }
102: break;
103: case CMOFLUSH:
104: if (fp2fflush(b.fp)<0) {
1.8 takayama 105: errorCmo("cmoOutputToBuf: CMOFLUSH failed in stream mode.");
1.1 maekawa 106: }
107: cb = (struct cmoBuffer *)sGC_malloc(sizeof(struct cmoBuffer));
108: cb->isStream = b.isStream;
109: cb->size = b.pos;
110: cb->pos = b.pos;
111: cb->buf = NULL;
112: return(cb);
113: break;
114: case CMOERROR:
115: b.errorno = size;
116: break;
117: default:
118: errorCmo("Unknown action.");
119: break;
120: }
121: return(NULL);
122: }else{
123: switch(a) {
124: case CMOINIT:
125: b.pos = 0;
126: b.rpos = 0; /* added, 1997, 12/5 */
127: b.isStream = 0;
128: b.errorno = 0;
129: break;
130: case CMOINITSTREAM:
131: b.pos = 0;
132: b.isStream = 1;
133: b.rpos = 0; /* added, 1997, 12/5 */
134: b.fp = (FILE2 *)data;
135: b.errorno = 0;
136: break;
137: case CMOPUT:
138: if (b.pos + size >= b.size) {
1.8 takayama 139: tmp = sGC_malloc((b.size)*2+size);
140: memcpy(tmp,b.buf,b.pos);
141: b.buf = tmp;
142: b.size = (b.size)*2+size;
1.1 maekawa 143: }
144: memcpy((void *) &(((char *)(b.buf))[b.pos]),data,size);
145: b.pos += size;
146: break;
147: case CMOFLUSH:
148: cb = (struct cmoBuffer *)sGC_malloc(sizeof(struct cmoBuffer));
149: cb->isStream = b.isStream;
150: cb->size = b.pos;
151: cb->pos = b.pos;
152: cb->buf = sGC_malloc((b.pos<=0?1:b.pos));
153: memcpy(cb->buf,b.buf,b.pos);
154: return(cb);
155: break;
156: case CMOERROR:
157: b.errorno = size;
158: break;
159: default:
160: errorCmo("Unknown action.");
161: break;
162: }
163: return(NULL);
164: }
165: }
166:
1.18 ! takayama 167: int dumpCmoBuf(struct cmoBuffer *cb)
1.1 maekawa 168: {
169: int i,size, tag;
170: char *s;
171: if (cb->isStream) {
172: printf("cmoBuffer is directed to a stream.\n");
1.14 takayama 173: return 0;
1.1 maekawa 174: }
175: size = cb->pos;
176: s = (char *)(cb->buf);
177: tag = htonl(*((int *) s));
1.18 ! takayama 178: printf("CMO StandardEncoding: size = %d, size/sizeof(int) = %d, tag=%s \n",size,size/((int)sizeof(int)),cmotagToName(tag));
1.1 maekawa 179: for (i=0; i<size; i++) {
180: if (i % 20 == 0) putchar('\n');
181: printf("%3x",(int)(unsigned char)s[i]);
182: }
183: putchar('\n');
1.14 takayama 184: return 0;
1.1 maekawa 185: }
186:
187: /* This obsolete function is used to write data
188: in cmoBuffer (cmo object in kan)
189: to a stream */
1.18 ! takayama 190: int cmoToStream(struct object cmoObj,struct object of)
1.1 maekawa 191: {
192: int i,size;
193: struct cmoBuffer *cb;
194: char *s;
195: int file2=0;
196: if (!(cmoObj.tag == Sclass && cmoObj.lc.ival == CMO)) {
197: errorCmo("cmoToStream: the first argument is not cmoObject.");
198: }
199: if (of.tag != Sfile) {
200: errorCmo("cmoToStream: the second argument is not file object.");
201: }
202: if (strcmp(of.lc.str,MAGIC2) == 0) {
203: file2 = 1;
204: }
205: cb = cmoObj.rc.voidp;
206: size = cb->pos;
207: s = (char *)(cb->buf);
208: for (i=0; i<size; i++) {
209: if (file2) {
1.3 takayama 210: fp2fputc((int) s[i],(FILE2 *)(of.rc.voidp));
1.1 maekawa 211: }else{
1.3 takayama 212: fputc((int) s[i],of.rc.file);
1.1 maekawa 213: }
214: }
215: }
216: /* This obsolete function is used to store data from the stream
217: to cmoBuffer in the raw form. (cmo object in kan).
218: cf. cmoObjectFromStream, cmoObjectToStream: these function
219: directly transmit objects of kan to a stream in CMO format.
220: */
221: struct object streamToCmo(struct object of)
222: {
223: int c;
224: unsigned char s[1];
1.13 takayama 225: struct object ob = OINIT;
1.1 maekawa 226: int file2 = 0;
227: if (of.tag == Sfile) {
228:
229: }else{
230: errorCmo("streamToCmo: no file is opened.");
231: }
232: if (strcmp(of.lc.str,MAGIC2) == 0) {
233: file2 = 1;
234: }
235: cmoOutputToBuf(CMOINIT,NULL,0);
236: /* Raw reading to the buffer from file. No cmoOutHeader(). */
237: if (file2) {
238: while ((c=fp2fgetc((FILE2 *)of.rc.voidp)) != EOF) {
239: s[0] = c;
240: cmoOutputToBuf(CMOPUT,s,1);
241: }
242: }else{
243: while ((c=fgetc(of.rc.file)) != EOF) {
244: s[0] = c;
245: cmoOutputToBuf(CMOPUT,s,1);
246: }
247: }
248: /* Raw reading to the buffer from file. No cmoOutTail(). */
249: ob.tag = Sclass;
250: ob.lc.ival = CMO;
251: ob.rc.voidp = cmoOutputToBuf(CMOFLUSH,NULL,0);
252: return(ob);
253: }
254:
255:
1.18 ! takayama 256: void cmoOutCmoNull() {
1.1 maekawa 257: cmoint tmp[1];
258: tmp[0] = htonl((cmoint) CMO_NULL);
259: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
260: }
261:
262:
263:
264:
265: /* unsigned short int must be 32 bits */
1.18 ! takayama 266: void cmoOutInt32(int k)
1.1 maekawa 267: {
268: cmoint tmp[2];
269: tmp[0] = htonl((cmoint) CMO_INT32);
270: tmp[1] = htonl((cmoint ) k);
271: cmoOutputToBuf(CMOPUT,tmp,2*sizeof(cmoint));
272: }
273:
1.18 ! takayama 274: int cmoOutString(char *d,int size) {
1.1 maekawa 275: cmoint tmp[2];
276: tmp[0] = htonl((cmoint) CMO_STRING);
277: tmp[1] = htonl((cmoint ) size);
278: cmoOutputToBuf(CMOPUT,tmp,2*sizeof(cmoint));
279: cmoOutputToBuf(CMOPUT,d,size);
1.18 ! takayama 280: return 0;
1.1 maekawa 281: }
282:
283:
284: int cmoOutMonomial32(POLY cell)
285: {
286: cmoint tmp[3+N0*2];
287: extern int ReverseOutputOrder;
288: int i,nn,tt;
289: if (cell == POLYNULL) {
290: tmp[0] = htonl(CMO_ZERO);
291: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
292: return(0);
293: }
294: tmp[0] = htonl(CMO_MONOMIAL32);
295: nn = cell->m->ringp->n;
296: tmp[1] = htonl(nn*2);
297: if (ReverseOutputOrder) {
298: for (i=0; i<nn; i++) {
299: tmp[2+i] = htonl(cell->m->e[nn-i-1].x);
300: tmp[2+nn+i] = htonl(cell->m->e[nn-i-1].D);
301: }
302: }else{
303: for (i=0; i<nn; i++) {
304: tmp[2+i] = htonl(cell->m->e[i].x);
305: tmp[2+nn+i] = htonl(cell->m->e[i].D);
306: }
307: }
308: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*(2+2*nn));
309: switch(cell->coeffp->tag) {
310: case INTEGER:
311: cmoOutInt32(cell->coeffp->val.i);
312: return(0);
313: break;
314: case MP_INTEGER:
315: /* errorCmo("Not implemented."); */
316: cmoOutGMPCoeff(cell->coeffp->val.bigp);
317: return(0);
318: break;
319: default:
320: cmoOutputToBuf(CMOERROR,NULL,-1); /* fatal, need reset_connection */
321: errorCmo("cmoOutMonomial32(): unknown coefficient tag.");
322: return(-1);
323: break;
324: }
325: }
326:
327: int cmoOutDMS()
328: {
329: cmoint tmp[1];
330: tmp[0] = htonl(CMO_DMS);
331: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
332: return(0);
333: }
334:
335: int cmoOutPolynomial(POLY f)
336: {
337: int size;
338: cmoint tmp[2];
339: if (f == POLYNULL) {
340: return(cmoOutMonomial32(f));
341: }
342: size = pLength(f);
343: tmp[0] = htonl(CMO_LIST);
344: tmp[1] = htonl(size+2);
345: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*2);
346: cmoOutDMS();
347: cmoOutRingDefinition(f->m->ringp,CmoDMSOutputOption);
348: while (f != POLYNULL) {
349: cmoOutMonomial32(f);
350: f = f->next;
351: }
352: return(0);
353: }
354:
355: int cmoOutPolynomial2(POLY f)
356: {
357: int size;
358: cmoint tmp[2];
359: if (f == POLYNULL) {
360: return(cmoOutMonomial32(f));
361: }
362: size = pLength(f);
363: tmp[0] = htonl(CMO_DISTRIBUTED_POLYNOMIAL);
364: tmp[1] = htonl(size);
365: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*2);
366: cmoOutRingDefinition2(f->m->ringp,CmoDMSOutputOption);
367: while (f != POLYNULL) {
368: cmoOutMonomial32(f);
369: f = f->next;
370: }
371: return(0);
372: }
373:
1.18 ! takayama 374: void cmoOutRingDefinition(struct ring *rp,int option)
1.1 maekawa 375: {
376: cmoint tmp[3];
377: /* minimal information */
378: switch(option) {
379: case 1: /* RING_BY_NAME */
380: cmoOutRawInt(CMO_RING_BY_NAME);
381: cmoOutString(rp->name,strlen(rp->name));
382: break;
383: case 2:
384: tmp[0] = htonl(CMO_DMS_OF_N_VARIABLES);
385: tmp[1] = htonl(CMO_LIST);
386: tmp[2] = htonl(2);
387: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*3);
388: cmoOutInt32((rp->n)*2); /* number of variables */
389: cmoOutInt32(rp->p); /* coefficient field.
1.8 takayama 390: CMO_INT32 or CMO_DMS_OF_N_VARIABLES */
1.1 maekawa 391: /* Optional arguments are name of variables, weight_vector, output_order */
392: break;
393: default: /* including 0. */
394: cmoOutInt32(CMO_DMS_GENERIC);
395: break;
396: }
397:
398: }
399:
1.18 ! takayama 400: void cmoOutRingDefinition2(struct ring *rp,int option)
1.1 maekawa 401: {
402: cmoint tmp[3];
403: /* minimal information */
404: switch(option) {
405: case 1: /* RING_BY_NAME */
406: cmoOutRawInt(CMO_RING_BY_NAME);
407: cmoOutString(rp->name,strlen(rp->name));
408: break;
409: case 2:
410: tmp[0] = htonl(CMO_DMS_OF_N_VARIABLES);
411: tmp[1] = htonl(CMO_LIST);
412: tmp[2] = htonl(2);
413: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*3);
414: cmoOutInt32((rp->n)*2); /* number of variables */
415: cmoOutInt32(rp->p); /* coefficient field.
1.8 takayama 416: CMO_INT32 or CMO_DMS_OF_N_VARIABLES */
1.1 maekawa 417: /* Optional arguments are list of indeterminates (name of variables),
418: weight_vector by list , output_order by list. */
419: break;
420: default: /* including 0. */
421: cmoOutRawInt(CMO_DMS_GENERIC);
422: break;
423: }
424:
425: }
426:
427: /* ------------------------------ */
428: int cmoGetIntFromBuf(cmoAction a,struct cmoBuffer *cb)
429: {
430: cmoint tmp[1];
431: char data[4];
432: int i;
433: int cc;
434: if (cb->isStream) {
435: switch(a) {
436: case CMOGET:
437: for (i=0; i<4; i++) {
1.8 takayama 438: cc = fp2fgetc(cb->fp);
439: if (cc < 0) {
440: return(-1);
441: errorCmo("cmoGetIntFromBuf CMOGET: unexpected EOF.\n");
442: }
443: data[i] = cc;
1.1 maekawa 444: }
445: return( (int) ntohl( *((cmoint *) data) ));
446: break;
447: case CMOGETBYTE:
448: cc = fp2fgetc(cb->fp);
449: if (cc < 0) {
1.8 takayama 450: return(-1);
451: errorCmo("cmoGetIntFromBuf CMOGETBYTE: unexpected EOF.\n");
1.1 maekawa 452: }
453: return(cc);
454: break;
455: case CMOINIT:
456: fprintf(stderr,"Invalid action CMOINIT for cmoBuffer in the stream mode.\n");
457: cb->rpos = 0;
458: cb->errorno = 0;
459: break;
460: case CMOINITSTREAM:
461: cb->errorno = 0;
462: break;
463: case CMOERROR:
464: cb->errorno = 1;
465: break;
466: case CMOERROR2:
467: cb->errorno = -1;
468: break;
469: }
470: return(0);
471: }else{
472: switch(a) {
473: case CMOGET:
474: if (cb->rpos + sizeof(cmoint) > cb->pos) {
1.8 takayama 475: fprintf(stderr,"No more data in the buffer. Returns -1.\n");
476: return(-1);
1.1 maekawa 477: }
478: memcpy(tmp,(void *) &(((char *)(cb->buf))[cb->rpos]),
1.8 takayama 479: sizeof(cmoint));
1.1 maekawa 480: cb->rpos += sizeof(cmoint);
481: return( (int) ntohl(tmp[0]));
482: break;
483: case CMOGETBYTE:
484: if (cb->rpos + 1 > cb->pos) {
1.8 takayama 485: fprintf(stderr,"No more data in the buffer. Returns -1.\n");
486: return(-1);
1.1 maekawa 487: }
488: tmp[0] = ((unsigned char *)(cb->buf))[cb->rpos];
489: cb->rpos += 1;
490: return( (int) tmp[0]);
491: break;
492: case CMOINIT:
493: cb->rpos = 0;
494: cb->errorno = 0;
495: break;
496: case CMOINITSTREAM:
497: cb->errorno = 0;
498: break;
499: case CMOERROR:
500: cb->errorno = 1;
501: break;
502: case CMOERROR2:
503: cb->errorno = -1;
504: break;
505: }
506: return(0);
507: }
508: }
509:
510:
511: /* ------------------------------------- */
512: /* This function is called after reading the tag CMO_INT32COEFF */
513: struct coeff * cmoGetInt32Coeff(struct cmoBuffer *cb)
514: {
515: struct coeff *c;
516: c = intToCoeff(cmoGetIntFromBuf(CMOGET,cb),CurrentRingp);
517: return(c);
518: }
519: void *cmoGetString(struct cmoBuffer *cb, int size)
520: {
521: char *d;
522: int i;
523: if (size > 0) {
524: d = (char *)sGC_malloc(size);
525: if (d == NULL) {
526: errorCmo("No more memory in cmoGetString().\n");
527: }
528: }else{
529: d = (char *)sGC_malloc(1); d[0] = '\0';
530: if (d == NULL) {
531: errorCmo("No more memory in cmoGetString().\n");
532: }
533: }
534: for (i=0; i<size; i++) {
535: d[i] = cmoGetIntFromBuf(CMOGETBYTE, cb);
536: }
537: return(d);
538: }
539:
540: POLY cmoGetMonomial32(struct cmoBuffer *cb)
541: {
542: int nn,i,tt;
543: struct coeff *c;
544: struct monomial *m;
545: MP_INT *mi;
546: MP_INT *mi2;
547: int skip;
548: int nn0,nn1;
549: extern int ReverseOutputOrder;
550: skip = 0;
551: nn = cmoGetIntFromBuf(CMOGET,cb);
552: if (nn > (CurrentRingp->n)*2 ) {
553: CurrentRingp = KopRingp(KdefaultPolyRing(KpoInteger(nn/2+(nn%2))));
554: warningCmo("cmoGetMonomials32(): Changed the current ring, because your peer sent a DMS that does not fit to the current ring.");
555:
556: /* original code.
1.8 takayama 557: skip = nn - (CurrentRingp->n)*2;
558: nn1 = nn0 = CurrentRingp->n;
559: if (! (cb->errorno) ) {
560: warningCmo("cmoGetMonomial32(): serialized polynomial \\not\\in CurrentRing.");
561: }
562: cmoGetIntFromBuf(CMOERROR,cb);
1.1 maekawa 563: */
564: }
565: if (nn == (CurrentRingp->n)*2 ) {
566: nn1 = nn0 = CurrentRingp->n;
567: skip = 0;
568: }else {
569: nn0 = nn/2;
570: nn1 = nn - nn0;
571: skip = 0;
572: }
573:
574: m = newMonomial(CurrentRingp);
575: if (ReverseOutputOrder) {
576: for (i=0; i<nn0; i++) {
577: m->e[nn0-i-1].x = cmoGetIntFromBuf(CMOGET,cb);
578: }
579: for (i=0; i<nn1; i++) {
580: m->e[nn1-i-1].D = cmoGetIntFromBuf(CMOGET,cb);
581: }
582: }else{
583: for (i=0; i<nn0; i++) {
584: m->e[i].x = cmoGetIntFromBuf(CMOGET,cb);
585: }
586: for (i=0; i<nn1; i++) {
587: m->e[i].D = cmoGetIntFromBuf(CMOGET,cb);
588: }
589: }
590:
591: /* Throw a way extra data. */
592: for (i=0; i<skip; i++) {
593: cmoGetIntFromBuf(CMOGET,cb);
594: }
595:
596: tt = cmoGetIntFromBuf(CMOGET,cb);
597: switch(tt) {
598: case CMO_INT32:
599: c = cmoGetInt32Coeff(cb);
600: break;
601: case CMO_ZZ_OLD:
602: case CMO_ZZ:
603: if (OxVersion >= 199907170 && tt == CMO_ZZ_OLD) {
604: errorCmo("CMO_ZZ_OLD is not implemented.");
605: }else if (OxVersion < 199907170 && tt == CMO_ZZ) {
606: errorCmo("CMO_ZZ is not implemented.");
607: }
608: mi = newMP_INT();
609: cmoGetGMPCoeff(mi, cb);
610: c = mpintToCoeff(mi,CurrentRingp);
611: /* errorCmo("Not implemented."); */
612: break;
613: case CMO_QQ:
614: if (! (cb->errorno) ) {
615: warningCmo("cmoGetMonomial32(): coefficient CMO_QQ is not supported. Denominators are ignored.");
616: }
617: cmoGetIntFromBuf(CMOERROR,cb);
618: mi = newMP_INT();
619: cmoGetGMPCoeff(mi,cb);
620: c = mpintToCoeff(mi,CurrentRingp); /* we take only numerator */
621: /* Throw a way denominators. */
622: mi2 = newMP_INT();
623: cmoGetGMPCoeff(mi2,cb);
624: break;
625: default:
626: cmoGetIntFromBuf(CMOERROR2,cb);
627: errorCmo("cmoGetMonomial32(): coeff type that is not implemented.");
628: break;
629: }
630: return(newCell(c,m));
631: }
632:
633:
634:
635: /* ------------------------------------- */
636: void cmoObjectToCmo00(struct object ob)
637: {
1.13 takayama 638: struct object rob = OINIT;
1.1 maekawa 639: cmoint tmp[16];
640: char tmpc[16];
641: int i,size;
1.13 takayama 642: struct object vlist = OINIT;
643: struct object vlist0 = OINIT;
1.1 maekawa 644: int m;
1.13 takayama 645: struct object ob2 = OINIT;
1.1 maekawa 646:
647: /* NO initialization */
648: switch(ob.tag) {
649: case Snull:
650: cmoOutCmoNull();
651: break;
652: case Sinteger:
653: /* fprintf(stderr,"For test.\n"); */
654: cmoOutInt32(ob.lc.ival);
655: break;
656: case Sdollar:
657: cmoOutString(ob.lc.str,strlen(ob.lc.str));
658: break;
659: case Spoly:
660: /* cmoOutPolynomial(KopPOLY(ob)); */
661: cmoOutPolynomial2(KopPOLY(ob));
662: break;
663: case Sarray:
664: tmp[0] = htonl(CMO_LIST);
665: tmp[1] = htonl(size=getoaSize(ob));
666: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint)*2);
667: for (i=0; i<size; i++) {
668: cmoObjectToCmo00(getoa(ob,i));
669: }
670: break;
671: case SuniversalNumber:
672: cmoOutGMPCoeff(ob.lc.universalNumber->val.bigp);
1.10 takayama 673: break;
674: case SrationalFunction:
675: tmp[0] = htonl(CMO_RATIONAL);
676: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
677: cmoObjectToCmo00(*(Knumerator(ob)));
678: cmoObjectToCmo00(*(Kdenominator(ob)));
1.1 maekawa 679: break;
680: case Sdouble:
681: if (sizeof(double) != 8) errorCmo("double is assumed to be 8 bytes.");
682: cmoOutRawInt(CMO_64BIT_MACHINE_DOUBLE);
683: *((double *) tmpc) = (double) *(ob.lc.dbl);
684: cmoOutputToBuf(CMOPUT,tmpc,8);
685: break;
686: case Sclass:
687: switch(ectag(ob)) {
688: case CLASSNAME_ERROR_PACKET:
689: /* fprintf(stderr,"ectag=%d\n",ectag(*KopErrorPacket(ob))); **kxx:CMO_ERROR*/
690: if (ectag(*KopErrorPacket(ob)) == CLASSNAME_ERROR_PACKET) {
1.8 takayama 691: tmp[0] = htonl(CMO_ERROR);
692: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
1.1 maekawa 693: }else{
1.8 takayama 694: tmp[0] = htonl(CMO_ERROR2);
695: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
696: /* Send without OX_DATA header !! */
697: cmoObjectToCmo00(*(KopErrorPacket(ob)));
1.1 maekawa 698: }
699: break;
700: case CLASSNAME_mathcap:
701: tmp[0] = htonl(CMO_MATHCAP);
702: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
703: /* Send without OX_DATA header !! */
704: cmoObjectToCmo00(*(KopMathCap(ob)));
705: break;
706: case CLASSNAME_indeterminate:
707: tmp[0] = htonl(CMO_INDETERMINATE);
708: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
709: /* cmoObjectToCmo00(KopIndeterminate(ob)); Old code. */
710: /* If you need to translate the name, do it here. */
711: if (CmoClientMode) {
1.7 takayama 712: ob = KopIndeterminate(ob);
1.1 maekawa 713: }else{
1.7 takayama 714: ob = cmoTranslateVariable_outGoing(KopIndeterminate(ob));
1.1 maekawa 715: }
716: cmoObjectToCmo00(ob);
717: break;
718: case CLASSNAME_recursivePolynomial:
719: /* We assume that the format of the recursive polynomial
1.8 takayama 720: is OK. */
1.1 maekawa 721: tmp[0] = htonl(CMO_RECURSIVE_POLYNOMIAL);
722: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
723: ob = KopRecursivePolynomial(ob);
724: vlist = getoa(ob,0);
725: vlist0 = newObjectArray(getoaSize(vlist));
726: for (i=0; i<getoaSize(vlist); i++) {
1.8 takayama 727: if (getoa(vlist,i).tag == Sdollar) {
728: if (CmoClientMode) {
729: putoa(vlist0,i,
730: KpoIndeterminate(getoa(vlist,i)));
731: }else{
732: putoa(vlist0,i,
733: KpoIndeterminate(cmoTranslateVariable_outGoing(getoa(vlist,i))));
734: }
735: }else{
736: putoa(vlist0,i,getoa(vlist,i));
737: }
1.1 maekawa 738: }
739: cmoObjectToCmo00(vlist0); /* output the list of variables. */
740: cmoObjectToCmo00(getoa(ob,1)); /* output the body of the recursive poly
1.8 takayama 741: polynomial in one variable or any object*/
1.1 maekawa 742: break;
743: case CLASSNAME_polynomialInOneVariable:
744: tmp[0] = htonl(CMO_POLYNOMIAL_IN_ONE_VARIABLE);
745: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
746: ob = KopPolynomialInOneVariable(ob);
747: if (ob.tag != Sarray) {
1.8 takayama 748: cmoObjectToCmo00(ob);
1.1 maekawa 749: }else{
1.8 takayama 750: /* We do not check the format. */
751: m = (getoaSize(ob)-1)/2; /* the number of monomials */
752: cmoOutRawInt(m);
753: ob2 = getoa(ob,0); /* the variable name by integer. */
754: if (ob2.tag != Sinteger) {
755: warningCmo("cmoObjectToCmo00(): polynomial in one variable: this field should be integer. Output 0");
756: /* cmoOutInt32(0); */
757: cmoOutRawInt(0);
758: }else{
759: /* cmoObjectToCmo00(ob2); */
760: cmoOutRawInt(KopInteger(ob2));
761: }
762: for (i=1; i<getoaSize(ob); i = i+2) {
763: cmoOutRawInt(KopInteger(getoa(ob,i))); /* exponent */
764: cmoObjectToCmo00(getoa(ob,i+1)); /* coefficient */
765: }
1.1 maekawa 766: }
767: break;
768: case CLASSNAME_tree:
769: cmoOutRawInt(CMO_TREE);
770: ob = KopTree(ob);
771: cmoObjectToCmo00(getoa(ob,0));
772: cmoObjectToCmo00(getoa(ob,1));
773: cmoObjectToCmo00(getoa(ob,2));
774: break;
775: default:
776: warningCmo("cmoObjectToCmo(): unknown etag for Sclass. Output CMO_NULL");
777: cmoOutCmoNull(); /* otherwise core dump. */
778: break;
779: }
780: break;
781: default:
782: warningCmo("cmoObjectToCmo(): unknown tag. Output CMO_NULL");
783: cmoOutCmoNull(); /* otherwise core dump. */
784: break;
785: }
786: /* no flush */
787: }
788:
789: struct object cmoObjectToCmo(struct object ob)
790: {
1.13 takayama 791: struct object rob = OINIT;
1.1 maekawa 792: if (DebugCMO) {
793: fprintf(stderr,"cmoObjectToCmo: ");
794: printObject(ob,1,stderr);
795: }
796: cmoOutputToBuf(CMOINIT,NULL,0);
797: cmoObjectToCmo00(ob);
798: rob.tag = Sclass;
799: rob.lc.ival = CMO;
800: rob.rc.voidp = cmoOutputToBuf(CMOFLUSH,NULL,0);
801: return(rob);
802: }
803: void cmoDumpCmo(struct object ob)
804: {
805: if (ob.tag == Sclass && ob.lc.ival == CMO) {
806: dumpCmoBuf((struct cmoBuffer *) ob.rc.voidp);
807: }else {
808: errorCmo("cmoDumpCmo(): Object is not CMO.");
809: }
810: }
811:
812: int Lisplike = 0;
813: /* It is for debugging. Internal use only. */
814: /* [(cmoLispLike) 1] extension can be used to turn this option on. */
815: /* debug/cmotest.sm1 test11, test12 */
816:
817: struct object cmoCmoToObject00(struct cmoBuffer *cb)
818: {
1.13 takayama 819: struct object rob = OINIT;
820: struct object ob1 = OINIT;
821: struct object ob2 = OINIT;
1.1 maekawa 822: int tt,ival;
823: int i,size;
824: MP_INT *mi;
825: MP_INT *mi2;
826: struct ring *oldringp;
827: char tmpc[16];
1.13 takayama 828: struct object vlist = OINIT;
829: struct object vlist0 = OINIT;
1.1 maekawa 830: int k;
831: int m;
1.13 takayama 832: struct object ob = OINIT;
1.1 maekawa 833:
834:
835: tt = cmoGetIntFromBuf(CMOGET,cb); /* read the tag */
836: /* fprintf(stderr,"CmoToObject00: tag=%d\n",tt); */
837: if (Lisplike) {
838: printf("(%s[%x],", cmotagToName(tt),tt);
839: }
840: switch (tt) {
841: case CMO_ERROR2:
842: rob = KnewErrorPacketObj(cmoCmoToObject00(cb));
843: if (Lisplike) { printObject(rob,0,stdout); }
844: break;
845: case CMO_ERROR:
846: rob = KnewErrorPacketObj(KnewErrorPacket(SerialCurrent,-1,"CMO_ERROR"));
847: break;
848: case CMO_NULL:
849: rob.tag = Snull;
850: break;
851: case CMO_INT32:
852: /* For test. */
853: ival = cmoGetIntFromBuf(CMOGET,cb);
854: rob = KpoInteger(ival);
855: if (Lisplike) { printObject(rob,0,stdout); }
856: break;
857: case CMO_STRING:
858: size = cmoGetIntFromBuf(CMOGET,cb);
859: if (Lisplike) { printf("[size=%d],",size); }
860: rob = KpoString((char *)cmoGetString(cb,size));
861: if (Lisplike) { printObject(rob,0,stdout); }
862: break;
863: case CMO_MATHCAP:
864: rob = newObjectArray(2);
865: putoa(rob,0,KpoString("mathcap-object"));
866: /* We should create Class.mathcap in a future by KpoMathCap */
867: ob1= cmoCmoToObject00(cb);
868: putoa(rob,1,ob1);
869: if (Lisplike) { printObject(rob,0,stdout); }
870: break;
871: case CMO_LIST:
872: case CMO_ARRAY:
873: size = cmoGetIntFromBuf(CMOGET,cb);
874: if (size < 0) errorCmo("cmoCmoToObject00(): size of array is negative.");
875: rob = newObjectArray(size);
876: if (Lisplike) { printf("[size=%d],",size); }
877: /* printf("size=%d\n",size); */
878: for (i=0; i<size; i++) {
879: putoa(rob,i,cmoCmoToObject00(cb));
880: /* printObject(getoa(rob,i),0,stdout); */
881: if (i==0) {
1.8 takayama 882: ob1 = getoa(rob,0);
883: if (ob1.tag == CMO+CMO_DMS) {
884: goto dmscase ;
885: }
1.1 maekawa 886: }
887: }
888: break;
889: case CMO_DMS:
890: rob.tag = CMO+CMO_DMS; /* OK?? */
891: break;
892: case CMO_DISTRIBUTED_POLYNOMIAL:
893: size = cmoGetIntFromBuf(CMOGET,cb);
894: if (Lisplike) { printf("[size=]%d,",size); }
895: if (size < 0) errorCmo("cmoCmoToObject00(): CMO_DISTRIBUTED_POLYNOMIAL : negative size field.");
896: rob = newObjectArray(size);
897: /* Case for DMS. */
898: oldringp = CurrentRingp;
899: ob1 = cmoCmoToObject00(cb);
900: if (ob1.tag == Sdollar) {
901: /* Change the CurrentRingp by looking up the name. */
902: ob1 = KfindUserDictionary(KopString(ob1));
903: if (ob1.tag != Sring) {
1.8 takayama 904: errorCmo("cmoCmoToObject00(): your ring is not defined in the name space.");
1.1 maekawa 905: }
906: CurrentRingp = KopRingp(ob1);
907: }
908: i = 0;
909: while (i<size) {
910: putoa(rob,i,cmoCmoToObject00(cb));
911: i++;
912: }
913: CurrentRingp = oldringp;
914: rob = cmoListToPoly2(rob);
915: break;
916:
917: case CMO_DMS_GENERIC:
918: rob.tag = Snull;
919: break;
920: case CMO_DMS_OF_N_VARIABLES:
921: rob = cmoCmoToObject00(cb); /* list structure will come. */
922: break;
923: case CMO_RING_BY_NAME:
924: rob = cmoCmoToObject00(cb); /* read the string. */
925: break;
926: case CMO_MONOMIAL32:
927: rob = KpoPOLY(cmoGetMonomial32(cb));
928: if (Lisplike) { printObject(rob,0,stdout); }
929: break;
930: case CMO_ZERO:
931: rob = KpoPOLY(POLYNULL);
932: break;
933: case CMO_ZZ_OLD:
934: case CMO_ZZ:
935: if (OxVersion >= 199907170 && tt == CMO_ZZ_OLD) {
936: errorCmo("CMO_ZZ_OLD is not implemented.");
937: }else if (OxVersion < 199907170 && tt == CMO_ZZ) {
938: errorCmo("CMO_ZZ is not implemented.");
939: }
940: mi = newMP_INT();
941: cmoGetGMPCoeff(mi, cb);
942: rob.tag = SuniversalNumber;
943: rob.lc.universalNumber = mpintToCoeff(mi,SmallRingp);
944: if (Lisplike) { printObject(rob,0,stdout); }
945: break;
946: case CMO_QQ:
947: mi = newMP_INT();
948: cmoGetGMPCoeff(mi, cb);
949: mi2 = newMP_INT();
950: cmoGetGMPCoeff(mi2, cb);
951: ob1.tag = SuniversalNumber;
952: ob1.lc.universalNumber = mpintToCoeff(mi,SmallRingp);
953: ob2.tag = SuniversalNumber;
954: ob2.lc.universalNumber = mpintToCoeff(mi2,SmallRingp);
955: rob = KooDiv2(ob1,ob2);
956: if (Lisplike) { printObject(rob,0,stdout); }
957: break;
958: case CMO_64BIT_MACHINE_DOUBLE:
959: for (i=0; i<8; i++) {
960: tmpc[i] = cmoGetIntFromBuf(CMOGETBYTE, cb);
961: }
962: rob = KpoDouble(*((double *)tmpc));
963: if (Lisplike) { printObject(rob,0,stdout); }
964: break;
965: case CMO_INDETERMINATE:
966: /* Old code. rob = KpoIndeterminate(cmoCmoToObject00(cb)); */
967: /* If you need to change the names of indeterminates,
968: do it here. */
969: if (CmoClientMode) {
970: rob = KpoIndeterminate(cmoCmoToObject00(cb));
971: }else{
972: rob = KpoIndeterminate(cmoTranslateVariable_inComming(cmoCmoToObject00(cb)));
973: }
974: break;
975: case CMO_RECURSIVE_POLYNOMIAL:
976: vlist0 = cmoCmoToObject00(cb); /* list of variables by indeterminates. */
977: vlist = newObjectArray(getoaSize(vlist0));
978: for (i=0; i<getoaSize(vlist0); i++) {
979: ob1 = getoa(vlist0,i);
980: if (ectag(ob1) == CLASSNAME_indeterminate) {
1.7 takayama 981: ob1 = KopIndeterminate(ob1);
982: }else if (ectag(ob1) == CLASSNAME_tree) {
983: /* do nothing. */
1.8 takayama 984: }
1.1 maekawa 985: putoa(vlist,i,ob1);
986: }
987: /* vlist is a list of variables by strings. */
988:
989: rob = newObjectArray(2);
990: putoa(rob,0,vlist);
991: putoa(rob,1,cmoCmoToObject00(cb));
992: rob = KpoRecursivePolynomial(rob);
993: if (!isRecursivePolynomial2(rob)) {
994: errorCmo("cmoCmoToObject00(): invalid format of recursive polynomial. Return null.");
995: rob.tag = Snull;
996: }
997: break;
998: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
999: m = cmoGetIntFromBuf(CMOGET,cb);
1000: if (Lisplike) { printf("[numberOfMonomials=%d],",m); }
1001: if (m < 0) {
1002: errorCmo("cmoCmoToObject00(): invalid size of polynomial in one variable.");
1003: rob.tag = Snull;
1004: break;
1005: }
1006: rob = newObjectArray(2*m+1);
1007: /* ob1 = cmoCmoToObject00(cb);
1008: putoa(rob,0,ob1); name of the variable */
1009: i = cmoGetIntFromBuf(CMOGET,cb);
1010: putoa(rob,0,KpoInteger(i));
1011: if (Lisplike) { printf("[the main variable=]%d,",i); }
1012: for (i=1; i< 2*m+1; i = i+2) {
1013: k = cmoGetIntFromBuf(CMOGET,cb); /* exponent */
1014: if (Lisplike) { printf("[exponent=]%d,",k); }
1015: putoa(rob,i,KpoInteger(k));
1016: ob2 = cmoCmoToObject00(cb); putoa(rob,i+1,ob2);
1017: }
1018: rob = KpoPolynomialInOneVariable(rob);
1019: break;
1020: case CMO_TREE:
1021: ob1 = cmoCmoToObject00(cb);
1022: ob2 = cmoCmoToObject00(cb);
1023: rob = newObjectArray(3);
1024: putoa(rob,0,ob1);
1025: putoa(rob,1,ob2);
1026: putoa(rob,2,cmoCmoToObject00(cb));
1027: if (getoaSize(rob) != 3) {
1028: warningCmo("CMO_TREE : the object is not an array of the length 3.");
1029: }else{
1030: ob1 = getoa(rob,0);
1031: if (ob1.tag != Sdollar) warningCmo("CMO_TREE : the first arg must be the node name by a string.");
1.9 takayama 1032: ob2 = getoa(rob,1); /* Attribute List */
1033: if (ob2.tag != Sarray) warningCmo("CMO_TREE : the second arg must be a list of attributes.");
1.1 maekawa 1034: rob = KpoTree(rob);
1035: }
1036: break;
1037: case CMO_RATIONAL:
1038: ob1 = cmoCmoToObject00(cb);
1039: ob2 = cmoCmoToObject00(cb);
1040: rob = KooDiv2(ob1,ob2);
1041: if (Lisplike) { printObject(rob,0,stdout); }
1042: break;
1043: defaut:
1044: fprintf(stderr,"tag=%d (%x) ",tt,tt);
1045: errorCmo("cmoCmoToObject00(): unknown CMO tag. returns null object.");
1046: rob.tag = Snull;
1047: break;
1048: }
1049: if (Lisplike) { printf("),"); fflush(stdout); }
1050: return(rob);
1051:
1052: dmscase: ;
1053: /* Case for DMS. */
1054: oldringp = CurrentRingp;
1055: i = 1;
1056: if (i >= size) errorCmo("cmoCmoToObject00(): DMS, ring-def, ...");
1057: putoa(rob,i,cmoCmoToObject00(cb));
1058: ob1 = getoa(rob,1);
1059: if (ob1.tag == Sdollar) {
1060: /* Change the CurrentRingp by looking up the name. */
1061: ob1 = KfindUserDictionary(KopString(ob1));
1062: if (ob1.tag != Sring) {
1063: errorCmo("cmoCmoToObject00(): your ring is not defined in the name space.");
1064: }
1065: CurrentRingp = KopRingp(ob1);
1066: }
1067: i = 2;
1068: while (i<size) {
1069: putoa(rob,i,cmoCmoToObject00(cb));
1070: i++;
1071: }
1072: CurrentRingp = oldringp;
1073: if (Lisplike) { printf("),"); fflush(stdout); }
1074: return(rob);
1075: }
1076:
1077: struct object cmoCmoToObject(struct object ob)
1078: {
1.13 takayama 1079: struct object rob = OINIT;
1080: struct object ob0 = OINIT;
1.1 maekawa 1081: struct cmoBuffer *cb;
1082: if (!(ob.tag == Sclass && ob.lc.ival == CMO)) {
1083: rob.tag = Snull;
1084: errorCmo("cmoCmoToObject(): the argument is not CMO.");
1085: return(rob);
1086: }
1087: cb = (struct cmoBuffer *) ob.rc.voidp;
1088: cmoGetIntFromBuf(CMOINIT,cb);
1089: if (cb->pos == 0) {
1090: /* null */
1091: rob.tag = Snull;
1092: return(rob);
1093: }
1094: rob = cmoCmoToObject00(cb);
1095: rob = cmoListToPoly(rob);
1096: if (DebugCMO) {
1097: fprintf(stderr,"cmoCmoToObject: ");
1098: printObject(rob,1,stderr);
1099: }
1100: return(rob);
1101: }
1102:
1103: struct object cmoListToPoly(struct object ob) {
1.13 takayama 1104: struct object ob0 = OINIT;
1105: struct object rob = OINIT;
1.1 maekawa 1106: int i,n;
1107: if (ob.tag == Sarray) {
1108: n = getoaSize(ob);
1109: if (n >= 1) {
1110: ob0 = getoa(ob,0);
1111: if (ob0.tag == CMO+CMO_DMS) {
1.8 takayama 1112: rob = KpoPOLY(cmoListToPOLY(ob)); /* not ToPoly, ToPOLY */
1.1 maekawa 1113: }else{
1.8 takayama 1114: rob = newObjectArray(n);
1115: for (i=0; i<n; i++) {
1116: putoa(rob,i,cmoListToPoly(getoa(ob,i)));
1117: }
1.1 maekawa 1118: }
1119: }else{
1120: rob = ob;
1121: }
1122: }else{
1123: rob = ob;
1124: }
1125: return(rob);
1126: }
1127:
1128: struct object cmoListToPoly2(struct object ob)
1129: {
1130: int size,i;
1.13 takayama 1131: struct object ob0 = OINIT;
1132: struct object ob1 = OINIT;
1.1 maekawa 1133: POLY f;
1134: /*
1.8 takayama 1135: printf("<<");printObject(ob,0,stdout); printf(">>\n"); fflush(stdout);
1136: */
1.1 maekawa 1137: if (ob.tag != Sarray) {
1138: errorCmo("cmoListToPoly2(): the argument must be array.");
1139: }
1140: size = getoaSize(ob);
1141: f = POLYNULL;
1142: for (i=size-1; i>=0; i--) {
1143: ob1 = getoa(ob,i);
1144: if (ob1.tag == Spoly) {
1145: f = ppAdd(f,KopPOLY(ob1));
1146: }else{
1147: errorCmo("cmoListToPoly2(): format error.");
1148: }
1149: }
1150: return(KpoPOLY(f));
1151: }
1152:
1153: /*
1154: main() {
1155: int i;
1156: struct cmoBuffer *cb;
1157: printf("%d\n",sizeof(long int));
1158: for (i=0; i<300; i++) {
1159: cmoOutInt32(i);
1160: }
1161: dumpCmoBuf(cb=cmoOutputToBuf(CMOFLUSH,NULL,0));
1162: cmoGetIntFromBuf(CMOINIT,cb);
1163: for (i=0; i<300; i++) {
1164: printf("%5d",cmoGetIntFromBuf(CMOGET,cb));
1165: }
1166: putchar('\n');
1167: }
1168: */
1169:
1170: POLY cmoListToPOLY(struct object ob)
1171: {
1172: int size,i;
1.13 takayama 1173: struct object ob0 = OINIT;
1174: struct object ob1 = OINIT;
1.1 maekawa 1175: POLY f;
1176: /*
1.8 takayama 1177: printf("<<");printObject(ob,0,stdout); printf(">>\n"); fflush(stdout);
1178: */
1.1 maekawa 1179: if (ob.tag != Sarray) {
1180: errorCmo("cmoListToPOLY(): the argument must be array.");
1181: }
1182: size = getoaSize(ob);
1183: if (size < 2) {
1184: errorCmo("cmoListToPOLY(): the first element of the array must be CMO-tag.");
1185: errorCmo("cmoListToPOLY(): the second element must be the ring definition.");
1186: }
1187: ob0 = getoa(ob,0);
1188: ob1 = getoa(ob,1); /* ring defintion. It is not used for now. */
1189: /* printObject(ob1,0,stdout); */
1190: switch(ob0.tag) {
1191: case (CMO+CMO_DMS):
1192: f = POLYNULL;
1193: for (i=size-1; i>=2; i--) {
1194: ob1 = getoa(ob,i);
1195: if (ob1.tag == Spoly) {
1.8 takayama 1196: f = ppAdd(f,KopPOLY(ob1));
1.1 maekawa 1197: }else{
1.8 takayama 1198: f = ppAdd(f,cmoListToPOLY(ob1));
1.1 maekawa 1199: }
1200: }
1201: return(f);
1202: break;
1203: default:
1204: errorCmo("cmoListToPoly(): unknown tag.");
1205: break;
1206: }
1207: }
1208:
1209:
1210: int Kan_PushBinary(int size,void *data)
1211: {
1212: struct cmoBuffer cb;
1.13 takayama 1213: struct object ob = OINIT;
1.1 maekawa 1214: cb.pos = size;
1215: cb.rpos = 0;
1216: cb.buf = data;
1217: cb.size = size;
1218: ob.tag = Sclass; ob.lc.ival = CMO;
1219: ob.rc.voidp = &cb;
1220: KSpush(cmoCmoToObject(ob));
1221: return(0);
1222: }
1223:
1224: void *Kan_PopBinary(int *sizep)
1225: {
1.13 takayama 1226: struct object ob = OINIT;
1.1 maekawa 1227: struct cmoBuffer *cb;
1228: ob = KSpop();
1229: ob = cmoObjectToCmo(ob);
1230: if (ob.tag == Sclass && ob.lc.ival == CMO) {
1231: cb = (struct cmoBuffer *) (ob.rc.voidp);
1232: *sizep = cb->pos;
1233: return(cb->buf);
1234: }
1235: return(NULL);
1236: }
1237:
1238:
1239:
1240:
1241:
1242: struct object cmoObjectFromStream(struct object obStream)
1243: {
1244: struct cmoBuffer cb;
1.13 takayama 1245: struct object rob = OINIT;
1.18 ! takayama 1246: extern int DebugCMO;
1.1 maekawa 1247: if (obStream.tag != Sfile) {
1248: errorCmo("cmoObjectFromStream: Argument must be of type file.");
1249: }
1250: if (strcmp(obStream.lc.str,MAGIC2) != 0) {
1251: errorCmo("cmoObjectFromStream: Argument must be of type plugin/file2 buffered IO.");
1252: }
1253: rob = cmoObjectFromStream2((FILE2 *)obStream.rc.voidp);
1254: if (DebugCMO >= 2) {
1255: fprintf(stderr,"cmoObjectFromStream: ");
1256: printObject(rob,1,stderr);
1257: }
1258: return(rob);
1259: }
1260: struct object cmoObjectFromStream2(FILE2 *fp2)
1261: {
1262: struct cmoBuffer cb;
1.13 takayama 1263: struct object rob = OINIT;
1.1 maekawa 1264: cb.isStream=1; cb.fp = fp2;
1265: cmoGetIntFromBuf(CMOINITSTREAM,&cb);
1266: rob = cmoCmoToObject00(&cb);
1267: rob = cmoListToPoly(rob);
1268: if (cb.errorno) errorCmo("at cmoObjectFromStream2");
1269: if (DebugCMO) {
1270: fprintf(stderr,"cmoObjectFromStream2: ");
1271: printObject(rob,1,stderr);
1272: }
1273: return(rob);
1274: }
1275:
1276: struct object cmoObjectToStream(struct object ob, struct object obStream)
1277: {
1.13 takayama 1278: struct object rob = OINIT;
1.1 maekawa 1279: extern int DebugCMO;
1280: if (obStream.tag != Sfile) {
1281: errorCmo("cmoObjectToStream: Argument must be of type file.");
1282: }
1283: if (strcmp(obStream.lc.str,MAGIC2) != 0) {
1284: errorCmo("cmoObjectToStream: Argument must be of type plugin/file2 buffered IO.");
1285: }
1286: if (DebugCMO >= 2) {
1287: fprintf(stderr,"cmoObjectToStream: ");
1288: printObject(ob,1,stderr);
1289: }
1290: return(cmoObjectToStream2(ob,(FILE2 *)obStream.rc.voidp));
1291: }
1292:
1293: struct object cmoObjectToStream2(struct object ob, FILE2 *fp2)
1294: {
1.13 takayama 1295: struct object rob = OINIT;
1.1 maekawa 1296: cmoOutputToBuf(CMOINITSTREAM,(void *)fp2,0);
1297: if (DebugCMO) {
1298: fprintf(stderr,"cmoObjectToStream2: ");
1299: printObject(ob,1,stderr);
1300: }
1301: cmoObjectToCmo00(ob);
1302: fp2fflush(fp2);
1303: rob = KpoInteger(0);
1304: return(rob);
1305: }
1306:
1307: int Kan_pushCMOFromStream(FILE2 *fp)
1308: {
1.13 takayama 1309: struct object ob = OINIT;
1310: struct object rob = OINIT;
1.1 maekawa 1311: ob.tag = Sfile; ob.rc.voidp = (void *)fp; ob.lc.str = MAGIC2;
1312: rob = cmoObjectFromStream(ob);
1313: KSpush(rob);
1314: return(0);
1315: }
1316:
1317: int Kan_popCMOToStream(FILE2 *fp,int serial)
1318: {
1.13 takayama 1319: struct object ob = OINIT;
1320: struct object sob = OINIT;
1.1 maekawa 1321: sob.tag = Sfile; sob.rc.file = (void *)fp; sob.lc.str = MAGIC2;
1322: ob = Kpop();
1323: /*outfp2(fp);*/ /* outfp2 is for debugging. see develop/97feb.. 1999, 1/19*/
1324: if (!cmoCheckMathCap(ob, (struct object *)(fp->mathcapList))) {
1325: fprintf(stderr,"%s\n","Protection by mathcap. You cannot send this object to your peer.");
1326: ob = KnewErrorPacket(serial,-1,"cmoObjectToStream: protection by mathcap");
1327: cmoObjectToStream(ob,sob);
1328: return(-1);
1329: }
1330: cmoObjectToStream(ob,sob);
1331: return(0);
1332: }
1333:
1334: int Kan_setMathCapToStream(FILE2 *fp,struct object ob) {
1335: struct object *obp;
1336: obp = (struct object *)sGC_malloc(sizeof(struct object));
1337: *obp = ob;
1338: fp->mathcapList = (void *)obp;
1339: }
1340:
1341: /* It is declared in oxmisc2.h, too. */
1342: struct object newMathCap(struct mathCap *mathcap){
1.13 takayama 1343: struct object rob = OINIT;
1344: struct object ob1 = OINIT;
1345: struct object ob2 = OINIT;
1346: struct object ob3 = OINIT;
1347: struct object obOx = OINIT;
1348: struct object obSm = OINIT;
1349: struct object ob3tmp = OINIT;
1.1 maekawa 1350: struct object *obp;
1.4 takayama 1351: int i,j;
1.13 takayama 1352: struct object mathinfo = OINIT;
1.1 maekawa 1353:
1354: rob = newObjectArray(3);
1355:
1356: mathinfo = *((struct object *) (mathcap->infop));
1357: ob1 = newObjectArray(getoaSize(mathinfo));
1358: for (i=0; i<getoaSize(mathinfo); i++) {
1359: putoa(ob1,i,getoa(mathinfo,i));
1360: }
1.4 takayama 1361: ob3 = newObjectArray(mathcap->oxSize);
1.1 maekawa 1362: for (i=0; i<mathcap->oxSize; i++) {
1.4 takayama 1363: ob3tmp = newObjectArray(2);
1364: putoa(ob3tmp,0,KpoInteger((mathcap->ox)[i]));
1365: ob2 = newObjectArray(mathcap->n);
1366: for (j=0; j<mathcap->n; j++) {
1367: putoa(ob2,j,KpoInteger((mathcap->cmo)[j]));
1368: }
1369: putoa(ob3tmp,1,ob2);
1370: putoa(ob3,i,ob3tmp);
1.1 maekawa 1371: }
1372:
1373: obSm = newObjectArray(mathcap->smSize);
1374: for (i=0; i<mathcap->smSize; i++) {
1375: putoa(obSm,i,KpoInteger((mathcap->sm)[i]));
1376: }
1377: putoa(rob,0,ob1); /* Version , name etc */
1378: putoa(rob,1,obSm); /* SM tags */
1379: putoa(rob,2,ob3); /* OX_DATA format, cmo types. */
1380: obp = (struct object *)sGC_malloc(sizeof(struct object));
1381: *obp = rob;
1382: return( KpoMathCap(obp) );
1383: }
1384:
1385: struct object KSmathCap(void)
1386: {
1387: struct mathCap *mathcap;
1388: mathcap = KSmathCapByStruct();
1389: return(newMathCap(mathcap));
1390: }
1391:
1392: void *KSmathCapByStruct(void)
1.8 takayama 1393: /* Return the math cap of kan/sm1 with cmo.c as a mathcap classObject*/
1.1 maekawa 1394: {
1395: struct mathCap *mathcap;
1.13 takayama 1396: struct object ob = OINIT;
1.1 maekawa 1397: char *s1,*s2;
1398: struct object *mathinfo;
1399: char *sys;
1400: char *sysVersion;
1401: extern char *OxSystem; /* Example : ox_sm1.plain */
1402: extern char *OxSystemVersion; /* Example : 0.1 */
1403: mathcap = (struct mathCap *)sGC_malloc(sizeof(struct mathCap));
1404: mathinfo = sGC_malloc(sizeof(struct object));
1405:
1406: sys = (char *) sGC_malloc(sizeof(char)*(strlen(OxSystem)+strlen("Ox_system=")+2));
1407: strcpy(sys,"Ox_system="); strcat(sys,OxSystem);
1408: sysVersion =
1409: (char *) sGC_malloc(sizeof(char)*(strlen(OxSystemVersion)+strlen("Version=")+2));
1410: strcpy(sysVersion,"Version="); strcat(sysVersion,OxSystemVersion);
1411:
1412: ob = newObjectArray(4);
1413: putoa(ob,0,KpoInteger(OxVersion)); /* Open XM protocol Version */
1414: /* The rest entries must be strings. See oxmisc2.c oxSendMathcap */
1415: putoa(ob,1,KpoString(sys));
1416: putoa(ob,2,KpoString(sysVersion));
1417: s1 = getenv("HOSTTYPE");
1.5 takayama 1418: if (s1 == NULL) s1="unknown";
1.1 maekawa 1419: s2 = (char *)sGC_malloc(strlen(s1)+2+strlen("HOSTTYPE="));
1420: strcpy(s2,"HOSTTYPE=");
1421: strcat(s2,s1);
1422: putoa(ob,3,KpoString(s2));
1423:
1424: *mathinfo = ob;
1425: mathcap->infop = (void *) mathinfo;
1426:
1427: mathcap->cmo[0] = CMO_ERROR2;
1428: mathcap->cmo[1] = CMO_NULL;
1429: mathcap->cmo[2] = CMO_INT32;
1430: mathcap->cmo[3] = CMO_STRING;
1431: mathcap->cmo[4] = CMO_MATHCAP;
1432: mathcap->cmo[5] = CMO_LIST;
1433: mathcap->cmo[6] = CMO_MONOMIAL32;
1434: if (OxVersion >= 199907170) {
1435: mathcap->cmo[7] = CMO_ZZ;
1436: }else{
1437: mathcap->cmo[7] = CMO_ZZ_OLD;
1438: }
1439: mathcap->cmo[8] = CMO_ZERO;
1440: mathcap->cmo[9] = CMO_DMS;
1441: mathcap->cmo[10] = CMO_DMS_GENERIC;
1442: mathcap->cmo[11]= CMO_DMS_OF_N_VARIABLES;
1443: mathcap->cmo[12]= CMO_RING_BY_NAME;
1444: mathcap->cmo[13]= CMO_INT32COEFF;
1445: mathcap->cmo[14]= CMO_DISTRIBUTED_POLYNOMIAL;
1446: mathcap->cmo[15]= CMO_INDETERMINATE;
1447: mathcap->cmo[16]= CMO_TREE;
1448: mathcap->cmo[17]= CMO_RECURSIVE_POLYNOMIAL;
1449: mathcap->cmo[18]= CMO_POLYNOMIAL_IN_ONE_VARIABLE;
1450: mathcap->cmo[19]= CMO_64BIT_MACHINE_DOUBLE;
1451: mathcap->cmo[20]= CMO_ARRAY;
1452: mathcap->cmo[21]= CMO_RATIONAL;
1.12 takayama 1453: mathcap->cmo[22]= CMO_QQ;
1.1 maekawa 1454:
1.12 takayama 1455: mathcap->n = 23 ; /* This is the number of cmo object. You can use
1.8 takayama 1456: cmo upto 1023. see mathcap.h */
1.1 maekawa 1457:
1458: mathcap->ox[0] = OX_DATA;
1459: mathcap->oxSize = 1 ; /* This is the number of OX object. You can use
1.8 takayama 1460: OX upto 1023. see mathcap.h */
1.1 maekawa 1461:
1462: mathcap->sm[0] = SM_popCMO;
1463: mathcap->sm[1] = SM_popString;
1464: mathcap->sm[2] = SM_mathcap;
1465: mathcap->sm[3] = SM_pops;
1466: mathcap->sm[4] = SM_setName;
1467: mathcap->sm[5] = SM_executeStringByLocalParser;
1468: mathcap->sm[6] = SM_executeFunction;
1469: mathcap->sm[7] = SM_shutdown;
1470: mathcap->sm[8] = SM_setMathCap;
1471: mathcap->sm[9] = SM_getsp;
1472: mathcap->sm[10] = SM_dupErrors;
1.6 takayama 1473: mathcap->sm[11] = SM_pushCMOtag;
1.11 takayama 1474: mathcap->sm[12] = SM_executeFunctionWithOptionalArgument;
1.15 takayama 1475: mathcap->sm[13] = SM_nop;
1476: mathcap->smSize = 14;
1.1 maekawa 1477:
1478: return((void *)mathcap);
1479: }
1480:
1481: int cmoOutRawInt(int k)
1482: {
1483: cmoint tmp[1];
1484: tmp[0] = htonl((cmoint ) k);
1485: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
1486: }
1487:
1.18 ! takayama 1488: void warningCmo(char *s) {
1.1 maekawa 1489: fprintf(stderr,"Warning: plugin/cmo.c : %s\n",s);
1490: }
1491:
1.18 ! takayama 1492: void errorCmo(char *s) {
1.1 maekawa 1493: fprintf(stderr,"plugin/cmo.c : %s\n",s);
1494: errorKan1("%s\n","cmo fatal error. ox servers need SM_control_reset_connection.");
1495: /* ErrorPacket is automatically push on the ErrorStack.
1496: cf. var.sm1, [(ErrorStack)] system_variable */
1497: /* KSexecuteString(" error "); */
1498: }
1499:
1500: /* for dubugging. Should be comment out later. */
1501: int outfp2(FILE2 *fp2) {
1502: int i;
1503: printf("--------- outfp2 ---------\n"); fflush(stdout);
1.8 takayama 1504: /* if (checkfp2(fp2," f2pdumpBuf ") == -1) {
1505: return(-1);
1506: }*/
1.1 maekawa 1507: printf("fd=%d\n",fp2->fd);
1508: printf("initialied=%d\n",fp2->initialized);
1509: printf("readpos=%d\n",fp2->readpos);
1510: printf("readsize=%d\n",fp2->readsize);
1511: printf("writepos=%d\n",fp2->writepos);
1512: printf("limit=%d\n",fp2->limit);
1513: for (i=0; i<fp2->readsize; i++) {
1514: printf("readBuf[%d]=%2x ",i,fp2->readBuf[i]);
1515: }
1516: for (i=0; i<fp2->writepos; i++) {
1517: printf("writeBuf[%d]=%2x ",i,fp2->writeBuf[i]);
1518: }
1519: printf("\n");
1520: printObject(*( (struct object *)fp2->mathcapList),0,stdout);
1521: printf("\n");
1522: return(0);
1523: }
1524:
1525: static char *translateReservedName(char *s) {
1526: /* We do not translate h and q */
1527: if (strcmp(s,"e_") == 0) { /* Should read the @@@E.symbol value */
1528: return("#65_");
1529: }else if (strcmp(s,"E") == 0) {
1530: return("#45");
1531: }else if (strcmp(s,"H") == 0) {
1532: return("#48");
1533: }else if (strcmp(s,"PAD")==0) {
1534: return("#4FAD");
1535: }else {
1536: return(NULL);
1537: }
1538: }
1.8 takayama 1539:
1.1 maekawa 1540: struct object cmoTranslateVariable_inComming(struct object ob) {
1541: /* ob must be Sdollar, return value must be Sdollar. */
1542: /* Read a variable name from an other system,
1543: and translate the variable name into
1544: a suitable sm1 variable name. */
1545: char *s;
1546: char *t;
1547: int n, i, count;
1548: if (ob.tag != Sdollar) errorCmo("cmoTranslateVariable_inComming: the argument must be a string.");
1549: s = KopString(ob);
1550: t = translateReservedName(s);
1551: if (t != NULL) {
1552: if (Lisplike) printf("[%s==>%s]",s,t);
1553: return(KpoString(t));
1554: }
1555:
1556: n = strlen(s);
1557: for (i=count=0; i<n; i++,count++) {
1558: if (s[i] <= ' ' || s[i] == '#') {
1559: count += 2;
1560: }
1561: }
1562: if (n != count) {
1563: t = (char *) sGC_malloc(sizeof(char)*(count+2));
1564: if (t == NULL) errorCmo("No more memory.");
1565: for (i=count=0; i<n; i++) {
1566: if (s[i] <= ' ' || s[i] == '#') {
1.8 takayama 1567: t[count++] = '#';
1568: t[count++] = (s[i]/16 < 10? s[i]/16+'0': (s[i]/16-10)+'A');
1569: t[count++] = (s[i]%16 < 10? s[i]%16+'0': (s[i]%16-10)+'A');
1.1 maekawa 1570: }else{
1.8 takayama 1571: t[count++] = s[i];
1.1 maekawa 1572: }
1573: }
1574: t[count] = '\0';
1575: }else{
1576: t = s;
1577: }
1578: if (Lisplike) {
1579: printf("[%s==>%s]",s,t);
1580: }
1581: return(KpoString(t));
1582: }
1583:
1584: #define isHex_cmo(a) ((a >= '0' && a <='9') || (a>='A' && a <='F')?1:0)
1585: #define hexnum_cmo(a) (a>='A' && a <='F'? a-'A'+10 : a-'0')
1586: struct object cmoTranslateVariable_outGoing(struct object ob) {
1587: /* ob must be Sdollar, return value must be Sdollar. */
1588: char *s, *t;
1589: int i,j,n;
1590: int p;
1591: if (ob.tag != Sdollar) errorCmo("cmoTranslateVariable_inComming: the argument must be a string.");
1592: s = KopString(ob);
1593: n = strlen(s);
1594: for (i=0; i<n; i++) {
1595: if (i < n-2 && s[i] == '#' && isHex_cmo(s[i+1]) && isHex_cmo(s[i+2])) {
1596: t = (char *) sGC_malloc(sizeof(char)*(n+2));
1597: if (t == NULL) errorCmo("No more memory.");
1598: break;
1599: }
1600: if (i== n-1) {
1601: return(KpoString(s));
1602: }
1603: }
1604: for (i=j=0; i<n; i++) {
1605: if (i < n-2 && s[i] == '#' && isHex_cmo(s[i+1]) && isHex_cmo(s[i+2])) {
1606: p = (hexnum_cmo(s[i+1]))*16+hexnum_cmo(s[i+2]);
1607: t[j++] = p; i += 2;
1608: }else{
1609: t[j++] = s[i];
1610: }
1611: }
1612: t[j] = '\0';
1613: if (Lisplike) {
1614: printf("[%s-->%s]",s,t);
1615: }
1616: return(KpoString(t));
1617: }
1618:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>