Node:Accessing Prolog Terms, Next:, Previous:Creating Prolog Terms, Up:Support Functions



Accessing Prolog Terms

These functions will take an SP_term_ref and convert it to C data. They return zero if the conversion fails, and a nonzero value otherwise, and (except the last two) store the C data in output arguments. Note that here, the term chars refers to a code-list, rather than to a char-list:

int SP_get_integer(SP_term_ref t, long *l)
Assigns to *l the C long corresponding to a Prolog number. The value must fit in *l for the operation to succeed. For numbers too large to fit in a long you can use SP_get_integer_bytes(), below.
int SP_get_float(SP_term_ref t, double *d)
Assigns to *d the C double corresponding to a Prolog number.
int SP_get_atom(SP_term_ref t, SP_atom *a)
Assigns to *a the canonical representation of a Prolog atom.
int SP_get_string(SP_term_ref t, char **name)
Assigns to *name a pointer to the encoded string representing the name of a Prolog atom. This string must not be modified.
int SP_get_address(SP_term_ref t, void **pointer)
Assigns to *pointer a C pointer from a Prolog term.
int SP_get_list_chars(SP_term_ref t, char **s)
Assigns to *s a zero-terminated array containing an encoded string that corresponds to the given Prolog code-list. The array is subject to reuse by other support functions, so if the value is going to be used on a more than temporary basis, it must be moved elsewhere.
int SP_get_list_n_chars(SP_term_ref t, SP_term_ref tail, long n, long *w, char *s)
Copies into s the encoded string representing the character codes in the initial elements of list t, so that at most n bytes are used. The number of bytes actually written is assigned to *w. tail is set to the remainder of the list. The array s must have room for at least n bytes.
int SP_get_integer_bytes(SP_term_ref tr, void *buf, size_t *pbuf_size, int native)
Allows C code to obtain arbitrary precision integers from Prolog.

When called, tr should refer to a Prolog integer; floating point values are not accepted. *pbuf_size should point at the size of the buffer buf, which will receive the result.

In the following, assume that the integer referred to by tr requires a minimum of size bytes to store (in twos-complement representation).

  1. If tr does not refer to a Prolog integer, zero is returned and the other arguments are ignored.
  2. If *pbuf_size is less than size, then *pbuf_size is updated to size and zero is returned. The fact that *pbuf_size has changed can be used to distinguish insufficient buffer size from other possible errors. By calling SP_get_integer_bytes() with *pbuf_size set to zero, you can determine the buffer size needed; in this case, buf is ignored.
  3. *pbuf_size is set to size.
  4. If native is zero, buf is filled with the twos complement representation of the integer, with the least significant bytes stored at lower indices in buf. Note that all of buf is filled, even though only size bytes was needed.
  5. If native is non-zero, buf is assumed to point at a native *pbuf_size byte integral type. On most platforms, native integer sizes of two (16-bit), four (32 bit) and eight (64 bytes) bytes are supported. Note that *pbuf_size == 1, which would correspond to signed char, is not supported with native.
  6. If an unsupported size is used with native, zero is returned.

The following example gets a Prolog integer into a (presumably 64 bit) long long C integer.

{
  long long x; // C99, GCC supports this
  size_t sz = sizeof x;
  if (!SP_get_integer_bytes(tr, &x, &sz, 1/* native */))
    .. error handling ..
  .. use x .. // sz may have decreased
}

The following example does the same using a dynamically allocated byte buffer

{
  unsigned int *buf;
  size_t buf_size = 0;
  long long x; // C99, GCC supports this

  (void) SP_get_integer_bytes(tr, NULL, &buf_size,
                              0/* !native */);
  if (buf_size == 0) ... error handling ...

  buf = SP_malloc(buf_size);
  if (!SP_get_integer_bytes(tr, buf, &buf_size,
                            0/* !native */))
    .. error handling ..

  if (buf[buf_size-1] & 0x80)  // negative
    x = -1; // all one bits
  else
    x = 1;  // all zero bits

  // note that buf_size may be less than sizeof x
  for (i = 0; i < buf_size; i++) {
    x = x<<8;
    x = x + buf[i];
  }
  SP_free(buf);
  .. use x ..
}

int SP_get_number_chars(SP_term_ref t, char **s)
Assigns to *s a zero-terminated array of characters corresponding to the printed representation of a Prolog number. The array is subject to reuse by other support functions, so if the value is going to be used on a more than temporary basis, it must be moved elsewhere.
int SP_get_functor(SP_term_ref t, SP_atom *name, int *arity)
Assigns to *name and *arity the canonical representation and arity of the principal functor of a Prolog compound term. If the value of t is an atom, then that atom is assigned to *name and 0 is assigned to *arity. This is similar to calling functor/3 with the first argument bound to a compound term or an atom and the second and third arguments unbound.
int SP_get_list(SP_term_ref t, SP_term_ref head, SP_term_ref tail)
Assigns to head and tail the head and tail of a Prolog list.
int SP_get_arg(int i, SP_term_ref t, SP_term_ref arg)
Assigns to arg the i:th argument of a Prolog compound term. This is similar to calling arg/3 with the third argument unbound.