/* NAME * math_func.c * * DESCRIPTION * * Sample function that links the sin() function into Illustra: * - checks for NULL input parameters * - initializes return value to NULL * - allocates the return value only once * - overloads the function with a debug option * NOTE: Debug messages also get output to * $MI_HOME/data/miserver.log * * If anybody knows how to handle numeric errors, send email to * jta@postgres.berkeley.edu. * * SAMPLE USAGE * * return sin(.12345); * return sin(.12345, 1); -- outputs debug messages * * BUILD INSTRUCTIONS * * OSF1: * cc -I$MI_HOME/h -c math_func.c * ld -shared -expect_unresolved '*' -o math_func.so math_func.o * * Solaris: * cc -I$MI_HOME/h -c -K PIC math_func.c * ld -dy -G -o math_func.so math_func.o * * SUN OS: * cc -I$MI_HOME/h -c -PIC math_func.c * ld -o math_func.so math_func.o * * chmod a+x math_func.so * * DATABASE CREATE * * drop function sin (double precision); * create function sin (double precision) returns double precision * as external name '/FULL_PATH/math_func.so(osf1_sin_n)' * language C; * * drop function sin (double precision, integer); * create function sin (double precision, integer) returns double precision * as external name '/FULL_PATH/math_func.so(osf1_sin)' * language C; * * MODS * 4/11/94 jta works with Montage 2.0.9, libmontage '3.0.1 M' * 6/07/94 jta upgraded to Illustra 2.0.12 * 7/22/94 jta works with 2.1 * * $Header: /usr/local/devel/montage/samples/functions/RCS/math_func.c,v 1.3 1994/07/22 23:12:44 jta Exp $ */ #include #include #include "mi.h" mi_double_precision * osf1_sin_n ARGS((mi_double_precision *x, MI_FPARAM *fParam)); mi_double_precision * osf1_sin ARGS((mi_double_precision *x, int debug, MI_FPARAM *fParam)); mi_double_precision * osf1_sin_n(x, fParam) mi_double_precision *x; MI_FPARAM *fParam; { return ( osf1_sin (x, 0, fParam) ); } mi_double_precision * osf1_sin(x, debug, fParam) mi_double_precision *x; int debug; MI_FPARAM *fParam; { char msg_buf[100]; mi_double_precision *retval; MI_CONNECTION *conn; MI_FP_SETRETURNISNULL(fParam, MI_TRUE); /* initialize to return null */ if (MI_FP_ARGISNULL(fParam, 0)) /* return if x is NULL */ return(NULL); if ((conn = mi_open(NULL, NULL, NULL)) == (MI_CONNECTION *) NULL) mi_db_error_raise(conn, MI_EXCEPTION, "osf1_sin: couldn't get a libmi connection"); /* mi_alloc retval once and reuse rather than mi_alloc each return. */ if((retval = (mi_double_precision *) MI_FP_FUNCSTATE(fParam)) == 0) { retval = (mi_double_precision *) mi_alloc(sizeof(mi_double_precision)); mi_set_mem_duration ((void *) retval, PER_COMMAND); MI_FP_SETFUNCSTATE (fParam, (void *) retval); } *retval = HUGE_VAL; /* initialize to infinity */ errno = 0; *retval = sin(*x); if (errno != 0) { strncpy(msg_buf, strerror(errno), sizeof(msg_buf) - 1); mi_db_error_raise(conn, MI_NOTICE, msg_buf); } else MI_FP_SETRETURNISNULL(fParam, MI_FALSE); if(debug) { sprintf(msg_buf, "osf1_sin: The sin of %g is %g", *x, *retval); mi_db_error_raise(conn, MI_NOTICE, msg_buf); } return (retval); }