The most basic option controlling how Yazoo will be compiled is the following line in userfn.c or userfn.cpp:
#define YazooMainProgram
As is, this line will cause Yazoo's int main() function to compile, which is appropriate if Yazoo is to be a stand-alone application. Yazoo can also be embedded within a larger C/C++ application by simply commenting this section out:
// #define YazooMainProgram
In this latter case, to run Yazoo one would #include "yzmain.h" in the appropriate header, and make the following call in the executable code:
rtrn = run_yazoo(argc, argv) | argc = 0 or 1
By setting argc to 0, Yazoo will try to run start.zoo in the default directory. If argv is 1 then the script to run should be stored in a file whose pathname is pointed at by *argv. Note that we omit the first *(argv+0) pathname that the command prompt traditionally passes to a C program.
All user-authored C or C++ functions make their formal acquaintance to Yazoo through the file userfn.c or userfn.cpp. (Which one of the two depends on whether it is the C or C++ version of Yazoo.) This file comes almost completely empty except for one short function named Debug(), which the author uses for setting breakpoints and printing trace statements, and a run_yazoo() function by which Yazoo can run itself recursively.
Following the example of Debug(), the first step in embedding a new function is to update the UserFunctionSet[] array by adding a new entry containing its Yazoo name (a string), and a pointer to the actual function. For example:
UserFunction UserFunctionSet[] = { { "Debug", &Debug },
{ "Integrate", &doIntegration } };
Note that the Yazoo name does not have to be the same as the name of the function, and it is not a variable name (so the user can still define an Integrate variable without causing any problems). This `Yazoo name' is only the string by which the call() function will recognize that the user wants to run the doIntegration() function, as in
call("Integrate", initial_conditions, 5, temp_storage, result) | run doIntegration()
As mentioned in the last section, doIntegration() must have been defined as a (int)(int, char **) or else there will an error in UserFunctionSet[] when Yazoo is recompiled.
The second step is to put the function in a place where the C or C++ compiler will be able to find it. The simplest way is to put the function directly inside userfn.c/cpp and prototype it somewhere above the UserFunctionSet[] declaration. Any header files should also be included at the top in the space provided. An alternative is to put the functions in separate source files, prototype the functions in separate header files, include these header files at the top of userfn.c/cpp, and add the new source and header files to Yazoo's makefile. The following changes would add (Numerics.c and Numerics.h) to a makefile:
...
SRC = yzmain.c cmpile.c ... userfn.c Numerics.c
OBJ = yzmain.o cmpile.o userfn.o Numerics.o
ALL_HEADERS = yzmain.h cmpile.h ... userfn.h Numerics.h
...
UserFunctions.o: $(ALL_HEADERS) userfn.c
Numerics.o: $(ALL_HEADERS) Numerics.c
The final step is to recompile Yazoo. The recommended method is to use the command-line tool make, which is available for free on many platforms. Of course it also requires that a C/C++ compiler like gcc be installed (some of these are free too). For simplicity all source and header files should be in the same directory as the makefile. To build Yazoo, navigate to that directory and type "make yazoo".
It is also possible to use a development environment for compiling Yazoo, in which case the makefile may not be necessary. The #include statements in userfn.c/cpp would probably still be needed.
Last update: July 28, 2013