Annotation of OpenXM_contrib2/asir2000/io/ox.c, Revision 1.14
1.5 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not limited to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as academic, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as permitted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.6 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.5 noro 27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
1.14 ! noro 47: * $OpenXM$
1.5 noro 48: */
1.1 noro 49: #include "ca.h"
50: #include "parse.h"
1.3 noro 51: #include "signal.h"
1.1 noro 52: #include "wsio.h"
53: #include "ox.h"
54:
55: #define ISIZ sizeof(int)
56:
57: extern Obj VOIDobj;
58:
59: extern int ox_need_conv;
1.14 ! noro 60: int ox_usr1_sent, ox_int_received, critical_when_signal;
1.1 noro 61: unsigned int ox_serial;
62: int ox_flushing;
63: int ox_batch;
64: int ox_check=1;
1.2 noro 65: int ox_exchange_mathcap=1;
1.13 noro 66: JMP_BUF ox_env;
1.1 noro 67:
68: MATHCAP my_mathcap;
69:
70: struct oxcap {
71: unsigned int ox;
72: int ncap;
73: int *cap;
74: };
75:
76: struct mathcap {
77: LIST mc;
78: unsigned int version;
79: char *servername;
80: int nsmcap;
81: unsigned int *smcap;
82: int noxcap;
83: struct oxcap *oxcap;
84: };
85:
86: struct oxcap *my_oxcap;
87:
88: static struct mathcap my_mc;
89: static struct mathcap *remote_mc;
90: static int remote_mc_len;
91:
1.12 noro 92: void mclist_to_mc(LIST mclist,struct mathcap *mc);
93:
1.9 noro 94: #if defined(VISUAL)
95: /* XXX : mainly used in engine2000/io.c, but declared here */
96: HANDLE hStreamNotify,hStreamNotify_Ack;
97:
98: void cleanup_events()
99: {
100: /* ox_watch_stream may be waiting for hStreamNotify_Ack to be set */
101:
102: ResetEvent(hStreamNotify);
103: SetEvent(hStreamNotify_Ack);
104: }
105: #endif
106:
1.12 noro 107: void ox_resetenv(char *s)
1.1 noro 108: {
1.9 noro 109: #if defined(VISUAL)
110: cleanup_events();
111: #endif
1.1 noro 112: fprintf(stderr,"%s\n",s);
1.13 noro 113: LONGJMP(ox_env,1);
1.1 noro 114: }
115:
116: static int available_cmo[] = {
117: CMO_NULL, CMO_INT32, CMO_DATUM, CMO_STRING, CMO_MATHCAP,
118: CMO_ERROR, CMO_ERROR2, CMO_LIST, CMO_MONOMIAL32,
119: CMO_ZZ, CMO_QQ, CMO_ZERO,
120: CMO_DMS_GENERIC, CMO_DMS_OF_N_VARIABLES,
121: CMO_RING_BY_NAME, CMO_DISTRIBUTED_POLYNOMIAL,
122: CMO_RECURSIVE_POLYNOMIAL, CMO_UNIVARIATE_POLYNOMIAL,
123: CMO_INDETERMINATE,
1.11 noro 124: CMO_TREE,
1.1 noro 125: 0
126: };
127:
128: static int available_sm[] = {
129: SM_dupErrors, SM_getsp, SM_popSerializedLocalObject,
1.7 noro 130: SM_popCMO, SM_popString, SM_pushCMOtag, SM_setName,
1.1 noro 131: SM_evalName, SM_executeStringByLocalParser,
132: SM_executeStringByLocalParserInBatchMode,
133: SM_executeFunction, SM_shutdown, SM_pops,
134: SM_mathcap, SM_setMathcap, SM_nop,
135: SM_beginBlock, SM_endBlock,
136: 0
137: };
138:
139: /*
140: mathcap =
141: [
142: version list,
143: SMlist,
144: [
145: [OX tag,CMO tag list],
146: [OX tag,CMO tag list],
147: ...
148: ]
149: ]
150: */
151:
152: void create_my_mathcap(char *system)
153: {
154: NODE n,n0;
155: int i,k;
156: STRING str;
1.12 noro 157: LIST sname,smlist,oxlist,cmolist,asirlist,oxasir,r;
1.1 noro 158: USINT tag,t,t1;
159:
160: if ( my_mathcap )
161: return;
162: /* version */
163: MKSTR(str,system);
164: MKUSINT(t,OX_VERSION);
165: n0 = mknode(2,t,str); MKLIST(sname,n0);
166:
167: /* cmo tag */
168: for ( n0 = 0, i = 0; k = available_sm[i]; i++ ) {
169: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
170: }
171: NEXT(n) = 0; MKLIST(smlist,n0);
172:
173: /* creation of [OX_DATA,CMO list] */
174: /* ox tag */
175: MKUSINT(tag,OX_DATA);
176: /* cmo tag */
177: for ( n0 = 0, i = 0; k = available_cmo[i]; i++ ) {
178: NEXTNODE(n0,n); MKUSINT(t,k); BDY(n) = (pointer)t;
179: }
180: NEXT(n) = 0; MKLIST(cmolist,n0);
181: /* [ox tag, cmo list] */
182: n0 = mknode(2,tag,cmolist);
183: MKLIST(oxlist,n0);
184:
185: /* creation of [OX_LOCAL_OBJECT_ASIR,ASIR tag] */
186: /* ox tag */
187: MKUSINT(tag,OX_LOCAL_OBJECT_ASIR);
188: /* local tag */
189: MKUSINT(t,ASIR_VL);
190: MKUSINT(t1,ASIR_OBJ);
191: n0 = mknode(2,t,t1); MKLIST(cmolist,n0);
192: /* [ox tag, local list] */
193: n0 = mknode(2,tag,cmolist);
194: MKLIST(asirlist,n0);
195:
196: /* [oxlist,asirlist] */
197: n0 = mknode(2,oxlist,asirlist); MKLIST(oxasir,n0);
198:
199: /* [version,sm,oxasir] */
200: n0 = mknode(3,sname,smlist,oxasir); MKLIST(r,n0);
201:
202: MKMATHCAP(my_mathcap,r);
203: mclist_to_mc(r,&my_mc);
204: my_oxcap = my_mc.oxcap;
205: }
206:
207: void store_remote_mathcap(int s,MATHCAP mc)
208: {
209: if ( !remote_mc ) {
210: remote_mc_len = 16;
211: remote_mc = (struct mathcap *)
212: CALLOC(remote_mc_len,sizeof(struct mathcap));
213: }
214: if ( s >= remote_mc_len ) {
215: remote_mc_len *= 2;
216: remote_mc = (struct mathcap *)REALLOC(remote_mc,
217: remote_mc_len*sizeof(struct mathcap));
218: }
219: mclist_to_mc(BDY(mc),&remote_mc[s]);
220: }
221:
222: /*
223: mathcap =
224: [
225: version list,
226: SMlist,
227: [
228: [OX tag,CMO tag list],
229: [OX tag,CMO tag list],
230: ...
231: ]
232: ]
233:
234: ===>
235:
236: mathcap
237: | version | &servername | nsmcap | &smcap | noxcap | &oxcap |
238: smcap
239: | SM_xxx | SM_yyy | ... |
240: oxcap
241: | oxcap[0] | oxcap[1] | ... |
242: oxcap[i]
243: | ox | ncap | &cap |
244: cap
245: | CMO_xxx | CMO_yyy | ... |
246: */
247:
248: void mclist_to_mc(LIST mclist,struct mathcap *mc)
249: {
1.12 noro 250: int l,i,j;
251: NODE n,t,oxcmo,cap;
1.1 noro 252: int *ptr;
253:
254: /*
255: [
256: [ version,servername ]
257: [sm1,sm2,...],
258: [
259: [o1,[n11,n12,...]],
260: [o2,[n21,n22,...]],
261: ...
262: ]
263: ]
264: */
265: n = BDY(mclist);
266: mc->mc = mclist;
267: mc->version = BDY((USINT)BDY(BDY((LIST)BDY(n))));
268: mc->servername = BDY((STRING)BDY(NEXT(BDY((LIST)BDY(n)))));
269:
270: /* smcap */
271: n = NEXT(n);
272: t = BDY((LIST)BDY(n));
273: mc->nsmcap = length(t);
274: mc->smcap = (int *)MALLOC_ATOMIC(mc->nsmcap*sizeof(int));
275: for ( j = 0, ptr = mc->smcap; j < mc->nsmcap; j++, t = NEXT(t) )
276: ptr[j] = BDY((USINT)BDY(t));
277:
278: n = NEXT(n);
279: n = BDY((LIST)BDY(n));
280: /* n -> BDY([[OX1,CMOlist1], [OX2,CMOlist2], ...]) */
281: mc->noxcap = length(n);
282: mc->oxcap = (struct oxcap *)MALLOC(mc->noxcap*sizeof(struct oxcap));
283: for ( j = 0; j < mc->noxcap; j++, n = NEXT(n) ) {
284: oxcmo = BDY((LIST)BDY(n));
285: /* oxcmo = BDY([OXj,CMOlistj]) */
286: mc->oxcap[j].ox = BDY((USINT)BDY(oxcmo));
287: cap = BDY((LIST)BDY(NEXT(oxcmo)));
288: /* cap ->BDY(CMOlistj) */
289: l = length(cap);
290: mc->oxcap[j].ncap = l;
291: mc->oxcap[j].cap = (unsigned int *)CALLOC(l+1,sizeof(unsigned int));
292: for ( t = cap, ptr = mc->oxcap[j].cap, i = 0; i < l; t = NEXT(t), i++ )
293: ptr[i] = BDY((USINT)BDY(t));
294: }
295: }
296:
1.12 noro 297: int check_sm_by_mc(int s,unsigned int smtag)
1.1 noro 298: {
299: struct mathcap *rmc;
300: int nsmcap,i;
301: unsigned int *smcap;
302:
303: /* XXX : return 1 if remote_mc is not available. */
304: if ( !remote_mc )
305: return 1;
306: rmc = &remote_mc[s];
307: nsmcap = rmc->nsmcap;
308: smcap = rmc->smcap;
309: if ( !smcap )
310: return 1;
311: for ( i = 0; i < nsmcap; i++ )
312: if ( smcap[i] == smtag )
313: break;
314: if ( i == nsmcap )
315: return 0;
316: else
317: return 1;
318: }
319:
1.12 noro 320: int check_by_mc(int s,unsigned int oxtag,unsigned int cmotag)
1.1 noro 321: {
322: struct mathcap *rmc;
323: int noxcap,ncap,i,j;
324: struct oxcap *oxcap;
325: unsigned int *cap;
326:
327: /* XXX : return 1 if remote_mc is not available. */
328: if ( !remote_mc )
329: return 1;
330: rmc = &remote_mc[s];
331: noxcap = rmc->noxcap;
332: oxcap = rmc->oxcap;
333: if ( !oxcap )
334: return 1;
335: for ( i = 0; i < noxcap; i++ )
336: if ( oxcap[i].ox == oxtag )
337: break;
338: if ( i == noxcap )
339: return 0;
340: ncap = oxcap[i].ncap;
341: cap = oxcap[i].cap;
342: for ( j = 0; j < ncap; j++ )
343: if ( cap[j] == cmotag )
344: break;
345: if ( j == ncap )
346: return 0;
347: else
348: return 1;
349: }
350:
351: void begin_critical() {
352: critical_when_signal = 1;
353: }
354:
355: void end_critical() {
356: critical_when_signal = 0;
357: if ( ox_usr1_sent ) {
1.12 noro 358: ox_usr1_sent = 0;
359: #if !defined(VISUAL)
360: ox_usr1_handler(SIGUSR1);
361: #else
362: ox_usr1_handler(0);
363: #endif
1.1 noro 364: }
365: if ( ox_int_received ) {
366: ox_int_received = 0; int_handler(SIGINT);
367: }
368: }
369:
1.12 noro 370: void ox_usr1_handler(int sig)
1.1 noro 371: {
372: #if !defined(VISUAL)
373: signal(SIGUSR1,ox_usr1_handler);
374: #endif
375: if ( critical_when_signal ) {
376: fprintf(stderr,"usr1 : critical\n");
377: ox_usr1_sent = 1;
378: } else {
379: ox_flushing = 1;
380: ox_resetenv("usr1 : return to toplevel by SIGUSR1");
381: }
382: }
383:
384: void clear_readbuffer()
385: {
386: #if defined(linux)
387: iofp[0].in->_IO_read_ptr = iofp[0].in->_IO_read_end;
388: #elif defined(__FreeBSD__)
389: fpurge(iofp[0].in);
390: #endif
391: /*
392: sock = fileno(iofp[0].in);
393: interval.tv_sec = (int)0;
394: interval.tv_usec = (int)0;
395:
396: FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e);
397: FD_SET(sock,&r);
398: while ( 1 ) {
399: n = select(FD_SETSIZE,&r,&w,&e,&interval);
400: if ( !n )
401: break;
402: read(sock,&c,1);
403: }
404: */
405: }
406:
407: #if MPI
408: int ox_data_is_available(int s)
409: {
410: return 1;
411: }
412:
413: void wait_for_data(int s)
414: {
415: return;
416: }
417: #else
418: int ox_data_is_available(int s)
419: {
420: return FP_DATA_IS_AVAILABLE(iofp[s].in);
421: }
422:
423: void wait_for_data(int s)
424: {
425: fd_set r;
426: int sock;
427:
428: if ( !FP_DATA_IS_AVAILABLE(iofp[s].in) ) {
429: #if defined(VISUAL)
430: sock = iofp[s].in->fildes;
431: FD_ZERO(&r);
1.12 noro 432: FD_SET((unsigned int)sock,&r);
1.1 noro 433: select(0,&r,NULL,NULL,NULL);
434: #else
435: sock = fileno(iofp[s].in);
436: FD_ZERO(&r);
437: FD_SET(sock,&r);
438: select(FD_SETSIZE,&r,NULL,NULL,NULL);
439: #endif
440: }
441: }
442: #endif
443:
444: void ox_send_data(int s,pointer p)
445: {
1.8 noro 446: ERR err;
447:
448: if ( ox_check && !ox_check_cmo(s,(Obj)p) ) {
449: create_error(&err,ox_serial,"ox_send_data : Mathcap violation");
450: p = (pointer)err;
451: }
1.1 noro 452: begin_critical();
453: ox_write_int(s,OX_DATA);
454: ox_write_int(s,ox_serial++);
455: ox_write_cmo(s,p);
456: ox_flush_stream(s);
457: end_critical();
458: }
459:
460: void ox_send_cmd(int s,int id)
461: {
462: if ( ox_check && !check_sm_by_mc(s,id) )
463: error("ox_send_cmd : Mathcap violation");
464: begin_critical();
465: ox_write_int(s,OX_COMMAND);
466: ox_write_int(s,ox_serial++);
467: ox_write_int(s,id);
468: ox_flush_stream(s);
469: end_critical();
470: }
471:
472: void ox_send_sync(int s)
473: {
474: begin_critical();
475: ox_write_int(s,OX_SYNC_BALL);
476: ox_write_int(s,ox_serial++);
477: ox_flush_stream(s);
478: end_critical();
479: }
480:
481: void ox_send_local_data(int s,Obj p)
482: {
483: begin_critical();
484: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
485: ox_write_int(s,ox_serial++);
486: ox_write_int(s,ASIR_OBJ);
1.12 noro 487: saveobj((FILE *)iofp[s].out,p);
1.1 noro 488: ox_flush_stream(s);
489: end_critical();
490: }
491:
492: void ox_send_local_ring(int s,VL vl)
493: {
494: begin_critical();
495: ox_write_int(s,OX_LOCAL_OBJECT_ASIR);
496: ox_write_int(s,ox_serial++);
497: ox_write_int(s,ASIR_VL);
1.12 noro 498: savevl((FILE *)iofp[s].out,vl);
1.1 noro 499: ox_flush_stream(s);
500: end_critical();
501: }
502:
1.12 noro 503: unsigned int ox_recv(int s, int *id, Obj *p)
1.1 noro 504: {
505: unsigned int cmd,serial;
506: USINT ui;
507:
508: wait_for_data(s);
509: begin_critical();
510: ox_read_int(s,id);
511: ox_read_int(s,&serial);
512: switch ( *id ) {
513: case OX_COMMAND:
514: ox_read_int(s,&cmd);
515: MKUSINT(ui,cmd);
1.12 noro 516: *p = (Obj)ui;
1.1 noro 517: break;
518: case OX_DATA:
519: ox_read_cmo(s,p);
520: break;
521: case OX_LOCAL_OBJECT_ASIR:
522: ox_read_local(s,p);
523: break;
524: default:
525: *p = 0;
526: break;
527: }
528: end_critical();
529: return serial;
530: }
531:
1.12 noro 532: void ox_get_result(int s,Obj *rp)
1.1 noro 533: {
534: int id;
535: Obj obj,r;
536: int level;
537:
538: level = 0;
539: r = 0;
540: do {
1.12 noro 541: ox_recv(s,&id,&obj);
1.1 noro 542: if ( id == OX_COMMAND ) {
543: switch ( ((USINT)obj)->body ) {
544: case SM_beginBlock:
545: level++;
546: break;
547: case SM_endBlock:
548: level--;
549: }
550: } else
551: r = obj;
552: } while ( level );
553: *rp = r;
554: }
555:
556: void ox_read_int(int s, int *n)
557: {
558: ox_need_conv = iofp[s].conv;
1.12 noro 559: read_int((FILE *)iofp[s].in,n);
1.1 noro 560: }
561:
562: void ox_read_cmo(int s, Obj *rp)
563: {
564: ox_need_conv = iofp[s].conv;
1.12 noro 565: read_cmo((FILE *)iofp[s].in,rp);
1.1 noro 566: }
567:
568: void ox_read_local(int s, Obj *rp)
569: {
570: int id;
571:
572: ox_need_conv = iofp[s].conv;
1.12 noro 573: read_int((FILE *)iofp[s].in,&id);
1.1 noro 574: switch ( id ) {
575: case ASIR_VL:
1.12 noro 576: loadvl((FILE *)iofp[s].in);
1.1 noro 577: *rp = VOIDobj;
578: break;
579: case ASIR_OBJ:
1.12 noro 580: loadobj((FILE *)iofp[s].in,rp);
1.1 noro 581: break;
582: default:
583: error("ox_read_local : unsupported id");
584: break;
585: }
586: }
587:
588: void ox_write_int(int s, int n)
589: {
590: ox_need_conv = iofp[s].conv;
1.12 noro 591: write_int((FILE *)iofp[s].out,&n);
1.1 noro 592: }
593:
594: void ox_write_cmo(int s, Obj obj)
595: {
596: ox_need_conv = iofp[s].conv;
1.12 noro 597: write_cmo((FILE *)iofp[s].out,obj);
1.1 noro 598: }
599:
600: int ox_check_cmo(int s, Obj obj)
601: {
602: NODE m;
603:
604: if ( !obj )
605: return 1;
606: switch ( OID(obj) ) {
607: case O_MATHCAP: case O_STR: case O_ERR: case O_USINT: case O_VOID:
1.10 noro 608: case O_BYTEARRAY:
1.1 noro 609: return 1;
610: case O_P:
611: if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
612: return 0;
613: else
614: return ox_check_cmo_p(s,(P)obj);
615: case O_R:
616: if ( !check_by_mc(s,OX_DATA,CMO_RATIONAL) )
617: return 0;
618: else if ( !check_by_mc(s,OX_DATA,CMO_RECURSIVE_POLYNOMIAL) )
619: return 0;
620: else
621: return ox_check_cmo_p(s,NM((R)obj)) && ox_check_cmo_p(s,DN((R)obj));
622: case O_DP:
623: return ox_check_cmo_dp(s,(DP)obj);
624: case O_N:
1.4 noro 625: switch ( NID((Num)obj) ) {
626: case N_Q:
627: if ( INT((Q)obj) )
628: return check_by_mc(s,OX_DATA,CMO_ZZ);
629: else
630: return check_by_mc(s,OX_DATA,CMO_QQ);
631: case N_R:
632: return 1;
633: default:
634: return 0;
635: }
636: break;
1.1 noro 637: case O_LIST:
638: for ( m = BDY((LIST)obj); m; m = NEXT(m) )
639: if ( !ox_check_cmo(s,(BDY(m))) )
640: return 0;
1.11 noro 641: return 1;
642: case O_QUOTE: /* XXX */
1.1 noro 643: return 1;
644: default:
645: return 0;
646: }
647: }
648:
649: void ox_get_serverinfo(int s, LIST *rp)
650: {
651: if ( remote_mc )
652: *rp = remote_mc[s].mc;
653: else {
654: MKLIST(*rp,0);
655: }
656: }
657:
658: int ox_check_cmo_p(int s, P p)
659: {
660: DCP dc;
661:
662: if ( NUM(p) )
663: return ox_check_cmo(s,(Obj)p);
664: else {
665: for ( dc = DC(p); dc; dc = NEXT(dc) )
666: if ( !ox_check_cmo_p(s,COEF(dc)) )
667: return 0;
668: return 1;
669: }
670: }
671:
672: int ox_check_cmo_dp(int s, DP p)
673: {
674: MP m;
675:
676: for ( m = BDY(p); m; m = NEXT(m) )
677: if ( !ox_check_cmo(s,(Obj)m->c) )
678: return 0;
679: return 1;
680: }
681:
1.12 noro 682: void ox_flush_stream(int s)
1.1 noro 683: {
684: if ( ox_batch )
685: return;
686: #if defined(VISUAL)
687: if ( _fileno(&iofp[s].out->fp) < 0 )
688: cflush(iofp[s].out);
689: else
690: #elif MPI
691: if ( (char)fileno(&iofp[s].out->fp) < 0 )
692: cflush(iofp[s].out);
693: else
694: #endif
1.12 noro 695: fflush((FILE *)iofp[s].out);
1.1 noro 696: }
697:
1.12 noro 698: void ox_flush_stream_force(int s)
1.1 noro 699: {
700: #if defined(VISUAL)
701: if ( _fileno(&iofp[s].out->fp) < 0 )
702: cflush(iofp[s].out);
703: else
704: #elif MPI
705: if ( (char)fileno(&iofp[s].out->fp) < 0 )
706: cflush(iofp[s].out);
707: else
708: #endif
1.12 noro 709: fflush((FILE *)iofp[s].out);
1.1 noro 710: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>