/* NAME * fib.c * * From the Illustra User Guide, p. 10-14. * * BUILD INSTRUCTIONS * * OSF1: cc -I$MI_HOME/h -c fib.c * ld -shared -expect_unresolved '*' -o fib.so fib.o * * Solaris: cc -I$MI_HOME/h -c -K PIC fib.c * ld -dy -G -o fib.so fib.o * * SUN OS: cc -I$MI_HOME/h -c -PIC fib.c * ld -o fib.so fib.o * * chmod a+x fib.so * * DATABASE CREATE * * create function fib (integer) returns setof(integer) * as external name '/FULL_PATH/fib.so' language C; * * SAMPLE USAGE * * * begin transaction; * + return fib(5); * --------------- * |fib | * --------------- * |fib_1_1_0 | * --------------- * one row selected * * + fetch from fib_1_1_0 all; * --------------- * |integer | * --------------- * |0 | * |1 | * |1 | * |2 | * |3 | * |5 | * --------------- * 6 rows fetched * + end transaction; * * $Header: /usr/local/devel/montage/samples/functions/RCS/fib.c,v 1.1 1994/10/06 16:27:30 jta Exp $ */ #include "mi.h" typedef struct fibstate { int fib_prec1; int fib_prec2; int fib_ncomputed; int fib_stopval; } FibState; int fib(stopVal, fParam) int stopVal; MI_FPARAM *fParam; { FibState *fibState; int next; switch(MI_FP_REQUEST(fParam)) { case SET_INIT: fibState = (FibState *) mi_alloc(sizeof(FibState)); MI_FP_SETFUNCSTATE(fParam, (void *) fibState); mi_set_mem_duration(fibState, PER_COMMAND); if(MI_FP_ARGISNULL(fParam, 0) || stopVal < 0) { MI_FP_SETRETURNISNULL(fParam, MI_TRUE); break; } if(stopVal < 1) { fibState->fib_prec1 = 0; fibState->fib_prec2 = 1; fibState->fib_ncomputed = 1; fibState->fib_stopval = stopVal; } else { fibState->fib_prec1 = 0; fibState->fib_prec2 = 1; fibState->fib_ncomputed = 0; fibState->fib_stopval = stopVal; } break; case SET_RETONE: fibState = (FibState *) MI_FP_FUNCSTATE(fParam); if (fibState->fib_ncomputed < 2) { return ((fibState->fib_ncomputed++ == 0) ? 0 : 1); } next = fibState->fib_prec1 + fibState->fib_prec2; if (next > fibState->fib_stopval) { MI_FP_SETISDONE(fParam, MI_TRUE); return 0; } if (next == 0) { fibState->fib_prec1 = 0; fibState->fib_prec2 = 1; } else { fibState->fib_prec1 = fibState->fib_prec2; fibState->fib_prec2 = next; } return(next); case SET_END: fibState = (FibState *) MI_FP_FUNCSTATE(fParam); mi_free(fibState); break; } }