.so page1.s
.Fc "Linked List Library" 1.3 "3/8/89"
.H 1 Introduction
This document describes the \fIllist\fR linked list library. 
The linked list library is a set of functions for manipulating linked
lists. The implementation tries to hide the actual data structures
from the application, thus allowing improvements in the
underlying implementation without affecting the application itself.
.P
The current implementation uses a linked list structure which
maintains a forward a backward pointer for fast traversal
and deletions, but does not keep a tail pointer. (Thus, appending
nodes to the end of the list are not performed optimally).
.P
The linked list library is a fundamental part of the CRISP
programming editor.
.P
The linked list library is ideally suitable to applications
which require the common operations of a FIFO data structure,
eg stacks. 
which it is being used for, ie the CRISP editor.
.P
If high performance random access is needed, then the splay tree
library ([1]) may be a better alternative library to use.
.H 2 References
.RL
.LI
Splay Tree Library, version 1.1. P. Fox, 14 September 1988.
.LE
.H 1 Overview
The linked list library is a set of functions for manipulating linked
lists (FIFO). The management of the linked list is separated from
the data being stored in the list, thus allowing the implementation
to be modified in an upwards compatible manner.
.P
The functions available for the linked list library are 
specified in this document in the form of manual pages.
.P
The following generic capabilities are provided for
in the library:
.AL
.LI
Creating a new list.
.LI
Adding new entries to a list, at the beginning, end or arbitrary
position in the middle.
.LI
Clearing and deleting entries in the list.
.LI
Treating the list as a stack.
.LI
Searching the list for an entry.
.LE
.P
.H 2 "Compiling and Linking"
The 
.I llist
library comes with a \fImakefile\fR for building on the
following operating systems:
.AL a
.LI
Xenix 386
.LI
Xenix 286
.LI
IBM 6150 running AIX
.LI
Microport System V.2/286
.LI
Microport System V.3/386
.LI
SunOS 3.x/4.x
.LE
This \fImakefile\fR creates the file \fIllist.a\fR. This file should
be placed in some convenient place on your system (eg /lib or /usr/lib).
.P
All C programs should contain the following line:
.DS I
# include    "llist.h"
.DE
.H 2 Warning
The 
.I llist 
library makes use of the functions
.I chk_alloc(),
and
.I chk_free().
These are part of the 
.I foxlib.a
library. If you do not have access to these functions, simply
#define 
.I chk_alloc 
as
.I malloc,
and 
.I chk_free
as
.I free.
.H 1 "Data Structures"
The 
.I llist.h
include file defines two typedef's -
.I Head_p
and
.I List_p.
The
.I Head_p
structure is used to contain the information for pointing to the
head of a linked list. The information in this structure is initialised
with the 
.I ll_init()
function.
.P
.I List_p
is used to refer to actual entries in the linked list.
.P
None of the fields in these structures are directly accessible
by the application. Access to the application private data structures
are controlled by functions in the 
.I llist 
library. This provides a form of data-hiding abstraction, common
to object oriented programming systems.
.bp
.Fo Name
ll_append, ll_insert - insert an entry at the end of a list or at a specific position
.Fo Synopsis
.DS
\f(CW
# include	"llist.h"

List_p	ll_append(Head_p head, char *data);
List_p	ll_insert(Head_p head, char *data, int position);
\fR
.DE
.Fo Description
.I ll_append()
takes the data structure pointed to by
.I data,
allocates space for a new linked-list node, and appends it to the
list pointed to by 
.I head. It returns the a pointer to the linked list element allocated
to contain
.I data.
.I ll_append()
is a special case of 
.I ll_insert()
and is equivalent to 
\fIll_insert(head, data, 32767);\fR.
.P
.I ll_insert()
is used to create a new linked list element, and insert it at a specific
position in the list pointed to by
.I head.
.Fo Examples
The following example is the equivalent to the 
.I ll_push()
operation:
.DS
\f(CW
Head_p	head;
struct mydata fred;

ll_insert(head, (char *) &fred, 0);
\fR
.DE
.Fo Bugs
If the parameter
.I position
to 
.I ll_insert()
is before the beginning or after the end of the list, then the item
will be inserted at the beginning of the list or at the end of the
list, respectively, without any error indication.
.P
Making
.I ll_append()
perform an 
.I ll_insert()
at the 32767th position relies on the above bug, and limits lists
to no more than 32767 elements.
.bp
.Fo Name
ll_clear - delete all entries in a linked list.
.Fo Synopsis
.DS
\f(CW
# include    "llist.h"

void ll_clear(Head_p head);
\fR
.DE
.Fo Description
.I ll_clear
deletes all entries in the list pointed to by head. It frees
the memory associated with each element in the list; note that it
performs a
.I chk_free()
on the data associated with each element of the list. If the data
associated with each element has not been previously allocated via
.I chk_alloc(),
then 
.I ll_clear()
should not be called.
.bp
.Fo Name
ll_delete - remove an element from a list.
.Fo Synopsis
.DS
\f(CW
# include    "llist.h"

void ll_delete(List_p element);
\fR
.DE
.Fo Description
.I ll_delete
deletes the entry
.I element
from the linked list in which it is located.
It does not free the memory associated with the users data (contrast
with 
.I ll_clear).
.P
Note that the head of the linked list is not necessary for this
function, since
.I ll_delete
can ascertain to which list 
.I element
belongs from the information in the list element itself.
.Fo Examples
The following example deletes the first entry in a linked list:
.DS I
\f(CW
Head_p	head;
List_p	lp;

lp = ll_first(head);
ll_delete(lp);
\fR
.DE
.bp
.Fo Name
ll_elem - return the data associated with a linked list element
.Fo Synopsis
.DS
\f(CW
# include    "llist.h"

char *ll_elem(List_p element);
\fR
.DE
.Fo Description
.I ll_elem
returns the data associated with a particular linked list element.
This function is necessary to hide the implementation details
of the
.I Head_p
and 
.I List_p
structures.
.P
Note that the function returns a generic 
\fIchar *\fR
type, and that the value returned by this function will probably
need casting to the appropriate type.
.Fo Bugs
This function should really return a \fIvoid *\fR.
.bp
.Fo Name
ll_first, ll_next, ll_prev - return first, next or previous element in a list
.Fo Synopsis
.DS
\f(CW
# include    "llist.h"

List_p	ll_first(Head_p head);

List_p	ll_next(List_p element);

List_p	ll_prev(List_p element);
\fR
.DE
.Fo Description
.I ll_first
returns a pointer to the first element in a linked list; it returns
NULL if the list is empty. Note that the argument is a pointer to the
head entry for the list.
.P
.I ll_next
returns a pointer to the next element in a list, given an arbitrary
pointer to an element in the list. It returns NULL if there is no
element after the designated entry.
.I ll_prev
returns a pointer to the preceeding entry in the list; it returns NULL
if the specified element is the first element in the list.
.Fo Example
The following code can be used to walk down each element in the list:
.DS
\f(CW
Head_p head;
List_p lp;

for (lp = ll_first(head); lp; lp = ll_next(lp)) {
	char *data = ll_elem(lp);
	  .
	  .
	}
\fR
.DE
.bp
.Fo Name
ll_init - create a new linked list.
.Fo Synopsis
.DS
\f(CW
# include	"llist.h"

Head_p	ll_init();
\fR
.DE
.Fo Description
.I ll_init 
is used to create a new head entry for a linked list. This function
must be called before any other linked list functions may be applied
to the list.
.bp
.Fo Name
ll_lookup - scan a list looking for a particular element.
.Fo Synopsis
.DS
\f(CW
# include	"llist.h"

List_p	ll_lookup(Head_p head, char *key, (int (*)()) func);
\fR
.DE
.Fo Description
.I ll_lookup()
is used to walk down a linked list, checking each element it visits
to see if it contains the 
key
.I key.
.I key
is an arbritrary data type which is passed as one of the parameters
to
.I func.
.P
.I func
is a function, similar to 
.I strcmp()
in nature, and is a function defined by the user for the purposes of
performing a key comparison with each element visited. 
.I func
should return 0 if they keys match, and non-zero if the keys do not match.
.I func
is called with the first parameter equal to
.I key, 
and the second parameter containing the
.I ll_elem()
value of the linked list entry being visited.
.P
.I ll_lookup()
returns the linked list element of the first entry matching the
.I key,
or NULL if no elements contain 
.I key.
.bp
.Fo Name
ll_push, ll_pop - emulate a stack functions.
.Fo Synopsis
.DS
\f(CW
# include	"llist.h"

char	*ll_push(Head_p head, char *data);
List_p	ll_pop(Head_p);

\fR
.DE
.Fo Description
.I ll_push()
takes
.I data,
allocates a new linked list element for it and inserts
it at the front of the list pointed to by 
.I head.
It returns 
.I data.
.P
.I ll_pop()
unhooks the first element of the list pointed to by
.I head,
and performs an 
.I ll_delete()
operation on that entry. It returns the new first entry in the list.
It is alright to perform an
.I ll_pop()
on a list with no elements in it.
.Fo Example
The following example removes all entries from a list in FIFO order:
.DS 
\f(CW
Head_p head;
List_p lp;

while ((lp = ll_pop(head)) != NULL) {
	/* Do something with lp */
	  .
	  .
	}
\fR
.DE
.TC
