Once code has been written for user functions, Vortex must be made
aware of them, by creating a new texis
executable (this is
usually a symbolic link to monitor
). The functions are listed
in the global array VUserFuncs[]
in the vufuncs.c
file.
This array determines what user functions are available in Vortex,
their names, how many arguments they take, and their return type. It
is an array of VUSERFUNC
structs (declared in vortex.h
):
typedef char **VUFUNC ARGS((char *arg[], ...));
typedef char **VA_VUFUNC ARGS((int argc, char **argv[]));
typedef struct VUSERFUNC_tag
{
char *name; /* name of function */
VUFUNC *func; /* pointer to VUFUNC or VA_VUFUNC to call */
int nargs; /* number of expected args (-1 for varargs) */
int type; /* FTN_... type to cast return value(s) to */
}
VUSERFUNC;
Each user function available in Vortex must have an entry in this
array, which is terminated with a NULL
entry. The name
field is the name of the function. func
is a pointer to the
function, declared in either of the two syntaxes above. nargs
is the number of arguments the function expects. If -1 is given, then
the function can take a variable number of arguments, and func
is expected to point to a VA_VUFUNC
-style declaration instead
of VUFUNC
-style. Non-variable-argument functions with more
than ten arguments must also be declared VA_VUFUNC
.
The type
field is a FTN_
... type (SQL type) that the
returned string value(s) will be cast to as $ret
. The default
is VUTYPE_DEFAULT
, which is string (varchar
). Other
possible values include FTN_LONG
for integer, FTN_DATE
for a date field, FTN_FLOAT
for a floating-point value, etc.
Note that the returned C
data from the function is always an
array of char *
text strings; the type
field indicates
what these strings will be cast to by Vortex when assigned to
$ret
.
To add new user functions, edit the vufunc.c
file and add
entries for your functions. Note that there are already entries for
standard Vortex functions, such as sum
, apicp
, etc.
Compile vufunc.c
and your code, and then re-link texis
with vufunc.o
, your code, and the Vortex, Texis and system
libs. An example makefile is in the /usr/local/morph3/api
directory; a typical version is excerpted here:
# `monitor' is the actual executable; `texis' is symlinked to it:
monitor: vufunc.o vufuncex.o
$(CC) $(LDFLAGS) $(OBJDIR)/monitor.o vufunc.o vufuncex.o \
-lvhttpd -lvortex -lcgi -lntexis -ltexis -lapi3 -lm -o $@
# `texis' and `tsql' are just symbolic links to `monitor':
texis tsql: monitor
rm -f $@
ln -s monitor $@
vufunc.o: vufunc.c vufunc.h
$(CC) $(CFLAGS) -c vufunc.c
vufuncex.o: vufuncex.c
$(CC) $(CFLAGS) -c vufuncex.c
OBJDIR
must be set to the installed API directory, normally
/usr/local/morph3/api
. The order of libs is important: note
that the -lvhttpd
lib is first, and the system libs like
-lm
are last. On some platforms, additional system libs may be
needed at the end, such as
-lsocket
, and/or the Thunderstone libs may need to be included
again at the end to resolve all symbols.
Note: Before running the new texis
, old Vortex P-code
files (*.vsc
) must be deleted to ensure that scripts are
re-compiled properly. Also, the executable or symlink must start with
the name texis
in order to run. Make sure that the proper path
to the new texis
is given when testing,
e.g. ./texis
, to ensure the old/current texis
in
/usr/local/morph3/bin
isn't run inadvertently to confuse things.
Once the new texis
is tested, the new monitor
that it
points to can replace the stock monitor
executable installed in
/usr/local/morph3/bin
(after backing it up). A symlink from
texis
to monitor
should already exist there.