next up previous contents index
Next: Calling Prolog from C Up: The Foreign Include File Previous: Constructing Terms   Contents   Index

Unifying data

The functions of this sections unify terms with other terms or translated C-data structures. Except for PL_unify, the functions of this section are specific to SWI-Prolog. They have been introduced to make translation of old code easier, but also because they provide for a faster mechanism for returning data to Prolog that requires less term-references. Consider the case where we want a foreign function to return the host name of the machine Prolog is running on. Using the PL_get_*() and PL_put_*() functions, the code becomes:


\begin{code}
foreign_t
pl_hostname(term_t name)
{ char buf[100];
\par if ( getho...
...atom_chars(tmp, buf);
return PL_unify(name, buf);
}
\par PL_fail;
}
\end{code}

Using PL_unify_atom_chars, this becomes:


\begin{code}
foreign_t
pl_hostname(term_t name)
{ char buf[100];
\par if ( getho...
...izeof(buf)) )
return PL_unify_atom_chars(name, buf);
\par PL_fail;
}
\end{code}

intPL_unifyterm_t ?t1, term_t ?t2 Unify two Prolog terms and return non-zero on success. intPL_unify_atomterm_t ?t, atom_t a Unify t with the atom a and return non-zero on success. intPL_unify_atom_charsterm_t ?t, const char *chars Unify t with an atom created from chars and return non-zero on success. intPL_unify_list_charsterm_t ?t, const char *chars Unify t with a list of ASCII characters constructed from chars. voidPL_unify_string_charsterm_t ?t, const char *chars Unify t with a Prolog string object created from the zero-terminated string chars. The data will be copied. See also PL_unify_string_nchars. voidPL_unify_string_ncharsterm_t ?t, unsigned int len, const char *chars Unify t with a Prolog string object created from the string created from the len/chars pair. The data will be copied. This interface can deal with 0-bytes in the string. See also foreigndata. intPL_unify_integerterm_t ?t, long n Unify t with a Prolog integer from n. intPL_unify_floatterm_t ?t, double f Unify t with a Prolog float from f. intPL_unify_pointerterm_t ?t, void *ptr Unify t with a Prolog integer describing the pointer. See also PL_put_pointer and PL_get_pointer. intPL_unify_functorterm_t ?t, functor_t f If t is a compound term with the given functor, just succeed. If it is unbound, create a term and bind the variable, else fails. Not that this function does not create a term if the argument is already instantiated. intPL_unify_listterm_t ?l, term_t -h, term_t -t Unify l with a list-cell (./2). If successful, write a reference to the head of the list to h and a reference to the tail of the list in t. This reference may be used for subsequent calls to this function. Suppose we want to return a list of atoms from a char **. We could use the example described by PL_put_list, followed by a call to PL_unify, or we can use the code below. If the predicate argument is unbound, the difference is minimal (the code based on PL_put_list is probably slightly faster). If the argument is bound, the code below may fail before reaching the end of the word-list, but even if the unification succeeds, this code avoids a duplicate (garbage) list and a deep unification.


\begin{code}
foreign_t
pl_get_environ(term_t env)
{ term_t l = PL_copy_term_ref(...
...unify_atom_chars(a, *e) )
PL_fail;
}
\par return PL_unify_nil(l);
}
\end{code}

intPL_unify_nilterm_t ?l Unify l with the atom []. intPL_unify_argint index, term_t ?t, term_t ?a Unifies the index-th argument (1-based) of t with a. intPL_unify_termterm_t ?t, ... Unify t with a (normally) compound term. The remaining arguments is a sequence of a type identifier, followed by the required arguments. This predicate is an extension to the Quintus and SICStus foreign interface from which the SWI-Prolog foreign interface has been derived, but has proved to be a powerful and comfortable way to create compound terms from C. Due to the vararg packing/unpacking and the required type-switching this interface is slightly slower than using the primitives. Please note that some bad C-compilers have fairly low limits on the number of arguments that may be passed to a function.

The type identifiers are:

PL_VARIABLE none No op. Used in arguments of PL_FUNCTOR. PL_ATOM atom_t Unify the argument with an atom, as in PL_unify_atom. PL_INTEGER long Unify the argument with an integer, as in PL_unify_integer. PL_FLOAT double Unify the argument with a float, as in PL_unify_float. Note that, as the argument is passed using the C vararg conventions, a float must be casted to a double explicitly. PL_STRING const char * Unify the argument with a string object, as in PL_unify_string_chars. PL_TERM term_t Unify a subterm. Note this may the return value of a PL_new_term_ref call to get access to a variable. PL_CHARS const char * Unify the argument with an atom, constructed from the C char *, as in PL_unify_atom_chars. PL_FUNCTOR functor_t, ... Unify the argument with a compound term. This specification should be followed by exactly as many specifications as the number of arguments of the compound term. PL_LIST int length, ... Create a list of the indicated length. The following arguments contain the elements of the list.

For example, to unify an argument with the term language(dutch), the following skeleton may be used:


\begin{code}
static functor_t FUNCTOR_language1;
\par static void
init_constants...
...gister_foreign(''get_lang'', 1, pl_get_lang, 0);
init_constants();
}
\end{code}

intPL_chars_to_termconst char *chars, term_t -t Parse the string chars and put the resulting Prolog term into t. chars may or may not be closed using a Prolog full-stop (i.e. a dot followed by a blank). Returns FALSE if a syntax error was encountered and TRUE after successful completion. In addition to returning FALSE, the exception-term is returned in t on a syntax error. See also term_to_atom2.

The following example build a goal-term from a string and calls it.


\begin{code}
int
call_chars(const char *goal)
{ fid_t fid = PL_open_foreign_fram...
...e(fid);
return rval;
}
\par ...
call_chars(''consult(load)'');
...
\end{code}

char *PL_quoteint chr, const char *string Return a quoted version of string. If chr is '\'', the result is a quoted atom. If chr is '"', the result is a string. The result string is stored in the same ring of buffers as described with the BUF_RING argument of PL_get_chars;

In the current implementation, the string is surrounded by chr and any occurence of chr is doubled. In the future the behaviour will depend on the character_escape prolog-flag. See current_prolog_flag2.


next up previous contents index
Next: Calling Prolog from C Up: The Foreign Include File Previous: Constructing Terms   Contents   Index
Dr. Richard Botting 2001-12-12