[BACK]Return to ox_plot.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / plot

File: [local] / OpenXM_contrib2 / asir2000 / plot / ox_plot.c (download)

Revision 1.7, Tue Sep 12 06:05:31 2000 UTC (23 years, 8 months ago) by noro
Branch: MAIN
CVS Tags: STABLE_1_1_3, RELEASE_1_1_3
Changes since 1.6: +3 -15 lines

ox_send_data() (the function for replying to popCMO) now returns an error
object when the data violates the mathcap.

/*
 * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED 
 * All rights reserved.
 * 
 * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
 * non-exclusive and royalty-free license to use, copy, modify and
 * redistribute, solely for non-commercial and non-profit purposes, the
 * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
 * conditions of this Agreement. For the avoidance of doubt, you acquire
 * only a limited right to use the SOFTWARE hereunder, and FLL or any
 * third party developer retains all rights, including but not limited to
 * copyrights, in and to the SOFTWARE.
 * 
 * (1) FLL does not grant you a license in any way for commercial
 * purposes. You may use the SOFTWARE only for non-commercial and
 * non-profit purposes only, such as academic, research and internal
 * business use.
 * (2) The SOFTWARE is protected by the Copyright Law of Japan and
 * international copyright treaties. If you make copies of the SOFTWARE,
 * with or without modification, as permitted hereunder, you shall affix
 * to all such copies of the SOFTWARE the above copyright notice.
 * (3) An explicit reference to this SOFTWARE and its copyright owner
 * shall be made on your publication or presentation in any form of the
 * results obtained by use of the SOFTWARE.
 * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
 * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
 * for such modification or the source code of the modified part of the
 * SOFTWARE.
 * 
 * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
 * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
 * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
 * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
 * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
 * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
 * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
 * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
 * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
 * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
 * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
 * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
 * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
 * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
 * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
 *
 * $OpenXM: OpenXM_contrib2/asir2000/plot/ox_plot.c,v 1.7 2000/09/12 06:05:31 noro Exp $ 
*/
#include "ca.h"
#include "parse.h"
#include "ox.h"
#include "ifplot.h"
#include "version.h"
#include <signal.h>
#if PARI
#include "genpari.h"
#endif

void ox_usr1_handler();

extern jmp_buf environnement;

extern int do_message;
extern int ox_flushing;
extern jmp_buf ox_env;
extern MATHCAP my_mathcap;

static int plot_OperandStackSize;
static Obj *plot_OperandStack;
static int plot_OperandStackPtr = -1;

void create_error(ERR *,unsigned int ,char *);

static void process_ox();
static void ox_io_init();
static void ox_asir_init(int,char **);
static Obj asir_pop_one();
static void asir_push_one(Obj);
static void asir_end_flush();
static void asir_executeFunction();
static int asir_executeString();
static void asir_evalName(unsigned int);
static void asir_setName(unsigned int);
static void asir_pops();
static void asir_popString();
static void asir_popCMO(unsigned int);
static void asir_popSerializedLocalObject();
static char *name_of_cmd(unsigned int);
static char *name_of_id(int);
static void asir_do_cmd(unsigned int,unsigned int);
static LIST asir_GetErrorList();

void ox_plot_main(int argc,char **argv) {
	int ds;
	fd_set r;
	int n;

	ox_asir_init(argc,argv);
	init_plot_display(argc,argv);
	ds = ConnectionNumber(display);
	if ( do_message )
		fprintf(stderr,"I'm an ox_plot, Version %d.\n",ASIR_VERSION);

	if ( setjmp(ox_env) ) {
		while ( NEXT(asir_infile) )
			closecurrentinput();
		reset_current_computation();
		ox_send_sync(0);
	}
	while ( 1 ) {
		if ( ox_data_is_available(0) )
			process_ox();
		else {
			FD_ZERO(&r);
			FD_SET(3,&r); FD_SET(ds,&r);
			select(FD_SETSIZE,&r,NULL,NULL,NULL);
			if ( FD_ISSET(3,&r) )
				process_ox();
			else if ( FD_ISSET(ds,&r) )
				process_xevent();
		}
	}
}

