/*------------------------ VIS_LIST.TXT ------------------------*/
/*                                                              */
/*  This file contains the VISIONS List Library Manual          */
/*                                                              */
/*         Copyright 1990 Dan Vogel & David Bernazzani          */
/*                                                              */
/*   Date        Initials        Comments                       */
/*                                                              */
/*  03/13/90       DCV       Initial Release 0.00.              */
/*--------------------------------------------------------------*/

                        Overview


   The VISIONS list library is a simple library, written in C, to 
provide generic list handling on PC/XT/AT class machines.  The library was 
originally written in Microsoft C 5.1.  The VISIONS list library uses 
the VISIONS Window library.
   The list library, although simple, provides the programmer an easy way 
of handling lists of any type of data structure.  The list library provides 
the programmer with the ability to create lists, sort lists, add items to 
lists, remove items from lists, and display list items.  All this is done 
with a minimum of programmer knowledge of the actual structure of the list.  
In fact, the definition of the list structure is not made available to the 
library user, in order to abstract away these complications.




                        Theory of Operation


   While it is not necessary for the programmer to know the details of the 
list structure, a brief description of this structure will help to explain 
some of the list routines.  A list is composed of three separate structures 
in VISIONS, a list head, list links, and list elements.  A list head is used 
to define the start of a list as well as some of the operations that may be 
performed upon this list.  A list link is a pointer structure used to connect 
list elements together in a doubly linked chain.  Finally a list element is 
the data of which the programmer wishes to create a list.  The list 
element(s) may be any type of data, although all data is treated as an 
unsigned character pointer by VISIONS.  The list head and list links 
are never directly manipulated by the programmer, only by VISIONS, although 
the programmer must keep a pointer reference to define the list he wishes to 
operate upon at any given time.  A list might appear as below:

   LIST_HEAD:
   +------------+
   |List delete |
   |List compare|
   |List display|
   |List Pointer|-----+
   +------------+     |  LIST_LINK:         LIST_LINK:
                      +->+--------+         +--------+
                         |Next    |-------->|Next    |----> etc.
                  NULL<--|Last    |<--------|Last    |
                         |Element |--+      |Element |--+
                         +--------+  |      +--------+  |
                                     |                  |
                                     |  ELEMENT:        |  ELEMENT:
                                     +->+------+        +->+------+
                                        |"One" |           |"Two" |
                                        +------+           +------+

  Storage for list heads and list links is allocated from the heap.  Thus 
a list's maximum length is bounded by the availability of heap storage, 
not by the size of any preallocated array.  Since list links may be 
frequently allocated and deallocated, the VISIONS list library performs its 
own garbage collection for list links.  This allows previously allocated and 
deallocated list links to be reused without be returned to the heap.  This 
helps prevents extreme memory fragmentation.
   The following is a brief overview of the operation of the list 
library routines.  This is intended to help the user to understand 
the library's operation better, so that it may be used more effectively.  
One key point to remember in reviewing these routines is that list elements 
are almost always manipulated by list link pointers, not by pointers to the 
actual list elements.  As an example, using the VISIONS routine ListTop of 
the above list structure would return a pointer to the first list link (which 
in turn points to the first element "One"), not to the the first list 
element.  Once your list manipulation is complete, you may recover your list 
element data by using the routine GetListItem.  This abstracts list 
manipulation apart from data manipulation.

   The VISIONS list system is intended to create and use lists of any type 
of items.  List functions may be broken up into the following groups.

   List Definition:
        DefineList - Define a list header with operations that may be
                     performed on the list.

   List Building:
        AddToList  -   Add an element to the list before the passed list 
                       link pointer.
        AppendToList - Append a new element to th eend of the list.

   List Item Selection:
        FindInList - Find the list link associated with a list element.
        ListBottom - Return pointer to list link at end of list.
        ListLast   - Return pointer to list link preceeding passed link.
        ListNext   - Return pointer to list link following passed link.
        ListNth    - Return pointer to nth list link in list.
        ListTop    - Return poiinter to list link at start of list.

   List Display:
        DisplayList     - Display all elements in passed list in the 
                          define window, as formatted by list display 
                          routine.
        DisplayListItem - Format a list element into a buffer for display.

   List Deletion:
        DeleteList     - Delete a list and all of its contents.
        DeleteFromList - Delete a list link and it element from its list.

   List Miscellaneous:
        CountList      - Count the number of elements in the passed list.
        GetListItem    - Return a pointer to the list element held by the 
                         passed list link.
        RemoveFromList - Remove a list link and its element from its list 
                         without deleting the element.  The link is returned 
                         to free memory.
        SortList       - Sort a list according to a passed comparison 
                         routine.


  The next section defines these routines in greater detail.



                        Routine Definitions

   In order to use the below routines you must include the file 
"USERLIST.H" in your source code with the following statement.

                #include "USERLIST.H"

