Annotation of OpenXM/src/kan96xx/plugin/oxmisc2.c, Revision 1.6
1.6 ! takayama 1: /* $OpenXM: OpenXM/src/kan96xx/plugin/oxmisc2.c,v 1.5 2000/02/02 03:30:48 takayama Exp $ */
1.1 maekawa 2: #include <stdio.h>
3: #include "ox_kan.h"
4: #include "oxmisc2.h" /* This file requires sm1 object description. */
5: #include "cmo.h"
6: extern FILE *MyErrorOut;
1.6 ! takayama 7: #define SET_MYERROROUT { if (MyErrorOut == NULL) MyErrorOut=stdout; }
! 8: /* It is also defined in oxmisc.c */
! 9:
1.1 maekawa 10: extern int SerialOX; /* defined in SerialOX */
11:
12: extern int OxVersion;
13:
14: int DebugMathCap = 1;
15:
16:
17:
18: int oxGet(oxclientp client, struct object *op,int *isObj)
19: /* This method should be synchronized. */
20: /* oxGet is a function for client. */
21: {
22: int ans;
23: ox_stream os;
24: int m;
25: struct object rob;
26: int sss; /* Serial number of the recieved packet. */
27: *isObj = 0;
28: op->tag = Snull;
29: os = client->datafp2;
30: switch(client->dstate) {
31: case DSTATE_ANY:
32: m = oxGetOXheader(os,&sss);
33: switch(m) {
34: case OX_DATA:
35: client->dstate = DSTATE_WAIT_OX_DATA;
36: return(oxGet(client,op,isObj));
37: case OX_SYNC_BALL:
38: client->dstate = DSTATE_ANY;
39: return(OX_SYNC_BALL);
40: default:
41: errorOxmisc2("oxGet: cannot handle this tag.\n");
42: client->dstate = DSTATE_ERROR;
43: return(-1);
44: }
45: break;
46: case DSTATE_FIRST_SYNC: /* waiting the first sync ball */
47: /* I need to clear the buffer?? */
48: oxWaitSyncBall(os);
49: client->dstate = DSTATE_ANY;
50: oxSendSyncBall(os);
51: return(OX_SYNC_BALL);
52: break;
53: case DSTATE_WAIT_OX_DATA: /* waiting a cmo data. */
54: *op = cmoObjectFromStream2(client->datafp2);
55: client->dstate = DSTATE_ANY;
56: *isObj = 1;
57: return(0);
58: break;
59: case DSTATE_ERROR:
60: client->dstate = DSTATE_ERROR;
61: errorOxmisc2("oxGet: dstate == DSTATE_ERROR (error state)\n");
62: return(-1);
63: default:
64: client->dstate = DSTATE_ERROR;
65: errorOxmisc2("oxGet: Unknown state number.");
66: }
67:
68: return(-1);
69: }
70:
71: int oxGetFromControl(oxclientp client)
72: {
73: int ans = -1;
74: if (client->cstate != -1) {
75: ans = oxGetResultOfControlInt32(client->controlfd);
76: if (ans != -1) { client->cstate = 0; }
77: else {client->cstate = -1; }
78: }
79: return(ans);
80: }
81:
82: int oxReq(oxclientp client,int func,struct object ob)
83: {
84: struct object *ob1p;
1.6 ! takayama 85: SET_MYERROROUT;
1.1 maekawa 86: /* request to the control channel */
87: if (func == SM_control_reset_connection ||
88: func == SM_control_kill) {
89: switch(func) {
90: case SM_control_reset_connection:
91: oxReqControlResetConnection(client->controlfd);
92: client->cstate = 1;
93: client->dstate = DSTATE_FIRST_SYNC;
94: break;
95: case SM_control_kill:
96: oxReqControlKill(client->controlfd);
97: client->cstate = 0;
98: client->dstate = DSTATE_ANY;
99: break;
100: }
101: fflush(NULL);
102: return(0);
103: }
104:
105: /* request to the data channel */
106: if (client->dstate != DSTATE_ANY) {
107: errorOxmisc2("oxReq: client->dstate != DSTATE_ANY, data channel is not ready to send data.\n");
108: return(-1);
109: }
110: switch(func) {
111: case SM_DUMMY_sendcmo:
112: if (!cmoCheckMathCap(ob,(struct object *)client->mathcapObjp)) {
113: errorOxmisc2("oxReq: your peer does not understand this cmo.\n");
114: return(-1);
115: }
116: oxSendOXheader(client->datafp2,OX_DATA,SerialOX++);
117: cmoObjectToStream2(ob,client->datafp2);
118: client->dstate = DSTATE_ANY;
119: break;
120: case SM_sync_ball:
121: oxSendSyncBall(client->datafp2);
122: client->dstate = DSTATE_ANY; /* We do not expect the sync ball.*/
123: client->cstate = 0; /* clear the cstate */
124: break;
125: case SM_popCMO:
126: oxReqPopCMO(client->datafp2);
127: client->dstate = DSTATE_ANY;
128: break;
129: case SM_mathcap:
130: oxReqMathCap(client->datafp2);
131: client->dstate = DSTATE_ANY;
132: break;
133: case SM_setMathCap:
134: /* ob = [(mathcap-obj) [[version num, system name] [sm tags]
135: ob1 smtags
1.4 takayama 136: oxtags [[ox numbers, [cmo numbers]]]
1.1 maekawa 137: ob3 ob2 */
1.4 takayama 138: /* oxtags [[OX_DATA, [cmo numbers]],[OX_DATA_LOCAL,[opt]],...]*/
1.1 maekawa 139: {
140: struct object ob1;
141: struct object ob2;
142: struct object ob3;
1.4 takayama 143: struct object obm;
1.1 maekawa 144: struct object smtags;
1.4 takayama 145: struct object oxtags;
146: struct object ox;
1.1 maekawa 147: int n,i;
148: struct mathCap mathcap;
149:
150: if (strcmp(KopString(getoa(ob,0)),"mathcap-object") != 0) {
151: errorOxmisc2("data format error in oxReqSetMathCap");
152: client->dstate = DSTATE_ANY;
153: break;
154: }
1.4 takayama 155: obm = getoa(ob,1);
156: ob1 = getoa(obm,0);
157: smtags = getoa(obm,1);
158: oxtags = getoa(obm,2);
159: if (smtags.tag != Sarray || oxtags.tag != Sarray) {
160: errorOxmisc2("data format error in oxReqSetMathCap");
161: }
1.1 maekawa 162: ob1p = (struct object *) sGC_malloc(sizeof(struct object));
163: *ob1p = ob1;
164: mathcap.infop = ob1p;
1.4 takayama 165:
166: n = getoaSize(oxtags);
1.1 maekawa 167: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
168: mathcap.oxSize = n;
169: for (i=0; i<n; i++) {
1.4 takayama 170: ox = getoa(oxtags,i);
171: if (ox.tag != Sarray) {
172: errorOxmisc2("Data format error of the third argument of mathcap.");
173: }
174: mathcap.ox[i] = KopInteger(getoa(ox,0));
175: if (mathcap.ox[i] == OX_DATA) {
176: if (getoaSize(ox) < 2) {
177: errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
178: }
179: ob2 = getoa(ox,1);
180: if (ob2.tag != Sarray) {
181: errorOxmisc2("Data format error in an entry of the third argument of mathcap.");
182: }
183: mathcap.n = getoaSize(ob2);
184: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
185: for (i=0; i<mathcap.n; i++) {
186: mathcap.cmo[i] = KopInteger(getoa(ob2,i));
187: }
188: }
1.1 maekawa 189: }
190:
191: n = getoaSize(smtags);
192: if (n >= MATHCAP_SIZE) errorOxmisc2("Too big mathcap of your peer.");
193: mathcap.smSize = n;
194: for (i=0; i<n; i++) {
195: mathcap.sm[i] = KopInteger(getoa(smtags,i));
196: }
197:
198: oxReqSetMathCap(client->datafp2,&mathcap);
199: client->dstate = DSTATE_ANY;
200: }
201: break;
202: case SM_pops:
203: if (ob.tag != Sinteger) {
204: errorOxmisc2("SM_pops : the argument must be an integer.");
205: return(-1);
206: }
207: oxReqPops(client->datafp2, KopInteger(ob));
208: client->dstate = DSTATE_ANY;
209: break;
210: case SM_executeStringByLocalParser:
211: if (ob.tag != Sdollar) {
212: errorOxmisc2("SM_executeStringByLocalParser : the argument must be a string.");
213: return(-1);
214: }
215: oxReqExecuteStringByLocalParser(client->datafp2,KopString(ob));
216: client->dstate = DSTATE_ANY;
217: break;
218: case SM_executeFunction:
219: if (ob.tag != Sdollar) {
220: errorOxmisc2("SM_executeFunction : the argument must be a string.");
221: return(-1);
222: }
223: oxReqExecuteFunction(client->datafp2,KopString(ob));
224: client->dstate = DSTATE_ANY;
225: break;
226: case SM_popString:
227: oxReqPopString(client->datafp2);
228: client->dstate = DSTATE_ANY;
229: break;
230: case SM_evalName:
231: if (ob.tag != Sdollar) {
232: errorOxmisc2("SM_evalName : the argument must be a string.");
233: return(-1);
234: }
235: oxReqEvalName(client->datafp2,KopString(ob));
236: client->dstate = DSTATE_ANY;
237: break;
238: case SM_setName:
239: if (ob.tag != Sdollar) {
240: errorOxmisc2("SM_setName : the argument must be a string.");
241: return(-1);
242: }
243: oxReqSetName(client->datafp2,KopString(ob));
244: client->dstate = DSTATE_ANY;
245: break;
246: case SM_getsp:
247: oxReqSingleOperand(client->datafp2,SM_getsp);
248: client->dstate = DSTATE_ANY;
249: break;
250: case SM_dupErrors:
251: oxReqSingleOperand(client->datafp2,SM_dupErrors);
252: client->dstate = DSTATE_ANY;
253: break;
254: default:
255: fprintf(MyErrorOut,"func=%d ",func);
256: errorOxmisc2("This function is not implemented.");
257: break;
258: }
259: fp2fflush(client->datafp2);
260: return(0);
261: }
262:
263: struct object KoxCreateClient(struct object ip,
264: struct object portStream,
265: struct object portControl)
266: {
267: struct object rob;
268: oxclientp client;
269: rob.tag = Snull;
270: if (ip.tag != Sdollar) {
271: errorOxmisc2("KoxCreateClient(): The first argument must be a hostname given by a string.");
272: return(rob);
273: }
274: if (portStream.tag == Sdollar) {
275: client = oxCreateClientFile(KopString(ip),KopString(portStream),
276: "/dev/null","w");
277: if (client == NULL) {
278: errorOxmisc2("KoxCreateClient(): Open error.");
279: return(rob);
280: }
281: rob = newObjectArray(N_OF_CLIENT_FIELDS);
282: oxClientToObject(client,rob);
283: return(rob);
284: }
285:
286: if (portStream.tag != Sinteger) {
287: errorOxmisc2("KoxCreateClient(): The second argument must be a port number given in an integer.");
288: return(rob);
289: }
290: if (portControl.tag != Sinteger) {
291: errorOxmisc2("KoxCreateClient(): The third argument must be a port number given in an integer.");
292: return(rob);
293: }
294: client = oxCreateClient(KopString(ip),KopInteger(portStream),KopInteger(portControl));
295: if (client == NULL) {
296: errorOxmisc2("KoxCreateClient(): Open error.");
297: return(rob);
298: }
299: rob = newObjectArray(N_OF_CLIENT_FIELDS);
300: oxClientToObject(client,rob);
301: return(rob);
302: }
303:
304: static int isItClientObject(struct object ob)
305: {
306: int size,i;
307: struct object ee[N_OF_CLIENT_FIELDS];
308: if (ob.tag != Sarray) {
309: return(0);
310: }
311: size = getoaSize(ob);
312: if (size != N_OF_CLIENT_FIELDS) return(0);
313: for (i=0; i<N_OF_CLIENT_FIELDS; i++) {
314: ee[i] = getoa(ob,i);
315: }
316:
317: if (ee[0].tag != Sdollar) return(0);
318: if (strcmp(KopString(ee[0]),"client")!=0) return(0);
319:
320: if (ee[1].tag != Sfile) return(0);
321: if (strcmp((ee[1]).lc.str,MAGIC2) != 0) return(0);
322:
323: for (i=2; i<=9; i++) {
324: if (ee[i].tag != Sinteger) return(0);
325: }
326: return(1);
327: }
328:
329:
330: struct object KoxIsThereErrorClient(struct object ob)
331: {
332: struct object rob;
333: int ans;
334: int size;
335: oxclient cc;
336: rob.tag = Snull;
337: if (!isItClientObject(ob)) {
338: errorOxmisc2("KoxIsThereErrorClient(): the argument must be an array for client object.");
339: return(rob);
340: }
341: if (oxObjectToClient(ob,&cc) == -1) return(KpoInteger(-1));
342: ans = oxIsThereErrorClient(&cc);
343: return(KpoInteger(ans));
344: }
345:
346: int oxClientToObject(oxclientp client,struct object rob)
347: {
348: struct object ob;
349: if (client == NULL) return;
350: /* rob = newObjectArray(N_OF_CLIENT_FIELDS); */
351: if (rob.tag != Sarray) {
352: errorOxmisc2("oxClientToObject(): the second argument must be an array.");
353: return(-1);
354: }
355: if (getoaSize(rob) != N_OF_CLIENT_FIELDS) {
356: errorOxmisc2("oxClientToObject(): the second argument must be an array of size N_OF_CLIENT_FIELDS.");
357: return(-1);
358: }
359:
360: ob = KpoString("client");
361: putoa(rob,0,ob);
362:
363: ob.tag = Sfile; ob.lc.str = MAGIC2; ob.rc.voidp = (void *)(client->datafp2);
364: putoa(rob,1,ob);
365:
366: putoa(rob,2,KpoInteger(client->dataport));
367: putoa(rob,3,KpoInteger(client->controlfd));
368: putoa(rob,4,KpoInteger(client->controlport));
369: putoa(rob,5,KpoInteger(client->dstate));
370: putoa(rob,6,KpoInteger(client->cstate));
371: putoa(rob,7,KpoInteger(client->humanio));
372: putoa(rob,8,KpoInteger(client->id));
373: putoa(rob,9,KpoInteger(client->type));
374: if (client->mathcapObjp == NULL) {
375: putoa(rob,10,NullObject);
376: }else{
377: putoa(rob,10,*((struct object *)(client->mathcapObjp)));
378: }
379: putoa(rob,11,KpoInteger(client->engineByteOrder));
380: putoa(rob,12,KpoInteger(client->controlByteOrder));
381: return(0);
382: }
383:
384: int oxObjectToClient(struct object ob,oxclientp cp)
385: {
386: struct object ob1;
387: struct object *obp;
388: if (cp == NULL) {
389: errorOxmisc2("oxObjectToClient(): the second argument is NULL");
390: return(-1);
391: }
392: if (!isItClientObject(ob)) {
393: errorOxmisc2("oxObjectToClient(): the first argument is not client object.");
394: oxInitClient(cp);
395: return(-1);
396: }
397:
398: ob1 = getoa(ob,1);
399: cp->datafp2 = (FILE2 *) (ob1.rc.voidp);
400:
401: ob1 = getoa(ob,2);
402: cp->dataport = KopInteger(ob1);
403:
404: ob1 = getoa(ob,3);
405: cp->controlfd = KopInteger(ob1);
406:
407: ob1 = getoa(ob,4);
408: cp->controlport = KopInteger(ob1);
409:
410: ob1 = getoa(ob,5);
411: cp->dstate = KopInteger(ob1);
412:
413: ob1 = getoa(ob,6);
414: cp->cstate = KopInteger(ob1);
415:
416: ob1 = getoa(ob,7);
417: cp->humanio = KopInteger(ob1);
418:
419: ob1 = getoa(ob,8);
420: cp->id = KopInteger(ob1);
421:
422: ob1 = getoa(ob,9);
423: cp->type = KopInteger(ob1);
424:
425: ob1 = getoa(ob,10);
426: if (ob1.tag == Snull) {
427: cp->mathcapObjp = NULL;
428: }else{
429: obp = (struct object *) sGC_malloc(sizeof(struct object));
430: *obp = ob1;
431: cp->mathcapObjp = (void *)obp;
432: }
433: ob1 = getoa(ob,11);
434: cp->engineByteOrder = KopInteger(ob1);
435: ob1 = getoa(ob,12);
436: cp->controlByteOrder = KopInteger(ob1);
437:
438:
439: return(0);
440: }
441:
442: struct object KoxReq(struct object client,
443: struct object func,
444: struct object ob1)
445: {
446: int ans;
447: static oxclientp cc1 = NULL;
448: struct object rob;
449: rob.tag = Snull;
450: if (cc1 == NULL) {
451: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
452: if (cc1 == NULL) {
453: errorOxmisc2("KoxReq(): no more memory.");
454: return(rob);
455: }
456: oxInitClient(cc1);
457: }
458:
459: if (oxObjectToClient(client,cc1) == -1) return(rob);
460: if (cc1 == NULL) {
461: errorOxmisc2("KoxReq(): the first argument must be a client object.");
462: return(rob);
463: }
464: if (func.tag != Sinteger) {
465: errorOxmisc2("KoxReq(): the second argument must be an integer.");
466: return(rob);
467: }
468: ans = oxReq(cc1,KopInteger(func),ob1);
469: /* synchronize cc1 and client. */
470: oxClientToObject(cc1,client);
471:
472: return(KpoInteger(ans));
473: }
474:
475: struct object KoxGet(struct object client)
476: {
477: int ans,k;
478: static oxclientp cc1 = NULL;
479: struct object rob;
480: rob.tag = Snull;
481: if (cc1 == NULL) {
482: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
483: if (cc1 == NULL) {
484: errorOxmisc2("KoxGet(): no more memory.");
485: return(rob);
486: }
487: oxInitClient(cc1);
488: }
489:
490: if (oxObjectToClient(client,cc1) == -1) return(rob);
491: if (cc1 == NULL) {
492: errorOxmisc2("KoxGet(): the first argument must be a client object.");
493: return(rob);
494: }
495:
496: ans = oxGet(cc1,&rob,&k);
497: /* synchronize cc1 and client. */
498: oxClientToObject(cc1,client);
499:
500: if (k) return(rob);
501: else {
502: return(KpoInteger(ans));
503: }
504: }
505:
506: struct object KoxGetFromControl(struct object client)
507: {
508: int ans;
509: static oxclientp cc1 = NULL;
510: struct object rob;
511: rob.tag = Snull;
512: if (cc1 == NULL) {
513: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
514: if (cc1 == NULL) {
515: errorOxmisc2("KoxGetFromControl(): no more memory.");
516: return(rob);
517: }
518: oxInitClient(cc1);
519: }
520:
521: if (oxObjectToClient(client,cc1) == -1) return(rob);
522: if (cc1 == NULL) {
523: errorOxmisc2("KoxGetFromControl(): the first argument must be a client object.");
524: return(rob);
525: }
526:
527: ans = oxGetFromControl(cc1);
528: /* synchronize cc1 and client. */
529: oxClientToObject(cc1,client);
530:
531: return(KpoInteger(ans));
532: }
533:
534: struct object KoxMultiSelect(struct object oclients,struct object t)
535: {
536: static int first = 1;
537: static int csize = 0;
538: static oxclientp *clients = NULL;
539: oxclientp cc1;
540: struct object rob;
541: int i;
542: int tt;
543: struct object ob1;
544: struct object ob2;
545: struct object ob0;
546: int size;
547: int ans;
548: int dataready[1024];
549: int controlready[1024];
550:
551: rob.tag = Snull;
552: if (oclients.tag != Sarray) {
553: errorOxmisc2("KoxMultiSelect(): the first argument must be an array.");
554: return(rob);
555: }
556: size = getoaSize(oclients);
557: if (first) {
558: first = 0; csize = size;
559: clients = (oxclientp *)mymalloc(sizeof(oxclientp)*(size+1));
560: if (clients == NULL) {
561: errorOxmisc2("KoxMultiSelect(): no more memory.");
562: return(rob);
563: }
564: for (i=0; i<size; i++) {
565: clients[i] = (oxclientp) mymalloc(sizeof(oxclient));
566: if (clients[i] == NULL) {
567: errorOxmisc2("KoxMultiSelect(): no more memory.");
568: return(rob);
569: }
570: oxInitClient(clients[i]);
571: }
572: }
573: if (csize < size) {
574: first = 1;
575: return(KoxMultiSelect(oclients,t));
576: }
577: for (i=0; i<size; i++) {
578: ob0 = getoa(oclients,i);
579: if (oxObjectToClient(ob0,clients[i]) == -1) return(rob);
580: }
581: if (t.tag != Sinteger) {
582: errorOxmisc2("KoxMultiSelect(): the second argument must be an integer.");
583: }
584: tt = KopInteger(t);
585: ans = oxclientMultiSelect(clients,dataready,controlready,size,tt);
586: /* synchronize oclients and clients. */
587: for (i=0; i<size; i++) {
588: ob0 = getoa(oclients,i);
589: oxClientToObject(clients[i],ob0);
590: putoa(oclients,i,ob0);
591: }
592: rob = newObjectArray(3);
593: putoa(rob,0,KpoInteger(ans));
594: ob1 = newObjectArray(size);
595: ob2 = newObjectArray(size);
596: for (i=0; i<size; i++) {
597: putoa(ob1,i,KpoInteger(dataready[i]));
598: putoa(ob2,i,KpoInteger(controlready[i]));
599: }
600: putoa(rob,1,ob1);
601: putoa(rob,2,ob2);
602: return(rob);
603: }
604:
605: struct object KoxWatch(struct object client,struct object f)
606: /* f is not used for now. It should be log file. */
607: {
608: int ans,k;
609: static oxclientp cc1 = NULL;
610: struct object rob;
1.3 takayama 611: extern int WatchStream;
1.1 maekawa 612: rob.tag = Snull;
1.3 takayama 613: if (client.tag == Sinteger) {
614: if (KopInteger(client)) {
615: WatchStream = 1;
616: }else{
617: WatchStream = 0;
618: }
619: return;
620: }
1.1 maekawa 621: if (cc1 == NULL) {
622: cc1 = (oxclientp) mymalloc(sizeof(oxclient));
623: if (cc1 == NULL) {
624: errorOxmisc2("KoxWatch(): no more memory.");
625: return(rob);
626: }
627: oxInitClient(cc1);
628: }
629:
630: if (oxObjectToClient(client,cc1) == -1) return(rob);
631: if (cc1 == NULL) {
632: errorOxmisc2("KoxWatch(): the first argument must be a client object.");
633: return(rob);
634: }
635:
636: k = fp2watch(cc1->datafp2,stdout);
637: /* synchronize cc1 and client. */
638: oxClientToObject(cc1,client);
639:
640: return(KpoInteger(ans));
641: }
642:
643:
644: struct object KoxCloseClient(struct object client) {
645: oxclientp cc1 = NULL;
646: oxclient cc;
647: struct object rob;
648: rob.tag = Snull;
649: cc1 = &cc;
650: if (oxObjectToClient(client,cc1) == -1) return(rob);
651: if (cc1 == NULL) {
652: errorOxmisc2("KoxCloseClient(): the first argument must be a client object.");
653: return(rob);
654: }
655:
656: fp2fflush(cc1->datafp2);
657: if (cc1->humanio) {
658: /* Do not close the file. */
659: return(KpoInteger(0));
660: }
661: switch (cc1->type) {
662: case CLIENT_SOCKET:
663: fp2fclose(cc1->datafp2);
664: close(cc1->controlfd);
665: break;
666: case CLIENT_FILE:
667: fp2fclose(cc1->datafp2);
668: close(cc1->controlfd);
669: break;
670: default:
671: errorOxmisc2("Unknown client->type\n");
672: break;
673: }
674: return(KpoInteger(0));
675:
676: }
677:
678: static int cmoCheck00(struct object obj,int cmo[], int n) {
679: int i,j,m;
680: int ttt;
681: #define CHECK00_N 4098 /* look up stackm.h and kclass.h */
682: static int typeTrans[CHECK00_N];
683: static int init = 0;
1.5 takayama 684: /* if n == 0, report the cmo tag of the object obj.
685: If it cannot be translated to cmo, then return -1. */
686:
1.1 maekawa 687: if (!init) {
688: for (i=0; i<CHECK00_N; i++) {
689: typeTrans[i] = 0; /* unknown cmo number */
690: }
691: typeTrans[Snull] = CMO_NULL;
692: typeTrans[Sinteger] = CMO_INT32;
693: typeTrans[Sdollar] = CMO_STRING;
694: if (OxVersion >= 199907170) {
695: typeTrans[SuniversalNumber] = CMO_ZZ;
696: }else{
697: typeTrans[SuniversalNumber] = CMO_ZZ_OLD;
698: }
699: typeTrans[Sarray] = CMO_LIST;
700: /* typeTrans[Spoly] = CMO_DMS; */
701: typeTrans[Spoly] = CMO_DISTRIBUTED_POLYNOMIAL;
702: typeTrans[Sdouble] = CMO_64BIT_MACHINE_DOUBLE;
703: typeTrans[CLASSNAME_ERROR_PACKET] = CMO_ERROR2;
704: typeTrans[CLASSNAME_mathcap] = CMO_MATHCAP;
705: typeTrans[CLASSNAME_indeterminate] = CMO_INDETERMINATE;
706: typeTrans[CLASSNAME_tree] = CMO_TREE;
707: typeTrans[CLASSNAME_recursivePolynomial] = CMO_RECURSIVE_POLYNOMIAL;
708: typeTrans[CLASSNAME_polynomialInOneVariable] = CMO_POLYNOMIAL_IN_ONE_VARIABLE;
709: init = 1;
710: }
711: ttt = typeTrans[obj.tag];
712: if (obj.tag == Sclass) {
713: ttt = typeTrans[ectag(obj)];
714: }
1.5 takayama 715: /* Only report the cmo tag. */
716: if (n == 0) {
717: if (ttt == 0) return(-1);
718: else return(ttt);
719: }
1.1 maekawa 720:
721: for (i=0; i<n; i++) {
722: if (ttt == cmo[i]) {
723: if (ttt != CMO_LIST) return(1);
724: else {
725: m = getoaSize(obj);
726: for (j=0; j<m; j++) {
727: if (!cmoCheck00(getoa(obj,j),cmo,n)) return(0);
728: }
729: return(1);
730: }
731: }
732: }
733: if (DebugMathCap) {
734: if (DebugMathCap && 1) {
735: fprintf(stderr,"Type translation table (internal object tag --> CMO tag)\n");
736: for (i=0; i<20; i++) {
737: printf("%d ", typeTrans[i]);
738: }
739: printf("\n");
740: }
741: fprintf(stderr,"The type of the argument object in sm1 is %d.\n",obj.tag);
742: fprintf(stderr,"The type of the argument object in CMO is %d.\n",ttt);
743: fprintf(stderr,"Available CMO tags in mathcap= %d elements : [ ",n);
744: for (i=0; i<n; i++) {
745: fprintf(stderr," %d ",cmo[i]);
746: }
747: fprintf(stderr," ] \n");
748: }
749: return(0);
750: }
751:
752: int cmoCheckMathCap(struct object obj, struct object *obp)
753: {
754: struct object mathcap;
755: struct object cmolist;
1.2 takayama 756: struct object mathcapMain;
1.4 takayama 757: struct object mathcapThird;
758: struct object ox;
759: struct object oxtag;
1.2 takayama 760: struct object ob0;
1.4 takayama 761: int oxsize;
1.1 maekawa 762: int n;
763: int i;
764: #define CMO_CHECK_MATH_CAP_LIST_SIZE 1024
765: int cmo[CMO_CHECK_MATH_CAP_LIST_SIZE];
766: if (obp == NULL) return(1);
1.2 takayama 767: /* printObject(*obp,0,stderr); for debug*/
1.1 maekawa 768: if (obp->tag != Sarray) {
769: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
770: printObject(*obp,0,stderr);
771: fprintf(stderr,"\n");
772: errorOxmisc2("cmoCheckMathCap: format error in the client->mathcapObjp field.\n");
773: }
774: mathcap = *obp;
1.2 takayama 775: /* Example of mathcap
776: [ $mathcap-object$ ,
777: [ [ 199909080 , $Ox_system=ox_sm1.plain$ , $Version=2.991106$ ,
778: $HOSTTYPE=i386$ ] ,
779: [ 262 , 263 , 264 , 265 , 266 , 268 , 269 , 272 , 273 , 275 ,
780: 276 ] ,
1.4 takayama 781: [ [ 514 , [ 2130706434 , 1 , 2 , 4 , 5 , 17 , 19 , 20 , 22 , 23 , 24 , 25 , 26 , 30 , 31 , 60 , 61 , 27 , 33 , 40 , 16 , 34 ] ] ] ] ]
1.2 takayama 782: */
783:
1.1 maekawa 784: n = getoaSize(mathcap);
785: if (n < 2) {
786: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
787: printObject(*obp,0,stderr);
788: fprintf(stderr,"\n");
789: errorOxmisc2("cmoCheckMathCap: length of mathcap is wrong in the client->mathcapObjp field.\n");
790: }
1.2 takayama 791: ob0 = getoa(mathcap,0);
792: if (ob0.tag != Sdollar) {
793: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
794: printObject(*obp,0,stderr);
795: fprintf(stderr,"\n");
796: errorOxmisc2("cmoCheckMathCap: The first field must be the string mathcap-object.\n");
797: }
798: if (strcmp(KopString(ob0),"mathcap-object") != 0) {
799: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
800: printObject(*obp,0,stderr);
801: fprintf(stderr,"\n");
802: errorOxmisc2("cmoCheckMathCap: The mathcap must be of the form [(mathcap-object) [...]]\n");
803: }
804:
1.1 maekawa 805: /* I should check
1.2 takayama 806: getoa(getoa(mathcap,1),2)
1.1 maekawa 807: contains OX_DATA.
808: It has not yet implemented.
809: */
1.2 takayama 810: mathcapMain = getoa(mathcap,1);
811: if (mathcapMain.tag != Sarray) {
812: fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
813: printObject(mathcapMain,0,stderr);
814: fprintf(stderr,"\n");
815: errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array.\n");
816: }
817: if (getoaSize(mathcapMain) < 3) {
818: fprintf(stderr,"cmoCheckMathCap: mathcap[1] is \n");
819: printObject(mathcapMain,0,stderr);
820: fprintf(stderr,"\n");
821: errorOxmisc2("cmoCheckMathCap: format error in the (client->mathcapObjp)[1] field. It should be an array of which length is more than 2.\n");
822: }
1.4 takayama 823: mathcapThird = getoa(mathcapMain,2);
824: oxsize = getoaSize(mathcapThird);
825: for (i=0; i<oxsize; i++) {
826: ox = getoa(mathcapThird,i);
827: if (ox.tag != Sarray) {
828: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
829: printObject(*obp,0,stderr);
830: fprintf(stderr,"\n");
831: errorOxmisc2("cmoCheckMathCap: the third element of mathcap is a list of lists.");
832: }
833: if (getoaSize(ox) != 0) {
834: oxtag = getoa(ox,0);
835: if (oxtag.tag != Sinteger) {
836: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
837: printObject(*obp,0,stderr);
838: fprintf(stderr,"\n");
839: errorOxmisc2("cmoCheckMathCap: the third element of mathcap must be [OX_DATA_xxx, [ ]].");
840: }
841: if (KopInteger(oxtag) == OX_DATA) {
842: if (getoaSize(ox) > 1) {
843: cmolist = getoa(ox,1);
844: if (cmolist.tag != Sarray) {
845: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
846: printObject(*obp,0,stderr);
847: fprintf(stderr,"\n");
848: errorOxmisc2("cmoCheckMathCap: mathcap[1] must be an array of integers.\n");
849: }
850: n = getoaSize(cmolist);
851: if (n > CMO_CHECK_MATH_CAP_LIST_SIZE) {
852: errorOxmisc2("cmoCheckMathCap: Too big cmo list.\n");
853: }
854: for (i=0; i<n; i++) {
855: cmo[i] = KopInteger(getoa(cmolist,i));
856: }
857: }else{
858: fprintf(stderr,"cmoCheckMathCap: the mathcap obj is \n");
859: printObject(*obp,0,stderr);
860: fprintf(stderr,"\nox=");
861: printObject(ox,0,stderr);
862: errorOxmisc2("cmoCheckMathCap: [OX_DATA, cmolist]");
863: }
864: }
865: }
1.1 maekawa 866: }
867: return(cmoCheck00(obj,cmo,n));
868: }
869:
870:
871: struct object KoxGenPortFile(void) {
872: struct object ob;
873: ob = KpoString(oxGenPortFile());
874: return(ob);
875: }
876: void KoxRemovePortFile(void) {
877: oxRemovePortFile();
878: }
879:
880: void oxPushMathCap(struct mathCap *mathcap)
881: {
882: struct object rob;
883: rob = newMathCap(mathcap);
884: Kpush(rob);
885: }
886:
887: struct object KoxGenPass(void) {
888: struct object rob;
889: rob = KpoString(oxGenPass());
890: return(rob);
891: }
892:
893: struct object KoxGetPort(struct object host)
894: {
895: struct object rob;
896: int fdStream, fdControl;
897: int portStream, portControl;
898: extern int OpenedSocket;
899: char *sname;
900: rob = NullObject;
901: if (host.tag != Sdollar) {
902: errorOxmisc2("KoxGetPort: argument is not a string.");
903: return(rob);
904: }
905: sname = KopString(host);
906: fdControl = socketOpen(sname,0);
907: portControl = OpenedSocket;
908: fdStream = socketOpen(sname,0);
909: portStream = OpenedSocket;
910: rob = newObjectArray(4);
911: putoa(rob,0,KpoInteger(fdStream));
912: putoa(rob,1,KpoInteger(portStream));
913: putoa(rob,2,KpoInteger(fdControl));
914: putoa(rob,3,KpoInteger(portControl));
915: return(rob);
916: }
917:
918: struct object KoxCreateClient2(struct object peer,
919: struct object ipmask,
920: struct object pass)
921: {
922: struct object rob;
923: oxclientp client;
924: int fdStream, portStream, fdControl, portControl;
925: int i;
926: struct object ob1;
927: rob.tag = Snull;
928: if (peer.tag != Sarray) {
929: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl]");
930: return(rob);
931: }
932: if (getoaSize(peer) != 4) {
933: errorOxmisc2("KoxCreateClient2(): The first argument must be an array [fdStream, portStream, fdControl, portControl] of size 4.");
934: return(rob);
935: }
936: for (i=0; i<4; i++) {
937: ob1 = getoa(peer,i);
938: if (ob1.tag != Sinteger) {
939: errorOxmisc2("KoxCreateClient2(): The element of the first argument must be an integer.");
940: }
941: }
942: fdStream = KopInteger(getoa(peer,0));
943: portStream = KopInteger(getoa(peer,1));
944: fdControl = KopInteger(getoa(peer,2));
945: portControl = KopInteger(getoa(peer,3));
946:
947: if (ipmask.tag != Sinteger) {
948: errorOxmisc2("KoxCreateClient2(): ipmask must be an integer.");
949: }
950: if (pass.tag != Sdollar) {
951: errorOxmisc2("KoxCreateClient2(): pass must be a string.");
952: }
953:
954: client = oxCreateClient2(fdStream, portStream, fdControl, portControl,
955: KopInteger(ipmask), KopString(pass));
956: if (client == NULL) {
957: errorOxmisc2("KoxCreateClient2(): Open error.");
958: return(rob);
959: }
960: rob = newObjectArray(N_OF_CLIENT_FIELDS);
961: oxClientToObject(client,rob);
962: return(rob);
1.5 takayama 963: }
964:
965: int KgetCmoTagOfObject(struct object obj) {
966: int k;
967: k=cmoCheck00(obj,(int *)NULL,0);
968: return(k);
1.1 maekawa 969: }
970:
971: errorOxmisc2(char *s) {
1.6 ! takayama 972: SET_MYERROROUT;
1.1 maekawa 973: fprintf(MyErrorOut,"error in oxmisc2.c: %s\n",s);
974: errorKan1("%s\n"," ");
975: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>