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