static void process_ox()
{
	int id;
	unsigned int cmd;
	Obj obj;
	ERR err;
	unsigned int serial;
	int ret;
	extern char LastError[];

	serial = ox_recv(0,&id,&obj);
	if ( do_message )
		fprintf(stderr,"#%d Got %s",serial,name_of_id(id));
	switch ( id ) {
		case OX_COMMAND:
			cmd = ((USINT)obj)->body;
			if ( ox_flushing )
				break;
			if ( do_message )
				fprintf(stderr," %s\n",name_of_cmd(cmd));
			if ( ret = setjmp(env) ) {
				if ( ret == 1 ) {
					create_error(&err,serial,LastError);
					asir_push_one((Obj)err);
				}
				break;
			}
			asir_do_cmd(cmd,serial);
			break;
		case OX_DATA:
		case OX_LOCAL_OBJECT_ASIR:
			if ( ox_flushing )
				break;
			if ( do_message )
				fprintf(stderr," -> data pushed");
			asir_push_one(obj);
			break;
		case OX_SYNC_BALL:
				asir_end_flush();
			break;
		default:
			break;
	}
	if ( do_message )
		fprintf(stderr,"\n");
}

static void asir_do_cmd(unsigned int cmd,unsigned int serial)
{
	MATHCAP client_mathcap;
	LIST list;
	int i;
	Q q;

	switch ( cmd ) {
		case SM_dupErrors:
			list = asir_GetErrorList();
			asir_push_one((Obj)list);
			break;
		case SM_getsp:
			i = plot_OperandStackPtr+1;
			STOQ(i,q);
			asir_push_one((Obj)q);
			break;
		case SM_popSerializedLocalObject:
			asir_popSerializedLocalObject();
			break;
		case SM_popCMO:
			asir_popCMO(serial);
			break;
		case SM_popString:
			asir_popString();
			break;
		case SM_setName:
			asir_setName(serial);
			break;
		case SM_evalName:
			asir_evalName(serial);
			break;
		case SM_executeStringByLocalParser:
			asir_executeString();
			break;
		case SM_executeFunction:
			asir_executeFunction();
			break;
		case SM_shutdown:
			asir_terminate(2);
			break;
		case SM_pops:
			asir_pops();
			break;
		case SM_mathcap:
			asir_push_one((Obj)my_mathcap);
			break;
		case SM_setMathcap:
			client_mathcap = (MATHCAP)asir_pop_one();
			store_remote_mathcap(0,client_mathcap);
			break;
		default:
			break;
	}
}

static char *name_of_id(int id)
{
	switch ( id ) {
		case OX_COMMAND:
			return "OX_COMMAND";
			break;
		case OX_DATA:
			return "OX_DATA";
			break;
		case OX_LOCAL_OBJECT_ASIR:
			return "OX_LOCAL_OBJECT_ASIR";
			break;  
		case OX_SYNC_BALL:
			return "OX_SYNC_BALL";
			break;
		default:
			return "Unknown id";
			break;
	}
}

static char *name_of_cmd(unsigned cmd)
{
	switch ( cmd ) {
		case SM_popSerializedLocalObject:
			return "SM_popSerializedLocalObject";
			break;
		case SM_popCMO:
			return "SM_popCMO";
			break;
		case SM_popString:
			return "SM_popString";
			break;
		case SM_pops:
			return "SM_pops";
			break;
		case SM_setName:
			return "SM_setName";
			break;
		case SM_evalName:
			return "SM_evalName";
			break;
		case SM_executeStringByLocalParser:
			return "SM_executeString";
			break;
		case SM_executeFunction:
			return "SM_executeFunction";
			break;
		case SM_shutdown:
			return "SM_shutdown";
			break;
		case SM_beginBlock:
			return "SM_beginBlock";
			break;
		case SM_endBlock:
			return "SM_endBlock";
			break;
		case SM_mathcap:
			return "SM_mathcap";
			break;
		case SM_setMathcap:
			return "SM_setMathcap";
			break;
		default:
			return "Unknown cmd";
			break;
	}
}

