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