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