12.4.3 Analysing Terms via the Foreign Interface
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
      • Foreign Language Interface
        • The Foreign Include File
          • Analysing Terms via the Foreign Interface
            • Testing the type of a term
            • Reading data from a term
            • Exchanging text using length and string
            • Wide-character versions
            • Reading a list
            • Processing option lists and dicts
              • PL_scan_options()
            • An example: defining write/1 in C
    • Packages

12.4.3.6 Processing option lists and dicts

int PL_scan_options(term_t options, int flags, const char* opttype, PL_option_t specs[], ...)
Process an option list as we find with, e.g., write_term/2 and many other builtin predicates. This function takes an option list (or dict) and in the variadic argument list pointers that receive the option values. PL_scan_options() takes care of validating the list, ensuring the list is not cyclic, validating the option type and storing the converted values using the supplied pointers.

Below is an example. While PL_option_t is a struct, its members are initialised using the PL_OPTION() macro. The data structure is not constant because PL_scan_options() adds the option names as atoms to speed up option processing. The macro PL_OPTIONS_END terminates the option list.

static PL_option_t mypred_options[] =
{ PL_OPTION("quoted",   OPT_BOOL),
  PL_OPTION("length",   OPT_SIZE),
  PL_OPTION("callback", OPT_TERM),
  PL_OPTIONS_END
};

static foreign_t
mypred(term_t a1, term_t options)
{ int    quoted   = FALSE;
  size_t length   = 10;
  term_t callback = 0;

  if ( !PL_scan_options(options, 0, "mypred_options", mypred_options,
                        &quoted, &length, &callback) )
    return FALSE;

  <implement mypred>
}

The only defined value for flags is currently OPT_ALL, which causes this function to raise a domain error if an option is passed that is not in specs. Default in SWI-Prolog is to silently ignore unknown options, unless the Prolog flag iso is true. The opttype argument defines the type (group) of the options, e.g., "write_option". Option types are defined by the ISO standard. SWI-Prolog only uses this if OPT_ALL is specified, to raise a domain_error of the indicated type if some option is unused. The type name is normally the name of the predicate followed by _option or the name of a representative of a group of predicates to which the options apply.

Defined option types and their corresponding pointer type are described below.

OPT_BOOL int
Convert the option value to a bool. This converts the values described by PL_get_bool(). In addition, an option without a value (i.e., a plain atom that denotes the option name) can act as a boolean TRUE.
OPT_INT int
OPT_INT64 int64_t
OPT_UINT64 uint64_t
OPT_SIZE size_t
OPT_DOUBLE double
Numeric values of various types. Raises an error if the Prolog value cannot be represented by the C type.
OPT_STRING char*
Uses PL_get_chars() using the flags CVT_ALL|REP_UTF8|BUF_STACK|CVT_EXCEPTION. The buffered string must be guarded using PL_STRINGS_MARK() and PL_STRINGS_RELEASE().
OPT_ATOM atom_t
Accepts an atom. Note that if the C function that implements the predicate wishes to keep hold of the atom after it returns it must use PL_register_atom().
OPT_TERM term_t
Accepts an arbitrary Prolog term. The term handle is scoped by the foreign predicate invocation. Terms can be preserved using PL_record().

The ISO standard demands that if an option is repeated the last occurance holds. This implies that PL_scan_options() must scan the option list to the end.