static void asir_popSerializedLocalObject()
{
	Obj obj;
	VL t,vl;

	obj = asir_pop_one();
	get_vars(obj,&vl);
	for ( t = vl; t; t = NEXT(t) )
		if ( t->v->attr == (pointer)V_UC || t->v->attr == (pointer)V_PF )
			error("bsave : not implemented");
	ox_send_cmd(0,SM_beginBlock);
	ox_send_local_ring(0,vl);
	ox_send_local_data(0,obj);
	ox_send_cmd(0,SM_endBlock);
}

static void asir_popCMO(unsigned int serial)
{
	Obj obj;
	ERR err;

	obj = asir_pop_one();
	if ( valid_as_cmo(obj) )
		ox_send_data(0,obj);
	else {
		create_error(&err,serial,"cannot convert to CMO object");
		ox_send_data(0,err);
		asir_push_one(obj);
	}
}

static void asir_popString()
{
	Obj val;
	char *buf,*obuf;
	int l;
	STRING str;

	val = asir_pop_one();
	if ( !val )
		obuf = 0;
	else {
		l = estimate_length(CO,val);
		buf = (char *)ALLOCA(l+1);
		soutput_init(buf);
		sprintexpr(CO,val);
		l = strlen(buf);
		obuf = (char *)MALLOC(l+1);
		strcpy(obuf,buf);
	}
	MKSTR(str,obuf);
	ox_send_data(0,str);
}

static void asir_pops()
{
	int n;

	n = (int)(((USINT)asir_pop_one())->body);
	plot_OperandStackPtr = MAX(plot_OperandStackPtr-n,-1);
}

static void asir_setName(unsigned int serial)
{
	char *name;
	int l,n;
	char *dummy = "=0;";
	SNODE snode;
	ERR err;

	name = ((STRING)asir_pop_one())->body;
	l = strlen(name);
	n = l+strlen(dummy)+1;
	parse_strp = (char *)ALLOCA(n);
	sprintf(parse_strp,"%s%s",name,dummy);
	if ( mainparse(&snode) ) {
		create_error(&err,serial,"cannot set to variable");
		asir_push_one((Obj)err);
	} else {
		FA1((FNODE)FA0(snode)) = (pointer)mkfnode(1,I_FORMULA,asir_pop_one());
		evalstat(snode);	
	}
}

static void asir_evalName(unsigned int serial)
{
	char *name;
	int l,n;
	SNODE snode;
	ERR err;
	pointer val;

	name = ((STRING)asir_pop_one())->body;
	l = strlen(name);
	n = l+2;
	parse_strp = (char *)ALLOCA(n);
	sprintf(parse_strp,"%s;",name);
	if ( mainparse(&snode) ) {
		create_error(&err,serial,"no such variable");
		val = (pointer)err;
	} else
		val = evalstat(snode);	
	asir_push_one(val);
}

static int asir_executeString()
{
	SNODE snode;
	pointer val;
	char *cmd;
#if PARI
	recover(0);
	if ( setjmp(environnement) ) {
		avma = top; recover(1);
		resetenv("");
	}
#endif
	cmd = ((STRING)asir_pop_one())->body;
	parse_strp = cmd;
	if ( mainparse(&snode) ) {
		return -1;
	}
	val = evalstat(snode);
	if ( NEXT(asir_infile) ) {
		while ( NEXT(asir_infile) ) {
			if ( mainparse(&snode) ) {
				asir_push_one(val);
				return -1;
			}
			nextbp = 0;
			val = evalstat(snode);
		}
	}
	asir_push_one(val);
	return 0;
}

static void asir_executeFunction()
{ 
	char *func;
	int argc;
	int id;
	FUNC f;
	Q ret;
	VL vl;
	NODE n,n1; 

	func = ((STRING)asir_pop_one())->body;
	argc = (int)(((USINT)asir_pop_one())->body);

	for ( n = 0; argc; argc-- ) {
		NEXTNODE(n,n1);
		BDY(n1) = (pointer)asir_pop_one();
	}
	if ( n )
		NEXT(n1) = 0;
	id = -1;
	if ( !strcmp(func,"plot") )
		id = plot(n);
	else if ( !strcmp(func,"arrayplot") )
		id = arrayplot(n);
	else if ( !strcmp(func,"plotover") )
		id = plotover(n);
	else if ( !strcmp(func,"drawcircle") )
		id = drawcircle(n);
	STOQ(id,ret);
#if 0
	asir_push_one((Obj)ret);
#endif
}

