Annotation of OpenXM_contrib2/asir2000/io/ox_asir.c, Revision 1.5
1.5 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/io/ox_asir.c,v 1.4 2000/01/19 09:31:00 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;
1.5 ! noro 459: Obj arg;
1.1 noro 460: static char buf[BUFSIZ];
461:
1.5 ! noro 462: arg = asir_pop_one();
! 463: if ( !arg || OID(arg) != O_STR ) {
! 464: sprintf(buf,"executeFunction : invalid function name");
! 465: goto error;
! 466: } else
! 467: func = ((STRING)arg)->body;
! 468:
! 469: arg = asir_pop_one();
! 470: if ( !arg || OID(arg) != O_USINT ) {
! 471: sprintf(buf,"executeFunction : invalid argc");
! 472: goto error;
! 473: } else
! 474: argc = (int)(((USINT)arg)->body);
1.1 noro 475:
476: for ( n = 0; argc; argc-- ) {
477: NEXTNODE(n,n1);
478: BDY(n1) = (pointer)asir_pop_one();
479: }
480: if ( n )
481: NEXT(n1) = 0;
482:
483: if ( !strcmp(func,"load") ) {
484: fname = (STRING)BDY(n);
485: if ( OID(fname) == O_STR ) {
486: searchasirpath(BDY(fname),&path);
487: if ( path ) {
488: if ( do_message )
489: fprintf(stderr,"loading %s\n",path);
490: execasirfile(path);
491: } else
492: if ( do_message )
493: fprintf(stderr,"load : %s not found in the search path\n",BDY(fname));
494: }
495: result = 0;
496: } else {
497: searchf(noargsysf,func,&f);
498: if ( !f )
499: searchf(sysf,func,&f);
500: if ( !f )
501: searchf(ubinf,func,&f);
502: if ( !f )
503: searchf(usrf,func,&f);
504: if ( !f ) {
505: sprintf(buf,"executeFunction : the function %s not found",func);
1.5 ! noro 506: goto error;
1.1 noro 507: } else {
508: result = (Obj)bevalf(f,n);
509: }
510: }
1.5 ! noro 511: asir_push_one(result);
! 512: return;
! 513:
! 514: error:
! 515: create_error(&err,serial,buf);
! 516: result = (Obj)err;
1.1 noro 517: asir_push_one(result);
518: }
519:
520: static void asir_end_flush()
521: {
522: ox_flushing = 0;
523: }
524:
525: /*
526: asir_OperandStackPtr points to the surface of the stack.
527: That is, the data at the stack top is
528: asir_OperandStack[asir_OperandStackPtr].
529: */
530:
531:
532: static void asir_push_one(Obj obj)
533: {
534: if ( !obj || OID(obj) != O_VOID ) {
535: asir_OperandStackPtr++;
536: if ( asir_OperandStackPtr >= asir_OperandStackSize ) {
537: asir_OperandStackSize += BUFSIZ;
538: asir_OperandStack
539: = (Obj *)REALLOC(asir_OperandStack,
540: asir_OperandStackSize*sizeof(Obj));
541: }
542: asir_OperandStack[asir_OperandStackPtr] = obj;
543: }
544: }
545:
546: static Obj asir_pop_one() {
547: if ( asir_OperandStackPtr < 0 ) {
548: if ( do_message )
549: fprintf(stderr,"OperandStack underflow");
550: return 0;
551: } else {
552: if ( do_message )
553: fprintf(stderr,"pop at %d\n",asir_OperandStackPtr);
554: return asir_OperandStack[asir_OperandStackPtr--];
555: }
556: }
557:
558: static void ox_asir_init(int argc,char **argv)
559: {
560: int tmp;
561: char ifname[BUFSIZ];
562: extern int GC_dont_gc;
563: extern int read_exec_file;
564: extern int do_asirrc;
565: extern int do_server_in_X11;
566: char *getenv();
567: static ox_asir_initialized = 0;
568: FILE *ifp;
1.4 noro 569: char *homedir;
570: char *ptr;
1.1 noro 571:
572: #if !defined(VISUAL) && !MPI
573: do_server_in_X11 = 1; /* XXX */
574: #endif
575: asir_save_handler();
576: #if PARI
577: risa_pari_init();
578: #endif
579: srandom((int)get_current_time());
580:
581: #if defined(THINK_C)
582: param_init();
583: #endif
584: StackBottom = &tmp + 1; /* XXX */
585: rtime_init();
586: env_init();
587: endian_init();
588: #if !defined(VISUAL) && !defined(THINK_C)
589: /* check_key(); */
590: #endif
591: GC_init();
592: process_args(--argc,++argv);
593: output_init();
594: arf_init();
595: nglob_init();
596: glob_init();
597: sig_init();
598: tty_init();
599: debug_init();
600: pf_init();
601: sysf_init();
602: parif_init();
603: #if defined(VISUAL)
604: init_socket();
605: #endif
606: #if defined(UINIT)
607: reg_sysf();
608: #endif
1.4 noro 609: /* if ASIR_CONFIG is set, execute it; else execute .asirrc */
610: if ( ptr = getenv("ASIR_CONFIG") )
611: strcpy(ifname,ptr);
612: else {
1.1 noro 613: #if defined(THINK_C)
1.4 noro 614: sprintf(ifname,"asirrc");
1.1 noro 615: #else
1.4 noro 616: homedir = getenv("HOME");
617: if ( !homedir ) {
618: char rootname[BUFSIZ];
619:
620: get_rootdir(rootname,sizeof(rootname));
621: homedir = rootname;
622: }
623: sprintf(ifname,"%s/.asirrc",homedir);
1.1 noro 624: #endif
1.4 noro 625: }
1.1 noro 626: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
627: input_init(ifp,ifname);
628: if ( !setjmp(env) ) {
629: read_exec_file = 1;
630: read_eval_loop();
631: read_exec_file = 0;
632: }
633: fclose(ifp);
634: }
635: input_init(0,"string");
636: #if !MPI
637: ox_io_init();
638: #endif
639: create_my_mathcap("ox_asir");
640: }
641:
642: static void ox_io_init() {
643: unsigned char c,rc;
644: extern int little_endian,ox_sock_id;
645:
646: endian_init();
647: #if defined(VISUAL)
648: if ( !ox_sock_id )
649: exit(0);
650: iofp[0].in = WSIO_open(ox_sock_id,"r");
651: iofp[0].out = WSIO_open(ox_sock_id,"w");
652: #else
653: iofp[0].in = fdopen(3,"r");
654: iofp[0].out = fdopen(4,"w");
655:
656: setbuffer(iofp[0].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
657: setbuffer(iofp[0].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
658: signal(SIGUSR1,ox_usr1_handler);
659: #endif
660: asir_OperandStackSize = BUFSIZ;
661: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
662: asir_OperandStackPtr = -1;
663: if ( little_endian )
664: c = 1;
665: else
666: c = 0xff;
667: /* server : write -> read */
668: write_char(iofp[0].out,&c); ox_flush_stream_force(0);
669: read_char(iofp[0].in,&rc);
670: iofp[0].conv = c == rc ? 0 : 1;
1.3 noro 671: }
672:
673: /*
674: * Library mode functions
675: */
676:
677: /*
678: * Converts a binary encoded CMO into a risa object
679: * and pushes it onto the stack.
680: */
681:
682: void asir_ox_push_cmo(void *cmo)
683: {
684: Obj obj;
685:
686: ox_copy_init(cmo);
687: ox_buf_to_obj_as_cmo(&obj);
688: asir_push_one(obj);
689: }
690:
691: /*
692: * Pop an object from the stack and converts it
693: * int a binary encoded CMO.
694: */
695:
696: int asir_ox_pop_cmo(void *cmo, int limit)
697: {
698: Obj obj;
699: int len;
700:
701: obj = asir_pop_one();
702: len = count_as_cmo(obj);
703: if ( len <= limit ) {
704: ox_copy_init(cmo);
705: ox_obj_to_buf_as_cmo(obj);
706: return len;
707: } else
708: return -1;
709: }
710:
711: /*
712: * Executes an SM command.
713: */
714:
715: void asir_ox_push_cmd(unsigned int cmd)
716: {
717: asir_do_cmd(cmd,0);
718: }
719:
720: /*
721: * Executes a string written in Asir.
722: */
723:
724: void asir_ox_execute_string(char *s)
725: {
726: STRING str;
727:
728: MKSTR(str,s);
729: asir_push_one((Obj)str);
730: asir_executeString();
731: }
732:
733: /*
734: * Returns the size as a CMO of the object
735: * at the top of the stack.
736: */
737:
738: int asir_ox_peek_cmo_size()
739: {
740: Obj obj;
741: int len;
742:
743: obj = asir_pop_one();
744: len = count_as_cmo(obj);
745: asir_push_one(obj);
746: return len;
747: }
748:
749: /*
750: * Initialization.
751: * byteorder = 1 : little endian
752: * 0 : big endian
753: */
754:
755: void asir_ox_io_init();
756:
757: void asir_ox_init(int byteorder)
758: {
759: int tmp;
760: char ifname[BUFSIZ];
761: extern int GC_dont_gc;
762: extern int read_exec_file;
763: extern int do_asirrc;
764: extern int do_server_in_X11;
765: char *getenv();
766: static ox_asir_initialized = 0;
767: FILE *ifp;
768:
769: #if !defined(VISUAL) && !MPI
770: do_server_in_X11 = 1; /* XXX */
771: #endif
772: asir_save_handler();
773: #if PARI
774: risa_pari_init();
775: #endif
776: srandom((int)get_current_time());
777:
778: #if defined(THINK_C)
779: param_init();
780: #endif
781: StackBottom = &tmp + 1; /* XXX */
782: rtime_init();
783: env_init();
784: endian_init();
785: #if !defined(VISUAL) && !defined(THINK_C)
786: /* check_key(); */
787: #endif
788: GC_init();
789: /* process_args(argc,argv); */
790: output_init();
791: arf_init();
792: nglob_init();
793: glob_init();
794: sig_init();
795: tty_init();
796: debug_init();
797: pf_init();
798: sysf_init();
799: parif_init();
800: #if defined(VISUAL)
801: init_socket();
802: #endif
803: #if defined(UINIT)
804: reg_sysf();
805: #endif
806: #if defined(THINK_C)
807: sprintf(ifname,"asirrc");
808: #else
809: sprintf(ifname,"%s/.asirrc",getenv("HOME"));
810: #endif
811: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
812: input_init(ifp,ifname);
813: if ( !setjmp(env) ) {
814: read_exec_file = 1;
815: read_eval_loop();
816: read_exec_file = 0;
817: }
818: fclose(ifp);
819: }
820: input_init(0,"string");
821: asir_ox_io_init(byteorder);
822: create_my_mathcap("ox_asir");
823: }
824:
825: void asir_ox_io_init(byteorder)
826: int byteorder;
827: {
828: unsigned char c;
829: extern int little_endian;
830: extern int lib_ox_initialized;
831:
832: endian_init();
833: asir_OperandStackSize = BUFSIZ;
834: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
835: asir_OperandStackPtr = -1;
836: if ( little_endian )
837: c = 1;
838: else
839: c = 0;
840: iofp[0].conv = c == byteorder ? 0 : 1;
841: lib_ox_initialized = 1;
842: do_message = 0;
1.1 noro 843: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>