Annotation of OpenXM_contrib2/asir2000/io/ox_asir.c, Revision 1.42
1.15 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.16 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.15 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.42 ! noro 47: * $OpenXM: OpenXM_contrib2/asir2000/io/ox_asir.c,v 1.41 2003/02/14 22:29:15 ohara Exp $
1.15 noro 48: */
1.1 noro 49: #include "ca.h"
50: #include "parse.h"
1.6 noro 51: #include "signal.h"
1.1 noro 52: #include "ox.h"
53: #include "version.h"
1.41 ohara 54: #if defined(PARI)
1.6 noro 55: #include "genpari.h"
56: #endif
1.1 noro 57:
58: void ox_usr1_handler();
1.13 noro 59: int asir_ox_init();
1.1 noro 60:
1.36 noro 61: /* environement is defined in libpari.a */
62: extern jmp_buf environnement;
1.1 noro 63:
64: extern int do_message;
65: extern int ox_flushing;
1.35 noro 66: extern JMP_BUF ox_env;
1.1 noro 67: extern MATHCAP my_mathcap;
68:
1.11 noro 69: extern int little_endian,ox_sock_id;
70:
1.1 noro 71: int ox_sock_id;
1.11 noro 72: int lib_ox_need_conv;
1.1 noro 73:
1.19 noro 74: void create_error(ERR *,unsigned int ,char *);
75:
1.20 noro 76: int asir_OperandStackSize;
77: Obj *asir_OperandStack;
78: int asir_OperandStackPtr = -1;
79:
80: void ox_io_init();
1.40 noro 81: void ox_asir_init(int,char **,char *);
1.20 noro 82: Obj asir_pop_one();
83: Obj asir_peek_one();
84: void asir_push_one(Obj);
85: void asir_end_flush();
86: int asir_executeString();
87: void asir_evalName(unsigned int);
88: void asir_setName(unsigned int);
89: void asir_pops();
90: void asir_popString();
91: void asir_popCMO(unsigned int);
92: void asir_popSerializedLocalObject();
93: void asir_pushCMOtag(unsigned int);
94: LIST asir_GetErrorList();
95: char *name_of_cmd(int);
96: char *name_of_id(int);
97:
98: static void asir_do_cmd(int,unsigned int);
1.1 noro 99: static void asir_executeFunction(int);
100:
1.42 ! noro 101: #if MPI
1.14 noro 102: /* XXX : currently MPI version supports only a homogeneous cluster. */
103:
1.1 noro 104: extern int mpi_nprocs,mpi_myid;
105:
106: void ox_mpi_master_init() {
1.14 noro 107: int i,idx;
1.1 noro 108:
1.14 noro 109: for ( i = 0; i < mpi_nprocs; i++ ) {
110: /* ordering information is not exchanged */
111: /* idx should be equal to i */
1.1 noro 112: idx = get_iofp(i,0,0);
1.14 noro 113: register_server(0,idx,idx);
1.1 noro 114: }
115: }
116:
117: void ox_mpi_slave_init() {
1.14 noro 118: int i,idx;
119:
1.1 noro 120: endian_init();
121: fclose(stdin);
1.14 noro 122: for ( i = 0; i < mpi_nprocs; i++ ) {
123: /* ordering information is not exchanged */
124: /* idx should be equal to i */
125: idx = get_iofp(i,0,0);
126: register_server(0,idx,idx);
127: }
1.1 noro 128: asir_OperandStackSize = BUFSIZ;
129: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
130: asir_OperandStackPtr = -1;
131: }
132: #endif
133:
134: void ox_main(int argc,char **argv) {
135: int id;
1.13 noro 136: int cmd;
1.1 noro 137: Obj obj;
138: ERR err;
139: unsigned int serial;
140: int ret;
141: extern char LastError[];
142:
1.40 noro 143: ox_asir_init(argc,argv,"ox_asir");
1.1 noro 144: if ( do_message )
145: fprintf(stderr,"I'm an ox_asir, Version %d.\n",ASIR_VERSION);
1.35 noro 146: if ( SETJMP(ox_env) ) {
1.1 noro 147: while ( NEXT(asir_infile) )
148: closecurrentinput();
149: ox_send_sync(0);
150: }
151: while ( 1 ) {
152: extern int recv_intr;
153:
154: serial = ox_recv(0,&id,&obj);
155: #if defined(VISUAL)
156: if ( recv_intr ) {
157: if ( recv_intr == 1 ) {
158: recv_intr = 0;
159: int_handler(SIGINT);
160: } else {
161: recv_intr = 0;
162: ox_usr1_handler(0);
163: }
164: }
165: #endif
166: if ( do_message )
167: fprintf(stderr,"#%d Got %s",serial,name_of_id(id));
168: switch ( id ) {
169: case OX_COMMAND:
170: cmd = ((USINT)obj)->body;
171: if ( ox_flushing )
172: break;
173: if ( do_message )
174: fprintf(stderr," %s\n",name_of_cmd(cmd));
1.35 noro 175: if ( ret = SETJMP(main_env) ) {
1.1 noro 176: if ( ret == 1 ) {
177: create_error(&err,serial,LastError);
178: asir_push_one((Obj)err);
179: }
180: break;
181: }
182: asir_do_cmd(cmd,serial);
183: break;
184: case OX_DATA:
185: case OX_LOCAL_OBJECT_ASIR:
186: if ( ox_flushing )
187: break;
188: if ( do_message )
189: fprintf(stderr," -> data pushed");
190: asir_push_one(obj);
191: break;
192: case OX_SYNC_BALL:
193: asir_end_flush();
194: break;
195: default:
196: break;
197: }
198: if ( do_message )
199: fprintf(stderr,"\n");
200: }
201: }
202:
1.13 noro 203: static void asir_do_cmd(int cmd,unsigned int serial)
1.1 noro 204: {
205: MATHCAP client_mathcap;
206: Q q;
207: int i;
208: LIST list;
209:
210: switch ( cmd ) {
211: case SM_dupErrors:
212: list = asir_GetErrorList();
213: asir_push_one((Obj)list);
214: break;
215: case SM_getsp:
216: i = asir_OperandStackPtr+1;
217: STOQ(i,q);
218: asir_push_one((Obj)q);
219: break;
220: case SM_popSerializedLocalObject:
221: asir_popSerializedLocalObject();
222: break;
223: case SM_popCMO:
224: asir_popCMO(serial);
225: break;
226: case SM_popString:
227: asir_popString();
228: break;
229: case SM_setName:
230: asir_setName(serial);
231: break;
232: case SM_evalName:
233: asir_evalName(serial);
234: break;
235: case SM_executeStringByLocalParser:
236: asir_executeString();
237: break;
238: case SM_executeStringByLocalParserInBatchMode:
239: asir_executeString();
240: asir_pop_one();
241: break;
242: case SM_executeFunction:
243: asir_executeFunction(serial);
244: break;
245: case SM_shutdown:
246: asir_terminate(2);
247: break;
248: case SM_pops:
249: asir_pops();
250: break;
251: case SM_mathcap:
252: asir_push_one((Obj)my_mathcap);
253: break;
254: case SM_setMathcap:
255: client_mathcap = (MATHCAP)asir_pop_one();
256: store_remote_mathcap(0,client_mathcap);
257: break;
1.18 noro 258: case SM_pushCMOtag:
259: asir_pushCMOtag(serial);
260: break;
1.1 noro 261: case SM_nop:
262: default:
263: break;
264: }
265: }
266:
1.20 noro 267: char *name_of_id(int id)
1.1 noro 268: {
269: switch ( id ) {
270: case OX_COMMAND:
271: return "OX_COMMAND";
272: break;
273: case OX_DATA:
274: return "OX_DATA";
275: break;
276: case OX_LOCAL_OBJECT_ASIR:
277: return "OX_LOCAL_OBJECT_ASIR";
278: break;
279: case OX_SYNC_BALL:
280: return "OX_SYNC_BALL";
281: break;
282: default:
283: return "Unknown id";
284: break;
285: }
286: }
287:
1.20 noro 288: char *name_of_cmd(int cmd)
1.1 noro 289: {
290: switch ( cmd ) {
291: case SM_popSerializedLocalObject:
292: return "SM_popSerializedLocalObject";
293: break;
294: case SM_popCMO:
295: return "SM_popCMO";
296: break;
297: case SM_popString:
298: return "SM_popString";
299: break;
300: case SM_pops:
301: return "SM_pops";
302: break;
303: case SM_setName:
304: return "SM_setName";
305: break;
306: case SM_evalName:
307: return "SM_evalName";
308: break;
309: case SM_executeStringByLocalParser:
310: return "SM_executeString";
311: break;
312: case SM_executeFunction:
313: return "SM_executeFunction";
314: break;
315: case SM_shutdown:
316: return "SM_shutdown";
317: break;
318: case SM_beginBlock:
319: return "SM_beginBlock";
320: break;
321: case SM_endBlock:
322: return "SM_endBlock";
323: break;
324: case SM_mathcap:
325: return "SM_mathcap";
326: break;
327: case SM_setMathcap:
328: return "SM_setMathcap";
329: break;
330: case SM_getsp:
331: return "SM_setMathcap";
332: break;
333: case SM_dupErrors:
334: return "SM_dupErrors";
335: break;
336: case SM_nop:
337: return "SM_nop";
1.18 noro 338: case SM_pushCMOtag:
339: return "SM_pushCMOtag";
1.1 noro 340: default:
341: return "Unknown cmd";
342: break;
343: }
344: }
345:
1.20 noro 346: LIST asir_GetErrorList()
1.1 noro 347: {
348: int i;
349: NODE n,n0;
350: LIST err;
351: Obj obj;
352:
353: for ( i = 0, n0 = 0; i <= asir_OperandStackPtr; i++ )
354: if ( (obj = asir_OperandStack[i]) && (OID(obj) == O_ERR) ) {
355: NEXTNODE(n0,n); BDY(n) = (pointer)obj;
356: }
357: if ( n0 )
358: NEXT(n) = 0;
359: MKLIST(err,n0);
360: return err;
361: }
362:
1.20 noro 363: void asir_popSerializedLocalObject()
1.1 noro 364: {
365: Obj obj;
366: VL t,vl;
367:
368: obj = asir_pop_one();
369: get_vars_recursive(obj,&vl);
370: for ( t = vl; t; t = NEXT(t) )
371: if ( t->v->attr == (pointer)V_UC )
372: error("bsave : not implemented");
373: ox_send_cmd(0,SM_beginBlock);
374: ox_send_local_ring(0,vl);
375: ox_send_local_data(0,obj);
376: ox_send_cmd(0,SM_endBlock);
377: }
378:
1.20 noro 379: void asir_popCMO(unsigned int serial)
1.1 noro 380: {
381: Obj obj;
382: ERR err;
383:
384: obj = asir_pop_one();
385: if ( valid_as_cmo(obj) )
386: ox_send_data(0,obj);
387: else {
388: create_error(&err,serial,"cannot convert to CMO object");
389: ox_send_data(0,err);
390: asir_push_one(obj);
391: }
392: }
393:
1.20 noro 394: void asir_pushCMOtag(unsigned int serial)
1.18 noro 395: {
396: Obj obj;
397: ERR err;
398: USINT ui;
399: int tag;
400:
401: obj = asir_peek_one();
402: if ( cmo_tag(obj,&tag) ) {
403: MKUSINT(ui,tag);
404: asir_push_one((Obj)ui);
405: } else {
406: create_error(&err,serial,"cannot convert to CMO object");
407: asir_push_one((Obj)err);
408: }
409: }
410:
1.20 noro 411: void asir_popString()
1.1 noro 412: {
413: Obj val;
414: char *buf,*obuf;
415: int l;
416: STRING str;
417:
418: val = asir_pop_one();
419: if ( !val )
1.24 noro 420: obuf = "0";
1.1 noro 421: else {
422: l = estimate_length(CO,val);
423: buf = (char *)ALLOCA(l+1);
424: soutput_init(buf);
425: sprintexpr(CO,val);
426: l = strlen(buf);
427: obuf = (char *)MALLOC(l+1);
428: strcpy(obuf,buf);
429: }
430: MKSTR(str,obuf);
431: ox_send_data(0,str);
432: }
433:
1.20 noro 434: void asir_pops()
1.1 noro 435: {
436: int n;
437:
438: n = (int)(((USINT)asir_pop_one())->body);
439: asir_OperandStackPtr = MAX(asir_OperandStackPtr-n,-1);
440: }
441:
1.20 noro 442: void asir_setName(unsigned int serial)
1.1 noro 443: {
444: char *name;
445: int l,n;
446: char *dummy = "=0;";
447: SNODE snode;
448: ERR err;
449:
450: name = ((STRING)asir_pop_one())->body;
451: l = strlen(name);
452: n = l+strlen(dummy)+1;
453: parse_strp = (char *)ALLOCA(n);
454: sprintf(parse_strp,"%s%s",name,dummy);
455: if ( mainparse(&snode) ) {
456: create_error(&err,serial,"cannot set to variable");
457: asir_push_one((Obj)err);
458: } else {
459: FA1((FNODE)FA0(snode)) = (pointer)mkfnode(1,I_FORMULA,asir_pop_one());
460: evalstat(snode);
461: }
462: }
463:
1.20 noro 464: void asir_evalName(unsigned int serial)
1.1 noro 465: {
466: char *name;
467: int l,n;
468: SNODE snode;
469: ERR err;
470: pointer val;
471:
472: name = ((STRING)asir_pop_one())->body;
473: l = strlen(name);
474: n = l+2;
475: parse_strp = (char *)ALLOCA(n);
476: sprintf(parse_strp,"%s;",name);
477: if ( mainparse(&snode) ) {
478: create_error(&err,serial,"no such variable");
479: val = (pointer)err;
480: } else
481: val = evalstat(snode);
482: asir_push_one(val);
483: }
484:
1.20 noro 485: int asir_executeString()
1.1 noro 486: {
487: SNODE snode;
488: pointer val;
489: char *cmd;
1.41 ohara 490: #if defined(PARI)
1.1 noro 491: recover(0);
1.36 noro 492: /* environement is defined in libpari.a */
493: if ( setjmp(environnement) ) {
1.1 noro 494: avma = top; recover(1);
495: resetenv("");
496: }
497: #endif
498: cmd = ((STRING)asir_pop_one())->body;
499: parse_strp = cmd;
500: if ( mainparse(&snode) ) {
501: return -1;
502: }
503: val = evalstat(snode);
504: if ( NEXT(asir_infile) ) {
505: while ( NEXT(asir_infile) ) {
506: if ( mainparse(&snode) ) {
507: asir_push_one(val);
508: return -1;
509: }
510: nextbp = 0;
511: val = evalstat(snode);
512: }
513: }
514: asir_push_one(val);
515: return 0;
516: }
517:
518: static void asir_executeFunction(int serial)
519: {
520: char *func;
521: int argc;
522: FUNC f;
523: Obj result;
524: NODE n,n1;
525: STRING fname;
526: char *path;
527: ERR err;
1.5 noro 528: Obj arg;
1.1 noro 529: static char buf[BUFSIZ];
530:
1.5 noro 531: arg = asir_pop_one();
532: if ( !arg || OID(arg) != O_STR ) {
533: sprintf(buf,"executeFunction : invalid function name");
534: goto error;
535: } else
536: func = ((STRING)arg)->body;
537:
538: arg = asir_pop_one();
539: if ( !arg || OID(arg) != O_USINT ) {
540: sprintf(buf,"executeFunction : invalid argc");
541: goto error;
542: } else
543: argc = (int)(((USINT)arg)->body);
1.1 noro 544:
545: for ( n = 0; argc; argc-- ) {
546: NEXTNODE(n,n1);
547: BDY(n1) = (pointer)asir_pop_one();
548: }
549: if ( n )
550: NEXT(n1) = 0;
551:
552: if ( !strcmp(func,"load") ) {
553: fname = (STRING)BDY(n);
554: if ( OID(fname) == O_STR ) {
555: searchasirpath(BDY(fname),&path);
556: if ( path ) {
557: if ( do_message )
558: fprintf(stderr,"loading %s\n",path);
559: execasirfile(path);
560: } else
561: if ( do_message )
562: fprintf(stderr,"load : %s not found in the search path\n",BDY(fname));
563: }
564: result = 0;
565: } else {
566: searchf(noargsysf,func,&f);
567: if ( !f )
568: searchf(sysf,func,&f);
569: if ( !f )
570: searchf(ubinf,func,&f);
571: if ( !f )
572: searchf(usrf,func,&f);
573: if ( !f ) {
574: sprintf(buf,"executeFunction : the function %s not found",func);
1.5 noro 575: goto error;
1.1 noro 576: } else {
577: result = (Obj)bevalf(f,n);
578: }
579: }
1.5 noro 580: asir_push_one(result);
581: return;
582:
583: error:
584: create_error(&err,serial,buf);
585: result = (Obj)err;
1.1 noro 586: asir_push_one(result);
587: }
588:
1.20 noro 589: void asir_end_flush()
1.1 noro 590: {
591: ox_flushing = 0;
592: }
593:
594: /*
595: asir_OperandStackPtr points to the surface of the stack.
596: That is, the data at the stack top is
597: asir_OperandStack[asir_OperandStackPtr].
598: */
599:
600:
1.20 noro 601: void asir_push_one(Obj obj)
1.1 noro 602: {
603: if ( !obj || OID(obj) != O_VOID ) {
604: asir_OperandStackPtr++;
605: if ( asir_OperandStackPtr >= asir_OperandStackSize ) {
606: asir_OperandStackSize += BUFSIZ;
607: asir_OperandStack
608: = (Obj *)REALLOC(asir_OperandStack,
609: asir_OperandStackSize*sizeof(Obj));
610: }
611: asir_OperandStack[asir_OperandStackPtr] = obj;
612: }
613: }
614:
1.20 noro 615: Obj asir_pop_one() {
1.1 noro 616: if ( asir_OperandStackPtr < 0 ) {
617: if ( do_message )
618: fprintf(stderr,"OperandStack underflow");
619: return 0;
620: } else {
621: if ( do_message )
622: fprintf(stderr,"pop at %d\n",asir_OperandStackPtr);
623: return asir_OperandStack[asir_OperandStackPtr--];
1.18 noro 624: }
625: }
626:
1.20 noro 627: Obj asir_peek_one() {
1.18 noro 628: if ( asir_OperandStackPtr < 0 ) {
629: if ( do_message )
630: fprintf(stderr,"OperandStack underflow");
631: return 0;
632: } else {
633: if ( do_message )
634: fprintf(stderr,"peek at %d\n",asir_OperandStackPtr);
635: return asir_OperandStack[asir_OperandStackPtr];
1.1 noro 636: }
637: }
638:
1.40 noro 639: void ox_asir_init(int argc,char **argv,char *servername)
1.1 noro 640: {
641: char ifname[BUFSIZ];
642: extern int GC_dont_gc;
643: extern int read_exec_file;
644: extern int do_asirrc;
645: extern int do_server_in_X11;
1.37 noro 646: extern char displayname[];
1.1 noro 647: char *getenv();
648: static ox_asir_initialized = 0;
649: FILE *ifp;
1.4 noro 650: char *homedir;
651: char *ptr;
1.32 noro 652: #if !defined(VISUAL)
653: int tmp;
654: #endif
1.1 noro 655:
1.42 ! noro 656: #if !defined(VISUAL) && !MPI
1.1 noro 657: do_server_in_X11 = 1; /* XXX */
658: #endif
659: asir_save_handler();
1.41 ohara 660: #if defined(PARI)
1.1 noro 661: risa_pari_init();
662: #endif
663: srandom((int)get_current_time());
664:
665: rtime_init();
666: env_init();
667: endian_init();
668: GC_init();
669: process_args(--argc,++argv);
1.37 noro 670: #if defined(__CYGWIN__)
671: if ( !displayname[0] )
672: do_server_in_X11 = 0; /* XXX */
673: #endif
1.1 noro 674: output_init();
675: arf_init();
676: nglob_init();
677: glob_init();
678: sig_init();
679: tty_init();
680: debug_init();
681: pf_init();
682: sysf_init();
683: parif_init();
684: #if defined(VISUAL)
685: init_socket();
686: #endif
687: #if defined(UINIT)
688: reg_sysf();
689: #endif
1.4 noro 690: /* if ASIR_CONFIG is set, execute it; else execute .asirrc */
691: if ( ptr = getenv("ASIR_CONFIG") )
692: strcpy(ifname,ptr);
693: else {
694: homedir = getenv("HOME");
695: if ( !homedir ) {
696: char rootname[BUFSIZ];
697:
698: get_rootdir(rootname,sizeof(rootname));
699: homedir = rootname;
700: }
701: sprintf(ifname,"%s/.asirrc",homedir);
702: }
1.1 noro 703: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
704: input_init(ifp,ifname);
1.35 noro 705: if ( !SETJMP(main_env) ) {
1.1 noro 706: read_exec_file = 1;
707: read_eval_loop();
708: read_exec_file = 0;
709: }
710: fclose(ifp);
711: }
712: input_init(0,"string");
1.30 noro 713: /* XXX Windows compatibility */
714: ox_io_init();
1.40 noro 715: create_my_mathcap(servername);
1.1 noro 716: }
717:
1.20 noro 718: void ox_io_init() {
1.1 noro 719: unsigned char c,rc;
1.21 noro 720: extern int I_am_server;
1.26 noro 721:
1.33 noro 722: /* XXX : ssh forwards stdin to a remote host on PC Unix */
723: #if defined(linux)
724: #include <sys/param.h>
1.32 noro 725: int i;
726:
727: close(0);
728: for ( i = 5; i < NOFILE; i++ )
729: close(i);
1.33 noro 730: #elif defined(__FreeBSD__)
1.27 noro 731: #include <sys/resource.h>
1.33 noro 732: int i;
1.32 noro 733: struct rlimit rl;
1.27 noro 734:
1.32 noro 735: getrlimit(RLIMIT_NOFILE,&rl);
736: close(0);
737: for ( i = 5; i < rl.rlim_cur; i++ )
738: close(i);
1.27 noro 739: #endif
1.1 noro 740:
1.21 noro 741: I_am_server = 1;
1.1 noro 742: endian_init();
743: #if defined(VISUAL)
744: if ( !ox_sock_id )
745: exit(0);
746: iofp[0].in = WSIO_open(ox_sock_id,"r");
747: iofp[0].out = WSIO_open(ox_sock_id,"w");
748: #else
749: iofp[0].in = fdopen(3,"r");
750: iofp[0].out = fdopen(4,"w");
751:
1.34 noro 752: #if !defined(__CYGWIN__)
1.1 noro 753: setbuffer(iofp[0].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
754: setbuffer(iofp[0].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
1.34 noro 755: #endif
1.1 noro 756: signal(SIGUSR1,ox_usr1_handler);
757: #endif
758: asir_OperandStackSize = BUFSIZ;
759: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
760: asir_OperandStackPtr = -1;
761: if ( little_endian )
762: c = 1;
763: else
764: c = 0xff;
765: /* server : write -> read */
766: write_char(iofp[0].out,&c); ox_flush_stream_force(0);
767: read_char(iofp[0].in,&rc);
768: iofp[0].conv = c == rc ? 0 : 1;
1.14 noro 769: /* XXX; for raw I/O */
770: register_server(0,0,0);
1.3 noro 771: }
772:
1.17 noro 773: #if !defined(VISUAL)
1.3 noro 774: /*
775: * Library mode functions
776: */
777:
778: /*
779: * Converts a binary encoded CMO into a risa object
780: * and pushes it onto the stack.
781: */
782:
783: void asir_ox_push_cmo(void *cmo)
784: {
785: Obj obj;
786:
787: ox_copy_init(cmo);
788: ox_buf_to_obj_as_cmo(&obj);
789: asir_push_one(obj);
790: }
791:
792: /*
793: * Pop an object from the stack and converts it
1.28 noro 794: * into a binary encoded CMO.
1.3 noro 795: */
796:
797: int asir_ox_pop_cmo(void *cmo, int limit)
798: {
799: Obj obj;
800: int len;
1.11 noro 801: ERR err;
1.3 noro 802:
803: obj = asir_pop_one();
1.10 noro 804: if ( !valid_as_cmo(obj) ) {
1.11 noro 805: asir_push_one(obj);
806: create_error(&err,0,"The object at the stack top is invalid as a CMO.");
807: obj = (Obj)err;
1.10 noro 808: }
1.3 noro 809: len = count_as_cmo(obj);
810: if ( len <= limit ) {
811: ox_copy_init(cmo);
812: ox_obj_to_buf_as_cmo(obj);
813: return len;
814: } else
815: return -1;
1.28 noro 816: }
817:
818: int asir_ox_pop_string(void *string, int limit)
819: {
820: Obj val;
821: int l;
822:
823: val = asir_pop_one();
824: if ( !val ) {
825: if ( limit >= 2 ) {
826: sprintf(string,"0");
827: l = strlen(string);
828: } else
829: l = -1;
830: } else {
831: l = estimate_length(CO,val);
832: if ( l+1 <= limit ) {
833: soutput_init(string);
834: sprintexpr(CO,val);
835: l = strlen(string);
836: } else
837: l = -1;
838: }
839: return l;
1.3 noro 840: }
841:
842: /*
843: * Executes an SM command.
844: */
845:
1.13 noro 846: void asir_ox_push_cmd(int cmd)
1.3 noro 847: {
1.7 noro 848: int ret;
849: ERR err;
850: extern char LastError[];
851:
1.35 noro 852: if ( ret = SETJMP(main_env) ) {
1.12 noro 853: asir_reset_handler();
1.7 noro 854: if ( ret == 1 ) {
855: create_error(&err,0,LastError); /* XXX */
856: asir_push_one((Obj)err);
857: }
1.12 noro 858: } else {
859: asir_save_handler();
860: asir_set_handler();
1.7 noro 861: asir_do_cmd(cmd,0);
1.12 noro 862: asir_reset_handler();
863: }
1.3 noro 864: }
865:
866: /*
867: * Executes a string written in Asir.
868: */
869:
870: void asir_ox_execute_string(char *s)
871: {
872: STRING str;
1.8 noro 873: int ret;
874: ERR err;
875: extern char LastError[];
1.3 noro 876:
877: MKSTR(str,s);
878: asir_push_one((Obj)str);
1.35 noro 879: if ( ret = SETJMP(main_env) ) {
1.12 noro 880: asir_reset_handler();
1.8 noro 881: if ( ret == 1 ) {
882: create_error(&err,0,LastError); /* XXX */
883: asir_push_one((Obj)err);
884: }
1.12 noro 885: } else {
886: asir_save_handler();
887: asir_set_handler();
1.8 noro 888: asir_executeString();
1.12 noro 889: asir_reset_handler();
890: }
1.3 noro 891: }
892:
893: /*
894: * Returns the size as a CMO of the object
895: * at the top of the stack.
896: */
897:
898: int asir_ox_peek_cmo_size()
899: {
900: Obj obj;
901: int len;
902:
1.38 noro 903: obj = asir_peek_one();
1.10 noro 904: if ( !valid_as_cmo(obj) ) {
905: fprintf(stderr,"The object at the stack top is invalid as a CMO.\n");
906: return 0;
907: }
1.3 noro 908: len = count_as_cmo(obj);
1.38 noro 909: return len;
910: }
911:
912: int asir_ox_peek_cmo_string_length()
913: {
914: Obj obj;
915: int len;
916:
917: obj = asir_peek_one();
918: if ( !valid_as_cmo(obj) ) {
919: fprintf(stderr,"The object at the stack top is invalid as a CMO.\n");
920: return 0;
921: }
922: len = estimate_length(CO,obj);
1.39 noro 923: return len+1;
1.3 noro 924: }
925:
926: /*
927: * Initialization.
1.11 noro 928: * byteorder=0 => native
929: * =1 => network byte order
1.3 noro 930: */
931:
1.13 noro 932: int asir_ox_init(int byteorder)
1.3 noro 933: {
934: int tmp;
935: char ifname[BUFSIZ];
936: extern int GC_dont_gc;
937: extern int read_exec_file;
938: extern int do_asirrc;
939: extern int do_server_in_X11;
940: char *getenv();
941: static ox_asir_initialized = 0;
942: FILE *ifp;
943:
1.42 ! noro 944: #if !defined(VISUAL) && !MPI
1.9 noro 945: do_server_in_X11 = 0; /* XXX */
1.3 noro 946: #endif
947: asir_save_handler();
1.41 ohara 948: #if defined(PARI)
1.3 noro 949: risa_pari_init();
950: #endif
951: srandom((int)get_current_time());
952:
953: rtime_init();
954: env_init();
955: endian_init();
956: GC_init();
957: /* process_args(argc,argv); */
958: output_init();
959: arf_init();
960: nglob_init();
961: glob_init();
962: sig_init();
963: tty_init();
964: debug_init();
965: pf_init();
966: sysf_init();
967: parif_init();
968: #if defined(VISUAL)
969: init_socket();
970: #endif
971: #if defined(UINIT)
972: reg_sysf();
973: #endif
974: sprintf(ifname,"%s/.asirrc",getenv("HOME"));
975: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
976: input_init(ifp,ifname);
1.35 noro 977: if ( !SETJMP(main_env) ) {
1.3 noro 978: read_exec_file = 1;
979: read_eval_loop();
980: read_exec_file = 0;
981: }
982: fclose(ifp);
983: }
984: input_init(0,"string");
985:
986: asir_OperandStackSize = BUFSIZ;
987: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
988: asir_OperandStackPtr = -1;
1.11 noro 989: if ( little_endian && byteorder )
990: lib_ox_need_conv = 1;
1.3 noro 991: else
1.11 noro 992: lib_ox_need_conv = 0;
1.3 noro 993: do_message = 0;
1.11 noro 994: create_my_mathcap("ox_asir");
1.12 noro 995: asir_reset_handler();
1.13 noro 996: return 0;
1.1 noro 997: }
1.17 noro 998: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>