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