Annotation of OpenXM_contrib2/asir2000/io/ox_asir.c, Revision 1.3
1.3 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/io/ox_asir.c,v 1.2 1999/12/22 07:01:39 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;
552:
553: #if !defined(VISUAL) && !MPI
554: do_server_in_X11 = 1; /* XXX */
555: #endif
556: asir_save_handler();
557: #if PARI
558: risa_pari_init();
559: #endif
560: srandom((int)get_current_time());
561:
562: #if defined(THINK_C)
563: param_init();
564: #endif
565: StackBottom = &tmp + 1; /* XXX */
566: rtime_init();
567: env_init();
568: endian_init();
569: #if !defined(VISUAL) && !defined(THINK_C)
570: /* check_key(); */
571: #endif
572: GC_init();
573: process_args(--argc,++argv);
574: output_init();
575: arf_init();
576: nglob_init();
577: glob_init();
578: sig_init();
579: tty_init();
580: debug_init();
581: pf_init();
582: sysf_init();
583: parif_init();
584: #if defined(VISUAL)
585: init_socket();
586: #endif
587: #if defined(UINIT)
588: reg_sysf();
589: #endif
590: #if defined(THINK_C)
591: sprintf(ifname,"asirrc");
592: #else
593: sprintf(ifname,"%s/.asirrc",getenv("HOME"));
594: #endif
595: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
596: input_init(ifp,ifname);
597: if ( !setjmp(env) ) {
598: read_exec_file = 1;
599: read_eval_loop();
600: read_exec_file = 0;
601: }
602: fclose(ifp);
603: }
604: input_init(0,"string");
605: #if !MPI
606: ox_io_init();
607: #endif
608: create_my_mathcap("ox_asir");
609: }
610:
611: static void ox_io_init() {
612: unsigned char c,rc;
613: extern int little_endian,ox_sock_id;
614:
615: endian_init();
616: #if defined(VISUAL)
617: if ( !ox_sock_id )
618: exit(0);
619: iofp[0].in = WSIO_open(ox_sock_id,"r");
620: iofp[0].out = WSIO_open(ox_sock_id,"w");
621: #else
622: iofp[0].in = fdopen(3,"r");
623: iofp[0].out = fdopen(4,"w");
624:
625: setbuffer(iofp[0].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
626: setbuffer(iofp[0].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
627: signal(SIGUSR1,ox_usr1_handler);
628: #endif
629: asir_OperandStackSize = BUFSIZ;
630: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
631: asir_OperandStackPtr = -1;
632: if ( little_endian )
633: c = 1;
634: else
635: c = 0xff;
636: /* server : write -> read */
637: write_char(iofp[0].out,&c); ox_flush_stream_force(0);
638: read_char(iofp[0].in,&rc);
639: iofp[0].conv = c == rc ? 0 : 1;
1.3 ! noro 640: }
! 641:
! 642: /*
! 643: * Library mode functions
! 644: */
! 645:
! 646: /*
! 647: * Converts a binary encoded CMO into a risa object
! 648: * and pushes it onto the stack.
! 649: */
! 650:
! 651: void asir_ox_push_cmo(void *cmo)
! 652: {
! 653: Obj obj;
! 654:
! 655: ox_copy_init(cmo);
! 656: ox_buf_to_obj_as_cmo(&obj);
! 657: asir_push_one(obj);
! 658: }
! 659:
! 660: /*
! 661: * Pop an object from the stack and converts it
! 662: * int a binary encoded CMO.
! 663: */
! 664:
! 665: int asir_ox_pop_cmo(void *cmo, int limit)
! 666: {
! 667: Obj obj;
! 668: int len;
! 669:
! 670: obj = asir_pop_one();
! 671: len = count_as_cmo(obj);
! 672: if ( len <= limit ) {
! 673: ox_copy_init(cmo);
! 674: ox_obj_to_buf_as_cmo(obj);
! 675: return len;
! 676: } else
! 677: return -1;
! 678: }
! 679:
! 680: /*
! 681: * Executes an SM command.
! 682: */
! 683:
! 684: void asir_ox_push_cmd(unsigned int cmd)
! 685: {
! 686: asir_do_cmd(cmd,0);
! 687: }
! 688:
! 689: /*
! 690: * Executes a string written in Asir.
! 691: */
! 692:
! 693: void asir_ox_execute_string(char *s)
! 694: {
! 695: STRING str;
! 696:
! 697: MKSTR(str,s);
! 698: asir_push_one((Obj)str);
! 699: asir_executeString();
! 700: }
! 701:
! 702: /*
! 703: * Returns the size as a CMO of the object
! 704: * at the top of the stack.
! 705: */
! 706:
! 707: int asir_ox_peek_cmo_size()
! 708: {
! 709: Obj obj;
! 710: int len;
! 711:
! 712: obj = asir_pop_one();
! 713: len = count_as_cmo(obj);
! 714: asir_push_one(obj);
! 715: return len;
! 716: }
! 717:
! 718: /*
! 719: * Initialization.
! 720: * byteorder = 1 : little endian
! 721: * 0 : big endian
! 722: */
! 723:
! 724: void asir_ox_io_init();
! 725:
! 726: void asir_ox_init(int byteorder)
! 727: {
! 728: int tmp;
! 729: char ifname[BUFSIZ];
! 730: extern int GC_dont_gc;
! 731: extern int read_exec_file;
! 732: extern int do_asirrc;
! 733: extern int do_server_in_X11;
! 734: char *getenv();
! 735: static ox_asir_initialized = 0;
! 736: FILE *ifp;
! 737:
! 738: #if !defined(VISUAL) && !MPI
! 739: do_server_in_X11 = 1; /* XXX */
! 740: #endif
! 741: asir_save_handler();
! 742: #if PARI
! 743: risa_pari_init();
! 744: #endif
! 745: srandom((int)get_current_time());
! 746:
! 747: #if defined(THINK_C)
! 748: param_init();
! 749: #endif
! 750: StackBottom = &tmp + 1; /* XXX */
! 751: rtime_init();
! 752: env_init();
! 753: endian_init();
! 754: #if !defined(VISUAL) && !defined(THINK_C)
! 755: /* check_key(); */
! 756: #endif
! 757: GC_init();
! 758: /* process_args(argc,argv); */
! 759: output_init();
! 760: arf_init();
! 761: nglob_init();
! 762: glob_init();
! 763: sig_init();
! 764: tty_init();
! 765: debug_init();
! 766: pf_init();
! 767: sysf_init();
! 768: parif_init();
! 769: #if defined(VISUAL)
! 770: init_socket();
! 771: #endif
! 772: #if defined(UINIT)
! 773: reg_sysf();
! 774: #endif
! 775: #if defined(THINK_C)
! 776: sprintf(ifname,"asirrc");
! 777: #else
! 778: sprintf(ifname,"%s/.asirrc",getenv("HOME"));
! 779: #endif
! 780: if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
! 781: input_init(ifp,ifname);
! 782: if ( !setjmp(env) ) {
! 783: read_exec_file = 1;
! 784: read_eval_loop();
! 785: read_exec_file = 0;
! 786: }
! 787: fclose(ifp);
! 788: }
! 789: input_init(0,"string");
! 790: asir_ox_io_init(byteorder);
! 791: create_my_mathcap("ox_asir");
! 792: }
! 793:
! 794: void asir_ox_io_init(byteorder)
! 795: int byteorder;
! 796: {
! 797: unsigned char c;
! 798: extern int little_endian;
! 799: extern int lib_ox_initialized;
! 800:
! 801: endian_init();
! 802: asir_OperandStackSize = BUFSIZ;
! 803: asir_OperandStack = (Obj *)CALLOC(asir_OperandStackSize,sizeof(Obj));
! 804: asir_OperandStackPtr = -1;
! 805: if ( little_endian )
! 806: c = 1;
! 807: else
! 808: c = 0;
! 809: iofp[0].conv = c == byteorder ? 0 : 1;
! 810: lib_ox_initialized = 1;
! 811: do_message = 0;
1.1 noro 812: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>