Exemplo n.º 1
0
Arquivo: ascmenu.c Projeto: E-LLP/QuIP
static COMMAND_FUNC( do_disp_obj )
{
	Data_Obj *dp;
	FILE *fp;

	dp=PICK_OBJ("");
	if( dp==NO_OBJ ) return;

	// We used to insist that the object be in RAM,
	// but we make life easier by automatically creating
	// a temporary object...

	dp = insure_ram_obj(QSP_ARG  dp);
	if( dp == NO_OBJ ) return;

	fp = tell_msgfile(SINGLE_QSP_ARG);
	if( fp == stdout ){
		if( IS_IMAGE(dp) || IS_SEQUENCE(dp) )
			if( !CONFIRM(
		"are you sure you want to display an image/sequence in ascii") )
				return;
		list_dobj(QSP_ARG  dp);
	}
	pntvec(QSP_ARG  dp,fp);
	fflush(fp);

	DELETE_IF_COPY(dp)
}
Exemplo n.º 2
0
Arquivo: ascmenu.c Projeto: E-LLP/QuIP
static COMMAND_FUNC( do_wrt_obj )
{
	Data_Obj *dp;
	FILE *fp;
	/* BUG what if pathname is longer than 256??? */
	const char *filename;

	dp=PICK_OBJ("");
	filename = NAMEOF("output file");

	if( dp==NO_OBJ ) return;

	if( strcmp(filename,"-") && strcmp(filename,"stdout") ){
		// BUG? we don't check append flag here,
		// but there is a separate append command...

		fp=TRYNICE( filename, "w" );
		if( !fp ) return;
	} else {
		// If the invoking script has redirected stdout,
		// then use that
		if( QS_MSG_FILE(THIS_QSP)!=NULL )
			fp = QS_MSG_FILE(THIS_QSP);
		else
			fp = stdout;
	}

	if( IS_IMAGE(dp) || IS_SEQUENCE(dp) )
		if( !CONFIRM(
		"are you sure you want to write an image/sequence in ascii") ){
			fclose(fp);
			return;
		}

	dp = insure_ram_obj(QSP_ARG  dp);
	if( dp == NO_OBJ ) return;

	pntvec(QSP_ARG  dp,fp);
	if( fp != stdout && QS_MSG_FILE(THIS_QSP)!=NULL && fp != QS_MSG_FILE(THIS_QSP) ) {
		if( verbose ){
			sprintf(MSG_STR,"closing file %s",filename);
			prt_msg(MSG_STR);
		}
		fclose(fp);
	}

	DELETE_IF_COPY(dp)
}
Exemplo n.º 3
0
Arquivo: ascmenu.c Projeto: E-LLP/QuIP
static COMMAND_FUNC( do_append )
{
	Data_Obj *dp;
	FILE *fp;

	dp=PICK_OBJ("");
	if( dp==NO_OBJ ) return;

	if( IS_IMAGE(dp) || IS_SEQUENCE(dp) )
		if( !CONFIRM(
		"are you sure you want to write an image/sequence in ascii") )
			return;
	fp=TRYNICE( NAMEOF("output file"), "a" );
	if( !fp ) return;

	dp = insure_ram_obj(QSP_ARG  dp);
	if( dp == NO_OBJ ) return;

	pntvec(QSP_ARG  dp,fp);
	fclose(fp);

	DELETE_IF_COPY(dp)
}
Exemplo n.º 4
0
object call_c(int func, object proc_ad, object arg_list)
/* Call a WIN32 or Linux C function in a DLL or shared library.
   Alternatively, call a machine-code routine at a given address. */
{
    volatile unsigned long arg;  // !!!! magic var to push values on the stack
    volatile int argsize;        // !!!! number of bytes to pop

    s1_ptr arg_list_ptr, arg_size_ptr;
    object_ptr next_arg_ptr, next_size_ptr;
    object next_arg, next_size;
    int iresult, i;
    double dbl_arg, dresult;
    float flt_arg, fresult;
    unsigned long size;
    int proc_index;
    int cdecl_call;
    int (*int_proc_address)();
    unsigned return_type;
    char NameBuff[100];

    // Setup and Check for Errors

    proc_index = get_pos_int("c_proc/c_func", proc_ad);
    if ((unsigned)proc_index >= c_routine_next) {
	sprintf(TempBuff, "c_proc/c_func: bad routine number (%d)", proc_index);
	RTFatal(TempBuff);
    }

    int_proc_address = c_routine[proc_index].address;
#if defined(EWINDOWS) && !defined(EWATCOM)
    cdecl_call = c_routine[proc_index].convention;
#endif
    if (IS_ATOM(arg_list)) {
	RTFatal("c_proc/c_func: argument list must be a sequence");
    }

    arg_list_ptr = SEQ_PTR(arg_list);
    next_arg_ptr = arg_list_ptr->base + arg_list_ptr->length;

    // only look at length of arg size sequence for now
    arg_size_ptr = c_routine[proc_index].arg_size;
    next_size_ptr = arg_size_ptr->base + arg_size_ptr->length;

    return_type = c_routine[proc_index].return_size; // will be INT

    if (func && return_type == 0 || !func && return_type != 0) {
	if (c_routine[proc_index].name->length < 100)
	    MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name));
	else
	    NameBuff[0] = '\0';
	sprintf(TempBuff, func ? "%s does not return a value" :
				 "%s returns a value",
				 NameBuff);
	RTFatal(TempBuff);
    }

    if (arg_list_ptr->length != arg_size_ptr->length) {
	if (c_routine[proc_index].name->length < 100)
	    MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name));
	else
	    NameBuff[0] = '\0';
	sprintf(TempBuff, "C routine %s() needs %d argument%s, not %d",
			  NameBuff,
			  arg_size_ptr->length,
			  (arg_size_ptr->length == 1) ? "" : "s",
			  arg_list_ptr->length);
	RTFatal(TempBuff);
    }

    argsize = arg_list_ptr->length << 2;


    // Push the Arguments

    for (i = 1; i <= arg_list_ptr->length; i++) {

	next_arg = *next_arg_ptr--;
	next_size = *next_size_ptr--;

	if (IS_ATOM_INT(next_size))
	    size = INT_VAL(next_size);
	else if (IS_ATOM(next_size))
	    size = (unsigned long)DBL_PTR(next_size)->dbl;
	else
	    RTFatal("This C routine was defined using an invalid argument type");

	if (size == C_DOUBLE || size == C_FLOAT) {
	    /* push 8-byte double or 4-byte float */
	    if (IS_ATOM_INT(next_arg))
		dbl_arg = (double)next_arg;
	    else if (IS_ATOM(next_arg))
		dbl_arg = DBL_PTR(next_arg)->dbl;
	    else {
		arg = arg+argsize+9999; // 9999 = 270f hex - just a marker for asm code
		RTFatal("arguments to C routines must be atoms");
	    }

	    if (size == C_DOUBLE) {
		arg = *(1+(unsigned long *)&dbl_arg);

		push();  // push high-order half first
		argsize += 4;
		arg = *(unsigned long *)&dbl_arg;
		push(); // don't combine this with the push() below - Lcc bug
	    }
	    else {
		/* C_FLOAT */
		flt_arg = (float)dbl_arg;
		arg = *(unsigned long *)&flt_arg;
		push();
	    }
	}
	else {
	    /* push 4-byte integer */
	    if (size >= E_INTEGER) {
		if (IS_ATOM_INT(next_arg)) {
		    if (size == E_SEQUENCE)
			RTFatal("passing an integer where a sequence is required");
		}
		else {
		    if (IS_SEQUENCE(next_arg)) {
			if (size != E_SEQUENCE && size != E_OBJECT)
			    RTFatal("passing a sequence where an atom is required");
		    }
		    else {
			if (size == E_SEQUENCE)
			    RTFatal("passing an atom where a sequence is required");
		    }
		    RefDS(next_arg);
		}
		arg = next_arg;
		push();
	    }
	    else if (IS_ATOM_INT(next_arg)) {
		arg = next_arg;
		push();
	    }
	    else if (IS_ATOM(next_arg)) {
		// atoms are rounded to integers

		arg = (unsigned long)DBL_PTR(next_arg)->dbl; //correct
		// if it's a -ve f.p. number, Watcom converts it to int and
		// then to unsigned int. This is exactly what we want.
		// Works with the others too.
		push();
	    }
	    else {
		arg = arg+argsize+9999; // just a marker for asm code
		RTFatal("arguments to C routines must be atoms");
	    }
	}
    }

    // Make the Call - The C compiler thinks it's a 0-argument call

    // might be VOID C routine, but shouldn't crash

    if (return_type == C_DOUBLE) {
	// expect double to be returned from C routine
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    dresult = (*((double (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    dresult = (*((double (__stdcall *)())int_proc_address))();

#ifdef ELINUX
	pop();
#endif
	return NewDouble(dresult);
    }

    else if (return_type == C_FLOAT) {
	// expect float to be returned from C routine
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    fresult = (*((float (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    fresult = (*((float (__stdcall *)())int_proc_address))();

#ifdef ELINUX
	pop();
#endif
	return NewDouble((double)fresult);
    }

    else {
	// expect integer to be returned
#if defined(EWINDOWS) && !defined(EWATCOM)
	if (cdecl_call) {
	    iresult = (*((int (  __cdecl *)())int_proc_address))();
	    pop();
	}
	else
#endif
	    iresult = (*((int (__stdcall *)())int_proc_address))();
#ifdef ELINUX
	pop();
#endif
	if ((return_type & 0x000000FF) == 04) {
	    /* 4-byte integer - usual case */
	    // check if unsigned result is required
	    if ((return_type & C_TYPE) == 0x02000000) {
		// unsigned integer result
		if ((unsigned)iresult <= (unsigned)MAXINT) {
		    return iresult;
		}
		else
		    return NewDouble((double)(unsigned)iresult);
	    }
	    else {
		// signed integer result
		if (return_type >= E_INTEGER ||
		    (iresult >= MININT && iresult <= MAXINT)) {
		    return iresult;
		}
		else
		    return NewDouble((double)iresult);
	    }
	}
	else if (return_type == 0) {
	    return 0; /* void - procedure */
	}
	/* less common cases */
	else if (return_type == C_UCHAR) {
	    return (unsigned char)iresult;
	}
	else if (return_type == C_CHAR) {
	    return (signed char)iresult;
	}
	else if (return_type == C_USHORT) {
	    return (unsigned short)iresult;
	}
	else if (return_type == C_SHORT) {
	    return (short)iresult;
	}
	else
	    return 0; // unknown function return type
    }
}