| Did you know ... | Search Documentation: |
| Reading a list |
The functions from this section are intended to read a Prolog list from C. Suppose we expect a list of atoms; the code below will print the atoms, each on a line. Please note the following:
term_t term reference for the
elements (head). This reference is reused for each element.term_t. As it is not allowed to
overwrite the term_t passed in as arguments to a predicate,
we must
copy the argument term_t.char*. We want it to convert atoms, return the
result as a multibyte string (REP_UTF8 may also be
used) and finally we want an exception on type, instantiation or
representation errors (if the system's default encoding cannot represent
some characters of the Unicode atom). This may create temporary copies
of the atom text - PL_STRINGS_MARK() ... PL_STRINGS_RELEASE()
handles that._ex suffix, but they raise type, domain,
or instantiation errors when the input is invalid; whereas the plain
version may only raise resource exceptions if the request cannot be
fulfilled due to resource exhaustion.
foreign_t
pl_write_atoms(term_t l)
{ term_t head = PL_new_term_ref(); /* the elements */
term_t tail = PL_copy_term_ref(l); /* copy (we modify tail) */
int rc = TRUE;
while( rc && PL_get_list_ex(tail, head, tail) )
{ PL_STRINGS_MARK();
char *s;
if (rc=PL_get_chars(head, &s, CVT_ATOM|REP_MB|CVT_EXCEPTION)) )
rc = Sfprintf(Scurrent_output, "%s\n", s);
PL_STRINGS_RELEASE();
}
return rc && PL_get_nil_ex(tail); /* test end for [] */
}
Note that as of version 7, lists have a new representation unless the option --traditional is used. see section 5.1.
It is allowed to pass 0 for tail and NULL for len.
(size_t)-1, call func
for all elements from start to the end of the list. The type
of func is below. The argument index is the index
of the element in the slice, i.e., it starts at 0 for the element start.
typedef int (*pl_list_slice_f)(term_t elem, size_t index, void *closure);
The term reference elem is reused for all elements and is
only valid during the call to func. func may call
any API function, including functions that create terms or call Prolog.
If
func returns FALSE, PL_get_list_slice()
stops and returns
FALSE, leaving an exception raised by func in
place. If
count is not NULL, it is filled with the number
of elements processed.
The function returns FALSE if the list is too short, if
length is (size_t)-1 and the list is partial,
does not end in or is cyclic, or if the
list is partial, not a list or cyclic before the end of the slice. If flags
includes
[]CVT_EXCEPTION, a partial list raises an instantiation error
and a cyclic list or a term that is not a list raises a type error. A
list that is too short does not raise an exception. Cycles are detected
without extra cost for short lists. Below is the list example using this
function:
static int
write_atom(term_t a, size_t index, void *closure)
{ int rc;
char *s;
PL_STRINGS_MARK();
if ( (rc=PL_get_chars(a, &s, CVT_ATOM|REP_MB|CVT_EXCEPTION)) )
rc = Sfprintf(closure, "%s\n", s) >= 0;
PL_STRINGS_RELEASE();
return rc;
}
foreign_t
pl_write_atoms(term_t l)
{ return PL_get_list_slice(l, 0, (size_t)-1,
write_atom, Scurrent_output,
NULL, CVT_EXCEPTION);
}