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