static void asir_end_flush()
{
	ox_flushing = 0;
}

static void asir_push_one(Obj obj)
{
	if ( !obj || OID(obj) != O_VOID ) {
		plot_OperandStackPtr++;
		if ( plot_OperandStackPtr >= plot_OperandStackSize ) {
			plot_OperandStackSize += BUFSIZ;
			plot_OperandStack
				= (Obj *)REALLOC(plot_OperandStack,
					plot_OperandStackSize*sizeof(Obj));
		}
		plot_OperandStack[plot_OperandStackPtr] = obj;
	}
}

static LIST asir_GetErrorList()
{
	int i;
	NODE n,n0;
	LIST err;
	Obj obj;

	for ( i = 0, n0 = 0; i <= plot_OperandStackPtr; i++ )
		if ( (obj = plot_OperandStack[i]) && (OID(obj) == O_ERR) ) {
			NEXTNODE(n0,n); BDY(n) = (pointer)obj;
		}
	if ( n0 )
		NEXT(n) = 0;
	MKLIST(err,n0);
	return err;
}

static Obj asir_pop_one() {
	if ( plot_OperandStackPtr < 0 ) {
		if ( do_message )
			fprintf(stderr,"OperandStack underflow");
		return 0;
	} else {
		if ( do_message )
			fprintf(stderr,"pop at %d\n",plot_OperandStackPtr);
		return plot_OperandStack[plot_OperandStackPtr--];
	}
}

static void ox_asir_init(int argc,char **argv)
{
	int tmp;
	char ifname[BUFSIZ];
	extern int GC_dont_gc;
	extern int read_exec_file;
	extern int do_asirrc;
	extern int do_server_in_X11;
	char *getenv();
	static ox_asir_initialized = 0;
	FILE *ifp;

	do_server_in_X11 = 1; /* XXX */
	asir_save_handler();
#if PARI
	risa_pari_init();
#endif
	srandom((int)get_current_time());

#if defined(THINK_C)
	param_init();
#endif
	StackBottom = &tmp + 1; /* XXX */
	rtime_init();
	env_init();
	endian_init();
#if !defined(VISUAL) && !defined(THINK_C)
/*	check_key(); */
#endif
	GC_init();
	process_args(--argc,++argv);
#if 0
	copyright();
#endif
	output_init();
	arf_init();
	nglob_init();
	glob_init();
	sig_init();
	tty_init();
	debug_init();
	pf_init();
	sysf_init();
	parif_init();
#if defined(VISUAL)
	init_socket();
#endif
#if defined(UINIT)
	reg_sysf();
#endif
#if defined(THINK_C)
	sprintf(ifname,"asirrc");
#else
	sprintf(ifname,"%s/.asirrc",getenv("HOME"));
#endif
	if ( do_asirrc && (ifp = fopen(ifname,"r")) ) {
		input_init(ifp,ifname);
		if ( !setjmp(env) ) {
			read_exec_file = 1;
			read_eval_loop();
			read_exec_file = 0;
		}
		fclose(ifp);
	}
	input_init(0,"string");
	ox_io_init();
	create_my_mathcap("ox_plot");
}

static void ox_io_init() {
	unsigned char c,rc;
	extern int little_endian;

	endian_init();
	iofp[0].in = fdopen(3,"r");
	iofp[0].out = fdopen(4,"w");
	setbuffer(iofp[0].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
	setbuffer(iofp[0].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
	plot_OperandStackSize = BUFSIZ;
	plot_OperandStack = (Obj *)CALLOC(plot_OperandStackSize,sizeof(Obj));
	plot_OperandStackPtr = -1;
	signal(SIGUSR1,ox_usr1_handler);
	if ( little_endian )
		c = 1;
	else
		c = 0xff;
	write_char(iofp[0].out,&c); ox_flush_stream(0);
	read_char(iofp[0].in,&rc);
	iofp[0].conv = c == rc ? 0 : 1;
}