# 3 The C Part

Program 2.1 shows a first attempt to provide access to the `getenv` C library function as explained above. In the following we will go through it in detail and successively improve it.

Every C program that will be linked to Oz must include the header file `mozart.h` (line 1 in Program 2.1), which is located in the `include` subdirectory of the Oz installation directory. It contains the definition of the data structures and functions used to interface C to Oz. All these data structures start with `OZ_` such that they will not clash with the user's name space.

To declare a C function that can be used from Oz you have to enclose its declaration into the macros `OZ_BI_define(`name`,`inarity`,`outarity`)` and `OZ_BI_end` . The following code fragment declares a C-function `BIgetenv` for inclusion into Oz, which has one input an one output argument:

> `OZ_BI_define(BIgetenv,1,1)
> {
> ...
> } OZ_BI_end`

Oz represents data like strings, integers, floats, etc. different than C. For this reason `mozart.h` provides type testing functions and routines to convert from the C into the Oz representation and vice versa. All Oz values are summarized in one abstract C data type called `OZ_Term` .

To signal whether the call to a C function was successful or not it must return a value of type `OZ_Return`, which may be `OZ_FAILED` (in which case failure will occur), `OZ_ENTAILED` to signal successful completion. `OZ_Return` also contains several other values, which are not visible to the user. They are only used for internal purposes, for example to handle suspension or raising exceptions.

It is important that your C function returns one of the above values. Not returning a value will inevitably crash the executing Oz engine!

In line 5 we use the macro `OZ_declareAtom(n,name)`: it checks whether the `n`-th input argument is an atom and declares a new C++ variable of type `char*` with name `name`. So line 5 declares `envVarName` which holds the C++ string representation of the first and only input argument.

Values that can be passed as input arguments can of course be logic variables! Do not confuse this with output arguments: Output arguments are handled only after the C function returns!

In line 7 we declare a C++ variable `envValue` which will temporarily hold the return value of `BIgetenv`.

In lines 9--11 of Program 2.1 we check whether an environment variable of the requested name exists and return `OZ_FAILED` if not.

Line 19 loads the result into the output argument of `BIgetenv` using the macro `OZ_RETURN_ATOM`: it converts its argument to an Oz atom assigns the first output register to that value and leaves the function with `OZ_ENTAILED` signalling that the call to `BIgetenv` was success full.

Lines 16--23 in Program 2.1 are needed for the linking step and will be explained in Section 4.3.