Annotation of OpenXM_contrib2/asir2000/io/ox_asir.c, Revision 1.4
1.4 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/io/ox_asir.c,v 1.3 2000/01/18 05:55:07 noro Exp $ */
1.1 noro 2: #include "ca.h"
3: #include "parse.h"
4: #include "ox.h"
5: #include "version.h"
6:
7: void ox_usr1_handler();
8:
9: extern jmp_buf environnement;
10:
11: extern int do_message;
12: extern int ox_flushing;
13: extern jmp_buf ox_env;
14: extern MATHCAP my_mathcap;
15:
16: int ox_sock_id;
17:
18: static int asir_OperandStackSize;
19: static Obj *asir_OperandStack;
20: static int asir_OperandStackPtr = -1;
21:
22: static void create_error(ERR *,unsigned int ,char *);
23: static void ox_io_init();
24: static void ox_asir_init(int,char **);
25: static Obj asir_pop_one();
26: static void asir_push_one(Obj);
27: static void asir_end_flush();
28: static void asir_executeFunction(int);
29: static int asir_executeString();
30: static void asir_evalName(unsigned int);
31: static void asir_setName(unsigned int);
32: static void asir_pops();
33: static void asir_popString();
34: static void asir_popCMO(unsigned int);
35: static void asir_popSerializedLocalObject();
36: static LIST asir_GetErrorList();
37: static char *name_of_cmd(unsigned int);
38: static char *name_of_id(int);
39: static void asir_do_cmd(unsigned int,unsigned int);
40:
41: #if MPI
42: extern int mpi_nprocs,mpi_myid;
43:
44: void ox_mpi_master_init() {
45: int i,idx,ret;
46:
47: for ( i = 1; i < mpi_nprocs; i++ ) {
48: /* client mode */
49: idx = get_iofp(i,0,0);
1.2 noro 50: ret = register_server(0,idx,idx);
1.1 noro 51: }
52: }
53:
54: void ox_mpi_slave_init() {
55: endian_init();
56: /* server mode */
57: get_iofp(0,0,1);
58: fclose(stdin);
59: asir_OperandStackSize = BUFSIZ;
60: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
61: asir_OperandStackPtr = -1;
62: }
63: #endif
64:
65: static void create_error(ERR *err,unsigned int serial,char *msg)
66: {
67: int len;
68: USINT ui;
69: NODE n,n1;
70: LIST list;
71: char *msg1;
72: STRING errmsg;
73:
74: MKUSINT(ui,serial);
75: len = strlen(msg);
76: msg1 = (char *)MALLOC(len+1);
77: strcpy(msg1,msg);
78: MKSTR(errmsg,msg1);
79: MKNODE(n1,errmsg,0); MKNODE(n,ui,n1); MKLIST(list,n);
80: MKERR(*err,list);
81: }
82:
83: void ox_main(int argc,char **argv) {
84: int id;
85: unsigned int cmd;
86: Obj obj;
87: USINT ui;
88: ERR err;
89: LIST list;
90: NODE n,n1;
91: unsigned int serial;
92: int ret;
93: extern char LastError[];
94:
95: ox_asir_init(argc,argv);
96: if ( do_message )
97: fprintf(stderr,"I'm an ox_asir, Version %d.\n",ASIR_VERSION);
98: if ( setjmp(ox_env) ) {
99: while ( NEXT(asir_infile) )
100: closecurrentinput();
101: ox_send_sync(0);
102: }
103: while ( 1 ) {
104: extern int recv_intr;
105:
106: serial = ox_recv(0,&id,&obj);
107: #if defined(VISUAL)
108: if ( recv_intr ) {
109: if ( recv_intr == 1 ) {
110: recv_intr = 0;
111: int_handler(SIGINT);
112: } else {
113: recv_intr = 0;
114: ox_usr1_handler(0);
115: }
116: }
117: #endif
118: if ( do_message )
119: fprintf(stderr,"#%d Got %s",serial,name_of_id(id));
120: switch ( id ) {
121: case OX_COMMAND:
122: cmd = ((USINT)obj)->body;
123: if ( ox_flushing )
124: break;
125: if ( do_message )
126: fprintf(stderr," %s\n",name_of_cmd(cmd));
127: if ( ret = setjmp(env) ) {
128: if ( ret == 1 ) {
129: create_error(&err,serial,LastError);
130: asir_push_one((Obj)err);
131: }
132: break;
133: }
134: asir_do_cmd(cmd,serial);
135: break;
136: case OX_DATA:
137: case OX_LOCAL_OBJECT_ASIR:
138: if ( ox_flushing )
139: break;
140: if ( do_message )
141: fprintf(stderr," -> data pushed");
142: asir_push_one(obj);
143: break;
144: case OX_SYNC_BALL:
145: asir_end_flush();
146: break;
147: default:
148: break;
149: }
150: if ( do_message )
151: fprintf(stderr,"\n");
152: }
153: }
154:
155: static void asir_do_cmd(unsigned int cmd,unsigned int serial)
156: {
157: MATHCAP client_mathcap;
158: Q q;
159: int i;
160: LIST list;
161:
162: switch ( cmd ) {
163: case SM_dupErrors:
164: list = asir_GetErrorList();
165: asir_push_one((Obj)list);
166: break;
167: case SM_getsp:
168: i = asir_OperandStackPtr+1;
169: STOQ(i,q);
170: asir_push_one((Obj)q);
171: break;
172: case SM_popSerializedLocalObject:
173: asir_popSerializedLocalObject();
174: break;
175: case SM_popCMO:
176: asir_popCMO(serial);
177: break;
178: case SM_popString:
179: asir_popString();
180: break;
181: case SM_setName:
182: asir_setName(serial);
183: break;
184: case SM_evalName:
185: asir_evalName(serial);
186: break;
187: case SM_executeStringByLocalParser:
188: asir_executeString();
189: break;
190: case SM_executeStringByLocalParserInBatchMode:
191: asir_executeString();
192: asir_pop_one();
193: break;
194: case SM_executeFunction:
195: asir_executeFunction(serial);
196: break;
197: case SM_shutdown:
198: asir_terminate(2);
199: break;
200: case SM_pops:
201: asir_pops();
202: break;
203: case SM_mathcap:
204: asir_push_one((Obj)my_mathcap);
205: break;
206: case SM_setMathcap:
207: client_mathcap = (MATHCAP)asir_pop_one();
208: store_remote_mathcap(0,client_mathcap);
209: break;
210: case SM_nop:
211: default:
212: break;
213: }
214: }
215:
216: static char *name_of_id(int id)
217: {
218: switch ( id ) {
219: case OX_COMMAND:
220: return "OX_COMMAND";
221: break;
222: case OX_DATA:
223: return "OX_DATA";
224: break;
225: case OX_LOCAL_OBJECT_ASIR:
226: return "OX_LOCAL_OBJECT_ASIR";
227: break;
228: case OX_SYNC_BALL:
229: return "OX_SYNC_BALL";
230: break;
231: default:
232: return "Unknown id";
233: break;
234: }
235: }
236:
237: static char *name_of_cmd(unsigned cmd)
238: {
239: switch ( cmd ) {
240: case SM_popSerializedLocalObject:
241: return "SM_popSerializedLocalObject";
242: break;
243: case SM_popCMO:
244: return "SM_popCMO";
245: break;
246: case SM_popString:
247: return "SM_popString";
248: break;
249: case SM_pops:
250: return "SM_pops";
251: break;
252: case SM_setName:
253: return "SM_setName";
254: break;
255: case SM_evalName:
256: return "SM_evalName";
257: break;
258: case SM_executeStringByLocalParser:
259: return "SM_executeString";
260: break;
261: case SM_executeFunction:
262: return "SM_executeFunction";
263: break;
264: case SM_shutdown:
265: return "SM_shutdown";
266: break;
267: case SM_beginBlock:
268: return "SM_beginBlock";
269: break;
270: case SM_endBlock:
271: return "SM_endBlock";
272: break;
273: case SM_mathcap:
274: return "SM_mathcap";
275: break;
276: case SM_setMathcap:
277: return "SM_setMathcap";
278: break;
279: case SM_getsp:
280: return "SM_setMathcap";
281: break;
282: case SM_dupErrors:
283: return "SM_dupErrors";
284: break;
285: case SM_nop:
286: return "SM_nop";
287: default:
288: return "Unknown cmd";
289: break;
290: }
291: }
292:
293: static LIST asir_GetErrorList()
294: {
295: int i;
296: NODE n,n0;
297: LIST err;
298: Obj obj;
299:
300: for ( i = 0, n0 = 0; i <= asir_OperandStackPtr; i++ )
301: if ( (obj = asir_OperandStack[i]) && (OID(obj) == O_ERR) ) {
302: NEXTNODE(n0,n); BDY(n) = (pointer)obj;
303: }
304: if ( n0 )
305: NEXT(n) = 0;
306: MKLIST(err,n0);
307: return err;
308: }
309:
310: static void asir_popSerializedLocalObject()
311: {
312: Obj obj;
313: VL t,vl;
314:
315: obj = asir_pop_one();
316: get_vars_recursive(obj,&vl);
317: for ( t = vl; t; t = NEXT(t) )
318: if ( t->v->attr == (pointer)V_UC )
319: error("bsave : not implemented");
320: ox_send_cmd(0,SM_beginBlock);
321: ox_send_local_ring(0,vl);
322: ox_send_local_data(0,obj);
323: ox_send_cmd(0,SM_endBlock);
324: }
325:
326: static void asir_popCMO(unsigned int serial)
327: {
328: Obj obj;
329: ERR err;
330:
331: obj = asir_pop_one();
332: if ( valid_as_cmo(obj) )
333: ox_send_data(0,obj);
334: else {
335: create_error(&err,serial,"cannot convert to CMO object");
336: ox_send_data(0,err);
337: asir_push_one(obj);
338: }
339: }
340:
341: static void asir_popString()
342: {
343: Obj val;
344: char *buf,*obuf;
345: int l;
346: STRING str;
347:
348: val = asir_pop_one();
349: if ( !val )
350: obuf = 0;
351: else {
352: l = estimate_length(CO,val);
353: buf = (char *)ALLOCA(l+1);
354: soutput_init(buf);
355: sprintexpr(CO,val);
356: l = strlen(buf);
357: obuf = (char *)MALLOC(l+1);
358: strcpy(obuf,buf);
359: }
360: MKSTR(str,obuf);
361: ox_send_data(0,str);
362: }
363:
364: static void asir_pops()
365: {
366: int n;
367:
368: n = (int)(((USINT)asir_pop_one())->body);
369: asir_OperandStackPtr = MAX(asir_OperandStackPtr-n,-1);
370: }
371:
372: static void asir_setName(unsigned int serial)
373: {
374: char *name;
375: int l,n;
376: char *dummy = "=0;";
377: SNODE snode;
378: ERR err;
379:
380: name = ((STRING)asir_pop_one())->body;
381: l = strlen(name);
382: n = l+strlen(dummy)+1;
383: parse_strp = (char *)ALLOCA(n);
384: sprintf(parse_strp,"%s%s",name,dummy);
385: if ( mainparse(&snode) ) {
386: create_error(&err,serial,"cannot set to variable");
387: asir_push_one((Obj)err);
388: } else {
389: FA1((FNODE)FA0(snode)) = (pointer)mkfnode(1,I_FORMULA,asir_pop_one());
390: evalstat(snode);
391: }
392: }
393:
394: static void asir_evalName(unsigned int serial)
395: {
396: char *name;
397: int l,n;
398: SNODE snode;
399: ERR err;
400: pointer val;
401:
402: name = ((STRING)asir_pop_one())->body;
403: l = strlen(name);
404: n = l+2;
405: parse_strp = (char *)ALLOCA(n);
406: sprintf(parse_strp,"%s;",name);
407: if ( mainparse(&snode) ) {
408: create_error(&err,serial,"no such variable");
409: val = (pointer)err;
410: } else
411: val = evalstat(snode);
412: asir_push_one(val);
413: }
414:
415: static int asir_executeString()
416: {
417: SNODE snode;
418: pointer val;
419: char *cmd;
420: #if PARI
421: recover(0);
422: if ( setjmp(environnement) ) {
423: avma = top; recover(1);
424: resetenv("");
425: }
426: #endif
427: cmd = ((STRING)asir_pop_one())->body;
428: parse_strp = cmd;
429: if ( mainparse(&snode) ) {
430: return -1;
431: }
432: val = evalstat(snode);
433: if ( NEXT(asir_infile) ) {
434: while ( NEXT(asir_infile) ) {
435: if ( mainparse(&snode) ) {
436: asir_push_one(val);
437: return -1;
438: }
439: nextbp = 0;
440: val = evalstat(snode);
441: }
442: }
443: asir_push_one(val);
444: return 0;
445: }
446:
447: static void asir_executeFunction(int serial)
448: {
449: char *func;
450: int argc;
451: FUNC f;
452: Obj result;
453: VL vl;
454: NODE n,n1;
455: STRING fname;
456: char *path;
457: USINT ui;
458: ERR err;
459: static char buf[BUFSIZ];
460:
461: func = ((STRING)asir_pop_one())->body;
462: argc = (int)(((USINT)asir_pop_one())->body);
463:
464: for ( n = 0; argc; argc-- ) {
465: NEXTNODE(n,n1);
466: BDY(n1) = (pointer)asir_pop_one();
467: }
468: if ( n )
469: NEXT(n1) = 0;
470:
471: if ( !strcmp(func,"load") ) {
472: fname = (STRING)BDY(n);
473: if ( OID(fname) == O_STR ) {
474: searchasirpath(BDY(fname),&path);
475: if ( path ) {
476: if ( do_message )
477: fprintf(stderr,"loading %s\n",path);
478: execasirfile(path);
479: } else
480: if ( do_message )
481: fprintf(stderr,"load : %s not found in the search path\n",BDY(fname));
482: }
483: result = 0;
484: } else {
485: searchf(noargsysf,func,&f);
486: if ( !f )
487: searchf(sysf,func,&f);
488: if ( !f )
489: searchf(ubinf,func,&f);
490: if ( !f )
491: searchf(usrf,func,&f);
492: if ( !f ) {
493: sprintf(buf,"executeFunction : the function %s not found",func);
494: create_error(&err,serial,buf);
495: result = (Obj)err;
496: } else {
497: result = (Obj)bevalf(f,n);
498: }
499: }
500: asir_push_one(result);
501: }
502:
503: static void asir_end_flush()
504: {
505: ox_flushing = 0;
506: }
507:
508: /*
509: asir_OperandStackPtr points to the surface of the stack.
510: That is, the data at the stack top is
511: asir_OperandStack[asir_OperandStackPtr].
512: */
513:
514:
515: static void asir_push_one(Obj obj)
516: {
517: if ( !obj || OID(obj) != O_VOID ) {
518: asir_OperandStackPtr++;
519: if ( asir_OperandStackPtr >= asir_OperandStackSize ) {
520: asir_OperandStackSize += BUFSIZ;
521: asir_OperandStack
522: = (Obj *)REALLOC(asir_OperandStack,
523: asir_OperandStackSize*sizeof(Obj));
524: }
525: asir_OperandStack[asir_OperandStackPtr] = obj;
526: }
527: }
528:
529: static Obj asir_pop_one() {
530: if ( asir_OperandStackPtr < 0 ) {
531: if ( do_message )
532: fprintf(stderr,"OperandStack underflow");
533: return 0;
534: } else {
535: if ( do_message )
536: fprintf(stderr,"pop at %d\n",asir_OperandStackPtr);
537: return asir_OperandStack[asir_OperandStackPtr--];
538: }
539: }
540:
541: static void ox_asir_init(int argc,char **argv)
542: {
543: int tmp;
544: char ifname[BUFSIZ];
545: extern int GC_dont_gc;
546: extern int read_exec_file;
547: extern int do_asirrc;
548: extern int do_server_in_X11;
549: char *getenv();
550: static ox_asir_initialized = 0;
551: FILE *ifp;
1.4 ! noro 552: char *homedir;
! 553: char *ptr;
1.1 noro 554:
555: #if !defined(VISUAL) && !MPI
556: do_server_in_X11 = 1; /* XXX */
557: #endif
558: asir_save_handler();
559: #if PARI
560: risa_pari_init();
561: #endif
562: srandom((int)get_current_time());
563:
564: #if defined(THINK_C)
565: param_init();
566: #endif
567: StackBottom = &tmp + 1; /* XXX */
568: rtime_init();
569: env_init();
570: endian_init();
571: #if !defined(VISUAL) && !defined(THINK_C)
572: /* check_key(); */
573: #endif
574: GC_init();
575: process_args(--argc,++argv);
576: output_init();
577: arf_init();
578: nglob_init();
579: glob_init();
580: sig_init();
581: tty_init();
582: debug_init();
583: pf_init();
584: sysf_init();
585: parif_init();
586: #if defined(VISUAL)
587: init_socket();
588: #endif
589: #if defined(UINIT)
590: reg_sysf();
591: #endif
1.4 ! noro 592: /* if ASIR_CONFIG is set, execute it; else execute .asirrc */
! 593: if ( ptr = getenv("ASIR_CONFIG") )
! 594: strcpy(ifname,ptr);
! 595: else {
1.1 noro 596: #if defined(THINK_C)
1.4 ! noro 597: sprintf(ifname,"asirrc");
1.1 noro 598: #else
1.4 ! noro 599: homedir = getenv("HOME");
! 600: if ( !homedir ) {
! 601: char rootname[BUFSIZ];
! 602:
! 603: get_rootdir(rootname,sizeof(rootname));
! 604: homedir = rootname;
! 605: }
! 606: sprintf(ifname,"%s/.asirrc",homedir);
1.1 noro 607: #endif
1.4 ! noro 608: }
1.1 noro 609: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
610: input_init(ifp,ifname);
611: if ( !setjmp(env) ) {
612: read_exec_file = 1;
613: read_eval_loop();
614: read_exec_file = 0;
615: }
616: fclose(ifp);
617: }
618: input_init(0,"string");
619: #if !MPI
620: ox_io_init();
621: #endif
622: create_my_mathcap("ox_asir");
623: }
624:
625: static void ox_io_init() {
626: unsigned char c,rc;
627: extern int little_endian,ox_sock_id;
628:
629: endian_init();
630: #if defined(VISUAL)
631: if ( !ox_sock_id )
632: exit(0);
633: iofp[0].in = WSIO_open(ox_sock_id,"r");
634: iofp[0].out = WSIO_open(ox_sock_id,"w");
635: #else
636: iofp[0].in = fdopen(3,"r");
637: iofp[0].out = fdopen(4,"w");
638:
639: setbuffer(iofp[0].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
640: setbuffer(iofp[0].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
641: signal(SIGUSR1,ox_usr1_handler);
642: #endif
643: asir_OperandStackSize = BUFSIZ;
644: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
645: asir_OperandStackPtr = -1;
646: if ( little_endian )
647: c = 1;
648: else
649: c = 0xff;
650: /* server : write -> read */
651: write_char(iofp[0].out,&c); ox_flush_stream_force(0);
652: read_char(iofp[0].in,&rc);
653: iofp[0].conv = c == rc ? 0 : 1;
1.3 noro 654: }
655:
656: /*
657: * Library mode functions
658: */
659:
660: /*
661: * Converts a binary encoded CMO into a risa object
662: * and pushes it onto the stack.
663: */
664:
665: void asir_ox_push_cmo(void *cmo)
666: {
667: Obj obj;
668:
669: ox_copy_init(cmo);
670: ox_buf_to_obj_as_cmo(&obj);
671: asir_push_one(obj);
672: }
673:
674: /*
675: * Pop an object from the stack and converts it
676: * int a binary encoded CMO.
677: */
678:
679: int asir_ox_pop_cmo(void *cmo, int limit)
680: {
681: Obj obj;
682: int len;
683:
684: obj = asir_pop_one();
685: len = count_as_cmo(obj);
686: if ( len <= limit ) {
687: ox_copy_init(cmo);
688: ox_obj_to_buf_as_cmo(obj);
689: return len;
690: } else
691: return -1;
692: }
693:
694: /*
695: * Executes an SM command.
696: */
697:
698: void asir_ox_push_cmd(unsigned int cmd)
699: {
700: asir_do_cmd(cmd,0);
701: }
702:
703: /*
704: * Executes a string written in Asir.
705: */
706:
707: void asir_ox_execute_string(char *s)
708: {
709: STRING str;
710:
711: MKSTR(str,s);
712: asir_push_one((Obj)str);
713: asir_executeString();
714: }
715:
716: /*
717: * Returns the size as a CMO of the object
718: * at the top of the stack.
719: */
720:
721: int asir_ox_peek_cmo_size()
722: {
723: Obj obj;
724: int len;
725:
726: obj = asir_pop_one();
727: len = count_as_cmo(obj);
728: asir_push_one(obj);
729: return len;
730: }
731:
732: /*
733: * Initialization.
734: * byteorder = 1 : little endian
735: * 0 : big endian
736: */
737:
738: void asir_ox_io_init();
739:
740: void asir_ox_init(int byteorder)
741: {
742: int tmp;
743: char ifname[BUFSIZ];
744: extern int GC_dont_gc;
745: extern int read_exec_file;
746: extern int do_asirrc;
747: extern int do_server_in_X11;
748: char *getenv();
749: static ox_asir_initialized = 0;
750: FILE *ifp;
751:
752: #if !defined(VISUAL) && !MPI
753: do_server_in_X11 = 1; /* XXX */
754: #endif
755: asir_save_handler();
756: #if PARI
757: risa_pari_init();
758: #endif
759: srandom((int)get_current_time());
760:
761: #if defined(THINK_C)
762: param_init();
763: #endif
764: StackBottom = &tmp + 1; /* XXX */
765: rtime_init();
766: env_init();
767: endian_init();
768: #if !defined(VISUAL) && !defined(THINK_C)
769: /* check_key(); */
770: #endif
771: GC_init();
772: /* process_args(argc,argv); */
773: output_init();
774: arf_init();
775: nglob_init();
776: glob_init();
777: sig_init();
778: tty_init();
779: debug_init();
780: pf_init();
781: sysf_init();
782: parif_init();
783: #if defined(VISUAL)
784: init_socket();
785: #endif
786: #if defined(UINIT)
787: reg_sysf();
788: #endif
789: #if defined(THINK_C)
790: sprintf(ifname,"asirrc");
791: #else
792: sprintf(ifname,"%s/.asirrc",getenv("HOME"));
793: #endif
794: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
795: input_init(ifp,ifname);
796: if ( !setjmp(env) ) {
797: read_exec_file = 1;
798: read_eval_loop();
799: read_exec_file = 0;
800: }
801: fclose(ifp);
802: }
803: input_init(0,"string");
804: asir_ox_io_init(byteorder);
805: create_my_mathcap("ox_asir");
806: }
807:
808: void asir_ox_io_init(byteorder)
809: int byteorder;
810: {
811: unsigned char c;
812: extern int little_endian;
813: extern int lib_ox_initialized;
814:
815: endian_init();
816: asir_OperandStackSize = BUFSIZ;
817: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
818: asir_OperandStackPtr = -1;
819: if ( little_endian )
820: c = 1;
821: else
822: c = 0;
823: iofp[0].conv = c == byteorder ? 0 : 1;
824: lib_ox_initialized = 1;
825: do_message = 0;
1.1 noro 826: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>