1997-10-30 21:05:56 +03:00
/* ========================================================================== **
* ubi_sLinkList . c
*
1998-03-10 18:39:41 +03:00
* Copyright ( C ) 1997 , 1998 by Christopher R . Hertel
1997-10-30 21:05:56 +03:00
*
* Email : crh @ ubiqx . mn . org
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
1998-03-10 18:39:41 +03:00
* This module implements a simple singly - linked list .
1997-10-30 21:05:56 +03:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation ; either
* version 2 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free
* Software Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*
2000-06-08 21:42:20 +04:00
* Log : ubi_sLinkList . c , v
* Revision 0.10 1999 / 06 / 19 16 : 58 : 06 crh
* Renamed the ubi_slRemove ( ) function in ubi_sLinkList to
* ubi_slRemoveNext ( ) . I was bothered by the fact that it didn ' t
* match the functionality of the ubi_dlRemove ( ) function in
* ubi_dLinkList . The new name is more ' correct ' .
*
1998-07-24 11:39:14 +04:00
* Revision 0.9 1998 / 07 / 24 07 : 30 : 20 crh
* Added the ubi_slNewList ( ) macro .
*
1998-06-25 04:22:48 +04:00
* Revision 0.8 1998 / 06 / 04 21 : 29 : 27 crh
* Upper - cased defined constants ( eg UBI_BINTREE_H ) in some header files .
* This is more " standard " , and is what people expect . Weird , eh ?
*
1998-06-04 01:38:51 +04:00
* Revision 0.7 1998 / 06 / 03 18 : 06 : 03 crh
* Further fiddling with sys_include . h , which has been moved from the . c file
* to the . h file .
*
1998-06-02 07:27:16 +04:00
* Revision 0.6 1998 / 06 / 02 01 : 38 : 47 crh
* Changed include file name from ubi_null . h to sys_include . h to make it
* more generic .
*
1998-05-21 21:14:20 +04:00
* Revision 0.5 1998 / 05 / 20 04 : 38 : 05 crh
* The C file now includes ubi_null . h . See ubi_null . h for more info .
*
1998-03-10 18:39:41 +03:00
* Revision 0.4 1998 / 03 / 10 02 : 23 : 20 crh
* Combined ubi_StackQueue and ubi_sLinkList into one module . Redesigned
* the functions and macros . Not a complete rewrite but close to it .
*
* Revision 0.3 1998 / 01 / 03 01 : 59 : 52 crh
* Added ubi_slCount ( ) macro .
*
1997-10-30 21:05:56 +03:00
* Revision 0.2 1997 / 10 / 21 03 : 35 : 18 crh
* Added parameter < After > in function Insert ( ) . Made necessary changes
* to macro AddHead ( ) and added macro AddHere ( ) .
*
* Revision 0.1 1997 / 10 / 16 02 : 53 : 45 crh
* Initial Revision .
*
1998-03-10 18:39:41 +03:00
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
* This module implements a singly - linked list which may also be used as a
* queue or a stack . For a queue , entries are added at the tail and removed
* from the head of the list . For a stack , the entries are entered and
* removed from the head of the list . A traversal of the list will always
* start at the head of the list and proceed toward the tail . This is all
* mind - numbingly simple , but I ' m surprised by the number of programs out
* there which re - implement this a dozen or so times .
*
1998-07-24 11:39:14 +04:00
* Note : When the list header is initialized , the Tail pointer is set to
* point to the Head pointer . This simplifies things a great deal ,
* except that you can ' t initialize a stack or queue by simply
* zeroing it out . One sure way to initialize the header is to call
* ubi_slInit ( ) . Another option would be something like this :
*
* ubi_slNewList ( MyList ) ;
*
* Which translates to :
1998-03-10 18:39:41 +03:00
*
1998-07-24 11:39:14 +04:00
* ubi_slList MyList [ 1 ] = { NULL , ( ubi_slNodePtr ) MyList , 0 } ;
1998-03-10 18:39:41 +03:00
*
1998-07-24 11:39:14 +04:00
* See ubi_slInit ( ) , ubi_slNewList ( ) , and the ubi_slList structure
* for more info .
1998-03-10 18:39:41 +03:00
*
* + Also , note that this module is similar to the ubi_dLinkList
* module . There are three key differences :
* - This is a singly - linked list , the other is a doubly - linked
* list .
* - In this module , if the list is empty , the tail pointer will
* point back to the head of the list as described above . This
* is not done in ubi_dLinkList .
2000-06-08 21:42:20 +04:00
* - The ubi_slRemoveNext ( ) function , by necessity , removes the
* ' next ' node . In ubi_dLinkList , the ubi_dlRemove ( ) function
* removes the ' current ' node .
1998-03-10 18:39:41 +03:00
*
1997-10-30 21:05:56 +03:00
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = * *
*/
1998-05-21 21:14:20 +04:00
# include "ubi_sLinkList.h" /* Header for *this* module. */
1997-10-30 21:05:56 +03:00
/* ========================================================================== **
* Functions . . .
*/
ubi_slListPtr ubi_slInitList ( ubi_slListPtr ListPtr )
/* ------------------------------------------------------------------------ **
* Initialize a singly - linked list header .
*
* Input : ListPtr - A pointer to the list structure that is to be
* initialized for use .
*
* Output : A pointer to the initialized list header ( i . e . , same as
* < ListPtr > ) .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*/
{
ListPtr - > Head = NULL ;
1998-03-10 18:39:41 +03:00
ListPtr - > Tail = ( ubi_slNodePtr ) ListPtr ;
1997-10-30 21:05:56 +03:00
ListPtr - > count = 0 ;
return ( ListPtr ) ;
} /* ubi_slInitList */
ubi_slNodePtr ubi_slInsert ( ubi_slListPtr ListPtr ,
ubi_slNodePtr New ,
ubi_slNodePtr After )
/* ------------------------------------------------------------------------ **
1998-03-10 18:39:41 +03:00
* Add a node to the list .
1997-10-30 21:05:56 +03:00
*
* Input : ListPtr - A pointer to the list into which the node is to
* be inserted .
* New - Pointer to the node that is to be added to the list .
* After - Pointer to a list in a node after which the new node
* will be inserted . If NULL , then the new node will
* be added at the head of the list .
*
* Output : A pointer to the node that was inserted into the list ( i . e . ,
* the same as < New > ) .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*/
{
1998-03-10 18:39:41 +03:00
After = After ? After : ( ubi_slNodePtr ) ListPtr ;
New - > Next = After - > Next ;
After - > Next = New ;
if ( ! ( New - > Next ) )
ListPtr - > Tail = New ;
( ListPtr - > count ) + + ;
1997-10-30 21:05:56 +03:00
return ( New ) ;
} /* ubi_slInsert */
2000-06-08 21:42:20 +04:00
ubi_slNodePtr ubi_slRemoveNext ( ubi_slListPtr ListPtr , ubi_slNodePtr AfterMe )
1997-10-30 21:05:56 +03:00
/* ------------------------------------------------------------------------ **
2000-06-08 21:42:20 +04:00
* Remove the node followng < AfterMe > . If < AfterMe > is NULL , remove from
* the head of the list .
1997-10-30 21:05:56 +03:00
*
* Input : ListPtr - A pointer to the list from which the node is to be
* removed .
2000-06-08 21:42:20 +04:00
* AfterMe - Pointer to the node preceeding the node to be
1998-03-10 18:39:41 +03:00
* removed .
1997-10-30 21:05:56 +03:00
*
1998-03-10 18:39:41 +03:00
* Output : A pointer to the node that was removed , or NULL if the list is
* empty .
1997-10-30 21:05:56 +03:00
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * *
*/
{
1998-03-10 18:39:41 +03:00
ubi_slNodePtr DelNode ;
1997-10-30 21:05:56 +03:00
2000-06-08 21:42:20 +04:00
AfterMe = AfterMe ? AfterMe : ( ubi_slNodePtr ) ListPtr ;
DelNode = AfterMe - > Next ;
1998-03-10 18:39:41 +03:00
if ( DelNode )
1997-10-30 21:05:56 +03:00
{
1998-03-10 18:39:41 +03:00
if ( ! ( DelNode - > Next ) )
2000-06-08 21:42:20 +04:00
ListPtr - > Tail = AfterMe ;
AfterMe - > Next = DelNode - > Next ;
1998-03-10 18:39:41 +03:00
( ListPtr - > count ) - - ;
1997-10-30 21:05:56 +03:00
}
1998-03-10 18:39:41 +03:00
return ( DelNode ) ;
2000-06-08 21:42:20 +04:00
} /* ubi_slRemoveNext */
1997-10-30 21:05:56 +03:00
/* ================================ The End ================================= */