@deffn Typedef slist
@fnindex slist

The minimum fields which must be present in a structure which
will be manipulated by these functions.

@end deffn

@deftypefn Typedef int slist_cmp_func slist_cmp_func(slist *t@var{try}, slist *r@var{refer})
@fnindex slist_cmp_func


The type of function used by @code{slist_get()} to compare list elements.

@end deftypefn

@deftypefn Typedef void slist_delete_func slist_delete_func(slist *n@var{node})
@fnindex slist_delete_func


The type of function used by @code{slist_delete()} to recycle list elements.

@end deftypefn

@deffn Macro  slist_cons (h@var{head}, t@var{tail})
@fnindex slist_cons


@var{tail} is linked into the %next pointer of @var{head}.


The new @var{head} is returned.

@end deffn

@deffn Macro  slist_new (h@var{head})
@fnindex slist_new


@@tail is linked into the %next pointer of @var{head}.


The new @var{head} is returned.

@end deffn

@deftypefn Function void slist_delete (slist *list, slist_delete_func *d@var{delfunc})
@fnindex slist_delete


@var{delfunc} is called with each element of @var{head} in turn, and is
assumed to recycle the contents of each node before it returns.

@end deftypefn

@deffn Macro NIL
@fnindex NIL

Use NIL to denote the empty list, to avoid confusion with other
0 valued pointers.

@end deffn

@deffn Macro  slist_hhead (h@var{head})
@fnindex slist_head



The address of the head of the list @var{head}  is returned,
unless @var{head} is %NIL, when NULL is returned.

@end deffn

@deffn Macro  slist_tail (h@var{head})
@fnindex slist_tail



The address of the head of a list which begins with the node
directly following @var{head} is returned, unless @var{head} is %NIL,
when NULL is returned.

@end deffn

@deftypefn Function slist* slist_reverse (slist *h@var{head})
@fnindex slist_reverse


The tails of each of the nodes in @var{head} are destructively reordered
to point to the preceding node.  This reverses the order of the %next
pointers in the list.


The new head of the list, formerly the last cons cell in @var{head}, is
returned.  Under normal circumstances, @var{head} now points to the new end
of the list, and should be reassigned to the return value of this function.

@smallexample
head = slist_reverse(head);
@end smallexample
@end deftypefn

@deftypefn Function slist* slist_nnth (slist *h@var{head}, unnsignned n@var{n})
@fnindex slist_nth



If @var{head} has at least @var{n} cells following, the address
of the @var{n}-th node in @var{head} is returned, otherwise NULL.

@end deftypefn

@deftypefn Function slist* slist_get (slist *h@var{head}, slist *d@var{data}, slist_ccmp_func *c@var{cmp})
@fnindex slist_get


@var{cmp} is called repeatedly until it returns 0 (i.e. @var{cmp} should behave
in a similar fashion to @code{strcmp()}) or until @var{head} is exhausted.  Each call
is made with @var{data}, and the car of the next cons cell in @var{head}, starting
at the beginning of the list.

This is useful to find a particular node based on part of its
contents.  For example, you could store pointers to a structure which
has a key and a data field, and use this function to find the data
associated with the first instance of that key in @var{head}.  Note the careful
use of casting, and that the reference element is both the second parameter
of @code{slist_get()}, and the second parameter passed to @code{cmp()}:

@smallexample
struct cdr @{
    char *key;
    struct data *data;
@};

int
cdrcmp (try, refer)
    struct cdr *try;
    const char *refer;
@{
    return strcmp(try->key, refer);
@}

struct data*
lookup (table, key)
    slist *table;
    char *key;
@{
    return (struct data*)slist_get(table, (ish_pointer)key,
                                     (slist_cmp_func*)cdrcmp);
@}
@end smallexample

If a match was found with @var{cmp}, then the matching node
is returned.  If not, then %NIL is returned.

@end deftypefn