This will automatically include the window definitions files at the 
same time.  Examples of the use of these routines are available in the 
VISIONS demonstration program, in the file DEMOLIST.C.






/*------------------------------------------------------------------------*/
                        AddToList

Purpose:  This routine inserts a new item into the current list before 
  the list item pointer passed.

Calling Sequence: 
   status = AddToList(list_root, list_ptr, new_item);

Inputs:
   LIST_HEAD *list_root;  - This is the head of the list added to.

   LIST_LINK *list_ptr;  - This is a pointer to insert the item before.

   unsigned char *new_item;  - This is a pointer to the item to be inserted 
 in the list.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        BAD_LINK_PTR    Pointer to link passed is invalid.
        <others>        As returned by called routines.

Functions called:
   AllocateLink.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        AppendToList

Purpose:  This routine adds an item to the end of the list.

Calling Sequence: 
   status = AppendToList(list_top, new_item);

Inputs:
   LIST_HEAD *list_top;  - This is a pointer to the head of the list to 
append to.

   unsigned char *new_item;  - This is the item to be appended to the list.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   AllocateLink.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        CountList

Purpose:  This routine passes back a count of items in the passed list.

Calling Sequence: 
   status = CountList(list_ptr);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list head to be counted.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        >=0             Success, this is the count of items in the list.
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   ListTop, ListNext.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        DefineList

Purpose:  This routine initializes a new list structure, and allocates 
  space for it.

Calling Sequence: 
   status =  DefineList(new_list,compare_f,delete_f,display_f);

Inputs:
   The following three functions are passed to this routine to be stored 
as part of the list defining the operations that can be performed on this 
list.  These operations include comparing two items in the list, deleting 
a list item, and generating a displayable buffer from a list item.

   int (*compare_f)(unsigned char *,unsigned char *);
   int (*delete_f)(unsigned char *);
   int (*display_f)(unsigned char *,char *);

Outputs:
   LIST_HEAD **new_list;  - This is the head of the new list created.

   int status;  - This is the result of the function.  Possible values are:
           0            Success
        <Others>        As returned by called routines.

Functions called:
   AllocateList.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        DeleteFromList

Purpose:  This routine removes a link from a list, releases the link to 
  the free link list, and passes the link's item pointer to the list delete 
  routine.

Calling Sequence: 
   status = DeleteFromList(list_ptr, remove_item);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list to remove the 
        item from.

   unsigned char *remove_item;  - This is a pointer to the item to be deleted
        from the list.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   FindInList,  <list delete routine>.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        DeleteList

Purpose:  This routine deletes an entire list, releasing its storage 
 back to the heap.

Calling Sequence: 
   status = DeleteList(del_list);

Inputs:
   LIST_HEAD *del_list;  - This is a pointer to the list to be 
        deleted.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   ListTop,  DeleteFromList.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        DisplayList

Purpose:  This routine displays the passed list in the specified window.

Calling Sequence: 
   status = DisplayList(topy, col, height, width, bkcol, txtcol, border, 
                title, d_list)

Inputs:
   BYTE topy, col, height, width;  - These are the coordinates of the window 
        in which to display the list.

   long int bkcol, txtcol;  - These are the colors to use for the window.

   BYTE border;  - This is the border type to use (NOBORDER,SINGLEBORDER,
        or DOUBLEBORDER).

   char *title;  - This is the title to display in the window (or NULL).

   LIST_HEAD *d_list;  - This is a pointer to the list to be displayed.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   DefineWindow,  DisplayWindow,  ListTop,  ListNext,  DisplayListItem,  
   WindMesg,  RemoveWindow,  DeleteWindow.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        DisplayListItem

Purpose:  This routine generates a displayable buffer of the item in the 
 passed list link pointer using the list's display routine.

Calling Sequence: 
   status = DisplayListItem(list_ptr, disp_link, buffer);

Inputs:
   LIST_HEAD *list_ptr;  - This is the list containing the item to be 
        displayed.

   LIST_LINK *disp_link;  - This is the link of the item to be displayed.

Outputs:
   char *buffer;  - This is the buffer in which the displayable string 
        is placed.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        BAD_LINK_PTR    Pointer to link passed is invalid.
        <others>        As returned by called routines.

Functions called:
   <list display function>

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        FindInList

Purpose:  This routine finds the list pointer in a list that holds the 
 passed item pointer.

Calling Sequence: 
   status = FindInList(list_ptr, find_item, list_fnd);

Inputs:
   LIST_HEAD *list_ptr;  - This is the list to be searched.

   unsigned char *find_item;  - This is the item to be found.

Outputs:
   LIST_LINK **list_fnd;  - This is a pointer to the pointer to the 
        found item.

   int status;  - This is the result of the function.  Possible values are:
        0                       Success
        LIST_ITEM_NOT_FOUND     Didn't find the item in the list.
        BAD_HEAD_PTR            Pointer to list passed is invalid.
        <others>                As returned by called routines.

