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