Annotation of OpenXM/src/kan96xx/plugin/cmo.c, Revision 1.5
1.5 ! takayama 1: /*$OpenXM: OpenXM/src/kan96xx/plugin/cmo.c,v 1.4 1999/11/27 01:41:11 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
19: here. */
20:
21: extern int OxVersion;
22:
23: int CmoClientMode = 1; /* This flag is used to translate names for
24: indeterminates.
25: It does not work well if ox_sm1 have a server, i.e.,
26: sm1 --> ox_sm1 --> ox_sm1
27: */
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,
41: newMathCap in cmo.c,
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.3 takayama 92: fp2fputc((int) ((char *)data)[i], b.fp);
1.1 maekawa 93: }
94: break;
95: case CMOFLUSH:
96: if (fp2fflush(b.fp)<0) {
97: errorCmo("cmoOutputToBuf: CMOFLUSH failed in stream mode.");
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) {
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;
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.
380: CMO_INT32 or CMO_DMS_OF_N_VARIABLES */
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.
406: CMO_INT32 or CMO_DMS_OF_N_VARIABLES */
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++) {
428: cc = fp2fgetc(cb->fp);
429: if (cc < 0) {
430: return(-1);
431: errorCmo("cmoGetIntFromBuf CMOGET: unexpected EOF.\n");
432: }
433: data[i] = cc;
434: }
435: return( (int) ntohl( *((cmoint *) data) ));
436: break;
437: case CMOGETBYTE:
438: cc = fp2fgetc(cb->fp);
439: if (cc < 0) {
440: return(-1);
441: errorCmo("cmoGetIntFromBuf CMOGETBYTE: unexpected EOF.\n");
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) {
465: fprintf(stderr,"No more data in the buffer. Returns -1.\n");
466: return(-1);
467: }
468: memcpy(tmp,(void *) &(((char *)(cb->buf))[cb->rpos]),
469: sizeof(cmoint));
470: cb->rpos += sizeof(cmoint);
471: return( (int) ntohl(tmp[0]));
472: break;
473: case CMOGETBYTE:
474: if (cb->rpos + 1 > cb->pos) {
475: fprintf(stderr,"No more data in the buffer. Returns -1.\n");
476: return(-1);
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.
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);
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);
662: break;
663: case Sdouble:
664: if (sizeof(double) != 8) errorCmo("double is assumed to be 8 bytes.");
665: cmoOutRawInt(CMO_64BIT_MACHINE_DOUBLE);
666: *((double *) tmpc) = (double) *(ob.lc.dbl);
667: cmoOutputToBuf(CMOPUT,tmpc,8);
668: break;
669: case Sclass:
670: switch(ectag(ob)) {
671: case CLASSNAME_ERROR_PACKET:
672: /* fprintf(stderr,"ectag=%d\n",ectag(*KopErrorPacket(ob))); **kxx:CMO_ERROR*/
673: if (ectag(*KopErrorPacket(ob)) == CLASSNAME_ERROR_PACKET) {
674: tmp[0] = htonl(CMO_ERROR);
675: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
676: }else{
677: tmp[0] = htonl(CMO_ERROR2);
678: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
679: /* Send without OX_DATA header !! */
680: cmoObjectToCmo00(*(KopErrorPacket(ob)));
681: }
682: break;
683: case CLASSNAME_mathcap:
684: tmp[0] = htonl(CMO_MATHCAP);
685: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
686: /* Send without OX_DATA header !! */
687: cmoObjectToCmo00(*(KopMathCap(ob)));
688: break;
689: case CLASSNAME_indeterminate:
690: tmp[0] = htonl(CMO_INDETERMINATE);
691: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
692: /* cmoObjectToCmo00(KopIndeterminate(ob)); Old code. */
693: /* If you need to translate the name, do it here. */
694: if (CmoClientMode) {
695: ob = KopIndeterminate(ob);
696: }else{
697: ob = cmoTranslateVariable_outGoing(KopIndeterminate(ob));
698: }
699: cmoObjectToCmo00(ob);
700: break;
701: case CLASSNAME_recursivePolynomial:
702: /* We assume that the format of the recursive polynomial
703: is OK. */
704: tmp[0] = htonl(CMO_RECURSIVE_POLYNOMIAL);
705: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
706: ob = KopRecursivePolynomial(ob);
707: vlist = getoa(ob,0);
708: vlist0 = newObjectArray(getoaSize(vlist));
709: for (i=0; i<getoaSize(vlist); i++) {
710: if (CmoClientMode) {
711: putoa(vlist0,i,
712: KpoIndeterminate(getoa(vlist,i)));
713: }else{
714: putoa(vlist0,i,
715: KpoIndeterminate(cmoTranslateVariable_outGoing(getoa(vlist,i))));
716: }
717: }
718: cmoObjectToCmo00(vlist0); /* output the list of variables. */
719: cmoObjectToCmo00(getoa(ob,1)); /* output the body of the recursive poly
720: polynomial in one variable or any object*/
721: break;
722: case CLASSNAME_polynomialInOneVariable:
723: tmp[0] = htonl(CMO_POLYNOMIAL_IN_ONE_VARIABLE);
724: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
725: ob = KopPolynomialInOneVariable(ob);
726: if (ob.tag != Sarray) {
727: cmoObjectToCmo00(ob);
728: }else{
729: /* We do not check the format. */
730: m = (getoaSize(ob)-1)/2; /* the number of monomials */
731: cmoOutRawInt(m);
732: ob2 = getoa(ob,0); /* the variable name by integer. */
733: if (ob2.tag != Sinteger) {
734: warningCmo("cmoObjectToCmo00(): polynomial in one variable: this field should be integer. Output 0");
735: /* cmoOutInt32(0); */
736: cmoOutRawInt(0);
737: }else{
738: /* cmoObjectToCmo00(ob2); */
739: cmoOutRawInt(KopInteger(ob2));
740: }
741: for (i=1; i<getoaSize(ob); i = i+2) {
742: cmoOutRawInt(KopInteger(getoa(ob,i))); /* exponent */
743: cmoObjectToCmo00(getoa(ob,i+1)); /* coefficient */
744: }
745: }
746: break;
747: case CLASSNAME_tree:
748: cmoOutRawInt(CMO_TREE);
749: ob = KopTree(ob);
750: cmoObjectToCmo00(getoa(ob,0));
751: cmoObjectToCmo00(getoa(ob,1));
752: cmoObjectToCmo00(getoa(ob,2));
753: break;
754: default:
755: warningCmo("cmoObjectToCmo(): unknown etag for Sclass. Output CMO_NULL");
756: cmoOutCmoNull(); /* otherwise core dump. */
757: break;
758: }
759: break;
760: default:
761: warningCmo("cmoObjectToCmo(): unknown tag. Output CMO_NULL");
762: cmoOutCmoNull(); /* otherwise core dump. */
763: break;
764: }
765: /* no flush */
766: }
767:
768: struct object cmoObjectToCmo(struct object ob)
769: {
770: struct object rob;
771: if (DebugCMO) {
772: fprintf(stderr,"cmoObjectToCmo: ");
773: printObject(ob,1,stderr);
774: }
775: cmoOutputToBuf(CMOINIT,NULL,0);
776: cmoObjectToCmo00(ob);
777: rob.tag = Sclass;
778: rob.lc.ival = CMO;
779: rob.rc.voidp = cmoOutputToBuf(CMOFLUSH,NULL,0);
780: return(rob);
781: }
782: void cmoDumpCmo(struct object ob)
783: {
784: if (ob.tag == Sclass && ob.lc.ival == CMO) {
785: dumpCmoBuf((struct cmoBuffer *) ob.rc.voidp);
786: }else {
787: errorCmo("cmoDumpCmo(): Object is not CMO.");
788: }
789: }
790:
791: int Lisplike = 0;
792: /* It is for debugging. Internal use only. */
793: /* [(cmoLispLike) 1] extension can be used to turn this option on. */
794: /* debug/cmotest.sm1 test11, test12 */
795:
796: struct object cmoCmoToObject00(struct cmoBuffer *cb)
797: {
798: struct object rob;
799: struct object ob1;
800: struct object ob2;
801: int tt,ival;
802: int i,size;
803: MP_INT *mi;
804: MP_INT *mi2;
805: struct ring *oldringp;
806: char tmpc[16];
807: struct object vlist, vlist0;
808: int k;
809: int m;
810: struct object ob;
811:
812:
813: tt = cmoGetIntFromBuf(CMOGET,cb); /* read the tag */
814: /* fprintf(stderr,"CmoToObject00: tag=%d\n",tt); */
815: if (Lisplike) {
816: printf("(%s[%x],", cmotagToName(tt),tt);
817: }
818: switch (tt) {
819: case CMO_ERROR2:
820: rob = KnewErrorPacketObj(cmoCmoToObject00(cb));
821: if (Lisplike) { printObject(rob,0,stdout); }
822: break;
823: case CMO_ERROR:
824: rob = KnewErrorPacketObj(KnewErrorPacket(SerialCurrent,-1,"CMO_ERROR"));
825: break;
826: case CMO_NULL:
827: rob.tag = Snull;
828: break;
829: case CMO_INT32:
830: /* For test. */
831: ival = cmoGetIntFromBuf(CMOGET,cb);
832: rob = KpoInteger(ival);
833: if (Lisplike) { printObject(rob,0,stdout); }
834: break;
835: case CMO_STRING:
836: size = cmoGetIntFromBuf(CMOGET,cb);
837: if (Lisplike) { printf("[size=%d],",size); }
838: rob = KpoString((char *)cmoGetString(cb,size));
839: if (Lisplike) { printObject(rob,0,stdout); }
840: break;
841: case CMO_MATHCAP:
842: rob = newObjectArray(2);
843: putoa(rob,0,KpoString("mathcap-object"));
844: /* We should create Class.mathcap in a future by KpoMathCap */
845: ob1= cmoCmoToObject00(cb);
846: putoa(rob,1,ob1);
847: if (Lisplike) { printObject(rob,0,stdout); }
848: break;
849: case CMO_LIST:
850: case CMO_ARRAY:
851: size = cmoGetIntFromBuf(CMOGET,cb);
852: if (size < 0) errorCmo("cmoCmoToObject00(): size of array is negative.");
853: rob = newObjectArray(size);
854: if (Lisplike) { printf("[size=%d],",size); }
855: /* printf("size=%d\n",size); */
856: for (i=0; i<size; i++) {
857: putoa(rob,i,cmoCmoToObject00(cb));
858: /* printObject(getoa(rob,i),0,stdout); */
859: if (i==0) {
860: ob1 = getoa(rob,0);
861: if (ob1.tag == CMO+CMO_DMS) {
862: goto dmscase ;
863: }
864: }
865: }
866: break;
867: case CMO_DMS:
868: rob.tag = CMO+CMO_DMS; /* OK?? */
869: break;
870: case CMO_DISTRIBUTED_POLYNOMIAL:
871: size = cmoGetIntFromBuf(CMOGET,cb);
872: if (Lisplike) { printf("[size=]%d,",size); }
873: if (size < 0) errorCmo("cmoCmoToObject00(): CMO_DISTRIBUTED_POLYNOMIAL : negative size field.");
874: rob = newObjectArray(size);
875: /* Case for DMS. */
876: oldringp = CurrentRingp;
877: ob1 = cmoCmoToObject00(cb);
878: if (ob1.tag == Sdollar) {
879: /* Change the CurrentRingp by looking up the name. */
880: ob1 = KfindUserDictionary(KopString(ob1));
881: if (ob1.tag != Sring) {
882: errorCmo("cmoCmoToObject00(): your ring is not defined in the name space.");
883: }
884: CurrentRingp = KopRingp(ob1);
885: }
886: i = 0;
887: while (i<size) {
888: putoa(rob,i,cmoCmoToObject00(cb));
889: i++;
890: }
891: CurrentRingp = oldringp;
892: rob = cmoListToPoly2(rob);
893: break;
894:
895: case CMO_DMS_GENERIC:
896: rob.tag = Snull;
897: break;
898: case CMO_DMS_OF_N_VARIABLES:
899: rob = cmoCmoToObject00(cb); /* list structure will come. */
900: break;
901: case CMO_RING_BY_NAME:
902: rob = cmoCmoToObject00(cb); /* read the string. */
903: break;
904: case CMO_MONOMIAL32:
905: rob = KpoPOLY(cmoGetMonomial32(cb));
906: if (Lisplike) { printObject(rob,0,stdout); }
907: break;
908: case CMO_ZERO:
909: rob = KpoPOLY(POLYNULL);
910: break;
911: case CMO_ZZ_OLD:
912: case CMO_ZZ:
913: if (OxVersion >= 199907170 && tt == CMO_ZZ_OLD) {
914: errorCmo("CMO_ZZ_OLD is not implemented.");
915: }else if (OxVersion < 199907170 && tt == CMO_ZZ) {
916: errorCmo("CMO_ZZ is not implemented.");
917: }
918: mi = newMP_INT();
919: cmoGetGMPCoeff(mi, cb);
920: rob.tag = SuniversalNumber;
921: rob.lc.universalNumber = mpintToCoeff(mi,SmallRingp);
922: if (Lisplike) { printObject(rob,0,stdout); }
923: break;
924: case CMO_QQ:
925: mi = newMP_INT();
926: cmoGetGMPCoeff(mi, cb);
927: mi2 = newMP_INT();
928: cmoGetGMPCoeff(mi2, cb);
929: ob1.tag = SuniversalNumber;
930: ob1.lc.universalNumber = mpintToCoeff(mi,SmallRingp);
931: ob2.tag = SuniversalNumber;
932: ob2.lc.universalNumber = mpintToCoeff(mi2,SmallRingp);
933: rob = KooDiv2(ob1,ob2);
934: if (Lisplike) { printObject(rob,0,stdout); }
935: break;
936: case CMO_64BIT_MACHINE_DOUBLE:
937: for (i=0; i<8; i++) {
938: tmpc[i] = cmoGetIntFromBuf(CMOGETBYTE, cb);
939: }
940: rob = KpoDouble(*((double *)tmpc));
941: if (Lisplike) { printObject(rob,0,stdout); }
942: break;
943: case CMO_INDETERMINATE:
944: /* Old code. rob = KpoIndeterminate(cmoCmoToObject00(cb)); */
945: /* If you need to change the names of indeterminates,
946: do it here. */
947: if (CmoClientMode) {
948: rob = KpoIndeterminate(cmoCmoToObject00(cb));
949: }else{
950: rob = KpoIndeterminate(cmoTranslateVariable_inComming(cmoCmoToObject00(cb)));
951: }
952: break;
953: case CMO_RECURSIVE_POLYNOMIAL:
954: vlist0 = cmoCmoToObject00(cb); /* list of variables by indeterminates. */
955: vlist = newObjectArray(getoaSize(vlist0));
956: for (i=0; i<getoaSize(vlist0); i++) {
957: ob1 = getoa(vlist0,i);
958: if (ectag(ob1) == CLASSNAME_indeterminate) {
959: ob1 = KopIndeterminate(ob1);
960: }
961: putoa(vlist,i,ob1);
962: }
963: /* vlist is a list of variables by strings. */
964:
965: rob = newObjectArray(2);
966: putoa(rob,0,vlist);
967: putoa(rob,1,cmoCmoToObject00(cb));
968: rob = KpoRecursivePolynomial(rob);
969: if (!isRecursivePolynomial2(rob)) {
970: errorCmo("cmoCmoToObject00(): invalid format of recursive polynomial. Return null.");
971: rob.tag = Snull;
972: }
973: break;
974: case CMO_POLYNOMIAL_IN_ONE_VARIABLE:
975: m = cmoGetIntFromBuf(CMOGET,cb);
976: if (Lisplike) { printf("[numberOfMonomials=%d],",m); }
977: if (m < 0) {
978: errorCmo("cmoCmoToObject00(): invalid size of polynomial in one variable.");
979: rob.tag = Snull;
980: break;
981: }
982: rob = newObjectArray(2*m+1);
983: /* ob1 = cmoCmoToObject00(cb);
984: putoa(rob,0,ob1); name of the variable */
985: i = cmoGetIntFromBuf(CMOGET,cb);
986: putoa(rob,0,KpoInteger(i));
987: if (Lisplike) { printf("[the main variable=]%d,",i); }
988: for (i=1; i< 2*m+1; i = i+2) {
989: k = cmoGetIntFromBuf(CMOGET,cb); /* exponent */
990: if (Lisplike) { printf("[exponent=]%d,",k); }
991: putoa(rob,i,KpoInteger(k));
992: ob2 = cmoCmoToObject00(cb); putoa(rob,i+1,ob2);
993: }
994: rob = KpoPolynomialInOneVariable(rob);
995: break;
996: case CMO_TREE:
997: ob1 = cmoCmoToObject00(cb);
998: ob2 = cmoCmoToObject00(cb);
999: rob = newObjectArray(3);
1000: putoa(rob,0,ob1);
1001: putoa(rob,1,ob2);
1002: putoa(rob,2,cmoCmoToObject00(cb));
1003: if (getoaSize(rob) != 3) {
1004: warningCmo("CMO_TREE : the object is not an array of the length 3.");
1005: }else{
1006: ob1 = getoa(rob,0);
1007: if (ob1.tag != Sdollar) warningCmo("CMO_TREE : the first arg must be the node name by a string.");
1008: ob2 = getoa(rob,1); /* content dictionary name. */
1009: if (ob2.tag != Sdollar) warningCmo("CMO_TREE : the second arg must be the node name by a string.");
1010: rob = KpoTree(rob);
1011: }
1012: break;
1013: case CMO_RATIONAL:
1014: ob1 = cmoCmoToObject00(cb);
1015: ob2 = cmoCmoToObject00(cb);
1016: rob = KooDiv2(ob1,ob2);
1017: if (Lisplike) { printObject(rob,0,stdout); }
1018: break;
1019: defaut:
1020: fprintf(stderr,"tag=%d (%x) ",tt,tt);
1021: errorCmo("cmoCmoToObject00(): unknown CMO tag. returns null object.");
1022: rob.tag = Snull;
1023: break;
1024: }
1025: if (Lisplike) { printf("),"); fflush(stdout); }
1026: return(rob);
1027:
1028: dmscase: ;
1029: /* Case for DMS. */
1030: oldringp = CurrentRingp;
1031: i = 1;
1032: if (i >= size) errorCmo("cmoCmoToObject00(): DMS, ring-def, ...");
1033: putoa(rob,i,cmoCmoToObject00(cb));
1034: ob1 = getoa(rob,1);
1035: if (ob1.tag == Sdollar) {
1036: /* Change the CurrentRingp by looking up the name. */
1037: ob1 = KfindUserDictionary(KopString(ob1));
1038: if (ob1.tag != Sring) {
1039: errorCmo("cmoCmoToObject00(): your ring is not defined in the name space.");
1040: }
1041: CurrentRingp = KopRingp(ob1);
1042: }
1043: i = 2;
1044: while (i<size) {
1045: putoa(rob,i,cmoCmoToObject00(cb));
1046: i++;
1047: }
1048: CurrentRingp = oldringp;
1049: if (Lisplike) { printf("),"); fflush(stdout); }
1050: return(rob);
1051: }
1052:
1053: struct object cmoCmoToObject(struct object ob)
1054: {
1055: struct object rob;
1056: struct object ob0;
1057: struct cmoBuffer *cb;
1058: if (!(ob.tag == Sclass && ob.lc.ival == CMO)) {
1059: rob.tag = Snull;
1060: errorCmo("cmoCmoToObject(): the argument is not CMO.");
1061: return(rob);
1062: }
1063: cb = (struct cmoBuffer *) ob.rc.voidp;
1064: cmoGetIntFromBuf(CMOINIT,cb);
1065: if (cb->pos == 0) {
1066: /* null */
1067: rob.tag = Snull;
1068: return(rob);
1069: }
1070: rob = cmoCmoToObject00(cb);
1071: rob = cmoListToPoly(rob);
1072: if (DebugCMO) {
1073: fprintf(stderr,"cmoCmoToObject: ");
1074: printObject(rob,1,stderr);
1075: }
1076: return(rob);
1077: }
1078:
1079: struct object cmoListToPoly(struct object ob) {
1080: struct object ob0;
1081: struct object rob;
1082: int i,n;
1083: if (ob.tag == Sarray) {
1084: n = getoaSize(ob);
1085: if (n >= 1) {
1086: ob0 = getoa(ob,0);
1087: if (ob0.tag == CMO+CMO_DMS) {
1088: rob = KpoPOLY(cmoListToPOLY(ob)); /* not ToPoly, ToPOLY */
1089: }else{
1090: rob = newObjectArray(n);
1091: for (i=0; i<n; i++) {
1092: putoa(rob,i,cmoListToPoly(getoa(ob,i)));
1093: }
1094: }
1095: }else{
1096: rob = ob;
1097: }
1098: }else{
1099: rob = ob;
1100: }
1101: return(rob);
1102: }
1103:
1104: struct object cmoListToPoly2(struct object ob)
1105: {
1106: int size,i;
1107: struct object ob0,ob1;
1108: POLY f;
1109: /*
1110: printf("<<");printObject(ob,0,stdout); printf(">>\n"); fflush(stdout);
1111: */
1112: if (ob.tag != Sarray) {
1113: errorCmo("cmoListToPoly2(): the argument must be array.");
1114: }
1115: size = getoaSize(ob);
1116: f = POLYNULL;
1117: for (i=size-1; i>=0; i--) {
1118: ob1 = getoa(ob,i);
1119: if (ob1.tag == Spoly) {
1120: f = ppAdd(f,KopPOLY(ob1));
1121: }else{
1122: errorCmo("cmoListToPoly2(): format error.");
1123: }
1124: }
1125: return(KpoPOLY(f));
1126: }
1127:
1128: /*
1129: main() {
1130: int i;
1131: struct cmoBuffer *cb;
1132: printf("%d\n",sizeof(long int));
1133: for (i=0; i<300; i++) {
1134: cmoOutInt32(i);
1135: }
1136: dumpCmoBuf(cb=cmoOutputToBuf(CMOFLUSH,NULL,0));
1137: cmoGetIntFromBuf(CMOINIT,cb);
1138: for (i=0; i<300; i++) {
1139: printf("%5d",cmoGetIntFromBuf(CMOGET,cb));
1140: }
1141: putchar('\n');
1142: }
1143: */
1144:
1145: POLY cmoListToPOLY(struct object ob)
1146: {
1147: int size,i;
1148: struct object ob0,ob1;
1149: POLY f;
1150: /*
1151: printf("<<");printObject(ob,0,stdout); printf(">>\n"); fflush(stdout);
1152: */
1153: if (ob.tag != Sarray) {
1154: errorCmo("cmoListToPOLY(): the argument must be array.");
1155: }
1156: size = getoaSize(ob);
1157: if (size < 2) {
1158: errorCmo("cmoListToPOLY(): the first element of the array must be CMO-tag.");
1159: errorCmo("cmoListToPOLY(): the second element must be the ring definition.");
1160: }
1161: ob0 = getoa(ob,0);
1162: ob1 = getoa(ob,1); /* ring defintion. It is not used for now. */
1163: /* printObject(ob1,0,stdout); */
1164: switch(ob0.tag) {
1165: case (CMO+CMO_DMS):
1166: f = POLYNULL;
1167: for (i=size-1; i>=2; i--) {
1168: ob1 = getoa(ob,i);
1169: if (ob1.tag == Spoly) {
1170: f = ppAdd(f,KopPOLY(ob1));
1171: }else{
1172: f = ppAdd(f,cmoListToPOLY(ob1));
1173: }
1174: }
1175: return(f);
1176: break;
1177: default:
1178: errorCmo("cmoListToPoly(): unknown tag.");
1179: break;
1180: }
1181: }
1182:
1183:
1184: int Kan_PushBinary(int size,void *data)
1185: {
1186: struct cmoBuffer cb;
1187: struct object ob;
1188: cb.pos = size;
1189: cb.rpos = 0;
1190: cb.buf = data;
1191: cb.size = size;
1192: ob.tag = Sclass; ob.lc.ival = CMO;
1193: ob.rc.voidp = &cb;
1194: KSpush(cmoCmoToObject(ob));
1195: return(0);
1196: }
1197:
1198: void *Kan_PopBinary(int *sizep)
1199: {
1200: struct object ob;
1201: struct cmoBuffer *cb;
1202: ob = KSpop();
1203: ob = cmoObjectToCmo(ob);
1204: if (ob.tag == Sclass && ob.lc.ival == CMO) {
1205: cb = (struct cmoBuffer *) (ob.rc.voidp);
1206: *sizep = cb->pos;
1207: return(cb->buf);
1208: }
1209: return(NULL);
1210: }
1211:
1212:
1213:
1214:
1215:
1216: struct object cmoObjectFromStream(struct object obStream)
1217: {
1218: struct cmoBuffer cb;
1219: struct object rob;
1220: extern DebugCMO;
1221: if (obStream.tag != Sfile) {
1222: errorCmo("cmoObjectFromStream: Argument must be of type file.");
1223: }
1224: if (strcmp(obStream.lc.str,MAGIC2) != 0) {
1225: errorCmo("cmoObjectFromStream: Argument must be of type plugin/file2 buffered IO.");
1226: }
1227: rob = cmoObjectFromStream2((FILE2 *)obStream.rc.voidp);
1228: if (DebugCMO >= 2) {
1229: fprintf(stderr,"cmoObjectFromStream: ");
1230: printObject(rob,1,stderr);
1231: }
1232: return(rob);
1233: }
1234: struct object cmoObjectFromStream2(FILE2 *fp2)
1235: {
1236: struct cmoBuffer cb;
1237: struct object rob;
1238: cb.isStream=1; cb.fp = fp2;
1239: cmoGetIntFromBuf(CMOINITSTREAM,&cb);
1240: rob = cmoCmoToObject00(&cb);
1241: rob = cmoListToPoly(rob);
1242: if (cb.errorno) errorCmo("at cmoObjectFromStream2");
1243: if (DebugCMO) {
1244: fprintf(stderr,"cmoObjectFromStream2: ");
1245: printObject(rob,1,stderr);
1246: }
1247: return(rob);
1248: }
1249:
1250: struct object cmoObjectToStream(struct object ob, struct object obStream)
1251: {
1252: struct object rob;
1253: extern int DebugCMO;
1254: if (obStream.tag != Sfile) {
1255: errorCmo("cmoObjectToStream: Argument must be of type file.");
1256: }
1257: if (strcmp(obStream.lc.str,MAGIC2) != 0) {
1258: errorCmo("cmoObjectToStream: Argument must be of type plugin/file2 buffered IO.");
1259: }
1260: if (DebugCMO >= 2) {
1261: fprintf(stderr,"cmoObjectToStream: ");
1262: printObject(ob,1,stderr);
1263: }
1264: return(cmoObjectToStream2(ob,(FILE2 *)obStream.rc.voidp));
1265: }
1266:
1267: struct object cmoObjectToStream2(struct object ob, FILE2 *fp2)
1268: {
1269: struct object rob;
1270: cmoOutputToBuf(CMOINITSTREAM,(void *)fp2,0);
1271: if (DebugCMO) {
1272: fprintf(stderr,"cmoObjectToStream2: ");
1273: printObject(ob,1,stderr);
1274: }
1275: cmoObjectToCmo00(ob);
1276: fp2fflush(fp2);
1277: rob = KpoInteger(0);
1278: return(rob);
1279: }
1280:
1281: int Kan_pushCMOFromStream(FILE2 *fp)
1282: {
1283: struct object ob;
1284: struct object rob;
1285: ob.tag = Sfile; ob.rc.voidp = (void *)fp; ob.lc.str = MAGIC2;
1286: rob = cmoObjectFromStream(ob);
1287: KSpush(rob);
1288: return(0);
1289: }
1290:
1291: int Kan_popCMOToStream(FILE2 *fp,int serial)
1292: {
1293: struct object ob;
1294: struct object sob;
1295: sob.tag = Sfile; sob.rc.file = (void *)fp; sob.lc.str = MAGIC2;
1296: ob = Kpop();
1297: /*outfp2(fp);*/ /* outfp2 is for debugging. see develop/97feb.. 1999, 1/19*/
1298: if (!cmoCheckMathCap(ob, (struct object *)(fp->mathcapList))) {
1299: fprintf(stderr,"%s\n","Protection by mathcap. You cannot send this object to your peer.");
1300: ob = KnewErrorPacket(serial,-1,"cmoObjectToStream: protection by mathcap");
1301: cmoObjectToStream(ob,sob);
1302: return(-1);
1303: }
1304: cmoObjectToStream(ob,sob);
1305: return(0);
1306: }
1307:
1308: int Kan_setMathCapToStream(FILE2 *fp,struct object ob) {
1309: struct object *obp;
1310: obp = (struct object *)sGC_malloc(sizeof(struct object));
1311: *obp = ob;
1312: fp->mathcapList = (void *)obp;
1313: }
1314:
1315: /* It is declared in oxmisc2.h, too. */
1316: struct object newMathCap(struct mathCap *mathcap){
1317: struct object rob;
1318: struct object ob1;
1319: struct object ob2;
1320: struct object ob3;
1321: struct object obOx;
1322: struct object obSm;
1.4 takayama 1323: struct object ob3tmp;
1.1 maekawa 1324: struct object *obp;
1.4 takayama 1325: int i,j;
1.1 maekawa 1326: struct object mathinfo;
1327:
1328: rob = newObjectArray(3);
1329:
1330: mathinfo = *((struct object *) (mathcap->infop));
1331: ob1 = newObjectArray(getoaSize(mathinfo));
1332: for (i=0; i<getoaSize(mathinfo); i++) {
1333: putoa(ob1,i,getoa(mathinfo,i));
1334: }
1.4 takayama 1335: ob3 = newObjectArray(mathcap->oxSize);
1.1 maekawa 1336: for (i=0; i<mathcap->oxSize; i++) {
1.4 takayama 1337: ob3tmp = newObjectArray(2);
1338: putoa(ob3tmp,0,KpoInteger((mathcap->ox)[i]));
1339: ob2 = newObjectArray(mathcap->n);
1340: for (j=0; j<mathcap->n; j++) {
1341: putoa(ob2,j,KpoInteger((mathcap->cmo)[j]));
1342: }
1343: putoa(ob3tmp,1,ob2);
1344: putoa(ob3,i,ob3tmp);
1.1 maekawa 1345: }
1346:
1347: obSm = newObjectArray(mathcap->smSize);
1348: for (i=0; i<mathcap->smSize; i++) {
1349: putoa(obSm,i,KpoInteger((mathcap->sm)[i]));
1350: }
1351: putoa(rob,0,ob1); /* Version , name etc */
1352: putoa(rob,1,obSm); /* SM tags */
1353: putoa(rob,2,ob3); /* OX_DATA format, cmo types. */
1354: obp = (struct object *)sGC_malloc(sizeof(struct object));
1355: *obp = rob;
1356: return( KpoMathCap(obp) );
1357: }
1358:
1359: struct object KSmathCap(void)
1360: {
1361: struct mathCap *mathcap;
1362: mathcap = KSmathCapByStruct();
1363: return(newMathCap(mathcap));
1364: }
1365:
1366: void *KSmathCapByStruct(void)
1367: /* Return the math cap of kan/sm1 with cmo.c as a mathcap classObject*/
1368: {
1369: struct mathCap *mathcap;
1370: struct object ob;
1371: char *s1,*s2;
1372: struct object *mathinfo;
1373: char *sys;
1374: char *sysVersion;
1375: extern char *OxSystem; /* Example : ox_sm1.plain */
1376: extern char *OxSystemVersion; /* Example : 0.1 */
1377: mathcap = (struct mathCap *)sGC_malloc(sizeof(struct mathCap));
1378: mathinfo = sGC_malloc(sizeof(struct object));
1379:
1380: sys = (char *) sGC_malloc(sizeof(char)*(strlen(OxSystem)+strlen("Ox_system=")+2));
1381: strcpy(sys,"Ox_system="); strcat(sys,OxSystem);
1382: sysVersion =
1383: (char *) sGC_malloc(sizeof(char)*(strlen(OxSystemVersion)+strlen("Version=")+2));
1384: strcpy(sysVersion,"Version="); strcat(sysVersion,OxSystemVersion);
1385:
1386: ob = newObjectArray(4);
1387: putoa(ob,0,KpoInteger(OxVersion)); /* Open XM protocol Version */
1388: /* The rest entries must be strings. See oxmisc2.c oxSendMathcap */
1389: putoa(ob,1,KpoString(sys));
1390: putoa(ob,2,KpoString(sysVersion));
1391: s1 = getenv("HOSTTYPE");
1.5 ! takayama 1392: if (s1 == NULL) s1="unknown";
1.1 maekawa 1393: s2 = (char *)sGC_malloc(strlen(s1)+2+strlen("HOSTTYPE="));
1394: strcpy(s2,"HOSTTYPE=");
1395: strcat(s2,s1);
1396: putoa(ob,3,KpoString(s2));
1397:
1398: *mathinfo = ob;
1399: mathcap->infop = (void *) mathinfo;
1400:
1401: mathcap->cmo[0] = CMO_ERROR2;
1402: mathcap->cmo[1] = CMO_NULL;
1403: mathcap->cmo[2] = CMO_INT32;
1404: mathcap->cmo[3] = CMO_STRING;
1405: mathcap->cmo[4] = CMO_MATHCAP;
1406: mathcap->cmo[5] = CMO_LIST;
1407: mathcap->cmo[6] = CMO_MONOMIAL32;
1408: if (OxVersion >= 199907170) {
1409: mathcap->cmo[7] = CMO_ZZ;
1410: }else{
1411: mathcap->cmo[7] = CMO_ZZ_OLD;
1412: }
1413: mathcap->cmo[8] = CMO_ZERO;
1414: mathcap->cmo[9] = CMO_DMS;
1415: mathcap->cmo[10] = CMO_DMS_GENERIC;
1416: mathcap->cmo[11]= CMO_DMS_OF_N_VARIABLES;
1417: mathcap->cmo[12]= CMO_RING_BY_NAME;
1418: mathcap->cmo[13]= CMO_INT32COEFF;
1419: mathcap->cmo[14]= CMO_DISTRIBUTED_POLYNOMIAL;
1420: mathcap->cmo[15]= CMO_INDETERMINATE;
1421: mathcap->cmo[16]= CMO_TREE;
1422: mathcap->cmo[17]= CMO_RECURSIVE_POLYNOMIAL;
1423: mathcap->cmo[18]= CMO_POLYNOMIAL_IN_ONE_VARIABLE;
1424: mathcap->cmo[19]= CMO_64BIT_MACHINE_DOUBLE;
1425: mathcap->cmo[20]= CMO_ARRAY;
1426: mathcap->cmo[21]= CMO_RATIONAL;
1427:
1428: mathcap->n = 22 ; /* This is the number of cmo object. You can use
1429: cmo upto 1023. see mathcap.h */
1430:
1431: mathcap->ox[0] = OX_DATA;
1432: mathcap->oxSize = 1 ; /* This is the number of OX object. You can use
1433: OX upto 1023. see mathcap.h */
1434:
1435: mathcap->sm[0] = SM_popCMO;
1436: mathcap->sm[1] = SM_popString;
1437: mathcap->sm[2] = SM_mathcap;
1438: mathcap->sm[3] = SM_pops;
1439: mathcap->sm[4] = SM_setName;
1440: mathcap->sm[5] = SM_executeStringByLocalParser;
1441: mathcap->sm[6] = SM_executeFunction;
1442: mathcap->sm[7] = SM_shutdown;
1443: mathcap->sm[8] = SM_setMathCap;
1444: mathcap->sm[9] = SM_getsp;
1445: mathcap->sm[10] = SM_dupErrors;
1446: mathcap->smSize = 11;
1447:
1448: return((void *)mathcap);
1449: }
1450:
1451: int cmoOutRawInt(int k)
1452: {
1453: cmoint tmp[1];
1454: tmp[0] = htonl((cmoint ) k);
1455: cmoOutputToBuf(CMOPUT,tmp,sizeof(cmoint));
1456: }
1457:
1458: warningCmo(char *s) {
1459: fprintf(stderr,"Warning: plugin/cmo.c : %s\n",s);
1460: }
1461:
1462: errorCmo(char *s) {
1463: fprintf(stderr,"plugin/cmo.c : %s\n",s);
1464: errorKan1("%s\n","cmo fatal error. ox servers need SM_control_reset_connection.");
1465: /* ErrorPacket is automatically push on the ErrorStack.
1466: cf. var.sm1, [(ErrorStack)] system_variable */
1467: /* KSexecuteString(" error "); */
1468: }
1469:
1470: /* for dubugging. Should be comment out later. */
1471: int outfp2(FILE2 *fp2) {
1472: int i;
1473: printf("--------- outfp2 ---------\n"); fflush(stdout);
1474: /* if (checkfp2(fp2," f2pdumpBuf ") == -1) {
1475: return(-1);
1476: }*/
1477: printf("fd=%d\n",fp2->fd);
1478: printf("initialied=%d\n",fp2->initialized);
1479: printf("readpos=%d\n",fp2->readpos);
1480: printf("readsize=%d\n",fp2->readsize);
1481: printf("writepos=%d\n",fp2->writepos);
1482: printf("limit=%d\n",fp2->limit);
1483: for (i=0; i<fp2->readsize; i++) {
1484: printf("readBuf[%d]=%2x ",i,fp2->readBuf[i]);
1485: }
1486: for (i=0; i<fp2->writepos; i++) {
1487: printf("writeBuf[%d]=%2x ",i,fp2->writeBuf[i]);
1488: }
1489: printf("\n");
1490: printObject(*( (struct object *)fp2->mathcapList),0,stdout);
1491: printf("\n");
1492: return(0);
1493: }
1494:
1495: static char *translateReservedName(char *s) {
1496: /* We do not translate h and q */
1497: if (strcmp(s,"e_") == 0) { /* Should read the @@@E.symbol value */
1498: return("#65_");
1499: }else if (strcmp(s,"E") == 0) {
1500: return("#45");
1501: }else if (strcmp(s,"H") == 0) {
1502: return("#48");
1503: }else if (strcmp(s,"PAD")==0) {
1504: return("#4FAD");
1505: }else {
1506: return(NULL);
1507: }
1508: }
1509:
1510: struct object cmoTranslateVariable_inComming(struct object ob) {
1511: /* ob must be Sdollar, return value must be Sdollar. */
1512: /* Read a variable name from an other system,
1513: and translate the variable name into
1514: a suitable sm1 variable name. */
1515: char *s;
1516: char *t;
1517: int n, i, count;
1518: if (ob.tag != Sdollar) errorCmo("cmoTranslateVariable_inComming: the argument must be a string.");
1519: s = KopString(ob);
1520: t = translateReservedName(s);
1521: if (t != NULL) {
1522: if (Lisplike) printf("[%s==>%s]",s,t);
1523: return(KpoString(t));
1524: }
1525:
1526: n = strlen(s);
1527: for (i=count=0; i<n; i++,count++) {
1528: if (s[i] <= ' ' || s[i] == '#') {
1529: count += 2;
1530: }
1531: }
1532: if (n != count) {
1533: t = (char *) sGC_malloc(sizeof(char)*(count+2));
1534: if (t == NULL) errorCmo("No more memory.");
1535: for (i=count=0; i<n; i++) {
1536: if (s[i] <= ' ' || s[i] == '#') {
1537: t[count++] = '#';
1538: t[count++] = (s[i]/16 < 10? s[i]/16+'0': (s[i]/16-10)+'A');
1539: t[count++] = (s[i]%16 < 10? s[i]%16+'0': (s[i]%16-10)+'A');
1540: }else{
1541: t[count++] = s[i];
1542: }
1543: }
1544: t[count] = '\0';
1545: }else{
1546: t = s;
1547: }
1548: if (Lisplike) {
1549: printf("[%s==>%s]",s,t);
1550: }
1551: return(KpoString(t));
1552: }
1553:
1554: #define isHex_cmo(a) ((a >= '0' && a <='9') || (a>='A' && a <='F')?1:0)
1555: #define hexnum_cmo(a) (a>='A' && a <='F'? a-'A'+10 : a-'0')
1556: struct object cmoTranslateVariable_outGoing(struct object ob) {
1557: /* ob must be Sdollar, return value must be Sdollar. */
1558: char *s, *t;
1559: int i,j,n;
1560: int p;
1561: if (ob.tag != Sdollar) errorCmo("cmoTranslateVariable_inComming: the argument must be a string.");
1562: s = KopString(ob);
1563: n = strlen(s);
1564: for (i=0; i<n; i++) {
1565: if (i < n-2 && s[i] == '#' && isHex_cmo(s[i+1]) && isHex_cmo(s[i+2])) {
1566: t = (char *) sGC_malloc(sizeof(char)*(n+2));
1567: if (t == NULL) errorCmo("No more memory.");
1568: break;
1569: }
1570: if (i== n-1) {
1571: return(KpoString(s));
1572: }
1573: }
1574: for (i=j=0; i<n; i++) {
1575: if (i < n-2 && s[i] == '#' && isHex_cmo(s[i+1]) && isHex_cmo(s[i+2])) {
1576: p = (hexnum_cmo(s[i+1]))*16+hexnum_cmo(s[i+2]);
1577: t[j++] = p; i += 2;
1578: }else{
1579: t[j++] = s[i];
1580: }
1581: }
1582: t[j] = '\0';
1583: if (Lisplike) {
1584: printf("[%s-->%s]",s,t);
1585: }
1586: return(KpoString(t));
1587: }
1588:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>