Functions called:
   ListTop,  ListNext.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        GetListItem

Purpose:  This routine returns a pointer to the item contained in the passed 
 list link.

Calling Sequence: 
   status = GetListItem(list_ptr, new_item);

Inputs:
   LIST_LINK *list_ptr;  - This is a pointer to the list link to get the 
        item pointer from.

Outputs:
   unsigned char **new_item;  - This is a pointer to the pointer to hold the
        returned item pointer.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_LINK_PTR    Pointer to link passed is invalid.
        <others>        As returned by called routines.

Functions called:
   None.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        ListBottom

Purpose:  This routine passes back a pointer to the last link in the
  passed list.

Calling Sequence: 
   status = ListBottom(list_ptr, bot_link);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list head.

Outputs:
   LIST_LINK **bot_link;  - This is the returned pointer to the last
        element of the passed list.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   ListTop, ListNext.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        ListLast

Purpose:  This routine passes back a pointer to the previous link in the
  passed list.

Calling Sequence: 
   status = ListLast(curr_link, last_link);

Inputs:
   LIST_LINK *curr_link;  - This is a pointer to the current link.

Outputs:
   LIST_LINK **last_link;  - This is the returned pointer to the link 
        preceeding the current link.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_LINK_PTR    Pointer to link passed is invalid.
        <others>        As returned by called routines.

Functions called:
   None.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        ListNext

Purpose:  This routine passes back a pointer to the next link in the
  passed list.

Calling Sequence: 
   status = ListNext(curr_link, next_link);

Inputs:
   LIST_LINK *curr_link;  - This is a pointer to the current link.

Outputs:
   LIST_LINK **next_link;  - This is the returned pointer to the link 
        following the current link.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_LINK_PTR    Pointer to link passed is invalid.
        <others>        As returned by called routines.

Functions called:
   None.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        ListNth

Purpose:  This routine passes back a pointer to the nth link in the
  passed list, where n ranges from 0 to the number of items in the list 
  minus 1.

Calling Sequence: 
   status = ListNth(list_ptr, list_num, ret_link);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list head.

   int list_num;  - This is the number of the desired item in the list.

Outputs:
   LIST_LINK **ret_link;  - This is the returned pointer to the nth element.

   int status;  - This is the result of the function.  Possible values are:
        0               Success
        LIST_TOO_SHORT  List is not long enough!
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   ListTop,  ListNext.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        ListTop

Purpose:  This routine passes back a pointer to the first link in the
  passed list.

Calling Sequence: 
   status = ListTop(list_ptr, top_link);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list head.

Outputs:
   LIST_LINK **top_link;  - This is the returned pointer to the first
        element of the passed list.

   int status;  - This is the result of the function.  Possible values are:
        0                Success
        BAD_HEAD_PTR     Pointer to list passed is invalid.

Functions called:
   None.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        RemoveFromList

Purpose:  This routine removes a link from a list, and releases the link to 
  the free link list.

Calling Sequence: 
   status = RemoveFromList(list_ptr, remove_item);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list to remove the 
        item from.

   unsigned char *remove_item;  - This is a pointer to the item to be 
        removed from the list.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0               Success
        BAD_HEAD_PTR    Pointer to list passed is invalid.
        <others>        As returned by called routines.

Functions called:
   FindInList.

/*------------------------------------------------------------------------*/




/*------------------------------------------------------------------------*/
                        SortList

Purpose:  This routine does a bubble sort of the passed list based upon the 
 passed comparison function.

Calling Sequence: 
   status = SortList(list_ptr,compare_f);

Inputs:
   LIST_HEAD *list_ptr;  - This is a pointer to the list head to be sorted.

   int (*compare_f)(unsigned char *,unsigned char *);  - This is the 
        comparison function to be used in the sort.  It must return 
        <0 if first argument should preceed second, =0 for two items are 
        equal, and >0 for first item should follow second.

Outputs:
   int status;  - This is the result of the function.  Possible values are:
        0                Success
        BAD_HEAD_PTR     Pointer to list passed is invalid.

Functions called:
   ListTop,  ListNext,  <passed comparison function>

/*------------------------------------------------------------------------*/






                        Error Codes

   The following is the list of error codes that can be returned from the 
VISIONS list library.  Errors from calls to the windows library will be 
passed back unchanged.  These error values can be found in the VISIONS 
window manual.

Error Name              Value       Description.

BAD_LINK_PTR             -11        Pointer to list link is bad.
BAD_HEAD_PTR             -12        Pointer to list head is bad.

UNABLE_TO_ALLOCATE_LINK  -21        Out of heap for link allocation.
UNABLE_TO_ALLOCATE_LIST  -22        Out of heap for head allocation.
LIST_TOO_SHORT           -23        List is shorter than needed item number.
LIST_ITEM_NOT_FOUND      -24        Item not found in passed list.

                                                                                                        